> [The hash function] also should be second-preimage resistant: For a given message M1, it must be virtually impossible to find a second message M2 where M1 != M2 that produces the same hash hash(M1) == hash(M2).
> These functions should be also collision resistant: it must be virtually impossible to find two messages M1 and M2 where hash(M1) == hash(M2).
I’m disappointed that they didn’t discuss my favorite feature of BLAKE3: it’s a tree hash. If you have a file and the BLAKE3 hash of that file, you can generate a proof that a portion of the file is correct. And you can take a file, split it into pieces (of known length and offset), hash them as you receive them, and then assemble them into the full file and efficiently calculate the full file’s hash. The other options cannot do this, although you could certainly build this on top of them.
Imagine how much better S3 would be if it used BLAKE3 instead of MD5. (Hah, S3 and its competitors don’t even manage to fully support MD5 for multipart uploads, although they could support BLAKE3 very well with multipart uploads!)
If you care about speed, security and simplicity, and you don't care about NIST compliance, BLAKE3 is hard to beat.