Loading changes/bug17544 0 → 100644 +4 −0 Original line number Diff line number Diff line o Minor bugfix (SipHash-2-4 performance): - Improve performance when hashing non-multiple of 8 sized buffers, based on Andrew Moon's Public Domain SipHash-2-4 implementation. Fixes bug 17544; bugfix on 0.2.5.3-alpha. src/ext/csiphash.c +20 −37 Original line number Diff line number Diff line Loading @@ -97,65 +97,48 @@ #endif uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *key) { const uint8_t *m = src; 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 last7 = (uint64_t)(src_sz & 0xff) << 56; size_t i, blocks; uint64_t v0 = k0 ^ 0x736f6d6570736575ULL; uint64_t v1 = k1 ^ 0x646f72616e646f6dULL; uint64_t v2 = k0 ^ 0x6c7967656e657261ULL; uint64_t v3 = k1 ^ 0x7465646279746573ULL; while (src_sz >= 8) { for (i = 0, blocks = (src_sz & ~7); i < blocks; i+= 8) { #ifdef UNALIGNED_OK uint64_t mi = _le64toh(*in); in += 1; uint64_t mi = _le64toh(*(m + i)); #else uint64_t mi; memcpy(&mi, in, 8); memcpy(&mi, m + i, 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]; switch (src_sz - 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:; } b |= _le64toh(t); v3 ^= b; v3 ^= last7; DOUBLE_ROUND(v0,v1,v2,v3); v0 ^= b; v2 ^= 0xff; v0 ^= last7; v2 ^= 0xff; DOUBLE_ROUND(v0,v1,v2,v3); DOUBLE_ROUND(v0,v1,v2,v3); return (v0 ^ v1) ^ (v2 ^ v3); return v0 ^ v1 ^ v2 ^ v3; } Loading Loading
changes/bug17544 0 → 100644 +4 −0 Original line number Diff line number Diff line o Minor bugfix (SipHash-2-4 performance): - Improve performance when hashing non-multiple of 8 sized buffers, based on Andrew Moon's Public Domain SipHash-2-4 implementation. Fixes bug 17544; bugfix on 0.2.5.3-alpha.
src/ext/csiphash.c +20 −37 Original line number Diff line number Diff line Loading @@ -97,65 +97,48 @@ #endif uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *key) { const uint8_t *m = src; 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 last7 = (uint64_t)(src_sz & 0xff) << 56; size_t i, blocks; uint64_t v0 = k0 ^ 0x736f6d6570736575ULL; uint64_t v1 = k1 ^ 0x646f72616e646f6dULL; uint64_t v2 = k0 ^ 0x6c7967656e657261ULL; uint64_t v3 = k1 ^ 0x7465646279746573ULL; while (src_sz >= 8) { for (i = 0, blocks = (src_sz & ~7); i < blocks; i+= 8) { #ifdef UNALIGNED_OK uint64_t mi = _le64toh(*in); in += 1; uint64_t mi = _le64toh(*(m + i)); #else uint64_t mi; memcpy(&mi, in, 8); memcpy(&mi, m + i, 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]; switch (src_sz - 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:; } b |= _le64toh(t); v3 ^= b; v3 ^= last7; DOUBLE_ROUND(v0,v1,v2,v3); v0 ^= b; v2 ^= 0xff; v0 ^= last7; v2 ^= 0xff; DOUBLE_ROUND(v0,v1,v2,v3); DOUBLE_ROUND(v0,v1,v2,v3); return (v0 ^ v1) ^ (v2 ^ v3); return v0 ^ v1 ^ v2 ^ v3; } Loading