There is a lot of code duplicated in convenience methods in each hash
implementation, and having a generic hash type makes implementing
higher-level constructs such as HMAC significantly easier down the road.
This is largely modeled off the SM3 versions of these routines, since
the relevant parts of the code are the same between SHA-256 and SM3,
and the alterations required to support SHA-512 are relatively simple.
The prior versions of update and the transform would leak memory, and
doing things this way also reduces the context buffer sizes by 1 block.
Assertions can be disabled, but at the point where cryptographic
anything is involved, a single branch has an infinitesimally small
performance impact.
The correct thing to do is to punch the caller in the face if they do
something that is blatantly incorrect, especially in a security critical
setting.