Skip to content

Commit 2ba01f8

Browse files
Update BLAKE3 library to 1.8.2
1 parent faf27d4 commit 2ba01f8

8 files changed

Lines changed: 446 additions & 98 deletions

File tree

src/blake3/blake3.c

Lines changed: 84 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -88,24 +88,30 @@ INLINE void output_chaining_value(const output_t *self, uint8_t cv[32]) {
8888

8989
INLINE void output_root_bytes(const output_t *self, uint64_t seek, uint8_t *out,
9090
size_t out_len) {
91+
if (out_len == 0) {
92+
return;
93+
}
9194
uint64_t output_block_counter = seek / 64;
9295
size_t offset_within_block = seek % 64;
9396
uint8_t wide_buf[64];
94-
while (out_len > 0) {
95-
blake3_compress_xof(self->input_cv, self->block, self->block_len,
96-
output_block_counter, self->flags | ROOT, wide_buf);
97-
size_t available_bytes = 64 - offset_within_block;
98-
size_t memcpy_len;
99-
if (out_len > available_bytes) {
100-
memcpy_len = available_bytes;
101-
} else {
102-
memcpy_len = out_len;
103-
}
104-
memcpy(out, wide_buf + offset_within_block, memcpy_len);
105-
out += memcpy_len;
106-
out_len -= memcpy_len;
97+
if(offset_within_block) {
98+
blake3_compress_xof(self->input_cv, self->block, self->block_len, output_block_counter, self->flags | ROOT, wide_buf);
99+
const size_t available_bytes = 64 - offset_within_block;
100+
const size_t bytes = out_len > available_bytes ? available_bytes : out_len;
101+
memcpy(out, wide_buf + offset_within_block, bytes);
102+
out += bytes;
103+
out_len -= bytes;
107104
output_block_counter += 1;
108-
offset_within_block = 0;
105+
}
106+
if(out_len / 64) {
107+
blake3_xof_many(self->input_cv, self->block, self->block_len, output_block_counter, self->flags | ROOT, out, out_len / 64);
108+
}
109+
output_block_counter += out_len / 64;
110+
out += out_len & -64;
111+
out_len -= out_len & -64;
112+
if(out_len) {
113+
blake3_compress_xof(self->input_cv, self->block, self->block_len, output_block_counter, self->flags | ROOT, wide_buf);
114+
memcpy(out, wide_buf, out_len);
109115
}
110116
}
111117

@@ -134,9 +140,7 @@ INLINE void chunk_state_update(blake3_chunk_state *self, const uint8_t *input,
134140
input_len -= BLAKE3_BLOCK_LEN;
135141
}
136142

137-
size_t take = chunk_state_fill_buf(self, input, input_len);
138-
input += take;
139-
input_len -= take;
143+
chunk_state_fill_buf(self, input, input_len);
140144
}
141145

142146
INLINE output_t chunk_state_output(const blake3_chunk_state *self) {
@@ -154,10 +158,10 @@ INLINE output_t parent_output(const uint8_t block[BLAKE3_BLOCK_LEN],
154158
// Given some input larger than one chunk, return the number of bytes that
155159
// should go in the left subtree. This is the largest power-of-2 number of
156160
// chunks that leaves at least 1 byte for the right subtree.
157-
INLINE size_t left_len(size_t content_len) {
158-
// Subtract 1 to reserve at least one byte for the right side. content_len
161+
INLINE size_t left_subtree_len(size_t input_len) {
162+
// Subtract 1 to reserve at least one byte for the right side. input_len
159163
// should always be greater than BLAKE3_CHUNK_LEN.
160-
size_t full_chunks = (content_len - 1) / BLAKE3_CHUNK_LEN;
164+
size_t full_chunks = (input_len - 1) / BLAKE3_CHUNK_LEN;
161165
return round_down_to_power_of_2(full_chunks) * BLAKE3_CHUNK_LEN;
162166
}
163167

@@ -246,26 +250,25 @@ INLINE size_t compress_parents_parallel(const uint8_t *child_chaining_values,
246250

247251
// The wide helper function returns (writes out) an array of chaining values
248252
// and returns the length of that array. The number of chaining values returned
249-
// is the dyanmically detected SIMD degree, at most MAX_SIMD_DEGREE. Or fewer,
253+
// is the dynamically detected SIMD degree, at most MAX_SIMD_DEGREE. Or fewer,
250254
// if the input is shorter than that many chunks. The reason for maintaining a
251255
// wide array of chaining values going back up the tree, is to allow the
252256
// implementation to hash as many parents in parallel as possible.
253257
//
254258
// As a special case when the SIMD degree is 1, this function will still return
255259
// at least 2 outputs. This guarantees that this function doesn't perform the
256260
// root compression. (If it did, it would use the wrong flags, and also we
257-
// wouldn't be able to implement exendable ouput.) Note that this function is
261+
// wouldn't be able to implement extendable output.) Note that this function is
258262
// not used when the whole input is only 1 chunk long; that's a different
259263
// codepath.
260264
//
261265
// Why not just have the caller split the input on the first update(), instead
262266
// of implementing this special rule? Because we don't want to limit SIMD or
263267
// multi-threading parallelism for that update().
264-
static size_t blake3_compress_subtree_wide(const uint8_t *input,
265-
size_t input_len,
266-
const uint32_t key[8],
267-
uint64_t chunk_counter,
268-
uint8_t flags, uint8_t *out) {
268+
size_t blake3_compress_subtree_wide(const uint8_t *input, size_t input_len,
269+
const uint32_t key[8],
270+
uint64_t chunk_counter, uint8_t flags,
271+
uint8_t *out, bool use_tbb) {
269272
// Note that the single chunk case does *not* bump the SIMD degree up to 2
270273
// when it is 1. If this implementation adds multi-threading in the future,
271274
// this gives us the option of multi-threading even the 2-chunk case, which
@@ -279,7 +282,7 @@ static size_t blake3_compress_subtree_wide(const uint8_t *input,
279282
// the input into left and right subtrees. (Note that this is only optimal
280283
// as long as the SIMD degree is a power of 2. If we ever get a SIMD degree
281284
// of 3 or something, we'll need a more complicated strategy.)
282-
size_t left_input_len = left_len(input_len);
285+
size_t left_input_len = left_subtree_len(input_len);
283286
size_t right_input_len = input_len - left_input_len;
284287
const uint8_t *right_input = &input[left_input_len];
285288
uint64_t right_chunk_counter =
@@ -299,12 +302,24 @@ static size_t blake3_compress_subtree_wide(const uint8_t *input,
299302
}
300303
uint8_t *right_cvs = &cv_array[degree * BLAKE3_OUT_LEN];
301304

302-
// Recurse! If this implementation adds multi-threading support in the
303-
// future, this is where it will go.
304-
size_t left_n = blake3_compress_subtree_wide(input, left_input_len, key,
305-
chunk_counter, flags, cv_array);
306-
size_t right_n = blake3_compress_subtree_wide(
307-
right_input, right_input_len, key, right_chunk_counter, flags, right_cvs);
305+
// Recurse!
306+
size_t left_n = -1;
307+
size_t right_n = -1;
308+
309+
#if defined(BLAKE3_USE_TBB)
310+
blake3_compress_subtree_wide_join_tbb(
311+
key, flags, use_tbb,
312+
// left-hand side
313+
input, left_input_len, chunk_counter, cv_array, &left_n,
314+
// right-hand side
315+
right_input, right_input_len, right_chunk_counter, right_cvs, &right_n);
316+
#else
317+
left_n = blake3_compress_subtree_wide(
318+
input, left_input_len, key, chunk_counter, flags, cv_array, use_tbb);
319+
right_n = blake3_compress_subtree_wide(right_input, right_input_len, key,
320+
right_chunk_counter, flags, right_cvs,
321+
use_tbb);
322+
#endif // BLAKE3_USE_TBB
308323

309324
// The special case again. If simd_degree=1, then we'll have left_n=1 and
310325
// right_n=1. Rather than compressing them into a single output, return
@@ -330,32 +345,37 @@ static size_t blake3_compress_subtree_wide(const uint8_t *input,
330345
//
331346
// As with compress_subtree_wide(), this function is not used on inputs of 1
332347
// chunk or less. That's a different codepath.
333-
INLINE void compress_subtree_to_parent_node(
334-
const uint8_t *input, size_t input_len, const uint32_t key[8],
335-
uint64_t chunk_counter, uint8_t flags, uint8_t out[2 * BLAKE3_OUT_LEN]) {
348+
INLINE void
349+
compress_subtree_to_parent_node(const uint8_t *input, size_t input_len,
350+
const uint32_t key[8], uint64_t chunk_counter,
351+
uint8_t flags, uint8_t out[2 * BLAKE3_OUT_LEN],
352+
bool use_tbb) {
336353
#if defined(BLAKE3_TESTING)
337354
assert(input_len > BLAKE3_CHUNK_LEN);
338355
#endif
339356

340357
uint8_t cv_array[MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN];
341358
size_t num_cvs = blake3_compress_subtree_wide(input, input_len, key,
342-
chunk_counter, flags, cv_array);
359+
chunk_counter, flags, cv_array, use_tbb);
343360
assert(num_cvs <= MAX_SIMD_DEGREE_OR_2);
344-
345-
// If MAX_SIMD_DEGREE is greater than 2 and there's enough input,
361+
// The following loop never executes when MAX_SIMD_DEGREE_OR_2 is 2, because
362+
// as we just asserted, num_cvs will always be <=2 in that case. But GCC
363+
// (particularly GCC 8.5) can't tell that it never executes, and if NDEBUG is
364+
// set then it emits incorrect warnings here. We tried a few different
365+
// hacks to silence these, but in the end our hacks just produced different
366+
// warnings (see https://github.com/BLAKE3-team/BLAKE3/pull/380). Out of
367+
// desperation, we ifdef out this entire loop when we know it's not needed.
368+
#if MAX_SIMD_DEGREE_OR_2 > 2
369+
// If MAX_SIMD_DEGREE_OR_2 is greater than 2 and there's enough input,
346370
// compress_subtree_wide() returns more than 2 chaining values. Condense
347371
// them into 2 by forming parent nodes repeatedly.
348372
uint8_t out_array[MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN / 2];
349-
// The second half of this loop condition is always true, and we just
350-
// asserted it above. But GCC can't tell that it's always true, and if NDEBUG
351-
// is set on platforms where MAX_SIMD_DEGREE_OR_2 == 2, GCC emits spurious
352-
// warnings here. GCC 8.5 is particularly sensitive, so if you're changing
353-
// this code, test it against that version.
354-
while (num_cvs > 2 && num_cvs <= MAX_SIMD_DEGREE_OR_2) {
373+
while (num_cvs > 2) {
355374
num_cvs =
356375
compress_parents_parallel(cv_array, num_cvs, key, flags, out_array);
357376
memcpy(cv_array, out_array, num_cvs * BLAKE3_OUT_LEN);
358377
}
378+
#endif
359379
memcpy(out, cv_array, 2 * BLAKE3_OUT_LEN);
360380
}
361381

@@ -427,7 +447,7 @@ INLINE void hasher_merge_cv_stack(blake3_hasher *self, uint64_t total_len) {
427447
// of the whole tree, and it would need to be ROOT finalized. We can't
428448
// compress it until we know.
429449
// 2) This 64 KiB input might complete a larger tree, whose root node is
430-
// similarly going to be the the root of the whole tree. For example, maybe
450+
// similarly going to be the root of the whole tree. For example, maybe
431451
// we have 196 KiB (that is, 128 + 64) hashed so far. We can't compress the
432452
// node at the root of the 256 KiB subtree until we know how to finalize it.
433453
//
@@ -452,8 +472,8 @@ INLINE void hasher_push_cv(blake3_hasher *self, uint8_t new_cv[BLAKE3_OUT_LEN],
452472
self->cv_stack_len += 1;
453473
}
454474

455-
void blake3_hasher_update(blake3_hasher *self, const void *input,
456-
size_t input_len) {
475+
INLINE void blake3_hasher_update_base(blake3_hasher *self, const void *input,
476+
size_t input_len, bool use_tbb) {
457477
// Explicitly checking for zero avoids causing UB by passing a null pointer
458478
// to memcpy. This comes up in practice with things like:
459479
// std::vector<uint8_t> v;
@@ -539,7 +559,7 @@ void blake3_hasher_update(blake3_hasher *self, const void *input,
539559
uint8_t cv_pair[2 * BLAKE3_OUT_LEN];
540560
compress_subtree_to_parent_node(input_bytes, subtree_len, self->key,
541561
self->chunk.chunk_counter,
542-
self->chunk.flags, cv_pair);
562+
self->chunk.flags, cv_pair, use_tbb);
543563
hasher_push_cv(self, cv_pair, self->chunk.chunk_counter);
544564
hasher_push_cv(self, &cv_pair[BLAKE3_OUT_LEN],
545565
self->chunk.chunk_counter + (subtree_chunks / 2));
@@ -561,6 +581,20 @@ void blake3_hasher_update(blake3_hasher *self, const void *input,
561581
}
562582
}
563583

584+
void blake3_hasher_update(blake3_hasher *self, const void *input,
585+
size_t input_len) {
586+
bool use_tbb = false;
587+
blake3_hasher_update_base(self, input, input_len, use_tbb);
588+
}
589+
590+
#if defined(BLAKE3_USE_TBB)
591+
void blake3_hasher_update_tbb(blake3_hasher *self, const void *input,
592+
size_t input_len) {
593+
bool use_tbb = true;
594+
blake3_hasher_update_base(self, input, input_len, use_tbb);
595+
}
596+
#endif // BLAKE3_USE_TBB
597+
564598
void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out,
565599
size_t out_len) {
566600
blake3_hasher_finalize_seek(self, 0, out, out_len);

src/blake3/blake3.h

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,33 @@
44
#include <stddef.h>
55
#include <stdint.h>
66

7+
#if !defined(BLAKE3_API)
8+
# if defined(_WIN32) || defined(__CYGWIN__)
9+
# if defined(BLAKE3_DLL)
10+
# if defined(BLAKE3_DLL_EXPORTS)
11+
# define BLAKE3_API __declspec(dllexport)
12+
# else
13+
# define BLAKE3_API __declspec(dllimport)
14+
# endif
15+
# define BLAKE3_PRIVATE
16+
# else
17+
# define BLAKE3_API
18+
# define BLAKE3_PRIVATE
19+
# endif
20+
# elif __GNUC__ >= 4
21+
# define BLAKE3_API __attribute__((visibility("default")))
22+
# define BLAKE3_PRIVATE __attribute__((visibility("hidden")))
23+
# else
24+
# define BLAKE3_API
25+
# define BLAKE3_PRIVATE
26+
# endif
27+
#endif
28+
729
#ifdef __cplusplus
830
extern "C" {
931
#endif
1032

11-
#define BLAKE3_VERSION_STRING "1.3.1"
33+
#define BLAKE3_VERSION_STRING "1.8.2"
1234
#define BLAKE3_KEY_LEN 32
1335
#define BLAKE3_OUT_LEN 32
1436
#define BLAKE3_BLOCK_LEN 64
@@ -38,20 +60,24 @@ typedef struct {
3860
uint8_t cv_stack[(BLAKE3_MAX_DEPTH + 1) * BLAKE3_OUT_LEN];
3961
} blake3_hasher;
4062

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);
63+
BLAKE3_API const char *blake3_version(void);
64+
BLAKE3_API void blake3_hasher_init(blake3_hasher *self);
65+
BLAKE3_API void blake3_hasher_init_keyed(blake3_hasher *self,
66+
const uint8_t key[BLAKE3_KEY_LEN]);
67+
BLAKE3_API void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context);
68+
BLAKE3_API void blake3_hasher_init_derive_key_raw(blake3_hasher *self, const void *context,
69+
size_t context_len);
70+
BLAKE3_API void blake3_hasher_update(blake3_hasher *self, const void *input,
71+
size_t input_len);
72+
#if defined(BLAKE3_USE_TBB)
73+
BLAKE3_API void blake3_hasher_update_tbb(blake3_hasher *self, const void *input,
74+
size_t input_len);
75+
#endif // BLAKE3_USE_TBB
76+
BLAKE3_API void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out,
77+
size_t out_len);
78+
BLAKE3_API void blake3_hasher_finalize_seek(const blake3_hasher *self, uint64_t seek,
79+
uint8_t *out, size_t out_len);
80+
BLAKE3_API void blake3_hasher_reset(blake3_hasher *self);
5581

5682
#ifdef __cplusplus
5783
}

src/blake3/blake3_avx2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ INLINE void transpose_vecs(__m256i vecs[DEGREE]) {
167167
__m256i gh_0145 = _mm256_unpacklo_epi32(vecs[6], vecs[7]);
168168
__m256i gh_2367 = _mm256_unpackhi_epi32(vecs[6], vecs[7]);
169169

170-
// Interleave 64-bit lates. The low unpack is lanes 00/22 and the high is
170+
// Interleave 64-bit lanes. The low unpack is lanes 00/22 and the high is
171171
// 11/33.
172172
__m256i abcd_04 = _mm256_unpacklo_epi64(ab_0145, cd_0145);
173173
__m256i abcd_15 = _mm256_unpackhi_epi64(ab_0145, cd_0145);

0 commit comments

Comments
 (0)