brian m. carlson brian m. carlson Code version 2 of the GNU General Public License the Creative Commons Attribution-ShareAlike 3.0 License

I’ve long enjoyed implementing cryptographic algorithms. One of the easiest types to implement is a hash, or message digest. These functions take a variable-length input and produce a fixed-length output, and they’re commonly used in digital signatures.

Several years back, the US Government created an algorithm called SHA-1, which has a 160-bit (20-byte) output. Much analysis ensued, and due to some weaknesses, as well as concern about the length of SHA-1, four additional hashes collectively referred to as SHA-2 were produced. They are SHA-224, SHA-256, SHA-384, and SHA-512.

SHA-224 and SHA-256 are really quite the same, except for some different constants and a truncated output. Similar comments apply to SHA-384 and SHA-512. One important difference is that the former two operate on 32-bit variables, and the latter two operate on 64-bit variables. The two 32-bit algorithms process messages in 64-byte chunks, and the two 64-bit algorithms process message in 128-byte chunks.

I’ve tested out the algorithms on my laptop, which is a Core 2 Duo. In 64-bit mode, SHA-256 runs at 96 MiB/s, whereas SHA-512 runs at 147 MiB/s. SHA-512 operates on larger amounts of data, so given the same amount of data, it has to do fewer iterations to process it all.

However, in 32-bit mode, SHA-256 far outperforms SHA-512 (65 MiB/s vs. 28 MiB/s). These algorithms are both very register-intensive: their internal states both eight variables for processing; as a consequence, amd64 code (which has twice as many registers) has a significant performance advantage. Other than the size of the operands, the structure of all four algorithms is very, very similar. The interesting thing to consider, though, is that using a 64-bit machine makes using a more secure algorithm faster than a less secure one. That’s something I hadn’t considered before.