BLAKE2(3)

πŸ‘‘ BLAKE2 β€” Library Functions Manual πŸ‘‘

okay bestie, sit DOWN, because we're about to talk about the BLAKE2 cryptographic hash functions and honestly? they ate. this is a page from the Library Functions Manual, so you know it's the real deal πŸ’…


✨ NAME ✨

blake2s, blake2b, blake2sp, blake2bp, blake2s_init, blake2s_init_key, blake2s_init_param, blake2s_update, blake2s_final, blake2b_init, blake2b_init_key, blake2b_init_param, blake2b_update, blake2b_final, blake2sp_init, blake2sp_init_key, blake2sp_update, blake2sp_final, blake2bp_init, blake2bp_init_key, blake2bp_update, blake2bp_final β€” the BLAKE2 cryptographic hash functions, aka the whole squad 🫢


🌈 SYNOPSIS 🌈

like, here's the whole cast list, no cap:

#include <blake2.h>

int
blake2s(uint8_t *out, const void *in, const void *key, size_t outlen,
    size_t inlen, size_t keylen);

int
blake2b(uint8_t *out, const void *in, const void *key, size_t outlen,
    size_t inlen, size_t keylen);

int
blake2sp(uint8_t *out, const void *in, const void *key, size_t outlen,
    size_t inlen, size_t keylen);

int
blake2bp(uint8_t *out, const void *in, const void *key, size_t outlen,
    size_t inlen, size_t keylen);

int
blake2s_init(blake2s_state *S, size_t outlen);

int
blake2s_init_key(blake2s_state *S, size_t outlen, const void *key,
    size_t keylen);

int
blake2s_init_param(blake2s_state *S, const blake2s_param *P);

int
blake2s_update(blake2s_state *S, const uint8_t *in, size_t inlen);

int
blake2s_final(blake2s_state *S, uint8_t *out, size_t outlen);

int
blake2b_init(blake2b_state *S, size_t outlen);

int
blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,
    size_t keylen);

int
blake2b_init_param(blake2b_state *S, const blake2b_param *P);

int
blake2b_update(blake2b_state *S, const uint8_t *in, size_t inlen);

int
blake2b_final(blake2b_state *S, uint8_t *out, size_t outlen);

int
blake2sp_init(blake2sp_state *S, size_t outlen);

int
blake2sp_init_key(blake2sp_state *S, size_t outlen, const void *key,
    size_t keylen);

int
blake2sp_update(blake2sp_state *S, const uint8_t *in, size_t inlen);

int
blake2sp_final(blake2sp_state *S, uint8_t *out, size_t outlen);

int
blake2bp_init(blake2bp_state *S, size_t outlen);

int
blake2bp_init_key(blake2bp_state *S, size_t outlen, const void *key,
    size_t keylen);

int
blake2bp_update(blake2bp_state *S, const uint8_t *in, size_t inlen);

int
blake2bp_final(blake2bp_state *S, uint8_t *out, size_t outlen);

πŸ’– DESCRIPTION πŸ’–

so the BLAKE2 family of cryptographic hash functions is literally an improved version of the SHA-3 finalist BLAKE. glow-up of the century, fr fr ✨

  • BLAKE2b is optimized for 64-bit platforms and produces up to 64 bytes of output.
  • BLAKE2s is optimized for 32-bit platforms and produces up to 32 bytes of output.
  • BLAKE2bp and BLAKE2sp are parallel versions of BLAKE2b and BLAKE2s, designed for increased performance on multicore and large-vector SIMD processors. main character energy, but make it multithreaded πŸ’…

πŸŽ€ getting set up (the init girlies) πŸŽ€

the blake2s_init(), blake2b_init(), blake2sp_init(), and blake2bp_init() functions initialize a hash state S to hash a message to an output of outlen bytes, without using a key. no key, just vibes.

bestie, S must be allocated by the caller. that's on you. 🫢

the blake2s_init_key(), blake2b_init_key(), blake2sp_init_key(), and blake2bp_init_key() functions initialize a hash state S to hash a message to an output of outlen bytes, using the key key of length keylen. now we're keyed, we're secure, we're iconic πŸ”

the blake2s_init_param() and blake2b_init_param() initialize a hash state S using a custom parameter block P, which must have been filled in completely by the caller. no half-finished param blocks, okay?? 😭

see the BLAKE2 paper and the <blake2.h> header file for details. iykyk πŸ“–

πŸ¦‹ feeding it data (the update girlies) πŸ¦‹

the blake2s_update(), blake2b_update(), blake2sp_update(), and blake2bp_update() functions hash the input buffer in of length inlen bytes into the hash state S. nibble nibble, munch munch 🌸


🌸 wrapping it up (the final girlies) 🌸

the blake2s_final(), blake2b_final(), blake2sp_final(), and blake2bp_final() functions compute the hash value accumulated in S and store it into out.

outlen must have the same value that was passed to the corresponding init function. same value, bestie, don't switch it up on me πŸ’€

⭐ one-shot mode (for the girlies in a hurry) ⭐

the blake2s(), blake2b(), blake2sp(), and blake2bp() functions hash a single-buffer input in one function call, optionally using a key. one call, one hash, done. slay.

to use the latter functions without a key, set keylen to 0 and key to NULL.


🧚 the rules about lengths (read this part, fr) 🧚

for all functions, the lengths outlen, inlen, and keylen are specified in bytes.

  • outlen must be positive and no greater than BLAKE2S_OUTBYTES (32) for the blake2s and blake2sp functions, or positive and no greater than BLAKE2B_OUTBYTES (64) for the blake2b and blake2bp functions.
  • keylen must be positive and no greater than BLAKE2S_KEYBYTES (32) for the blake2s and blake2sp functions, or positive and no greater than BLAKE2B_KEYBYTES (64) for the blake2b and blake2bp functions.

πŸ”₯ RETURN VALUES πŸ”₯

all of these functions return 0 if successful, or -1 if they detect an error. binary. no in-between. πŸ’…

all detected, reported errors are caused by invalid pointer arguments or out-of-bounds length arguments.

not all invalid arguments are detected. yes bestie, some stuff slides right past πŸ™ˆ

these functions do not set errno themselves, but do call standard C library functions which might set errno.


πŸ’€ BUGS πŸ’€

okay so, the tea. not everything is perfect, and we're being honest about it:

  • the library does not include a self-test function. no mirror selfie check. 😭
  • the library does not attempt to detect or report an error if the caller exceeds the input length limits specified for the BLAKE2 functions β€” even for BLAKE2s and BLAKE2sp, whose length limits (2**64-1 bytes and 2**67-1 bytes respectively) could theoretically be reached. so like, theoretically reachable but nobody's checking. wild.
  • blake2s_final(), blake2b_final(), blake2sp_final(), and blake2bp_final() do not erase the state S, and do not treat the hash value as sensitive, even if they are used to compute a keyed hash. no scrubbing, no wipe, it just sits there. 🫠
  • blake2s_final(), blake2b_final(), blake2sp_final(), and blake2bp_final() alter the state such that further calls to the _update or _final functions will produce poorly-behaved results, and they do not mark the state as no longer valid in order to detect and prevent such programmer errors.
so like… don't call _update or _final again after _final. the library will not stop you. it will not warn you. it will simply let you cook, and the results will be poorly-behaved. that's the whole warning, bestie πŸ”₯

and that's the page!! this whole thing is from the Debian edition, dated October 17, 2015 β€” so yeah, vintage, but still absolutely iconic. take care of your hash states, allocate your own S, and don't reuse a finalized one. mwah πŸ’œβœ¨