#include #include "siphash.h" #if defined(_MSC_VER) #include #define INLINE __forceinline #define NOINLINE __declspec(noinline) #define ROTL64(a,b) _rotl64(a,b) #define MM16 __declspec(align(16)) typedef unsigned int uint32_t; typedef unsigned __int64 uint64_t; #if (_MSC_VER >= 1500) #define __SSSE3__ #endif #if (_MSC_VER > 1200) || defined(_mm_free) #define __SSE2__ #endif #else #include #include #define INLINE __attribute__((always_inline)) #define NOINLINE __attribute__((noinline)) #define ROTL64(a,b) (((a)<<(b))|((a)>>(64-b))) #define MM16 __attribute__((aligned(16))) #endif uint64_t siphash(const siphash_key_t *key, const unsigned char *m, size_t len) { uint64_t v0, v1, v2, v3; uint64_t mi, k0, k1; uint64_t last7; size_t i, blocks; k0 = key->key[0]; k1 = key->key[1]; v0 = k0 ^ 0x736f6d6570736575ull; v1 = k1 ^ 0x646f72616e646f6dull; v2 = k0 ^ 0x6c7967656e657261ull; v3 = k1 ^ 0x7465646279746573ull; last7 = (uint64_t)(len & 0xff) << 56; #define sipcompress() \ v0 += v1; v2 += v3; \ v1 = ROTL64(v1,13); v3 = ROTL64(v3,16); \ v1 ^= v0; v3 ^= v2; \ v0 = ROTL64(v0,32); \ v2 += v1; v0 += v3; \ v1 = ROTL64(v1,17); v3 = ROTL64(v3,21); \ v1 ^= v2; v3 ^= v0; \ v2 = ROTL64(v2,32); for (i = 0, blocks = (len & ~7); i < blocks; i += 8) { memcpy(&mi, m + i, sizeof(mi)); v3 ^= mi; sipcompress() sipcompress() v0 ^= mi; } switch (len - blocks) { case 7: last7 |= (uint64_t)m[i + 6] << 48; case 6: last7 |= (uint64_t)m[i + 5] << 40; case 5: last7 |= (uint64_t)m[i + 4] << 32; case 4: last7 |= (uint64_t)m[i + 3] << 24; case 3: last7 |= (uint64_t)m[i + 2] << 16; case 2: last7 |= (uint64_t)m[i + 1] << 8; case 1: last7 |= (uint64_t)m[i + 0] ; case 0: default:; }; v3 ^= last7; sipcompress() sipcompress() v0 ^= last7; v2 ^= 0xff; sipcompress() sipcompress() sipcompress() sipcompress() return v0 ^ v1 ^ v2 ^ v3; }