uint64_t siphash24(const void *src, unsigned long src_sz, const char key[16]) { const uint64_t *_key = (uint64_t *)key; uint64_t k0 = _le64toh(_key[0]); uint64_t k1 = _le64toh(_key[1]); uint64_t b = (uint64_t)src_sz << 56; const uint64_t *in = (uint64_t *)src; uint64_t v0 = k0 ^ 0x736f6d6570736575ULL; uint64_t v1 = k1 ^ 0x646f72616e646f6dULL; uint64_t v2 = k0 ^ 0x6c7967656e657261ULL; uint64_t v3 = k1 ^ 0x7465646279746573ULL; while (src_sz >= 8) { uint64_t mi = _le64toh(RD64p(in)); in += 1; src_sz -= 8; v3 ^= mi; DOUBLE_ROUND(v0, v1, v2, v3); v0 ^= mi; } uint64_t t = 0; uint8_t *pt = (uint8_t *)&t; uint8_t *m = (uint8_t *)in; switch (src_sz) { case 7: pt[6] = m[6]; case 6: pt[5] = m[5]; case 5: pt[4] = m[4]; case 4: *((uint32_t *)&pt[0]) = RD32p(&m[0]); break; case 3: pt[2] = m[2]; case 2: pt[1] = m[1]; case 1: pt[0] = m[0]; } b |= _le64toh(t); v3 ^= b; DOUBLE_ROUND(v0, v1, v2, v3); v0 ^= b; v2 ^= 0xff; DOUBLE_ROUND(v0, v1, v2, v3); DOUBLE_ROUND(v0, v1, v2, v3); return (v0 ^ v1) ^ (v2 ^ v3); }
uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *key) { uint64_t k0 = key->k0; uint64_t k1 = key->k1; uint64_t b = (uint64_t)src_sz << 56; const uint64_t *in = (uint64_t*)src; uint64_t t; uint8_t *pt, *m; uint64_t v0 = k0 ^ 0x736f6d6570736575ULL; uint64_t v1 = k1 ^ 0x646f72616e646f6dULL; uint64_t v2 = k0 ^ 0x6c7967656e657261ULL; uint64_t v3 = k1 ^ 0x7465646279746573ULL; while (src_sz >= 8) { #ifdef UNALIGNED_OK uint64_t mi = _le64toh(*in); #else uint64_t mi; memcpy(&mi, in, 8); mi = _le64toh(mi); #endif in += 1; src_sz -= 8; v3 ^= mi; DOUBLE_ROUND(v0,v1,v2,v3); v0 ^= mi; } t = 0; pt = (uint8_t*)&t; m = (uint8_t*)in; switch (src_sz) { case 7: pt[6] = m[6]; case 6: pt[5] = m[5]; case 5: pt[4] = m[4]; #ifdef UNALIGNED_OK case 4: *((uint32_t*)&pt[0]) = *((uint32_t*)&m[0]); break; #else case 4: pt[3] = m[3]; #endif case 3: pt[2] = m[2]; case 2: pt[1] = m[1]; case 1: pt[0] = m[0]; } b |= _le64toh(t); v3 ^= b; DOUBLE_ROUND(v0,v1,v2,v3); v0 ^= b; v2 ^= 0xff; DOUBLE_ROUND(v0,v1,v2,v3); DOUBLE_ROUND(v0,v1,v2,v3); return (v0 ^ v1) ^ (v2 ^ v3); }
uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *key) { uint64_t k0 = key->k0; uint64_t k1 = key->k1; uint64_t b = (uint64_t)src_sz << 56; #ifdef UNALIGNED_OK const uint64_t *in = (uint64_t*)src; #else /* On platforms where alignment matters, if 'in' is a pointer to a * datatype that must be aligned, the compiler is allowed to * generate code that assumes that it is aligned as such. */ const uint8_t *in = (uint8_t *)src; #endif uint64_t t; uint8_t *pt, *m; uint64_t v0 = k0 ^ 0x736f6d6570736575ULL; uint64_t v1 = k1 ^ 0x646f72616e646f6dULL; uint64_t v2 = k0 ^ 0x6c7967656e657261ULL; uint64_t v3 = k1 ^ 0x7465646279746573ULL; while (src_sz >= 8) { #ifdef UNALIGNED_OK uint64_t mi = _le64toh(*in); in += 1; #else uint64_t mi; memcpy(&mi, in, 8); mi = _le64toh(mi); in += 8; #endif src_sz -= 8; v3 ^= mi; DOUBLE_ROUND(v0,v1,v2,v3); v0 ^= mi; } t = 0; pt = (uint8_t*)&t; m = (uint8_t*)in; switch (src_sz) { case 7: pt[6] = m[6]; case 6: pt[5] = m[5]; case 5: pt[4] = m[4]; #ifdef UNALIGNED_OK case 4: *((uint32_t*)&pt[0]) = *((uint32_t*)&m[0]); break; #else case 4: pt[3] = m[3]; #endif case 3: pt[2] = m[2]; case 2: pt[1] = m[1]; case 1: pt[0] = m[0]; } b |= _le64toh(t); v3 ^= b; DOUBLE_ROUND(v0,v1,v2,v3); v0 ^= b; v2 ^= 0xff; DOUBLE_ROUND(v0,v1,v2,v3); DOUBLE_ROUND(v0,v1,v2,v3); return (v0 ^ v1) ^ (v2 ^ v3); }