#pragma once #include #include struct BLAKE2s_param { uint8_t outlen; // digest length uint8_t keylen; // key length uint8_t fanout; uint8_t depth; uint32_t leaf_length; uint32_t node_offset; uint16_t node_offset_ex; uint8_t node_depth; uint8_t inner_length; uint64_t salt; uint64_t personalization; }; struct BLAKE2s_ctx { uint8_t b[64]; // input buffer size_t c; // pointer for b[] size_t outlen; // digest size TODO remove uint32_t h[8]; // chained state vector h uint32_t t[2]; // total number of bytes struct BLAKE2s_param param; // parameter block }; uint32_t rotr_u32(uint32_t word, uint8_t c); /** * 3.1 Mixing Function G */ void G(uint32_t V[16], unsigned a, unsigned b, unsigned c, unsigned d, uint32_t x, uint32_t y); /** * 3.2 Compression Function F * @param t: 2w-bit offset counter t * @param f: final block indicator flag f */ void F(struct BLAKE2s_ctx *context, uint32_t m[16], uint32_t f); [[nodiscard]] int BLAKE2s_init(struct BLAKE2s_ctx *ctx, size_t outlen, const void *key, size_t keylen); void BLAKE2s_update(struct BLAKE2s_ctx *ctx, const void *d, size_t dd); void BLAKE2s_final(struct BLAKE2s_ctx *ctx, void *out); // All-in-one convenience function. [[maybe_unused]] static int BLAKE2s(void *out, size_t outlen, // return buffer for digest const void *key, size_t keylen, // optional secret key const void *in, size_t inlen) // data to be hashed { struct BLAKE2s_ctx ctx; if (BLAKE2s_init(&ctx, outlen, key, keylen)) return -1; BLAKE2s_update(&ctx, in, inlen); BLAKE2s_final(&ctx, out); return 0; }