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