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