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