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

..03-May-2022-

.gitignoreH A D25-Aug-202011 32

Makefile.testingH A D31-Aug-20201.8 KiB7657

README.mdH A D10-Sep-20208.5 KiB270209

blake3.cH A D29-Sep-202026.3 KiB604380

blake3.hH A D10-Sep-20201.9 KiB5943

blake3_avx2.cH A D25-Aug-202012.1 KiB326294

blake3_avx2_x86-64_unix.SH A D31-Aug-202064.5 KiB1,8161,809

blake3_avx2_x86-64_windows_gnu.SH A D25-Aug-202065.2 KiB1,8181,815

blake3_avx2_x86-64_windows_msvc.asmH A D25-Aug-202064.4 KiB1,8291,813

blake3_avx512.cH A D25-Aug-202046.8 KiB1,2051,046

blake3_avx512_x86-64_unix.SH A D31-Aug-202087.3 KiB2,5862,578

blake3_avx512_x86-64_windows_gnu.SH A D25-Aug-202088.9 KiB2,6162,607

blake3_avx512_x86-64_windows_msvc.asmH A D25-Aug-202089.5 KiB2,6352,626

blake3_dispatch.cH A D31-Aug-20207.2 KiB271250

blake3_impl.hH A D29-Sep-20209.7 KiB270224

blake3_neon.cH A D29-Sep-202012.4 KiB347295

blake3_portable.cH A D29-Sep-20205.8 KiB161144

blake3_sse2.cH A D02-Sep-202020.5 KiB566502

blake3_sse2_x86-64_unix.SH A D31-Aug-202067.2 KiB2,2922,284

blake3_sse2_x86-64_windows_gnu.SH A D31-Aug-202069.5 KiB2,3332,327

blake3_sse2_x86-64_windows_msvc.asmH A D31-Aug-202069.3 KiB2,3512,333

blake3_sse41.cH A D25-Aug-202020.3 KiB560497

blake3_sse41_x86-64_unix.SH A D31-Aug-202059.7 KiB2,0292,021

blake3_sse41_x86-64_windows_gnu.SH A D25-Aug-202062 KiB2,0702,064

blake3_sse41_x86-64_windows_msvc.asmH A D25-Aug-202061.7 KiB2,0902,070

main.cH A D25-Aug-20203.9 KiB167141

test.pyH A D25-Aug-20203.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
38If you save the example code above as `example.c`, and you're on x86\_64
39with a Unix-like OS, you can compile a working binary like this:
40
41```bash
42gcc -O3 -o example example.c blake3.c blake3_dispatch.c blake3_portable.c \
43    blake3_sse2_x86-64_unix.S blake3_sse41_x86-64_unix.S blake3_avx2_x86-64_unix.S \
44    blake3_avx512_x86-64_unix.S
45```
46
47# API
48
49## The Struct
50
51```c
52typedef struct {
53  // private fields
54} blake3_hasher;
55```
56
57An incremental BLAKE3 hashing state, which can accept any number of
58updates. This implementation doesn't allocate any heap memory, but
59`sizeof(blake3_hasher)` itself is relatively large, currently 1912 bytes
60on x86-64. This size can be reduced by restricting the maximum input
61length, as described in Section 5.4 of [the BLAKE3
62spec](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf),
63but this implementation doesn't currently support that strategy.
64
65## Common API Functions
66
67```c
68void blake3_hasher_init(
69  blake3_hasher *self);
70```
71
72Initialize a `blake3_hasher` in the default hashing mode.
73
74---
75
76```c
77void blake3_hasher_update(
78  blake3_hasher *self,
79  const void *input,
80  size_t input_len);
81```
82
83Add input to the hasher. This can be called any number of times.
84
85---
86
87```c
88void blake3_hasher_finalize(
89  const blake3_hasher *self,
90  uint8_t *out,
91  size_t out_len);
92```
93
94Finalize the hasher and emit an output of any length. This doesn't
95modify the hasher itself, and it's possible to finalize again after
96adding more input. The constant `BLAKE3_OUT_LEN` provides the default
97output length, 32 bytes.
98
99## Less Common API Functions
100
101```c
102void blake3_hasher_init_keyed(
103  blake3_hasher *self,
104  const uint8_t key[BLAKE3_KEY_LEN]);
105```
106
107Initialize a `blake3_hasher` in the keyed hashing mode. The key must be
108exactly 32 bytes.
109
110---
111
112```c
113void blake3_hasher_init_derive_key(
114  blake3_hasher *self,
115  const char *context);
116```
117
118Initialize a `blake3_hasher` in the key derivation mode. The context
119string is given as an initialization parameter, and afterwards input key
120material should be given with `blake3_hasher_update`. The context string
121is a null-terminated C string which should be **hardcoded, globally
122unique, and application-specific**. The context string should not
123include any dynamic input like salts, nonces, or identifiers read from a
124database at runtime. A good default format for the context string is
125`"[application] [commit timestamp] [purpose]"`, e.g., `"example.com
1262019-12-25 16:18:03 session tokens v1"`.
127
128This function is intended for application code written in C. For
129language bindings, see `blake3_hasher_init_derive_key_raw` below.
130
131---
132
133```c
134void blake3_hasher_init_derive_key_raw(
135  blake3_hasher *self,
136  const void *context,
137  size_t context_len);
138```
139
140As `blake3_hasher_init_derive_key` above, except that the context string
141is given as a pointer to an array of arbitrary bytes with a provided
142length. This is intended for writing language bindings, where C string
143conversion would add unnecessary overhead and new error cases. Unicode
144strings should be encoded as UTF-8.
145
146Application code in C should prefer `blake3_hasher_init_derive_key`,
147which takes the context as a C string. If you need to use arbitrary
148bytes as a context string in application code, consider whether you're
149violating the requirement that context strings should be hardcoded.
150
151---
152
153```c
154void blake3_hasher_finalize_seek(
155  const blake3_hasher *self,
156  uint64_t seek,
157  uint8_t *out,
158  size_t out_len);
159```
160
161The same as `blake3_hasher_finalize`, but with an additional `seek`
162parameter for the starting byte position in the output stream. To
163efficiently stream a large output without allocating memory, call this
164function in a loop, incrementing `seek` by the output length each time.
165
166# Building
167
168This implementation is just C and assembly files. It doesn't include a
169public-facing build system. (The `Makefile` in this directory is only
170for testing.) Instead, the intention is that you can include these files
171in whatever build system you're already using. This section describes
172the commands your build system should execute, or which you can execute
173by hand. Note that these steps may change in future versions.
174
175## x86
176
177Dynamic dispatch is enabled by default on x86. The implementation will
178query the CPU at runtime to detect SIMD support, and it will use the
179widest instruction set available. By default, `blake3_dispatch.c`
180expects to be linked with code for five different instruction sets:
181portable C, SSE2, SSE4.1, AVX2, and AVX-512.
182
183For each of the x86 SIMD instruction sets, two versions are available,
184one in assembly (with three flavors: Unix, Windows MSVC, and Windows
185GNU) and one using C intrinsics. The assembly versions are generally
186preferred: they perform better, they perform more consistently across
187different compilers, and they build more quickly. On the other hand, the
188assembly versions are x86\_64-only, and you need to select the right
189flavor for your target platform.
190
191Here's an example of building a shared library on x86\_64 Linux using
192the assembly implementations:
193
194```bash
195gcc -shared -O3 -o libblake3.so blake3.c blake3_dispatch.c blake3_portable.c \
196    blake3_sse2_x86-64_unix.S blake3_sse41_x86-64_unix.S blake3_avx2_x86-64_unix.S \
197    blake3_avx512_x86-64_unix.S
198```
199
200When building the intrinsics-based implementations, you need to build
201each implementation separately, with the corresponding instruction set
202explicitly enabled in the compiler. Here's the same shared library using
203the intrinsics-based implementations:
204
205```bash
206gcc -c -fPIC -O3 -msse2 blake3_sse2.c -o blake3_sse2.o
207gcc -c -fPIC -O3 -msse4.1 blake3_sse41.c -o blake3_sse41.o
208gcc -c -fPIC -O3 -mavx2 blake3_avx2.c -o blake3_avx2.o
209gcc -c -fPIC -O3 -mavx512f -mavx512vl blake3_avx512.c -o blake3_avx512.o
210gcc -shared -O3 -o libblake3.so blake3.c blake3_dispatch.c blake3_portable.c \
211    blake3_avx2.o blake3_avx512.o blake3_sse41.o blake3_sse2.o
212```
213
214Note above that building `blake3_avx512.c` requires both `-mavx512f` and
215`-mavx512vl` under GCC and Clang, as shown above. Under MSVC, the single
216`/arch:AVX512` flag is sufficient. The MSVC equivalent of `-mavx2` is
217`/arch:AVX2`. MSVC enables SSE4.1 by defaut, and it doesn't have a
218corresponding flag.
219
220If you want to omit SIMD code on x86, you need to explicitly disable
221each instruction set. Here's an example of building a shared library on
222x86 with only portable code:
223
224```bash
225gcc -shared -O3 -o libblake3.so -DBLAKE3_NO_SSE2 -DBLAKE3_NO_SSE41 -DBLAKE3_NO_AVX2 \
226    -DBLAKE3_NO_AVX512 blake3.c blake3_dispatch.c blake3_portable.c
227```
228
229## ARM NEON
230
231The NEON implementation is not enabled by default on ARM, since not all
232ARM targets support it. To enable it, set `BLAKE3_USE_NEON=1`. Here's an
233example of building a shared library on ARM Linux with NEON support:
234
235```bash
236gcc -shared -O3 -o libblake3.so -DBLAKE3_USE_NEON blake3.c blake3_dispatch.c \
237    blake3_portable.c blake3_neon.c
238```
239
240Note that on some targets (ARMv7 in particular), extra flags may be
241required to activate NEON support in the compiler. If you see an error
242like...
243
244```
245/usr/lib/gcc/armv7l-unknown-linux-gnueabihf/9.2.0/include/arm_neon.h:635:1: error: inlining failed
246in call to always_inline ‘vaddq_u32’: target specific option mismatch
247```
248
249...then you may need to add something like `-mfpu=neon-vfpv4
250-mfloat-abi=hard`.
251
252## Other Platforms
253
254The portable implementation should work on most other architectures. For
255example:
256
257```bash
258gcc -shared -O3 -o libblake3.so blake3.c blake3_dispatch.c blake3_portable.c
259```
260
261# Differences from the Rust Implementation
262
263The single-threaded Rust and C implementations use the same algorithms,
264and their performance is the same if you use the assembly
265implementations or if you compile the intrinsics-based implementations
266with Clang. (Both Clang and rustc are LLVM-based.)
267
268The C implementation doesn't currently include any multithreading
269optimizations. OpenMP support or similar might be added in the future.
270