16#include "hashx_endian.h"
18static const uint64_t blake2b_IV[8] = {
19 UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b),
20 UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1),
21 UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f),
22 UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179) };
24#define BLAKE2_SIGMA_0_0 0
25#define BLAKE2_SIGMA_0_1 1
26#define BLAKE2_SIGMA_0_2 2
27#define BLAKE2_SIGMA_0_3 3
28#define BLAKE2_SIGMA_0_4 4
29#define BLAKE2_SIGMA_0_5 5
30#define BLAKE2_SIGMA_0_6 6
31#define BLAKE2_SIGMA_0_7 7
32#define BLAKE2_SIGMA_0_8 8
33#define BLAKE2_SIGMA_0_9 9
34#define BLAKE2_SIGMA_0_10 10
35#define BLAKE2_SIGMA_0_11 11
36#define BLAKE2_SIGMA_0_12 12
37#define BLAKE2_SIGMA_0_13 13
38#define BLAKE2_SIGMA_0_14 14
39#define BLAKE2_SIGMA_0_15 15
41#define BLAKE2_SIGMA_1_0 14
42#define BLAKE2_SIGMA_1_1 10
43#define BLAKE2_SIGMA_1_2 4
44#define BLAKE2_SIGMA_1_3 8
45#define BLAKE2_SIGMA_1_4 9
46#define BLAKE2_SIGMA_1_5 15
47#define BLAKE2_SIGMA_1_6 13
48#define BLAKE2_SIGMA_1_7 6
49#define BLAKE2_SIGMA_1_8 1
50#define BLAKE2_SIGMA_1_9 12
51#define BLAKE2_SIGMA_1_10 0
52#define BLAKE2_SIGMA_1_11 2
53#define BLAKE2_SIGMA_1_12 11
54#define BLAKE2_SIGMA_1_13 7
55#define BLAKE2_SIGMA_1_14 5
56#define BLAKE2_SIGMA_1_15 3
58#define BLAKE2_SIGMA_2_0 11
59#define BLAKE2_SIGMA_2_1 8
60#define BLAKE2_SIGMA_2_2 12
61#define BLAKE2_SIGMA_2_3 0
62#define BLAKE2_SIGMA_2_4 5
63#define BLAKE2_SIGMA_2_5 2
64#define BLAKE2_SIGMA_2_6 15
65#define BLAKE2_SIGMA_2_7 13
66#define BLAKE2_SIGMA_2_8 10
67#define BLAKE2_SIGMA_2_9 14
68#define BLAKE2_SIGMA_2_10 3
69#define BLAKE2_SIGMA_2_11 6
70#define BLAKE2_SIGMA_2_12 7
71#define BLAKE2_SIGMA_2_13 1
72#define BLAKE2_SIGMA_2_14 9
73#define BLAKE2_SIGMA_2_15 4
75#define BLAKE2_SIGMA_3_0 7
76#define BLAKE2_SIGMA_3_1 9
77#define BLAKE2_SIGMA_3_2 3
78#define BLAKE2_SIGMA_3_3 1
79#define BLAKE2_SIGMA_3_4 13
80#define BLAKE2_SIGMA_3_5 12
81#define BLAKE2_SIGMA_3_6 11
82#define BLAKE2_SIGMA_3_7 14
83#define BLAKE2_SIGMA_3_8 2
84#define BLAKE2_SIGMA_3_9 6
85#define BLAKE2_SIGMA_3_10 5
86#define BLAKE2_SIGMA_3_11 10
87#define BLAKE2_SIGMA_3_12 4
88#define BLAKE2_SIGMA_3_13 0
89#define BLAKE2_SIGMA_3_14 15
90#define BLAKE2_SIGMA_3_15 8
92#define BLAKE2_SIGMA_4_0 9
93#define BLAKE2_SIGMA_4_1 0
94#define BLAKE2_SIGMA_4_2 5
95#define BLAKE2_SIGMA_4_3 7
96#define BLAKE2_SIGMA_4_4 2
97#define BLAKE2_SIGMA_4_5 4
98#define BLAKE2_SIGMA_4_6 10
99#define BLAKE2_SIGMA_4_7 15
100#define BLAKE2_SIGMA_4_8 14
101#define BLAKE2_SIGMA_4_9 1
102#define BLAKE2_SIGMA_4_10 11
103#define BLAKE2_SIGMA_4_11 12
104#define BLAKE2_SIGMA_4_12 6
105#define BLAKE2_SIGMA_4_13 8
106#define BLAKE2_SIGMA_4_14 3
107#define BLAKE2_SIGMA_4_15 13
109#define BLAKE2_SIGMA_5_0 2
110#define BLAKE2_SIGMA_5_1 12
111#define BLAKE2_SIGMA_5_2 6
112#define BLAKE2_SIGMA_5_3 10
113#define BLAKE2_SIGMA_5_4 0
114#define BLAKE2_SIGMA_5_5 11
115#define BLAKE2_SIGMA_5_6 8
116#define BLAKE2_SIGMA_5_7 3
117#define BLAKE2_SIGMA_5_8 4
118#define BLAKE2_SIGMA_5_9 13
119#define BLAKE2_SIGMA_5_10 7
120#define BLAKE2_SIGMA_5_11 5
121#define BLAKE2_SIGMA_5_12 15
122#define BLAKE2_SIGMA_5_13 14
123#define BLAKE2_SIGMA_5_14 1
124#define BLAKE2_SIGMA_5_15 9
126#define BLAKE2_SIGMA_6_0 12
127#define BLAKE2_SIGMA_6_1 5
128#define BLAKE2_SIGMA_6_2 1
129#define BLAKE2_SIGMA_6_3 15
130#define BLAKE2_SIGMA_6_4 14
131#define BLAKE2_SIGMA_6_5 13
132#define BLAKE2_SIGMA_6_6 4
133#define BLAKE2_SIGMA_6_7 10
134#define BLAKE2_SIGMA_6_8 0
135#define BLAKE2_SIGMA_6_9 7
136#define BLAKE2_SIGMA_6_10 6
137#define BLAKE2_SIGMA_6_11 3
138#define BLAKE2_SIGMA_6_12 9
139#define BLAKE2_SIGMA_6_13 2
140#define BLAKE2_SIGMA_6_14 8
141#define BLAKE2_SIGMA_6_15 11
143#define BLAKE2_SIGMA_7_0 13
144#define BLAKE2_SIGMA_7_1 11
145#define BLAKE2_SIGMA_7_2 7
146#define BLAKE2_SIGMA_7_3 14
147#define BLAKE2_SIGMA_7_4 12
148#define BLAKE2_SIGMA_7_5 1
149#define BLAKE2_SIGMA_7_6 3
150#define BLAKE2_SIGMA_7_7 9
151#define BLAKE2_SIGMA_7_8 5
152#define BLAKE2_SIGMA_7_9 0
153#define BLAKE2_SIGMA_7_10 15
154#define BLAKE2_SIGMA_7_11 4
155#define BLAKE2_SIGMA_7_12 8
156#define BLAKE2_SIGMA_7_13 6
157#define BLAKE2_SIGMA_7_14 2
158#define BLAKE2_SIGMA_7_15 10
160#define BLAKE2_SIGMA_8_0 6
161#define BLAKE2_SIGMA_8_1 15
162#define BLAKE2_SIGMA_8_2 14
163#define BLAKE2_SIGMA_8_3 9
164#define BLAKE2_SIGMA_8_4 11
165#define BLAKE2_SIGMA_8_5 3
166#define BLAKE2_SIGMA_8_6 0
167#define BLAKE2_SIGMA_8_7 8
168#define BLAKE2_SIGMA_8_8 12
169#define BLAKE2_SIGMA_8_9 2
170#define BLAKE2_SIGMA_8_10 13
171#define BLAKE2_SIGMA_8_11 7
172#define BLAKE2_SIGMA_8_12 1
173#define BLAKE2_SIGMA_8_13 4
174#define BLAKE2_SIGMA_8_14 10
175#define BLAKE2_SIGMA_8_15 5
177#define BLAKE2_SIGMA_9_0 10
178#define BLAKE2_SIGMA_9_1 2
179#define BLAKE2_SIGMA_9_2 8
180#define BLAKE2_SIGMA_9_3 4
181#define BLAKE2_SIGMA_9_4 7
182#define BLAKE2_SIGMA_9_5 6
183#define BLAKE2_SIGMA_9_6 1
184#define BLAKE2_SIGMA_9_7 5
185#define BLAKE2_SIGMA_9_8 15
186#define BLAKE2_SIGMA_9_9 11
187#define BLAKE2_SIGMA_9_10 9
188#define BLAKE2_SIGMA_9_11 14
189#define BLAKE2_SIGMA_9_12 3
190#define BLAKE2_SIGMA_9_13 12
191#define BLAKE2_SIGMA_9_14 13
192#define BLAKE2_SIGMA_9_15 0
194#define BLAKE2_SIGMA_10_0 0
195#define BLAKE2_SIGMA_10_1 1
196#define BLAKE2_SIGMA_10_2 2
197#define BLAKE2_SIGMA_10_3 3
198#define BLAKE2_SIGMA_10_4 4
199#define BLAKE2_SIGMA_10_5 5
200#define BLAKE2_SIGMA_10_6 6
201#define BLAKE2_SIGMA_10_7 7
202#define BLAKE2_SIGMA_10_8 8
203#define BLAKE2_SIGMA_10_9 9
204#define BLAKE2_SIGMA_10_10 10
205#define BLAKE2_SIGMA_10_11 11
206#define BLAKE2_SIGMA_10_12 12
207#define BLAKE2_SIGMA_10_13 13
208#define BLAKE2_SIGMA_10_14 14
209#define BLAKE2_SIGMA_10_15 15
211#define BLAKE2_SIGMA_11_0 14
212#define BLAKE2_SIGMA_11_1 10
213#define BLAKE2_SIGMA_11_2 4
214#define BLAKE2_SIGMA_11_3 8
215#define BLAKE2_SIGMA_11_4 9
216#define BLAKE2_SIGMA_11_5 15
217#define BLAKE2_SIGMA_11_6 13
218#define BLAKE2_SIGMA_11_7 6
219#define BLAKE2_SIGMA_11_8 1
220#define BLAKE2_SIGMA_11_9 12
221#define BLAKE2_SIGMA_11_10 0
222#define BLAKE2_SIGMA_11_11 2
223#define BLAKE2_SIGMA_11_12 11
224#define BLAKE2_SIGMA_11_13 7
225#define BLAKE2_SIGMA_11_14 5
226#define BLAKE2_SIGMA_11_15 3
228static FORCE_INLINE uint64_t rotr64(
const uint64_t w,
const unsigned c) {
229 return (w >> c) | (w << (64 - c));
232static FORCE_INLINE
void blake2b_set_lastblock(
blake2b_state* S) {
233 S->f[0] = (uint64_t)-1;
236static FORCE_INLINE
void blake2b_increment_counter(
blake2b_state* S,
239 S->t[1] += (S->t[0] < inc);
243 memset(S, 0,
sizeof(*S));
244 memcpy(S->h, blake2b_IV,
sizeof(S->h));
248 const unsigned char* p = (
const unsigned char*)P;
251 if (NULL == P || NULL == S) {
257 for (i = 0; i < 8; ++i) {
258 S->h[i] ^= load64(&p[i *
sizeof(S->h[i])]);
260 S->outlen = P->digest_length;
264#define SIGMA(r, k) BLAKE2_SIGMA_ ## r ## _ ## k
266#define G(r, i, j, a, b, c, d) \
268 a = a + b + m[SIGMA(r, i)]; \
269 d = rotr64(d ^ a, 32); \
271 b = rotr64(b ^ c, 24); \
272 a = a + b + m[SIGMA(r, j)]; \
273 d = rotr64(d ^ a, 16); \
275 b = rotr64(b ^ c, 63); \
278#define ROUND_INNER(r) \
280 G(r, 0, 1, v[0], v[4], v[8], v[12]); \
281 G(r, 2, 3, v[1], v[5], v[9], v[13]); \
282 G(r, 4, 5, v[2], v[6], v[10], v[14]); \
283 G(r, 6, 7, v[3], v[7], v[11], v[15]); \
284 G(r, 8, 9, v[0], v[5], v[10], v[15]); \
285 G(r, 10, 11, v[1], v[6], v[11], v[12]); \
286 G(r, 12, 13, v[2], v[7], v[8], v[13]); \
287 G(r, 14, 15, v[3], v[4], v[9], v[14]); \
290#define ROUND(r) ROUND_INNER(r)
292static void blake2b_compress(
blake2b_state* S,
const uint8_t* block) {
297 for (i = 0; i < 16; ++i) {
298 m[i] = load64(block + i *
sizeof(m[i]));
301 for (i = 0; i < 8; ++i) {
305 v[8] = blake2b_IV[0];
306 v[9] = blake2b_IV[1];
307 v[10] = blake2b_IV[2];
308 v[11] = blake2b_IV[3];
309 v[12] = blake2b_IV[4] ^ S->t[0];
310 v[13] = blake2b_IV[5] ^ S->t[1];
311 v[14] = blake2b_IV[6] ^ S->f[0];
312 v[15] = blake2b_IV[7] ^ S->f[1];
327 for (i = 0; i < 8; ++i) {
328 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
332static void blake2b_compress_4r(
blake2b_state* S,
const uint8_t* block) {
337 for (i = 0; i < 16; ++i) {
338 m[i] = load64(block + i *
sizeof(m[i]));
341 for (i = 0; i < 8; ++i) {
345 v[8] = blake2b_IV[0];
346 v[9] = blake2b_IV[1];
347 v[10] = blake2b_IV[2];
348 v[11] = blake2b_IV[3];
349 v[12] = blake2b_IV[4] ^ S->t[0];
350 v[13] = blake2b_IV[5] ^ S->t[1];
351 v[14] = blake2b_IV[6] ^ S->f[0];
352 v[15] = blake2b_IV[7] ^ S->f[1];
359 for (i = 0; i < 8; ++i) {
360 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
364int hashx_blake2b_update(
blake2b_state* S,
const void* in,
size_t inlen) {
365 const uint8_t* pin = (
const uint8_t*)in;
372 if (S == NULL || in == NULL) {
381 if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) {
383 size_t left = S->buflen;
384 size_t fill = BLAKE2B_BLOCKBYTES - left;
385 memcpy(&S->buf[left], pin, fill);
386 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
387 blake2b_compress(S, S->buf);
392 while (inlen > BLAKE2B_BLOCKBYTES) {
393 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
394 blake2b_compress(S, pin);
395 inlen -= BLAKE2B_BLOCKBYTES;
396 pin += BLAKE2B_BLOCKBYTES;
399 memcpy(&S->buf[S->buflen], pin, inlen);
400 S->buflen += (
unsigned int)inlen;
404int hashx_blake2b_final(
blake2b_state* S,
void* out,
size_t outlen) {
405 uint8_t buffer[BLAKE2B_OUTBYTES] = { 0 };
409 if (S == NULL || out == NULL || outlen < S->outlen) {
418 blake2b_increment_counter(S, S->buflen);
419 blake2b_set_lastblock(S);
420 memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen);
421 blake2b_compress(S, S->buf);
423 for (i = 0; i < 8; ++i) {
424 store64(buffer +
sizeof(S->h[i]) * i, S->h[i]);
427 memcpy(out, buffer, S->outlen);
433void hashx_blake2b_4r(
const blake2b_param* params,
const void* in,
434 size_t inlen,
void* out) {
437 const uint8_t* p = (
const uint8_t*)params;
439 blake2b_init0(&state);
441 for (
unsigned i = 0; i < 8; ++i) {
442 state.h[i] ^= load64(&p[i *
sizeof(state.h[i])]);
446 const uint8_t* pin = (
const uint8_t*)in;
448 while (inlen > BLAKE2B_BLOCKBYTES) {
449 blake2b_increment_counter(&state, BLAKE2B_BLOCKBYTES);
450 blake2b_compress_4r(&state, pin);
451 inlen -= BLAKE2B_BLOCKBYTES;
452 pin += BLAKE2B_BLOCKBYTES;
455 memcpy(state.buf, pin, inlen);
456 blake2b_increment_counter(&state, inlen);
457 blake2b_set_lastblock(&state);
458 blake2b_compress_4r(&state, state.buf);
461 memcpy(out, state.h,
sizeof(state.h));