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_VERSION_STRING "1.3.3" 12 #define BLAKE3_KEY_LEN 32 13 #define BLAKE3_OUT_LEN 32 14 #define BLAKE3_BLOCK_LEN 64 15 #define BLAKE3_CHUNK_LEN 1024 16 #define BLAKE3_MAX_DEPTH 54 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 blake3_hasher { 30 uint32_t key[8]; 31 blake3_chunk_state chunk; 32 uint8_t cv_stack_len; 33 // The stack size is MAX_DEPTH + 1 because we do lazy merging. For example, 34 // with 7 chunks, we have 3 entries in the stack. Adding an 8th chunk 35 // requires a 4th entry, rather than merging everything down to 1, because we 36 // don't know whether more input is coming. This is different from how the 37 // reference implementation does things. 38 uint8_t cv_stack[(BLAKE3_MAX_DEPTH + 1) * BLAKE3_OUT_LEN]; 39 } blake3_hasher; 40 41 const char *blake3_version(void); 42 void blake3_hasher_init(blake3_hasher *self); 43 void blake3_hasher_init_keyed(blake3_hasher *self, 44 const uint8_t key[BLAKE3_KEY_LEN]); 45 void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context); 46 void blake3_hasher_init_derive_key_raw(blake3_hasher *self, const void *context, 47 size_t context_len); 48 void blake3_hasher_update(blake3_hasher *self, const void *input, 49 size_t input_len); 50 void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out, 51 size_t out_len); 52 void blake3_hasher_finalize_seek(const blake3_hasher *self, uint64_t seek, 53 uint8_t *out, size_t out_len); 54 void blake3_hasher_reset(blake3_hasher *self); 55 56 #ifdef __cplusplus 57 } 58 #endif 59 60 #endif /* BLAKE3_H */ 61