26.9.2009 15:40, pesco
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.
So here's the latest installment of my exploits into the forbidden realm of
implementing cryptographic primitives.
After building my little crypto chat experiment last month, one thing sorely
missing was message authentication (from
p2p.c):
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.
Appendix:
skein.c