• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.gitignoreH A D01-Jan-197019 43

Makefile.testingH A D01-Jan-19701.9 KiB7959

README.mdH A D01-Jan-19709.3 KiB283221

blake3.cH A D01-Jan-197026.4 KiB606381

blake3.hH A D01-Jan-19701.9 KiB6044

blake3_avx2.cH A D01-Jan-197012.1 KiB326294

blake3_avx2_x86-64_unix.SH A D01-Jan-197064.5 KiB1,8161,809

blake3_avx2_x86-64_windows_gnu.SH A D01-Jan-197065.2 KiB1,8181,815

blake3_avx2_x86-64_windows_msvc.asmH A D01-Jan-197064.4 KiB1,8291,813

blake3_avx512.cH A D01-Jan-197046.8 KiB1,2051,046

blake3_avx512_x86-64_unix.SH A D01-Jan-197087.3 KiB2,5862,578

blake3_avx512_x86-64_windows_gnu.SH A D01-Jan-197088.9 KiB2,6162,607

blake3_avx512_x86-64_windows_msvc.asmH A D01-Jan-197089.5 KiB2,6352,626

blake3_dispatch.cH A D01-Jan-19707.4 KiB277255

blake3_impl.hH A D01-Jan-19709.7 KiB270224

blake3_neon.cH A D01-Jan-197012.4 KiB347295

blake3_portable.cH A D01-Jan-19705.8 KiB161144

blake3_sse2.cH A D01-Jan-197020.5 KiB566502

blake3_sse2_x86-64_unix.SH A D01-Jan-197067.2 KiB2,2922,284

blake3_sse2_x86-64_windows_gnu.SH A D01-Jan-197069.5 KiB2,3332,327

blake3_sse2_x86-64_windows_msvc.asmH A D01-Jan-197069.3 KiB2,3512,333

blake3_sse41.cH A D01-Jan-197020.3 KiB560497

blake3_sse41_x86-64_unix.SH A D01-Jan-197059.7 KiB2,0292,021

blake3_sse41_x86-64_windows_gnu.SH A D01-Jan-197062 KiB2,0702,064

blake3_sse41_x86-64_windows_msvc.asmH A D01-Jan-197061.7 KiB2,0902,070

example.cH A D01-Jan-1970661 2819

main.cH A D01-Jan-19703.9 KiB167141

test.pyH A D01-Jan-19703.6 KiB9870

README.md

1The official C implementation of BLAKE3.
2
3# Example
4
5An example program that hashes bytes from standard input and prints the
6result:
7
8```c
9#include "blake3.h"
10#include <stdio.h>
11#include <unistd.h>
12
13int main() {
14  // Initialize the hasher.
15  blake3_hasher hasher;
16  blake3_hasher_init(&hasher);
17
18  // Read input bytes from stdin.
19  unsigned char buf[65536];
20  ssize_t n;
21  while ((n = read(STDIN_FILENO, buf, sizeof(buf))) > 0) {
22    blake3_hasher_update(&hasher, buf, n);
23  }
24
25  // Finalize the hash. BLAKE3_OUT_LEN is the default output length, 32 bytes.
26  uint8_t output[BLAKE3_OUT_LEN];
27  blake3_hasher_finalize(&hasher, output, BLAKE3_OUT_LEN);
28
29  // Print the hash as hexadecimal.
30  for (size_t i = 0; i < BLAKE3_OUT_LEN; i++) {
31    printf("%02x", output[i]);
32  }
33  printf("\n");
34  return 0;
35}
36```
37
38The code above is included in this directory as `example.c`. If you're
39on x86\_64 with a Unix-like OS, you can compile a working binary like
40this:
41
42```bash
43gcc -O3 -o example example.c blake3.c blake3_dispatch.c blake3_portable.c \
44    blake3_sse2_x86-64_unix.S blake3_sse41_x86-64_unix.S blake3_avx2_x86-64_unix.S \
45    blake3_avx512_x86-64_unix.S
46```
47
48# API
49
50## The Struct
51
52```c
53typedef struct {
54  // private fields
55} blake3_hasher;
56```
57
58An incremental BLAKE3 hashing state, which can accept any number of
59updates. This implementation doesn't allocate any heap memory, but
60`sizeof(blake3_hasher)` itself is relatively large, currently 1912 bytes
61on x86-64. This size can be reduced by restricting the maximum input
62length, as described in Section 5.4 of [the BLAKE3
63spec](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf),
64but this implementation doesn't currently support that strategy.
65
66## Common API Functions
67
68```c
69void blake3_hasher_init(
70  blake3_hasher *self);
71```
72
73Initialize a `blake3_hasher` in the default hashing mode.
74
75---
76
77```c
78void blake3_hasher_update(
79  blake3_hasher *self,
80  const void *input,
81  size_t input_len);
82```
83
84Add input to the hasher. This can be called any number of times.
85
86---
87
88```c
89void blake3_hasher_finalize(
90  const blake3_hasher *self,
91  uint8_t *out,
92  size_t out_len);
93```
94
95Finalize the hasher and return an output of any length, given in bytes.
96This doesn't modify the hasher itself, and it's possible to finalize
97again after adding more input. The constant `BLAKE3_OUT_LEN` provides
98the default output length, 32 bytes, which is recommended for most
99callers.
100
101Outputs shorter than the default length of 32 bytes (256 bits) provide
102less security. An N-bit BLAKE3 output is intended to provide N bits of
103first and second preimage resistance and N/2 bits of collision
104resistance, for any N up to 256. Longer outputs don't provide any
105additional security.
106
107Shorter BLAKE3 outputs are prefixes of longer ones. Explicitly
108requesting a short output is equivalent to truncating the default-length
109output. (Note that this is different between BLAKE2 and BLAKE3.)
110
111## Less Common API Functions
112
113```c
114void blake3_hasher_init_keyed(
115  blake3_hasher *self,
116  const uint8_t key[BLAKE3_KEY_LEN]);
117```
118
119Initialize a `blake3_hasher` in the keyed hashing mode. The key must be
120exactly 32 bytes.
121
122---
123
124```c
125void blake3_hasher_init_derive_key(
126  blake3_hasher *self,
127  const char *context);
128```
129
130Initialize a `blake3_hasher` in the key derivation mode. The context
131string is given as an initialization parameter, and afterwards input key
132material should be given with `blake3_hasher_update`. The context string
133is a null-terminated C string which should be **hardcoded, globally
134unique, and application-specific**. The context string should not
135include any dynamic input like salts, nonces, or identifiers read from a
136database at runtime. A good default format for the context string is
137`"[application] [commit timestamp] [purpose]"`, e.g., `"example.com
1382019-12-25 16:18:03 session tokens v1"`.
139
140This function is intended for application code written in C. For
141language bindings, see `blake3_hasher_init_derive_key_raw` below.
142
143---
144
145```c
146void blake3_hasher_init_derive_key_raw(
147  blake3_hasher *self,
148  const void *context,
149  size_t context_len);
150```
151
152As `blake3_hasher_init_derive_key` above, except that the context string
153is given as a pointer to an array of arbitrary bytes with a provided
154length. This is intended for writing language bindings, where C string
155conversion would add unnecessary overhead and new error cases. Unicode
156strings should be encoded as UTF-8.
157
158Application code in C should prefer `blake3_hasher_init_derive_key`,
159which takes the context as a C string. If you need to use arbitrary
160bytes as a context string in application code, consider whether you're
161violating the requirement that context strings should be hardcoded.
162
163---
164
165```c
166void blake3_hasher_finalize_seek(
167  const blake3_hasher *self,
168  uint64_t seek,
169  uint8_t *out,
170  size_t out_len);
171```
172
173The same as `blake3_hasher_finalize`, but with an additional `seek`
174parameter for the starting byte position in the output stream. To
175efficiently stream a large output without allocating memory, call this
176function in a loop, incrementing `seek` by the output length each time.
177
178# Building
179
180This implementation is just C and assembly files. It doesn't include a
181public-facing build system. (The `Makefile` in this directory is only
182for testing.) Instead, the intention is that you can include these files
183in whatever build system you're already using. This section describes
184the commands your build system should execute, or which you can execute
185by hand. Note that these steps may change in future versions.
186
187## x86
188
189Dynamic dispatch is enabled by default on x86. The implementation will
190query the CPU at runtime to detect SIMD support, and it will use the
191widest instruction set available. By default, `blake3_dispatch.c`
192expects to be linked with code for five different instruction sets:
193portable C, SSE2, SSE4.1, AVX2, and AVX-512.
194
195For each of the x86 SIMD instruction sets, four versions are available:
196three flavors of assembly (Unix, Windows MSVC, and Windows GNU) and one
197version using C intrinsics. The assembly versions are generally
198preferred. They perform better, they perform more consistently across
199different compilers, and they build more quickly. On the other hand, the
200assembly versions are x86\_64-only, and you need to select the right
201flavor for your target platform.
202
203Here's an example of building a shared library on x86\_64 Linux using
204the assembly implementations:
205
206```bash
207gcc -shared -O3 -o libblake3.so blake3.c blake3_dispatch.c blake3_portable.c \
208    blake3_sse2_x86-64_unix.S blake3_sse41_x86-64_unix.S blake3_avx2_x86-64_unix.S \
209    blake3_avx512_x86-64_unix.S
210```
211
212When building the intrinsics-based implementations, you need to build
213each implementation separately, with the corresponding instruction set
214explicitly enabled in the compiler. Here's the same shared library using
215the intrinsics-based implementations:
216
217```bash
218gcc -c -fPIC -O3 -msse2 blake3_sse2.c -o blake3_sse2.o
219gcc -c -fPIC -O3 -msse4.1 blake3_sse41.c -o blake3_sse41.o
220gcc -c -fPIC -O3 -mavx2 blake3_avx2.c -o blake3_avx2.o
221gcc -c -fPIC -O3 -mavx512f -mavx512vl blake3_avx512.c -o blake3_avx512.o
222gcc -shared -O3 -o libblake3.so blake3.c blake3_dispatch.c blake3_portable.c \
223    blake3_avx2.o blake3_avx512.o blake3_sse41.o blake3_sse2.o
224```
225
226Note above that building `blake3_avx512.c` requires both `-mavx512f` and
227`-mavx512vl` under GCC and Clang. Under MSVC, the single `/arch:AVX512`
228flag is sufficient. The MSVC equivalent of `-mavx2` is `/arch:AVX2`.
229MSVC enables SSE2 and SSE4.1 by defaut, and it doesn't have a
230corresponding flag.
231
232If you want to omit SIMD code entirely, you need to explicitly disable
233each instruction set. Here's an example of building a shared library on
234x86 with only portable code:
235
236```bash
237gcc -shared -O3 -o libblake3.so -DBLAKE3_NO_SSE2 -DBLAKE3_NO_SSE41 -DBLAKE3_NO_AVX2 \
238    -DBLAKE3_NO_AVX512 blake3.c blake3_dispatch.c blake3_portable.c
239```
240
241## ARM NEON
242
243The NEON implementation is not enabled by default on ARM, since not all
244ARM targets support it. To enable it, set `BLAKE3_USE_NEON=1`. Here's an
245example of building a shared library on ARM Linux with NEON support:
246
247```bash
248gcc -shared -O3 -o libblake3.so -DBLAKE3_USE_NEON blake3.c blake3_dispatch.c \
249    blake3_portable.c blake3_neon.c
250```
251
252Note that on some targets (ARMv7 in particular), extra flags may be
253required to activate NEON support in the compiler. If you see an error
254like...
255
256```
257/usr/lib/gcc/armv7l-unknown-linux-gnueabihf/9.2.0/include/arm_neon.h:635:1: error: inlining failed
258in call to always_inline ‘vaddq_u32’: target specific option mismatch
259```
260
261...then you may need to add something like `-mfpu=neon-vfpv4
262-mfloat-abi=hard`.
263
264## Other Platforms
265
266The portable implementation should work on most other architectures. For
267example:
268
269```bash
270gcc -shared -O3 -o libblake3.so blake3.c blake3_dispatch.c blake3_portable.c
271```
272
273# Multithreading
274
275Unlike the Rust implementation, the C implementation doesn't currently support
276multithreading. A future version of this library could add support by taking an
277optional dependency on OpenMP or similar. Alternatively, we could expose a
278lower-level API to allow callers to implement concurrency themselves. The
279former would be more convenient and less error-prone, but the latter would give
280callers the maximum possible amount of control. The best choice here depends on
281the specific use case, so if you have a use case for multithreaded hashing in
282C, please file a GitHub issue and let us know.
283