If you don't know http://www.burtleburtle.net/bob/hash/ then you miss a lot of great ideas, publicly published while they are probably well known and taught in the secret circles of state-sponsored cryptogeeks. It's only a modest personal research though it contains a lot of essential background so go read it.
When I was exploring the field of CRC/block checksums for my custom protocols (mostly 2006-2009) I was seduced by Bob's lookup3.c and examined it for a while. Scanning a block would apply this transform for each triplet of 32-bit words:
#define mix(a,b,c) \
{ \
a -= c; a ^= rot(c, 4); c += b; \
b -= a; b ^= rot(a, 6); a += c; \
c -= b; c ^= rot(b, 8); b += a; \
a -= c; a ^= rot(c,16); c += b; \
b -= a; b ^= rot(a,19); a += c; \
c -= b; c ^= rot(b, 4); b += a; \
}
Going back to this today, several similarities and parallels strike me. It now feels familiar... And I'm connecting the dots tonight.
- Bob's article proves that reversibility is a critical requirement for a hash function.
- There are 3 variables, that would act like a 3-deep lagged Fibonacci or LFSR with extra steps. So we could remove the rot() and the subtractions and still get away with a semi-decent Fibonacci step, with bad mixing because the carry bit is not reinjected in the LSB.
- This is a circular algorithm with slightly varying parameters to optimise the mixing. There could be any number of registers, 3 seemed like a good compromise for Bob's application (96 bits is quite a lot for embedded applications but not enough for modern databases).
Hindsight is 20/20 they say and I have learned a lot since then. Today, while exchanging a message with him, I realise:
- PEAC is reversible (we can go forward and backwards) so it is naturally suited as a basis for hashes and more. By itself it won't go far (because mixing is limited to the LSB) but better algorithms can be built around/with/on top of it. I sort of knew it since the beginning but now it is obvious.
- Each line of lookup3's mix() function could be seen as a scrambler (look: we have the x+=y part at the end of the line!) which scramble each other in turn. There are 3 registers but there could be 4, or even more, right ? That would be another type of "lagged Fibonacci with extra steps" and this is not a theoretical limit, since Marsaglia made PRNGs with hundreds of registers (but with specific length).
- Bob applied the same idea as I did on Fletcher, where I loop operations on themselves.
That and a few other things (such as when I scrambled the output of a LFSR) came to my mind, and I wondered:
Why don't I use X × PEAC scramblers that scramble each other's states in a ring ?
why, oh why...
Such a system, for example with 4 or 8× PEAC16x2, would be simple, fast and provably robust. It could still work as scrambler, PRNG and checksum. And I wouldn't have to spend ages to prove that w32 (or larger) is or is not perfect or maximal.
And if mixing is really important for you, between steps you can also perform LUT scrambling (or similar non-linear operations) because PEAC can't be 0-crashed (just don't mess with the carry bit).
I still need some time to unfold everything in my head so stay tuned...
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.