1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3
4 /*
5 BLAKE2 reference source code package - reference C implementations
6
7 Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
8 terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
9 your option. The terms of these licenses can be found at:
10
11 - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
12 - OpenSSL license : https://www.openssl.org/source/license.html
13 - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
14
15 More information about the BLAKE2 hash function can be found at
16 https://blake2.net.
17 */
18 /* see also https://www.ietf.org/rfc/rfc7693.txt */
19
20 #include "tomcrypt_private.h"
21
22 #ifdef LTC_BLAKE2B
23
24 enum blake2b_constant {
25 BLAKE2B_BLOCKBYTES = 128,
26 BLAKE2B_OUTBYTES = 64,
27 BLAKE2B_KEYBYTES = 64,
28 BLAKE2B_SALTBYTES = 16,
29 BLAKE2B_PERSONALBYTES = 16,
30 BLAKE2B_PARAM_SIZE = 64
31 };
32
33 /* param offsets */
34 enum {
35 O_DIGEST_LENGTH = 0,
36 O_KEY_LENGTH = 1,
37 O_FANOUT = 2,
38 O_DEPTH = 3,
39 O_LEAF_LENGTH = 4,
40 O_NODE_OFFSET = 8,
41 O_XOF_LENGTH = 12,
42 O_NODE_DEPTH = 16,
43 O_INNER_LENGTH = 17,
44 O_RESERVED = 18,
45 O_SALT = 32,
46 O_PERSONAL = 48
47 };
48
49 /*
50 struct blake2b_param {
51 unsigned char digest_length;
52 unsigned char key_length;
53 unsigned char fanout;
54 unsigned char depth;
55 ulong32 leaf_length;
56 ulong32 node_offset;
57 ulong32 xof_length;
58 unsigned char node_depth;
59 unsigned char inner_length;
60 unsigned char reserved[14];
61 unsigned char salt[BLAKE2B_SALTBYTES];
62 unsigned char personal[BLAKE2B_PERSONALBYTES];
63 };
64 */
65
66 const struct ltc_hash_descriptor blake2b_160_desc =
67 {
68 "blake2b-160",
69 25,
70 20,
71 128,
72 { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 5 },
73 11,
74 &blake2b_160_init,
75 &blake2b_process,
76 &blake2b_done,
77 &blake2b_160_test,
78 NULL
79 };
80
81 const struct ltc_hash_descriptor blake2b_256_desc =
82 {
83 "blake2b-256",
84 26,
85 32,
86 128,
87 { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 8 },
88 11,
89 &blake2b_256_init,
90 &blake2b_process,
91 &blake2b_done,
92 &blake2b_256_test,
93 NULL
94 };
95
96 const struct ltc_hash_descriptor blake2b_384_desc =
97 {
98 "blake2b-384",
99 27,
100 48,
101 128,
102 { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 12 },
103 11,
104 &blake2b_384_init,
105 &blake2b_process,
106 &blake2b_done,
107 &blake2b_384_test,
108 NULL
109 };
110
111 const struct ltc_hash_descriptor blake2b_512_desc =
112 {
113 "blake2b-512",
114 28,
115 64,
116 128,
117 { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 16 },
118 11,
119 &blake2b_512_init,
120 &blake2b_process,
121 &blake2b_done,
122 &blake2b_512_test,
123 NULL
124 };
125
126 static const ulong64 blake2b_IV[8] =
127 {
128 CONST64(0x6a09e667f3bcc908), CONST64(0xbb67ae8584caa73b),
129 CONST64(0x3c6ef372fe94f82b), CONST64(0xa54ff53a5f1d36f1),
130 CONST64(0x510e527fade682d1), CONST64(0x9b05688c2b3e6c1f),
131 CONST64(0x1f83d9abfb41bd6b), CONST64(0x5be0cd19137e2179)
132 };
133
134 static const unsigned char blake2b_sigma[12][16] =
135 {
136 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
137 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
138 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
139 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
140 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
141 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
142 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
143 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
144 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
145 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
146 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
147 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
148 };
149
s_blake2b_set_lastnode(hash_state * md)150 static void s_blake2b_set_lastnode(hash_state *md) { md->blake2b.f[1] = CONST64(0xffffffffffffffff); }
151
152 /* Some helper functions, not necessarily useful */
s_blake2b_is_lastblock(const hash_state * md)153 static int s_blake2b_is_lastblock(const hash_state *md) { return md->blake2b.f[0] != 0; }
154
s_blake2b_set_lastblock(hash_state * md)155 static void s_blake2b_set_lastblock(hash_state *md)
156 {
157 if (md->blake2b.last_node) {
158 s_blake2b_set_lastnode(md);
159 }
160 md->blake2b.f[0] = CONST64(0xffffffffffffffff);
161 }
162
s_blake2b_increment_counter(hash_state * md,ulong64 inc)163 static void s_blake2b_increment_counter(hash_state *md, ulong64 inc)
164 {
165 md->blake2b.t[0] += inc;
166 if (md->blake2b.t[0] < inc) md->blake2b.t[1]++;
167 }
168
s_blake2b_init0(hash_state * md)169 static void s_blake2b_init0(hash_state *md)
170 {
171 unsigned long i;
172 XMEMSET(&md->blake2b, 0, sizeof(md->blake2b));
173
174 for (i = 0; i < 8; ++i) {
175 md->blake2b.h[i] = blake2b_IV[i];
176 }
177 }
178
179 /* init xors IV with input parameter block */
s_blake2b_init_param(hash_state * md,const unsigned char * P)180 static int s_blake2b_init_param(hash_state *md, const unsigned char *P)
181 {
182 unsigned long i;
183
184 s_blake2b_init0(md);
185
186 /* IV XOR ParamBlock */
187 for (i = 0; i < 8; ++i) {
188 ulong64 tmp;
189 LOAD64L(tmp, P + i * 8);
190 md->blake2b.h[i] ^= tmp;
191 }
192
193 md->blake2b.outlen = P[O_DIGEST_LENGTH];
194 return CRYPT_OK;
195 }
196
197 /**
198 Initialize the hash/MAC state
199
200 Use this function to init for arbitrary sizes.
201
202 Give a key and keylen to init for MAC mode.
203
204 @param md The hash state you wish to initialize
205 @param outlen The desired output-length
206 @param key The key of the MAC
207 @param keylen The length of the key
208 @return CRYPT_OK if successful
209 */
blake2b_init(hash_state * md,unsigned long outlen,const unsigned char * key,unsigned long keylen)210 int blake2b_init(hash_state *md, unsigned long outlen, const unsigned char *key, unsigned long keylen)
211 {
212 unsigned char P[BLAKE2B_PARAM_SIZE];
213 int err;
214
215 LTC_ARGCHK(md != NULL);
216
217 if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) {
218 return CRYPT_INVALID_ARG;
219 }
220 if ((key && !keylen) || (keylen && !key) || (keylen > BLAKE2B_KEYBYTES)) {
221 return CRYPT_INVALID_ARG;
222 }
223
224 XMEMSET(P, 0, sizeof(P));
225
226 P[O_DIGEST_LENGTH] = (unsigned char)outlen;
227 P[O_KEY_LENGTH] = (unsigned char)keylen;
228 P[O_FANOUT] = 1;
229 P[O_DEPTH] = 1;
230
231 err = s_blake2b_init_param(md, P);
232 if (err != CRYPT_OK) return err;
233
234 if (key) {
235 unsigned char block[BLAKE2B_BLOCKBYTES];
236
237 XMEMSET(block, 0, BLAKE2B_BLOCKBYTES);
238 XMEMCPY(block, key, keylen);
239 blake2b_process(md, block, BLAKE2B_BLOCKBYTES);
240
241 #ifdef LTC_CLEAN_STACK
242 zeromem(block, sizeof(block));
243 #endif
244 }
245
246 return CRYPT_OK;
247 }
248
249 /**
250 Initialize the hash state
251 @param md The hash state you wish to initialize
252 @return CRYPT_OK if successful
253 */
blake2b_160_init(hash_state * md)254 int blake2b_160_init(hash_state *md) { return blake2b_init(md, 20, NULL, 0); }
255
256 /**
257 Initialize the hash state
258 @param md The hash state you wish to initialize
259 @return CRYPT_OK if successful
260 */
blake2b_256_init(hash_state * md)261 int blake2b_256_init(hash_state *md) { return blake2b_init(md, 32, NULL, 0); }
262
263 /**
264 Initialize the hash state
265 @param md The hash state you wish to initialize
266 @return CRYPT_OK if successful
267 */
blake2b_384_init(hash_state * md)268 int blake2b_384_init(hash_state *md) { return blake2b_init(md, 48, NULL, 0); }
269
270 /**
271 Initialize the hash state
272 @param md The hash state you wish to initialize
273 @return CRYPT_OK if successful
274 */
blake2b_512_init(hash_state * md)275 int blake2b_512_init(hash_state *md) { return blake2b_init(md, 64, NULL, 0); }
276
277 #define G(r, i, a, b, c, d) \
278 do { \
279 a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
280 d = ROR64(d ^ a, 32); \
281 c = c + d; \
282 b = ROR64(b ^ c, 24); \
283 a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
284 d = ROR64(d ^ a, 16); \
285 c = c + d; \
286 b = ROR64(b ^ c, 63); \
287 } while (0)
288
289 #define ROUND(r) \
290 do { \
291 G(r, 0, v[0], v[4], v[8], v[12]); \
292 G(r, 1, v[1], v[5], v[9], v[13]); \
293 G(r, 2, v[2], v[6], v[10], v[14]); \
294 G(r, 3, v[3], v[7], v[11], v[15]); \
295 G(r, 4, v[0], v[5], v[10], v[15]); \
296 G(r, 5, v[1], v[6], v[11], v[12]); \
297 G(r, 6, v[2], v[7], v[8], v[13]); \
298 G(r, 7, v[3], v[4], v[9], v[14]); \
299 } while (0)
300
301 #ifdef LTC_CLEAN_STACK
ss_blake2b_compress(hash_state * md,const unsigned char * buf)302 static int ss_blake2b_compress(hash_state *md, const unsigned char *buf)
303 #else
304 static int s_blake2b_compress(hash_state *md, const unsigned char *buf)
305 #endif
306 {
307 ulong64 m[16];
308 ulong64 v[16];
309 unsigned long i;
310
311 for (i = 0; i < 16; ++i) {
312 LOAD64L(m[i], buf + i * sizeof(m[i]));
313 }
314
315 for (i = 0; i < 8; ++i) {
316 v[i] = md->blake2b.h[i];
317 }
318
319 v[8] = blake2b_IV[0];
320 v[9] = blake2b_IV[1];
321 v[10] = blake2b_IV[2];
322 v[11] = blake2b_IV[3];
323 v[12] = blake2b_IV[4] ^ md->blake2b.t[0];
324 v[13] = blake2b_IV[5] ^ md->blake2b.t[1];
325 v[14] = blake2b_IV[6] ^ md->blake2b.f[0];
326 v[15] = blake2b_IV[7] ^ md->blake2b.f[1];
327
328 ROUND(0);
329 ROUND(1);
330 ROUND(2);
331 ROUND(3);
332 ROUND(4);
333 ROUND(5);
334 ROUND(6);
335 ROUND(7);
336 ROUND(8);
337 ROUND(9);
338 ROUND(10);
339 ROUND(11);
340
341 for (i = 0; i < 8; ++i) {
342 md->blake2b.h[i] = md->blake2b.h[i] ^ v[i] ^ v[i + 8];
343 }
344 return CRYPT_OK;
345 }
346
347 #undef G
348 #undef ROUND
349
350 #ifdef LTC_CLEAN_STACK
s_blake2b_compress(hash_state * md,const unsigned char * buf)351 static int s_blake2b_compress(hash_state *md, const unsigned char *buf)
352 {
353 int err;
354 err = ss_blake2b_compress(md, buf);
355 burn_stack(sizeof(ulong64) * 32 + sizeof(unsigned long));
356 return err;
357 }
358 #endif
359
360 /**
361 Process a block of memory through the hash
362 @param md The hash state
363 @param in The data to hash
364 @param inlen The length of the data (octets)
365 @return CRYPT_OK if successful
366 */
blake2b_process(hash_state * md,const unsigned char * in,unsigned long inlen)367 int blake2b_process(hash_state *md, const unsigned char *in, unsigned long inlen)
368 {
369 LTC_ARGCHK(md != NULL);
370 LTC_ARGCHK(in != NULL);
371
372 if (md->blake2b.curlen > sizeof(md->blake2b.buf)) {
373 return CRYPT_INVALID_ARG;
374 }
375
376 if (inlen > 0) {
377 unsigned long left = md->blake2b.curlen;
378 unsigned long fill = BLAKE2B_BLOCKBYTES - left;
379 if (inlen > fill) {
380 md->blake2b.curlen = 0;
381 XMEMCPY(md->blake2b.buf + (left % sizeof(md->blake2b.buf)), in, fill); /* Fill buffer */
382 s_blake2b_increment_counter(md, BLAKE2B_BLOCKBYTES);
383 s_blake2b_compress(md, md->blake2b.buf); /* Compress */
384 in += fill;
385 inlen -= fill;
386 while (inlen > BLAKE2B_BLOCKBYTES) {
387 s_blake2b_increment_counter(md, BLAKE2B_BLOCKBYTES);
388 s_blake2b_compress(md, in);
389 in += BLAKE2B_BLOCKBYTES;
390 inlen -= BLAKE2B_BLOCKBYTES;
391 }
392 }
393 XMEMCPY(md->blake2b.buf + md->blake2b.curlen, in, inlen);
394 md->blake2b.curlen += inlen;
395 }
396 return CRYPT_OK;
397 }
398
399 /**
400 Terminate the hash to get the digest
401 @param md The hash state
402 @param out [out] The destination of the hash (size depending on the length used on init)
403 @return CRYPT_OK if successful
404 */
blake2b_done(hash_state * md,unsigned char * out)405 int blake2b_done(hash_state *md, unsigned char *out)
406 {
407 unsigned char buffer[BLAKE2B_OUTBYTES] = { 0 };
408 unsigned long i;
409
410 LTC_ARGCHK(md != NULL);
411 LTC_ARGCHK(out != NULL);
412
413 /* if(md->blakebs.outlen != outlen) return CRYPT_INVALID_ARG; */
414
415 if (s_blake2b_is_lastblock(md)) {
416 return CRYPT_ERROR;
417 }
418
419 s_blake2b_increment_counter(md, md->blake2b.curlen);
420 s_blake2b_set_lastblock(md);
421 XMEMSET(md->blake2b.buf + md->blake2b.curlen, 0, BLAKE2B_BLOCKBYTES - md->blake2b.curlen); /* Padding */
422 s_blake2b_compress(md, md->blake2b.buf);
423
424 for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */
425 STORE64L(md->blake2b.h[i], buffer + i * 8);
426 }
427
428 XMEMCPY(out, buffer, md->blake2b.outlen);
429 zeromem(md, sizeof(hash_state));
430 #ifdef LTC_CLEAN_STACK
431 zeromem(buffer, sizeof(buffer));
432 #endif
433 return CRYPT_OK;
434 }
435
436 /**
437 Self-test the hash
438 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
439 */
blake2b_512_test(void)440 int blake2b_512_test(void)
441 {
442 #ifndef LTC_TEST
443 return CRYPT_NOP;
444 #else
445 static const struct {
446 const char *msg;
447 unsigned char hash[64];
448 } tests[] = {
449 { "",
450 { 0x78, 0x6a, 0x02, 0xf7, 0x42, 0x01, 0x59, 0x03,
451 0xc6, 0xc6, 0xfd, 0x85, 0x25, 0x52, 0xd2, 0x72,
452 0x91, 0x2f, 0x47, 0x40, 0xe1, 0x58, 0x47, 0x61,
453 0x8a, 0x86, 0xe2, 0x17, 0xf7, 0x1f, 0x54, 0x19,
454 0xd2, 0x5e, 0x10, 0x31, 0xaf, 0xee, 0x58, 0x53,
455 0x13, 0x89, 0x64, 0x44, 0x93, 0x4e, 0xb0, 0x4b,
456 0x90, 0x3a, 0x68, 0x5b, 0x14, 0x48, 0xb7, 0x55,
457 0xd5, 0x6f, 0x70, 0x1a, 0xfe, 0x9b, 0xe2, 0xce } },
458 { "abc",
459 { 0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d,
460 0x6a, 0x27, 0x97, 0xb6, 0x9f, 0x12, 0xf6, 0xe9,
461 0x4c, 0x21, 0x2f, 0x14, 0x68, 0x5a, 0xc4, 0xb7,
462 0x4b, 0x12, 0xbb, 0x6f, 0xdb, 0xff, 0xa2, 0xd1,
463 0x7d, 0x87, 0xc5, 0x39, 0x2a, 0xab, 0x79, 0x2d,
464 0xc2, 0x52, 0xd5, 0xde, 0x45, 0x33, 0xcc, 0x95,
465 0x18, 0xd3, 0x8a, 0xa8, 0xdb, 0xf1, 0x92, 0x5a,
466 0xb9, 0x23, 0x86, 0xed, 0xd4, 0x00, 0x99, 0x23 } },
467
468 { NULL, { 0 } }
469 };
470
471 int i;
472 unsigned char tmp[64];
473 hash_state md;
474
475 for (i = 0; tests[i].msg != NULL; i++) {
476 blake2b_512_init(&md);
477 blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
478 blake2b_done(&md, tmp);
479 if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_512", i)) {
480 return CRYPT_FAIL_TESTVECTOR;
481 }
482 }
483 return CRYPT_OK;
484 #endif
485 }
486
487 /**
488 Self-test the hash
489 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
490 */
blake2b_384_test(void)491 int blake2b_384_test(void)
492 {
493 #ifndef LTC_TEST
494 return CRYPT_NOP;
495 #else
496 static const struct {
497 const char *msg;
498 unsigned char hash[48];
499 } tests[] = {
500 { "",
501 { 0xb3, 0x28, 0x11, 0x42, 0x33, 0x77, 0xf5, 0x2d,
502 0x78, 0x62, 0x28, 0x6e, 0xe1, 0xa7, 0x2e, 0xe5,
503 0x40, 0x52, 0x43, 0x80, 0xfd, 0xa1, 0x72, 0x4a,
504 0x6f, 0x25, 0xd7, 0x97, 0x8c, 0x6f, 0xd3, 0x24,
505 0x4a, 0x6c, 0xaf, 0x04, 0x98, 0x81, 0x26, 0x73,
506 0xc5, 0xe0, 0x5e, 0xf5, 0x83, 0x82, 0x51, 0x00 } },
507 { "abc",
508 { 0x6f, 0x56, 0xa8, 0x2c, 0x8e, 0x7e, 0xf5, 0x26,
509 0xdf, 0xe1, 0x82, 0xeb, 0x52, 0x12, 0xf7, 0xdb,
510 0x9d, 0xf1, 0x31, 0x7e, 0x57, 0x81, 0x5d, 0xbd,
511 0xa4, 0x60, 0x83, 0xfc, 0x30, 0xf5, 0x4e, 0xe6,
512 0xc6, 0x6b, 0xa8, 0x3b, 0xe6, 0x4b, 0x30, 0x2d,
513 0x7c, 0xba, 0x6c, 0xe1, 0x5b, 0xb5, 0x56, 0xf4 } },
514
515 { NULL, { 0 } }
516 };
517
518 int i;
519 unsigned char tmp[48];
520 hash_state md;
521
522 for (i = 0; tests[i].msg != NULL; i++) {
523 blake2b_384_init(&md);
524 blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
525 blake2b_done(&md, tmp);
526 if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_384", i)) {
527 return CRYPT_FAIL_TESTVECTOR;
528 }
529 }
530 return CRYPT_OK;
531 #endif
532 }
533
534 /**
535 Self-test the hash
536 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
537 */
blake2b_256_test(void)538 int blake2b_256_test(void)
539 {
540 #ifndef LTC_TEST
541 return CRYPT_NOP;
542 #else
543 static const struct {
544 const char *msg;
545 unsigned char hash[32];
546 } tests[] = {
547 { "",
548 { 0x0e, 0x57, 0x51, 0xc0, 0x26, 0xe5, 0x43, 0xb2,
549 0xe8, 0xab, 0x2e, 0xb0, 0x60, 0x99, 0xda, 0xa1,
550 0xd1, 0xe5, 0xdf, 0x47, 0x77, 0x8f, 0x77, 0x87,
551 0xfa, 0xab, 0x45, 0xcd, 0xf1, 0x2f, 0xe3, 0xa8 } },
552 { "abc",
553 { 0xbd, 0xdd, 0x81, 0x3c, 0x63, 0x42, 0x39, 0x72,
554 0x31, 0x71, 0xef, 0x3f, 0xee, 0x98, 0x57, 0x9b,
555 0x94, 0x96, 0x4e, 0x3b, 0xb1, 0xcb, 0x3e, 0x42,
556 0x72, 0x62, 0xc8, 0xc0, 0x68, 0xd5, 0x23, 0x19 } },
557 { "12345678901234567890123456789012345678901234567890"
558 "12345678901234567890123456789012345678901234567890"
559 "12345678901234567890123456789012345678901234567890"
560 "12345678901234567890123456789012345678901234567890"
561 "12345678901234567890123456789012345678901234567890"
562 "12345678901234567890123456789012345678901234567890",
563 { 0x0f, 0x6e, 0x01, 0x8d, 0x38, 0xd6, 0x3f, 0x08,
564 0x4d, 0x58, 0xe3, 0x0c, 0x90, 0xfb, 0xa2, 0x41,
565 0x5f, 0xca, 0x17, 0xfa, 0x66, 0x26, 0x49, 0xf3,
566 0x8a, 0x30, 0x41, 0x7c, 0x57, 0xcd, 0xa8, 0x14 } },
567
568 { NULL, { 0 } }
569 };
570
571 int i;
572 unsigned char tmp[32];
573 hash_state md;
574
575 for (i = 0; tests[i].msg != NULL; i++) {
576 blake2b_256_init(&md);
577 blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
578 blake2b_done(&md, tmp);
579 if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_256", i)) {
580 return CRYPT_FAIL_TESTVECTOR;
581 }
582 }
583 return CRYPT_OK;
584 #endif
585 }
586
587 /**
588 Self-test the hash
589 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
590 */
blake2b_160_test(void)591 int blake2b_160_test(void)
592 {
593 #ifndef LTC_TEST
594 return CRYPT_NOP;
595 #else
596 static const struct {
597 const char *msg;
598 unsigned char hash[20];
599 } tests[] = {
600 { "",
601 { 0x33, 0x45, 0x52, 0x4a, 0xbf, 0x6b, 0xbe, 0x18,
602 0x09, 0x44, 0x92, 0x24, 0xb5, 0x97, 0x2c, 0x41,
603 0x79, 0x0b, 0x6c, 0xf2 } },
604 { "abc",
605 { 0x38, 0x42, 0x64, 0xf6, 0x76, 0xf3, 0x95, 0x36,
606 0x84, 0x05, 0x23, 0xf2, 0x84, 0x92, 0x1c, 0xdc,
607 0x68, 0xb6, 0x84, 0x6b } },
608
609 { NULL, { 0 } }
610 };
611
612 int i;
613 unsigned char tmp[20];
614 hash_state md;
615
616 for (i = 0; tests[i].msg != NULL; i++) {
617 blake2b_160_init(&md);
618 blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
619 blake2b_done(&md, tmp);
620 if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_160", i)) {
621 return CRYPT_FAIL_TESTVECTOR;
622 }
623 }
624 return CRYPT_OK;
625 #endif
626 }
627
628 #endif
629