24 #ifndef INC_BLAKE3_HPP_3FD9634A_21F0_43D6_A445_D8860A200C6E
25 #define INC_BLAKE3_HPP_3FD9634A_21F0_43D6_A445_D8860A200C6E
60 enum class Flags : uint8_t
67 DERIVE_KEY_CONTEXT = 1 << 5,
68 DERIVE_KEY_MATERIAL = 1 << 6,
71 static constexpr
size_t BLAKE3_KEY_LEN = 32;
72 static constexpr
size_t BLAKE3_OUT_LEN = 32;
73 static constexpr
size_t BLAKE3_BLOCK_LEN = 64;
74 static constexpr
size_t BLAKE3_MAX_DEPTH = 54;
75 static constexpr
size_t BLAKE3_CHUNK_LEN = 1024;
76 static constexpr uint32_t IV[8] = { UINT32_C(0x6A09E667), UINT32_C(0xBB67AE85),
77 UINT32_C(0x3C6EF372), UINT32_C(0xA54FF53A),
78 UINT32_C(0x510E527F), UINT32_C(0x9B05688C),
79 UINT32_C(0x1F83D9AB), UINT32_C(0x5BE0CD19) };
80 static constexpr uint8_t MSG_SCHEDULE[7][16] =
82 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
83 { 2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8 },
84 { 3, 4, 10, 12, 13, 2, 7, 14, 6, 5, 9, 0, 11, 15, 8, 1 },
85 { 10, 7, 12, 9, 14, 3, 13, 15, 4, 0, 11, 2, 5, 8, 1, 6 },
86 { 12, 13, 9, 11, 15, 10, 14, 8, 7, 2, 5, 3, 0, 1, 6, 4 },
87 { 9, 14, 11, 5, 8, 12, 15, 1, 13, 3, 0, 10, 2, 6, 4, 7 },
88 { 11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13 },
96 uint8_t block[BLAKE3_BLOCK_LEN];
101 Output(
const uint32_t input_cv[8],
const uint8_t block[BLAKE3_BLOCK_LEN],
102 uint8_t block_len, uint64_t counter, uint8_t flags);
105 Output& operator=(
const Output&) =
default;
106 void chainingValue(uint8_t cv[32])
const;
107 void rootBytes(uint64_t seek, uint8_t *out,
size_t out_len);
108 static Output parentOutput(
const uint8_t block[BLAKE3_BLOCK_LEN],
109 const uint32_t key[8], uint8_t flags);
112 class ChunkState final
116 uint64_t chunk_counter;
117 uint8_t buf[BLAKE3_BLOCK_LEN];
119 uint8_t blocks_compressed;
123 size_t fillBuf(
const uint8_t* input,
size_t input_len);
124 uint8_t maybeStartFlag()
const;
127 uint8_t getFlags()
const {
return flags; }
128 uint64_t getChunkCounter()
const {
return chunk_counter; }
129 void setChunkCounter(
const uint64_t chunk_counter) { this->chunk_counter = chunk_counter; }
130 void init(
const uint32_t key[8],
const uint8_t flags);
131 void reset(
const uint32_t key[8],
const uint64_t chunk_counter);
133 void update(
const uint8_t* input,
size_t input_len);
134 Output stateOutput()
const;
141 uint8_t cv_stack_len;
147 uint8_t cv_stack[(BLAKE3_MAX_DEPTH + 1) * BLAKE3_OUT_LEN];
150 static constexpr
size_t simdDegree() {
return 1; }
151 static unsigned int popcnt(uint64_t x);
152 static unsigned int highestOne(uint64_t x);
153 static uint64_t roundDownToPowerOf2(uint64_t x);
154 static uint32_t counterLow(uint64_t counter);
155 static uint32_t counterHigh(uint64_t counter);
156 static uint32_t load32(
const void *src);
157 static uint32_t rotr32(
const uint32_t w,
const uint32_t c);
158 static size_t left_len(
size_t content_len);
159 static void store32(
void *dst, uint32_t w);
160 static void storeCvWords(uint8_t bytes_out[32], uint32_t cv_words[8]);
161 static void g(uint32_t *state,
const size_t a,
const size_t b,
162 const size_t c,
const size_t d,
const uint32_t x,
164 static void roundFn(uint32_t state[16],
const uint32_t *msg,
size_t round);
165 static void compressPre(uint32_t state[16],
const uint32_t cv[8],
166 const uint8_t block[BLAKE3_BLOCK_LEN],
167 uint8_t block_len, uint64_t counter, uint8_t flags);
168 static void compressInPlace(uint32_t cv[8],
const uint8_t block[BLAKE3_BLOCK_LEN],
169 uint8_t block_len, uint64_t counter, uint8_t flags);
170 static void compressXof(
const uint32_t cv[8],
171 const uint8_t block[BLAKE3_BLOCK_LEN],
172 uint8_t block_len, uint64_t counter,
173 uint8_t flags, uint8_t out[64]);
174 static void hashOne(
const uint8_t *input,
size_t blocks,
const uint32_t key[8],
175 uint64_t counter, uint8_t flags, uint8_t flags_start,
176 uint8_t flags_end, uint8_t out[BLAKE3_OUT_LEN]);
177 static void hashMany(
const uint8_t *
const *inputs,
size_t num_inputs,
178 size_t blocks,
const uint32_t key[8], uint64_t counter,
179 bool increment_counter, uint8_t flags, uint8_t flags_start,
180 uint8_t flags_end, uint8_t *out);
181 static size_t compressChunksParallel(
const uint8_t *input,
size_t input_len,
182 const uint32_t key[8],
183 uint64_t chunk_counter, uint8_t flags,
185 static size_t compressParentsParallel(
const uint8_t *child_chaining_values,
186 size_t num_chaining_values,
187 const uint32_t key[8], uint8_t flags,
189 static size_t compressSubtreeWide(
const uint8_t *input,
size_t input_len,
190 const uint32_t key[8],
191 uint64_t chunk_counter,
192 uint8_t flags, uint8_t *out);
193 static void compressSubtreeToParentNode(
const uint8_t *input,
195 const uint32_t key[8],
196 uint64_t chunk_counter,
198 uint8_t out[2 * BLAKE3_OUT_LEN]);
201 void mergeCvStack(uint64_t total_len);
202 void pushCv(uint8_t new_cv[BLAKE3_OUT_LEN], uint64_t chunk_counter);
203 void finalizeSeek(uint64_t seek, uint8_t *out,
size_t out_len);
234 size_t getSize()
const override {
return BLAKE3_OUT_LEN; }
242 void update(
const uint8_t* buf,
size_t len)
override;
290 return ChecksumAlgoId::BLAKE3;
Add some utilities to Checksum class.
Computes the BLAKE3 hash from a byte stream.
uint8_t * getValue(uint8_t *buffer) const override
Returns the BLAKE3 hash value in the first 32 bytes of the given address.
static constexpr ChecksumAlgoId getIdentifier()
Returns an unique identifier for the hash algorithm.
std::string getName() const override
Returns the name of the checksum or the hash algorithm.
void reset() override
Resets the BLAKE3 hash to initial state of computation.
BLAKE3()
Default constructor.
static Checksum * getNewInstance()
Gets a new instance of this class.
void update(const uint8_t *buf, size_t len) override
Updates the BLAKE3 hash with specified array of bytes.
size_t getSize() const override
Returns the minimal size to allocate in memory to store the hash with the getValue(buffer) method.
static std::string getHashName()
Returns the name of the hash algorithm.
ChecksumAlgoId getID() const override
Returns an unique identifier for the checksum or the hash algorithm.
Computes a hash from a byte stream.
Computes a checksum from a byte stream.
ChecksumAlgoId
Ids of algorithms of checksums.