Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
blake2s.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7/*
8 BLAKE2 reference source code package - reference C implementations
9
10 Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
11 terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
12 your option. The terms of these licenses can be found at:
13
14 - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
15 - OpenSSL license : https://www.openssl.org/source/license.html
16 - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
17
18 More information about the BLAKE2 hash function can be found at
19 https://blake2.net.
20*/
21
22#include <cstdint>
23#include <cstdio>
24#include <cstring>
25
26#include "blake2-impl.hpp"
27#include "blake2s.hpp"
28
29namespace bb::crypto {
30
31static const uint32_t blake2s_IV[8] = { 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
32 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL };
33
34static const uint8_t blake2s_sigma[10][16] = {
35 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
36 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
37 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
38 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
39 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
40};
41
42static void blake2s_set_lastnode(blake2s_state* S)
43{
44 S->f[1] = (uint32_t)-1;
45}
46
47/* Some helper functions, not necessarily useful */
48static int blake2s_is_lastblock(const blake2s_state* S)
49{
50 return S->f[0] != 0;
51}
52
53static void blake2s_set_lastblock(blake2s_state* S)
54{
55 if (S->last_node)
56 blake2s_set_lastnode(S);
57
58 S->f[0] = (uint32_t)-1;
59}
60
61static void blake2s_increment_counter(blake2s_state* S, const uint32_t inc)
62{
63 S->t[0] += inc;
64 S->t[1] += (S->t[0] < inc);
65}
66
67static void blake2s_init0(blake2s_state* S)
68{
69 size_t i;
70 memset(S, 0, sizeof(blake2s_state));
71
72 for (i = 0; i < 8; ++i)
73 S->h[i] = blake2s_IV[i];
74}
75
76/* init2 xors IV with input parameter block */
78{
79 const unsigned char* p = (const unsigned char*)(P);
80 size_t i;
81
82 blake2s_init0(S);
83
84 /* IV XOR ParamBlock */
85 for (i = 0; i < 8; ++i)
86 S->h[i] ^= load32(&p[i * 4]);
87
88 S->outlen = P->digest_length;
89 return 0;
90}
91
92/* Sequential blake2s initialization */
93int blake2s_init(blake2s_state* S, size_t outlen)
94{
95 blake2s_param P[1];
96
97 /* Move interval verification here? */
98 if ((!outlen) || (outlen > BLAKE2S_OUTBYTES))
99 return -1;
100
101 P->digest_length = (uint8_t)outlen;
102 P->key_length = 0;
103 P->fanout = 1;
104 P->depth = 1;
105 store32(&P->leaf_length, 0);
106 store32(&P->node_offset, 0);
107 store16(&P->xof_length, 0);
108 P->node_depth = 0;
109 P->inner_length = 0;
110 /* memset(P->reserved, 0, sizeof(P->reserved) ); */
111 memset(P->salt, 0, sizeof(P->salt));
112 memset(P->personal, 0, sizeof(P->personal));
113 return blake2s_init_param(S, P);
114}
115
116#define G(r, i, a, b, c, d) \
117 do { \
118 a = a + b + m[blake2s_sigma[r][2 * i + 0]]; \
119 d = rotr32(d ^ a, 16); \
120 c = c + d; \
121 b = rotr32(b ^ c, 12); \
122 a = a + b + m[blake2s_sigma[r][2 * i + 1]]; \
123 d = rotr32(d ^ a, 8); \
124 c = c + d; \
125 b = rotr32(b ^ c, 7); \
126 } while (0)
127
128#define ROUND(r) \
129 do { \
130 G(r, 0, v[0], v[4], v[8], v[12]); \
131 G(r, 1, v[1], v[5], v[9], v[13]); \
132 G(r, 2, v[2], v[6], v[10], v[14]); \
133 G(r, 3, v[3], v[7], v[11], v[15]); \
134 G(r, 4, v[0], v[5], v[10], v[15]); \
135 G(r, 5, v[1], v[6], v[11], v[12]); \
136 G(r, 6, v[2], v[7], v[8], v[13]); \
137 G(r, 7, v[3], v[4], v[9], v[14]); \
138 } while (0)
139
140static void blake2s_compress(blake2s_state* S, const uint8_t in[BLAKE2S_BLOCKBYTES])
141{
142 uint32_t m[16];
143 uint32_t v[16];
144 size_t i;
145
146 for (i = 0; i < 16; ++i) {
147 m[i] = load32(in + i * sizeof(m[i]));
148 }
149
150 for (i = 0; i < 8; ++i) {
151 v[i] = S->h[i];
152 }
153
154 v[8] = blake2s_IV[0];
155 v[9] = blake2s_IV[1];
156 v[10] = blake2s_IV[2];
157 v[11] = blake2s_IV[3];
158 v[12] = S->t[0] ^ blake2s_IV[4];
159 v[13] = S->t[1] ^ blake2s_IV[5];
160 v[14] = S->f[0] ^ blake2s_IV[6];
161 v[15] = S->f[1] ^ blake2s_IV[7];
162
163 ROUND(0);
164 ROUND(1);
165 ROUND(2);
166 ROUND(3);
167 ROUND(4);
168 ROUND(5);
169 ROUND(6);
170 ROUND(7);
171 ROUND(8);
172 ROUND(9);
173
174 for (i = 0; i < 8; ++i) {
175 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
176 }
177}
178
179#undef G
180#undef ROUND
181
182int blake2s_update(blake2s_state* S, const void* pin, size_t inlen)
183{
184 const unsigned char* in = (const unsigned char*)pin;
185 if (inlen > 0) {
186 size_t left = S->buflen;
187 size_t fill = BLAKE2S_BLOCKBYTES - left;
188 if (inlen > fill) {
189 S->buflen = 0;
190 memcpy(S->buf + left, in, fill); /* Fill buffer */
191 blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);
192 blake2s_compress(S, S->buf); /* Compress */
193 in += fill;
194 inlen -= fill;
195 while (inlen > BLAKE2S_BLOCKBYTES) {
196 blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);
197 blake2s_compress(S, in);
198 in += BLAKE2S_BLOCKBYTES;
199 inlen -= BLAKE2S_BLOCKBYTES;
200 }
201 }
202 memcpy(S->buf + S->buflen, in, inlen);
203 S->buflen += inlen;
204 }
205 return 0;
206}
207
208int blake2s_final(blake2s_state* S, void* out, size_t outlen)
209{
210 uint8_t buffer[BLAKE2S_OUTBYTES] = { 0 };
211 size_t i;
212
213 if (out == NULL || outlen < S->outlen)
214 return -1;
215
216 if (blake2s_is_lastblock(S))
217 return -1;
218
219 blake2s_increment_counter(S, (uint32_t)S->buflen);
220 blake2s_set_lastblock(S);
221 memset(S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen); /* Padding */
222 blake2s_compress(S, S->buf);
223
224 for (i = 0; i < 8; ++i) /* Output full hash to temp buffer */
225 store32(buffer + sizeof(S->h[i]) * i, S->h[i]);
226
227 memcpy(out, buffer, outlen);
228 secure_zero_memory(buffer, sizeof(buffer));
229 return 0;
230}
231
232std::array<uint8_t, BLAKE2S_OUTBYTES> blake2s(std::vector<uint8_t> const& input)
233{
234 blake2s_state S[1];
237 blake2s_update(S, (const uint8_t*)input.data(), input.size());
238 blake2s_final(S, output.data(), output.size());
239 return output;
240}
241
242} // namespace bb::crypto
#define ROUND(r)
Definition blake2s.cpp:128
uint8_t buffer[RANDOM_BUFFER_SIZE]
Definition engine.cpp:34
int blake2s_update(blake2s_state *S, const void *pin, size_t inlen)
Definition blake2s.cpp:182
@ BLAKE2S_OUTBYTES
Definition blake2s.hpp:38
@ BLAKE2S_BLOCKBYTES
Definition blake2s.hpp:37
struct blake2s_param__ blake2s_param
Definition blake2s.hpp:69
int blake2s_init(blake2s_state *S, size_t outlen)
Definition blake2s.cpp:93
std::array< uint8_t, BLAKE2S_OUTBYTES > blake2s(std::vector< uint8_t > const &input)
Definition blake2s.cpp:232
int blake2s_init_param(blake2s_state *S, const blake2s_param *P)
Definition blake2s.cpp:77
struct bb::crypto::blake2s_state__ blake2s_state
int blake2s_final(blake2s_state *S, void *out, size_t outlen)
Definition blake2s.cpp:208
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
uint8_t buf[BLAKE2S_BLOCKBYTES]
Definition blake2s.hpp:48