1 #ifndef BLAKE3_H 2 #define BLAKE3_H 3 4 #include <stddef.h> 5 #include <stdint.h> 6 7 #ifdef __cplusplus 8 extern "C" { 9 #endif 10 11 #define BLAKE3_KEY_LEN 32 12 #define BLAKE3_OUT_LEN 32 13 #define BLAKE3_BLOCK_LEN 64 14 #define BLAKE3_CHUNK_LEN 1024 15 #define BLAKE3_MAX_DEPTH 54 16 #define BLAKE3_MAX_SIMD_DEGREE 16 17 18 // This struct is a private implementation detail. It has to be here because 19 // it's part of blake3_hasher below. 20 typedef struct { 21 uint32_t cv[8]; 22 uint64_t chunk_counter; 23 uint8_t buf[BLAKE3_BLOCK_LEN]; 24 uint8_t buf_len; 25 uint8_t blocks_compressed; 26 uint8_t flags; 27 } blake3_chunk_state; 28 29 typedef struct { 30 FILE* log; 31 size_t counter; 32 uint32_t key[8]; 33 blake3_chunk_state chunk; 34 uint8_t cv_stack_len; 35 // The stack size is MAX_DEPTH + 1 because we do lazy merging. For example, 36 // with 7 chunks, we have 3 entries in the stack. Adding an 8th chunk 37 // requires a 4th entry, rather than merging everything down to 1, because we 38 // don't know whether more input is coming. This is different from how the 39 // reference implementation does things. 40 uint8_t cv_stack[(BLAKE3_MAX_DEPTH + 1) * BLAKE3_OUT_LEN]; 41 } blake3_hasher; 42 43 void blake3_hasher_init(blake3_hasher *self); 44 void blake3_hasher_init_keyed(blake3_hasher *self, 45 const uint8_t key[BLAKE3_KEY_LEN]); 46 void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context); 47 void blake3_hasher_update(blake3_hasher *self, const void *input, 48 size_t input_len); 49 void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out, 50 size_t out_len); 51 void blake3_hasher_finalize_seek(const blake3_hasher *self, uint64_t seek, 52 uint8_t *out, size_t out_len); 53 54 #ifdef __cplusplus 55 } 56 #endif 57 58 #endif /* BLAKE3_H */ 59