+#define ROL32(a, offset) (((a) << (offset)) | ((a) >> ((32 - (offset)) & 31)))
+
+static uint64_t ROL64(uint64_t val, int offset)
+{
+ if (offset == 0) {
+ return val;
+ } else if (sizeof(void *) == 8) {
+ return (val << offset) | (val >> (64-offset));
+ } else {
+ uint32_t hi = (uint32_t)(val >> 32), lo = (uint32_t)val;
+
+ if (offset & 1) {
+ uint32_t tmp = hi;
+
+ offset >>= 1;
+ hi = ROL32(lo, offset);
+ lo = ROL32(tmp, offset + 1);
+ } else {
+ offset >>= 1;
+ lo = ROL32(lo, offset);
+ hi = ROL32(hi, offset);
+ }
+
+ return ((uint64_t)hi << 32) | lo;
+ }
+}
+
+static const unsigned char rhotates[5][5] = {
+ { 0, 1, 62, 28, 27 },
+ { 36, 44, 6, 55, 20 },
+ { 3, 10, 43, 25, 39 },
+ { 41, 45, 15, 21, 8 },
+ { 18, 2, 61, 56, 14 }
+};
+
+static const uint64_t iotas[] = {
+ sizeof(void *) == 8 ? 0x0000000000000001U : 0x0000000000000001U,
+ sizeof(void *) == 8 ? 0x0000000000008082U : 0x0000008900000000U,
+ sizeof(void *) == 8 ? 0x800000000000808aU : 0x8000008b00000000U,
+ sizeof(void *) == 8 ? 0x8000000080008000U : 0x8000808000000000U,
+ sizeof(void *) == 8 ? 0x000000000000808bU : 0x0000008b00000001U,
+ sizeof(void *) == 8 ? 0x0000000080000001U : 0x0000800000000001U,
+ sizeof(void *) == 8 ? 0x8000000080008081U : 0x8000808800000001U,
+ sizeof(void *) == 8 ? 0x8000000000008009U : 0x8000008200000001U,
+ sizeof(void *) == 8 ? 0x000000000000008aU : 0x0000000b00000000U,
+ sizeof(void *) == 8 ? 0x0000000000000088U : 0x0000000a00000000U,
+ sizeof(void *) == 8 ? 0x0000000080008009U : 0x0000808200000001U,
+ sizeof(void *) == 8 ? 0x000000008000000aU : 0x0000800300000000U,
+ sizeof(void *) == 8 ? 0x000000008000808bU : 0x0000808b00000001U,
+ sizeof(void *) == 8 ? 0x800000000000008bU : 0x8000000b00000001U,
+ sizeof(void *) == 8 ? 0x8000000000008089U : 0x8000008a00000001U,
+ sizeof(void *) == 8 ? 0x8000000000008003U : 0x8000008100000001U,
+ sizeof(void *) == 8 ? 0x8000000000008002U : 0x8000008100000000U,
+ sizeof(void *) == 8 ? 0x8000000000000080U : 0x8000000800000000U,
+ sizeof(void *) == 8 ? 0x000000000000800aU : 0x0000008300000000U,
+ sizeof(void *) == 8 ? 0x800000008000000aU : 0x8000800300000000U,
+ sizeof(void *) == 8 ? 0x8000000080008081U : 0x8000808800000001U,
+ sizeof(void *) == 8 ? 0x8000000000008080U : 0x8000008800000000U,
+ sizeof(void *) == 8 ? 0x0000000080000001U : 0x0000800000000001U,
+ sizeof(void *) == 8 ? 0x8000000080008008U : 0x8000808200000000U
+};