a 128-bit hash

51 views
Skip to first unread message

Bob Jenkins

unread,
Oct 27, 2010, 12:33:38 AM10/27/10
to Hash Functions
I'm finishing a 128-bit hash, aimed at noncryptographic checksums.
Code at
http://burtleburtle.net/bob/c/akron.h
http://burtleburtle.net/bob/c/akron.c
http://burtleburtle.net/bob/c/TestAkron.c
It hashes 4 bytes per cycle once it gets going. It has a startup cost
so it uses a 1-byte-per-cycle 128-bit hash for inputs under 96 bytes.
Right now I use 3 copies of the mix as the finalizer, I may change
that.

The interesting bit is the mix:

#define AkronMix(data,h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11) \
h0 +=(data)[0]; h2 =rot64(h2, 32)^h0; h4 +=h0; h0 +=h3; \
h1 +=(data)[1]; h3 =rot64(h3, 37)^h1; h5 +=h1; h1 +=h4; \
h2 +=(data)[2]; h4 =rot64(h4, 27)^h2; h6 +=h2; h2 +=h5; \
h3 +=(data)[3]; h5 =rot64(h5, 48)^h3; h7 +=h3; h3 +=h6; \
h4 +=(data)[4]; h6 =rot64(h6, 5) ^h4; h8 +=h4; h4 +=h7; \
h5 +=(data)[5]; h7 =rot64(h7, 7) ^h5; h9 +=h5; h5 +=h8; \
h6 +=(data)[6]; h8 =rot64(h8, 50)^h6; h10+=h6; h6 +=h9; \
h7 +=(data)[7]; h9 =rot64(h9, 18)^h7; h11+=h7; h7 +=h10;\
h8 +=(data)[8]; h10=rot64(h10,9) ^h8; h0 +=h8; h8 +=h11;\
h9 +=(data)[9]; h11=rot64(h11,44)^h9; h1 +=h9; h9 +=h0; \
h10+=(data)[10]; h0 =rot64(h0, 14)^h10; h2 +=h10; h10+=h1; \
h11+=(data)[11]; h1 =rot64(h1, 30)^h11; h3 +=h11; h11+=h2;

The requirement on the mix is that if the hash output is n bits, then
every input bit flips n internal state bit positions half the time (or
the equivalent amount of entropy) before those bit positions are all
overwritten. Same goes for pairs of inputs bits. This mix is
interesting in that the input trickles in, the internal state doesn't
get overwritten all at once. After 12 8-byte words are added in,
enough entropy has been pumped in to overwrite the entire internal
state ... I interpreted the criteria as flipping 128 bit positions
half the time after 12 words, both forward and backward. This mix
flips an average of at least 109 bits for a pair of keys differing in
one bit, and 146 bits for two such pairs of keys.

The specific shift constants don't matter much. Most of the search
space was arranging the variables to be simultaneously fast and
satisfy the bit flipping requirement both forwards and backwards.
Tests of bit flipping could be parameterized, but testing for fast
meant generating code, 4000 functions at a time, and compiling them
with Visual Studio (cl /O2).
Reply all
Reply to author
Forward
0 new messages