You can also look at things like the Strobe framework, which builds essentially all of its symmetric crypto out of the SHA-3 core permutation: https://strobe.sourceforge.io/
Yes, I imlemented a whole pile of hash functions, and I agree wholeheartedly. Whereas md5/sha seem to be have been designed by pouring a hodgepodge of complexity into a algorithm until something indecipherable turned up sha3 is simple. It's just a small number of easily understood operations, each with a clear purpose.
Actually, it looked to me like it's been an evolution. md5 is insanely complex and the sha2 family got simpler, then then we get t sha3.
Symmetric algorithms look to be going the same way. DES is insanely complex, AES less so, and Speck in almost unbelievably simple (look at the source code on Wikipedia https://en.wikipedia.org/wiki/Speck_(cipher)). It seems to be an unfashionable viewpoint, but in my mind that simplicity makes Speck seem more worthy of trust that a lot of it's rivals.
Mind you,
https://github.com/BLAKE3-team/BLAKE3/blob/b404c851c284ed01f...
I peeked at the reference impl (380 lines of safe Rust) and found this. It has a 1,728-byte array for tree state, which is enough for 2 ^ 64 bytes.
So in practice it's also fixed.
BLAKE3 is faster, sometimes a lot faster, on hardware without SHA instructions. On hardware with SHA instructions SHA may be faster. Same as the AES story where AES is faster than ChaCha on CPUs with dedicated hardware but slower otherwise.
You can't just do SHA256(key + message) to generate a safe MAC. With BLAKE (and all SHA3 finalists) you can do that safely.
It's true every time you make the algorithm more misuse resistant, the universe will come up with a more dunning Kruger, but despite that, it's something that can actually improve, the security is already more than adequate: Like Schneier so eloquently put it, "we're building a fence for sheep, it doesn't matter if the fence pole is a mile or two miles high".
Repeating a nonce is easier than you might think if you are using threads and accessing a nonce counter non-atomically, have a bad RNG, are on an embedded platform with bad RNG seeding, have a bug that overwrites some memory used to generate nonces, or just transfer a ton of data with the same key (birthday attack). SIV makes nonce reuse fairly benign. The only consequence is that if you happen to reuse a nonce with two identical messages, an attacker could tell that you sent the same message twice. That's generally not catastrophic and statistically is far less likely than repeating a nonce with different messages. Repeating a nonce with different messages generally does nothing in SIV.
You could theoretically use SIV with no nonce, with the only consequence being that an attacker could always tell if you sent duplicate messages. Not sure why you'd do that though.
IMHO since we now have ciphers that are probably "unbreakable for the foreseeable future" (e.g. AES and ChaCha) we should probably concentrate on creating and popularizing misuse-resistant constructions as much as possible. It's good to remove footguns.
The big downside is that it requires two passes on encrypt: one to create the MAC and derive the IV and another to encrypt. The overhead for this is small for message/packet based systems though since after pass one the data will be sitting hot in the processor's L0 cache. Decryption can be done in one pass.
Can you explain this?
h = SHA-256(k || m1)
you can easily compute a function `F(h, m2)` such that SHA-256(k || m1 || m2) = F(h, m2)
allowing you to forge a verifier for `m1 || m2` under `k` for any `m2` you wish without actually knowing `k`.As a result of that, I asked for rustls to default to AES instead of the previous ChaCha20 default [1]