A Skein hash implementation in Java

Introduction

I've created an independent implementation of the Skein hash function. The Skein hash function family has been proposed by Niels Ferguson, Stefan Lucks, Bruce Schneier, Doug Whiting, Mihir Bellare, Tadayoshi Kohno, Jon Callas and Jesse Walker as a candidate for the SHA-3 competition by NIST. This implementation has been created with only the paper and the test vectors as input. The main reason for implementing Skein was to see if I could create a secure hash implementation from scratch. Another reason to implement Skein was to see if there were any snags in the paper or the test vectors. I've ignored the part in the Skein paper on how to implement Skein altogether; the implementation has been designed directly from the mathematical definition. The Threefish block cipher has been implemented as a separate module and includes a blockDecrypt() method for Threefish decryption. Only Simple Skein has been implemented for now, the hash tree versions will have to follow. All Simple Skein block and output sizes are supported. It is possible to configure the number of Threefish rounds as well as the logging of Threefish intermediate states.

A tiny error in the first official Skein implementation

One small error quickly came up: the block size is used as input for the tweak instead of the size of the configuration block. So the test vectors in the original paper are off for each case where the block size is different from 256 bits. Unfortunately form me, I cannot claim to be the first to have found the error. Hagen Fuerstenau was able to point it out before me. I've understood that he did this by analyzing the source code provided by the Skein team and comparing it with the specification. I've left in a small boolean constant in the source code to switch between the block size and the configuration size as input for the tweak. Note that the complete configuration block will be processed even if the configuration size given to the tweak (so it is unlikely in the extreme that this has any influence on the security of the hash function). I've send the test vectors that I've generated to Doug Whiting and they seem to match the new vectors he has re-calculated using his implementation. These new vectors are present within version 1.1 of the specification, so please treat this version as the only correct one. It seems that the references to the old 1.0 version have been removed - if you need one I'll send you a copy. Note that only the test vectors have been changed in the new Skein specification due to an implementation bug; the specification itself is completely unaltered.

Implementing Skein

One important thing to remember when implementing Skein is that the tweak value is handled as a single 128 bit number. Since Skein has been defined for an LSB machine, the least significant 64 bits will come "before" the most significant 64 bits. Please refer to the different implementations on how the tweak should be handled. I've encountered no other problems when implementing Skein. In fact, the whole Threefish block encrypt has not been significantly changed in any way from it's creation. I do believe that this is a testament to the ease of implementation of the Threefish algorithm.

Implementation notes

This implementation should not be used for any application that needs to perform, since the Threefish rounds have not been unrolled. The implementation does use arrays in fields instead of local arrays to avoid garbage collection . On my puny 32 bit machine, the Java performance is about 2,5 MB/s, whereas a Java port of the original code from Doug Whiting will manage to perform at least ten times better. I'll try and create a performing Java implementation for the Bouncy Castle Java security provider after publishing this page. That implementation will be based on the reference implementation of Doug Whiting. I've put in many logging calls within the code to make it easier for other developers to implement Skein. In the mean time, if you want to use a better performing Skein in Java you could use the Java port of Skein 512 created by Thomas Mueller.

The source

Keeping in true Skein tradition, a small implementation error crept in. In the old version the key was not updated, invalidating all the Skein test vectors (the decryption and initial chaining values were still correct though, so I figured everything should be fine). I've now rechecked the test vectors and updated the source. My apologies if this caused some confusion. Reminder to all developers: don't code hash methods after midnight.

The source code is available here. Anyone that understands Java should be able to read and compile the code. An Eclipse project file is included to make life easier for anyone using Eclipse. A Java 5 compliant SDK is required. If you run into any problems please let me know. The JavaDoc API is also included, but you can also browse it here. The nl.warper.skein.SkeinMain.USE_BLOCK_SIZE constant should be set to "true" to make the implementation compliant to the first implementation by the Skein team. Before I forget, please feel free to use my Skein code the way you see fit. I would be very annoyed if you would clame it yours or if you would do anything illegal with it. The code comes with no warranties whatsoever, I'll spare you the legalize.

The test vectors

These vectors have been generated by my Skein implementation. Please treat them as such and keep to those in the official 1.1 specification. For fellow developers of Skein, here are the intermediate values for a reduced round Threefish encrypt using a random key. When read in reverse, they are also the values for the Threefish decrypt of course.

On the author of the implementation

Maarten Bodewes has been using cryptography for about 7/8 years continuously. This includes creating designs and implementations using hardware security modules as well as smart cards and other hardware security devices. I've also been participating in the creation of (high-level) protocols that contain many different cryptographic algorithms. That said, I do not have the mathematical background to do any serious crypto analysis on the SHA-3 hash participants. Java is my preferred language of choice. In case you are wondering: warper has been my IRC nickname of old. Needless to say, I was visiting the Startrek channel back in the days.

PS: My appologies for the very basic page "design", I've just used my favourite text editor to come up with something resembling a web page due to time constraints. I'll be updating the page at the earliest convenience. I'll include the generated test vectors as well as the intermediate values of a reduced round Threefish encryption of a single block.