There are security improvements in new primitives, often based on a notion of "misuse-resistance". SHA2 isn't broken; it remains quite strong. But it's a classic Merkle Damgard design, which means you can take the output of SHA2 and hash more data into it, which breaks simple keyed hash constructions like H(k, m) (this is why we have HMAC!). SHA3 and other modern hashes don't have this property; you can safely build simple keyed hash constructions out of them. You can see the same thing with AEADs (the SIVs vs. GCM) and with curves (Curve25519, for instance, where keys are --- don't @ me --- just simple random byte strings).
And these days there are also the primitives purposefully designed to run in blockchain....whatever it is, using large GF(p) or GF(2^n) field operations as components. This mostly falls under the "more limited hardware" umbrella.
Isn't this problem fixed by simply dropping some bits from the end? See SHA-224 for instance.
IIRC, just simple random byte strings with a couple of specific bits forced to 0 and another couple of specific bits forced to 1.
I hesitate to link to it because I already know of a potential attack, but I played around with an implementation that does this with matrix multiplication over galois field elements of reinterpreted hash digests [1]. I mean, the associative / non-commutative part works nicely, but I expect that factoring the matrix is possible which makes it utterly useless as a cryptographic primitive [2]. "don't roll your own crypto" would apply, but I'm obviously not using such an academic exercise in production.
[1]: https://blog.infogulch.com/2021/07/15/Merklist-GF.html
[2]: https://math.stackexchange.com/questions/4200988/using-rando...
Using 8x8 Binary Matrices as a hash - https://math.stackexchange.com/questions/1902462/using-8x8-b...
Finding Prime Binary Matrices - https://math.stackexchange.com/questions/1914853/finding-pri...
A lot of security proofs assume the random oracle model (but not for hash functions though, which are supposed to implement the "random oracle"). Strictly speaking, the model is incorrect, because a hash function is never a random oracle. I don't know if a suitable substitute has been found.