The Skein
hash function in 256 lines of C
Note:
I'm going to switch this thing over to English now, because I expect
to ask some non-Germans for feedback in the future. I might also translate some
old posts.
A view across the lake at HAR 2009 towards the CCC's geodesic party tent. Me
and friends camped just about outside the right edge of the picture.
printf("receiving packets on port %d\n", LOCALPORT);
printf("CAUTION: Message senders can be spoofed.\n");
The obvious solution to this problem are message authentication codes,
particularly because the diffie-hellman setup already yields shared secrets
between any two parties. A typical way to construct MACs is to take a
cryptographic hash function and compute its value over a combination of the
message and the secret (the standard construction of this kind is called HMAC).
So I set out to find a nice little hash function which could be easily and
elegantly implemented. Unfortunately, the obvious candidates didn't quite
satisfy me. I kept looking and eventually ended up with the promising
description of Skein:
Skein is a new family of cryptographic hash functions. Its design combines speed, security, simplicity, and a great deal of flexibility in a modular package that is easy to analyze.Without much regret, I commited the next step up on the ladder of serious crimes in the construction of crypto systems: I set out to use an unproven algorithm. Hooray! >:) Incidentally, one very nice feature of Skein is that it already offers a mechanism to turn it into a keyed hash function. If my understanding is correct, this is essentially due to the fact that Skein is actually derived from a block cipher (actually called
Threefish;)). I have yet to implement this MAC mode, but it's basically a detail once the rest is set up. As of yesterday, the code finally produces the correct output on the official one-byte test vector. Feel free to try it on the longer ones. What took me so long? First, there was HAR. I had it pretty much complete at that point, except for one of those nasty segfault bugs. When I took a good hard look at things again this week, it turned out to be an overlong memset() corrupting my stack. God, I love those! ;) There are some limitations to the code at this point:
- Only the 512-bit variant of Skein is implemented. However, the threefish function is already generalized to any block size, so the others should be easy to add.
- The supplied main routine simply hashes the test vector, prints the result and exits. Anything more useful basically needs to wait for the next point:
- No support for directly slurping input from FILE handles. I've already prepared the code for it, just need to write the actual routine.
- As stated above, no MAC mode, yet. None of the other fancy stuff (personalization, tree hashing, …) either. Just plain and simple hashing.