Maybe you shouldn't skip SHA-3
posted June 2017
Speed drives adoption, Daniel J. Bernstein (djb) probably understand this more than anyone else. And this is what led Adam Langley to decide to either stay on SHA-2 or move to BLAKE2. Is that a good advice? Should we all follow his steps?
I think it is important to remember that Google, as well as the other big players, have an agenda for speed. I'm not saying that they do not care about security, it would be stupid for me to say that, especially seeing all of the improvements we've had in the field thanks to them in the last few years (Project Zero, Android, Chrome, Wycheproof, Tink, BoringSSL, email encryption, Key Transparency, Certificate Transparency, ...)
What I'm saying is that although they care deeply about security, they are also looking for compromises to gain speed. This can be seen with the push for 0-RTT in TLS, but I believe we're seeing it here as well with a push for either KangarooTwelve (K12) or BLAKE2 instead of SHA-3/SHAKE and BLAKE (which are more secure versions of K12 and BLAKE2).
Adam Langley even went as far as to recommend folks to stay on SHA-2.
But how can we keep advising SHA-2 when we know it can be badly misused? Yes I'm talking about length extension attacks. These attacks that prevent you from using
SHA-2(key|data) to create a Message Authentication Code (MAC).
We recently cared so much about misuses of AES-GCM (documented misuses!) that Adam Langley's previous blog post to the SHA-3 one is about AES-GCM-SIV. We cared so much about simple APIs, that recently Tink simply removed the nonce argument from AES-GCM's API.
If we cared so much about documented misusage of crypto APIs, how can we not care about this undocumented misuse of SHA-2? Intuitively, if SHA-2 was to behave like a random oracle there would be no problem at all with the
SHA-2(key|data) construction. Actually, none of the more secure hash functions like Blake and SHA-3 have this problem.
If we cared so much about simple APIs, why would we advise people to "fix" SHA-2 by truncating 256 bits of SHA-512's output (SHA-512/256)?
The reality is that you should use SHA-3. I'm making this as a broad recommendation for people who do not know much about cryptography. You can't go wrong with the NIST's standard.
Now let's see how we can dilute a good advice.
If you care about speed you should use SHAKE or BLAKE.
If you really care about speed you should use KangarooTwelve or BLAKE2.
If you really really care about speed you should use SHA-512/256. (edit: people are pointing to me that Blake2 is also faster than that)
If you really really really care about speed you should use CRC32 (don't, it's a joke).
How big of a security compromise are you willing to make? We know the big players have decided, but have they decided for you?
Is SHA-3 that slow?
Where is a hash function usually used? One major use is in signing messages. You hash the message before signing it because you can't sign something that is too big.
Here is a number taken from djb's benchmarks on how many cycles it takes to sign with ed25519:
Here is a number taken from djb's benchmarks on how many cycles it takes to hash a byte with keccak512:
Spoiler Alert: you probably don't care about a few cycles.
Not to say there are no cases where this is relevant, but if you're doing a huge amount of hashing and you're hashing big messages, you should rather switch to a tree-hashing mode. KangarooTwelve, BLAKE2bp and BLAKE2sp all support that.
EDIT: The Keccak team just released a response as well.