Implement BLAKE2 Hashing in stdlib
Adds BLAKE2 hashing (also see blake2.net) to the C3 standard library, along with various thorough unit tests.
The creation of this module was a bit unconventional, due to the various renditions this hash type can assume. While generic modules were an option, I chose to limit code generation while imposing a specified compile-time "length" in the init and a matching compile-time final length. However, this requirement is cleanly masked when just calling the different aliases that read easily.
import std::hash::blake2;
// Just from reading left-to-right, it's very clear that this is BLAKE2s-256...
// No extra frivolities required.
char[] my_hash = blake2::s_256("A typical type to call!", "my_OPTIONAL_key");
// OR:
char[] my_hash_same = blake2::s(256, "A typical type to call!", "my_OPTIONAL_key");
To demonstrate, considering the compile-time size agreements is only required when using a hash streaming context:
import std::hash::blake2;
Blake2b myctx @noinit;
defer myctx.destroy();
myctx.init(blake2::SIZE_384, "my_OPTIONAL_secret");
while (/* read some data from the network or other buffer */)
{
myctx.update(read_content_bytes);
}
if (expected_hash != myctx.final(blake2::SIZE_384)) return SOME_ERROR?;
Additionally, something may be necessary for some of the 'error' cases in the code. I chose not to implement any faultdefs for the module at this time, because it would complicate invocations for the sake of unlikely edge cases.
BLAKE2b is optimized for 64-bit platforms. BLAKE2s for 32-bit. HOWEVER, these should not be limited or swapped by Arch type, since they produce distinct hashes for the same inputs. These are, to my knowledge, the much more popular variants of BLAKE2 that are out there.