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