chiark / gitweb /
97a3f7a8afe7b8d755abbdd082bcb4e3fdfdb504
[catacomb] / symm / sha3.c
1 /* -*-c-*-
2  *
3  * The SHA3 algorithm family
4  *
5  * (c) 2017 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of Catacomb.
11  *
12  * Catacomb is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU Library General Public License as
14  * published by the Free Software Foundation; either version 2 of the
15  * License, or (at your option) any later version.
16  *
17  * Catacomb is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public
23  * License along with Catacomb; if not, write to the Free
24  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25  * MA 02111-1307, USA.
26  */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #include <assert.h>
31 #include <stdarg.h>
32 #include <string.h>
33
34 #include "hash.h"
35 #include "ghash-def.h"
36 #include "sha3.h"
37
38 /*----- General utilities -------------------------------------------------*/
39
40 static void absorb(sha3_ctx *ctx, const octet *p, unsigned r)
41 {
42   kludge64 t[25];
43   unsigned i;
44
45 /* memdump("absorb", p, 8*r, 0); */
46   for (i = 0; i < r; i++) { LOAD64_L_(t[i], p); p += 8; }
47   keccak1600_mix(&ctx->s, t, r);
48 }
49
50 static void step(sha3_ctx *ctx) { keccak1600_p(&ctx->s, &ctx->s, 24); }
51
52 static void pad(sha3_ctx *ctx, unsigned lo, unsigned hi)
53 {
54   size_t spare = ctx->r - ctx->n;
55
56   if (spare == 1)
57     ctx->buf[ctx->n] = lo | hi;
58   else {
59     ctx->buf[ctx->n] = lo;
60     ctx->buf[ctx->r - 1] = hi;
61     memset(ctx->buf + ctx->n + 1, 0, spare - 2);
62   }
63   absorb(ctx, ctx->buf, ctx->r/8);
64 }
65
66 static void squeeze(sha3_ctx *ctx, octet *p, unsigned r)
67 {
68   kludge64 t[25];
69   unsigned i;
70
71   keccak1600_extract(&ctx->s, t, r);
72   for (i = 0; i < r; i++) { STORE64_L_(p, t[i]); p += 8; }
73 /* memdump("squeeze", p - 8*r, 8*r, 0); */
74 }
75
76 enum {
77   OP_CSHAKE = 0x04,
78   OP_SHA3 = 0x06,
79   OP_SHAKE = 0x1f
80 };
81
82 enum { ST_ABSORB, ST_SQUEEZE, ST_DEAD };
83
84 /*----- The SHA3 algorithms -----------------------------------------------*/
85
86 /* --- @sha3_{224,256,384,512}_init@ --- *
87  *
88  * Arguments:   @sha3_ctx *ctx@ = pointer to context block to initialize
89  *
90  * Returns:     ---
91  *
92  * Use:         Initializes a SHA3 hashing context for use.
93  */
94
95 static void init_sha3(sha3_ctx *ctx, unsigned w)
96 {
97   keccak1600_init(&ctx->s);
98   ctx->w = w/8; ctx->r = (1600 - 2*w)/8; ctx->n = 0;
99 }
100
101 void sha3_224_init(sha3_ctx *ctx) { init_sha3(ctx, 224); }
102 void sha3_256_init(sha3_ctx *ctx) { init_sha3(ctx, 256); }
103 void sha3_384_init(sha3_ctx *ctx) { init_sha3(ctx, 384); }
104 void sha3_512_init(sha3_ctx *ctx) { init_sha3(ctx, 512); }
105
106 /* --- @sha3_hash@ --- *
107  *
108  * Arguments:   @sha3_ctx *ctx@ = pointer to context bock
109  *              @const void *p@ = pointer to data to hash
110  *              @size_t sz@ = size of buffer to hash
111  *
112  * Returns:     ---
113  *
114  * Use:         Hashes a buffer of data.  The buffer may be of any size and
115  *              alignment.
116  */
117
118 void sha3_hash(sha3_ctx *ctx, const void *p, size_t sz)
119 {
120   const octet *q = p;
121   size_t spare = ctx->r - ctx->n;
122
123   if (sz < spare) {
124     memcpy(ctx->buf + ctx->n, q, sz);
125     ctx->n += sz;
126     return;
127   }
128   if (ctx->n) {
129     memcpy(ctx->buf + ctx->n, q, spare);
130     absorb(ctx, ctx->buf, ctx->r/8);
131     step(ctx);
132     q += spare; sz -= spare;
133   }
134   while (sz >= ctx->r) {
135     absorb(ctx, q, ctx->r/8);
136     step(ctx);
137     q += ctx->r; sz -= ctx->r;
138   }
139   if (sz) memcpy(ctx->buf, q, sz);
140   ctx->n = sz;
141 }
142
143 /* --- @sha3_done@ --- *
144  *
145  * Arguments:   @sha3_ctx *ctx@ = pointer to context block
146  *              @void *hash@ = pointer to output buffer
147  *
148  * Returns:     ---
149  *
150  * Use:         Returns the hash of the data read so far.
151  */
152
153 void sha3_done(sha3_ctx *ctx, void *hash)
154 {
155   pad(ctx, OP_SHA3, 0x80);
156   step(ctx);
157
158   if (ctx->w%8 == 0)
159     squeeze(ctx, hash, ctx->w/8);
160   else {
161     squeeze(ctx, ctx->buf, (ctx->w + 7)/8);
162     memcpy(hash, ctx->buf, ctx->w);
163   }
164 }
165
166 /* --- @sha3_{224,256,384,512}_set@ --- *
167  *
168  * Arguments:   @sha3_ctx *ctx@ = pointer to context block
169  *              @const void *buf@ = pointer to state buffer
170  *              @unsigned long count@ = current count of bytes processed
171  *
172  * Returns:     ---
173  *
174  * Use:         Initializes a context block from a given state.  This is
175  *              something of a kludge for the benefit of HMAC, but there are
176  *              better ways to use SHA3 as a MAC.
177  *
178  *              Furthermore, the @count@ argument is expected to be zero or
179  *              be the output of @sha3_state@ below.  Doing anything else
180  *              won't work properly.
181  */
182
183 static void set(sha3_ctx *ctx, const void *buf,
184                 unsigned long count, unsigned w)
185 {
186   if (count)
187     memcpy(ctx, buf, sizeof(*ctx));
188   else {
189     static const char *prefix = "Catacomb SHA3 NMAC kludge";
190     init_sha3(ctx, w);
191     sha3_hash(ctx, prefix, sizeof(prefix));
192     sha3_hash(ctx, buf, SHA3_STATESZ);
193   }
194 }
195
196 void sha3_224_set(sha3_ctx *ctx, const void *buf, unsigned long count)
197   { set(ctx, buf, count, 224); }
198 void sha3_256_set(sha3_ctx *ctx, const void *buf, unsigned long count)
199   { set(ctx, buf, count, 256); }
200 void sha3_384_set(sha3_ctx *ctx, const void *buf, unsigned long count)
201   { set(ctx, buf, count, 384); }
202 void sha3_512_set(sha3_ctx *ctx, const void *buf, unsigned long count)
203   { set(ctx, buf, count, 512); }
204
205 /* --- @sha3_state@ --- *
206  *
207  * Arguments:   @sha3_ctx *ctx@ = pointer to context block
208  *              @void *state@ = pointer to buffer for current state
209  *
210  * Returns:     A value which is meaningful to @sha3_..._set@.
211  *
212  * Use:         Returns the current state of the hash function such that it
213  *              can be passed to @sha3_..._set@.
214  */
215
216 unsigned long sha3_state(sha3_ctx *ctx, void *state)
217   { memcpy(state, ctx, sizeof(*ctx)); return (1); }
218
219 #define HASHES(_)                                                       \
220   _(SHA3_224, sha3_224, "sha3-224")                                     \
221   _(SHA3_256, sha3_256, "sha3-256")                                     \
222   _(SHA3_384, sha3_384, "sha3-384")                                     \
223   _(SHA3_512, sha3_512, "sha3-512")
224 HASHES(GHASH_DEFX)
225
226 /*----- The cSHAKE XOF algorithm ------------------------------------------*/
227
228 static void leftenc_sz(shake_ctx *ctx, size_t n)
229 {
230   kludge64 t;
231   octet b[9];
232   unsigned i;
233
234   SET64(t, ((n&~MASK32) >> 16) >> 16, n&MASK32);
235   STORE64_B_(b + 1, t);
236   for (i = 1; i < 8 && !b[i]; i++);
237   i--; b[i] = 8 - i;
238   shake_hash(ctx, b + i, 9 - i);
239 }
240
241 static void rightenc_sz(shake_ctx *ctx, size_t n)
242 {
243   kludge64 t;
244   octet b[9];
245   unsigned i;
246
247   SET64(t, ((n&~MASK32) >> 16) >> 16, n&MASK32);
248   STORE64_B_(b, t);
249   for (i = 0; i < 7 && !b[i]; i++);
250   b[8] = 8 - i;
251   shake_hash(ctx, b + i, 9 - i);
252 }
253
254 static void stringenc(shake_ctx *ctx, const void *p, size_t sz)
255   { leftenc_sz(ctx, 8*sz); if (sz) shake_hash(ctx, p, sz); }
256
257 static void bytepad_before(shake_ctx *ctx)
258   { leftenc_sz(ctx, ctx->h.r); }
259
260 static void bytepad_after(shake_ctx *ctx)
261 {
262   unsigned pad;
263
264   if (ctx->h.n%8) {
265     pad = 8 - ctx->h.n%8;
266     memset(ctx->h.buf + ctx->h.n, 0, pad);
267     ctx->h.n += pad;
268   }
269   if (ctx->h.n) {
270     absorb(&ctx->h, ctx->h.buf, ctx->h.n/8);
271     step(&ctx->h); ctx->h.n = 0;
272   }
273 }
274
275 const octet
276   shake128_keysz[] = { KSZ_ANY, SHAKE128_KEYSZ },
277   shake256_keysz[] = { KSZ_ANY, SHAKE256_KEYSZ };
278
279 /* --- @cshake{128,256}_init@ --- *
280  *
281  * Arguments:   @shake_ctx *ctx@ = pointer to context to initialize
282  *              @const void *func@ = NIST-allocated function name
283  *              @size_t fsz@ = length of function name
284  *              @const void *perso@ = user personalization string
285  *              @size_t psz@ = length of personalization string
286  *
287  * Returns:     ---
288  *
289  * Use:         Initializes a cSHAKE context.  The context is initially in
290  *              the `absorbing' state: feed it data with @shake_hash@.
291  */
292
293 static void init_shake(shake_ctx *ctx, unsigned c0,
294                        const void *func, size_t fsz,
295                        const void *perso, size_t psz)
296 {
297   keccak1600_init(&ctx->h.s); ctx->st = ST_ABSORB;
298   ctx->h.r = (1600 - 2*c0)/8; ctx->h.w = 0; ctx->h.n = 0;
299   if (!fsz && !psz)
300     ctx->op = OP_SHAKE;
301   else {
302     bytepad_before(ctx);
303     stringenc(ctx, func, fsz);
304     stringenc(ctx, perso, psz);
305     bytepad_after(ctx);
306     ctx->op = OP_CSHAKE;
307   }
308 }
309
310 void cshake128_init(shake_ctx *ctx,
311                     const void *func, size_t fsz,
312                     const void *perso, size_t psz)
313   { init_shake(ctx, 128, func, fsz, perso, psz); }
314
315 void cshake256_init(shake_ctx *ctx,
316                     const void *func, size_t fsz,
317                     const void *perso, size_t psz)
318   { init_shake(ctx, 256, func, fsz, perso, psz); }
319
320 /* --- @shake{128,256}_init@ --- *
321  *
322  * Arguments:   @sha3_ctx *ctx@ = pointer to context to initialize
323  *
324  * Returns:     ---
325  *
326  * Use:         Initializes a SHAKE context.  The context is initially in
327  *              the `absorbing' state: feed it data with @shake_hash@.
328  */
329
330 void shake128_init(shake_ctx *ctx) { init_shake(ctx, 128, 0, 0, 0, 0); }
331 void shake256_init(shake_ctx *ctx) { init_shake(ctx, 256, 0, 0, 0, 0); }
332
333 /* --- @shake_hash@ --- *
334  *
335  * Arguments:   @shake_ctx *ctx@ = context to update
336  *              @const void *p@ = input buffer
337  *              @size_t sz@ = size of input
338  *
339  * Returns:     ---
340  *
341  * Use:         Feeds input data into a SHAKE context.  The context must be
342  *              in `absorbing' state.
343  */
344
345 void shake_hash(shake_ctx *ctx, const void *p, size_t sz)
346   { assert(ctx->st == ST_ABSORB); sha3_hash(&ctx->h, p, sz); }
347
348 /* --- @shake_xof@ --- *
349  *
350  * Arguments:   @shake_ctx *ctx@ = context to update
351  *
352  * Returns:     ---
353  *
354  * Use:         Switches the context into `squeezing' state.  Use @shake_get@
355  *              or @shake_mask@ to extract data.
356  */
357
358 void shake_xof(shake_ctx *ctx)
359 {
360   assert(ctx->st == ST_ABSORB);
361   pad(&ctx->h, ctx->op, 0x80);
362   ctx->st = ST_SQUEEZE;
363   ctx->h.n = ctx->h.r;
364 }
365
366 /* --- @shake_get@ --- *
367  *
368  * Arguments:   @shake_ctx *ctx@ = context to update
369  *              @void *p@ = output buffer
370  *              @size_t sz@ = size of output
371  *
372  * Returns:     ---
373  *
374  * Use:         Extracts output from a SHAKE context.  The context must be
375  *              in `squeezing' state.
376  */
377
378 void shake_get(shake_ctx *ctx, void *p, size_t sz)
379 {
380   octet *q = p;
381   size_t left = ctx->h.r - ctx->h.n;
382
383   assert(ctx->st == ST_SQUEEZE);
384   if (left >= sz) {
385     memcpy(q, ctx->h.buf + ctx->h.n, sz);
386     ctx->h.n += sz;
387     return;
388   }
389   if (left) {
390     memcpy(q, ctx->h.buf + ctx->h.n, left);
391     q += left; sz -= left;
392   }
393   while (sz >= ctx->h.r) {
394     step(&ctx->h);
395     squeeze(&ctx->h, q, ctx->h.r/8);
396     q += ctx->h.r; sz -= ctx->h.r;
397   }
398   if (!sz)
399     ctx->h.n = ctx->h.r;
400   else {
401     step(&ctx->h);
402     squeeze(&ctx->h, ctx->h.buf, ctx->h.r/8);
403     memcpy(q, ctx->h.buf, sz);
404     ctx->h.n = sz;
405   }
406 }
407
408 /* --- @shake_mask@ --- *
409  *
410  * Arguments:   @shake_ctx *ctx@ = context to update
411  *              @const void *src@ = pointer to source data, or null
412  *              @void *dest@ = output buffer
413  *              @size_t sz@ = size of output
414  *
415  * Returns:     ---
416  *
417  * Use:         Mask the @src@ data by XORing it with output from the SHAKE
418  *              context, writing the result to @dest@.  The @src@ and @dest
419  *              buffers may be equal but must not otherwise overlap.  The
420  *              context must be in `squeezing' state.
421  */
422
423 void shake_mask(shake_ctx *ctx, const void *src, void *dest, size_t sz)
424 {
425   const octet *p = src, *pp, *l;
426   octet *q = dest;
427   size_t left = ctx->h.r - ctx->h.n;
428
429   if (!src) { shake_get(ctx, dest, sz); return; }
430
431   assert(ctx->st == ST_SQUEEZE);
432   if (left >= sz) {
433     pp = ctx->h.buf + ctx->h.n; l = q + sz;
434     while (q < l) *q++ = *p++ ^ *pp++;
435     ctx->h.n += sz;
436     return;
437   }
438   if (left) {
439     pp = ctx->h.buf + ctx->h.n; l = q + left;
440     while (q < l) *q++ = *p++ ^ *pp++;
441     sz -= left;
442   }
443   while (sz >= ctx->h.r) {
444     step(&ctx->h);
445     squeeze(&ctx->h, ctx->h.buf, ctx->h.r/8);
446     pp = ctx->h.buf; l = pp + ctx->h.r;
447     while (pp < l) *q++ = *p++ ^ *pp++;
448     sz -= ctx->h.r;
449   }
450   if (!sz)
451     ctx->h.n = ctx->h.r;
452   else {
453     step(&ctx->h);
454     squeeze(&ctx->h, ctx->h.buf, ctx->h.r/8);
455     pp = ctx->h.buf; l = q + sz;
456     while (q < l) *q++ = *p++ ^ *pp++;
457     ctx->h.n = sz;
458   }
459 }
460
461 /* --- @shake_done@ --- *
462  *
463  * Arguments:   @shake_ctx *ctx@ = context to update
464  *              @void *h@ = where to write the hash
465  *              @size_t hsz@ = size of the hash to make
466  *
467  * Returns:     ---
468  *
469  * Use:         Switches the context into `squeezing' state.  Use @shake_get@
470  *              or @shake_mask@ to extract data.
471  */
472
473 void shake_done(shake_ctx *ctx, void *h, size_t hsz)
474   { shake_xof(ctx); shake_get(ctx, h, hsz); ctx->st = ST_DEAD; }
475
476 /* --- Hash interface --- */
477
478 typedef struct shake_ghctx {
479   ghash h;
480   shake_ctx c;
481   octet hb[SHAKE256_HASHSZ];
482 } shake_ghctx;
483
484 static const ghash_ops shake128_ghops, shake256_ghops;
485
486 static void shake_ghhash(ghash *h, const void *p, size_t sz)
487   { shake_ghctx *cc = (shake_ghctx *)h; shake_hash(&cc->c, p, sz); }
488
489 static octet *shake_ghdone(ghash *h, void *buf)
490 {
491   shake_ghctx *cc = (shake_ghctx *)h;
492   if (!buf) buf = cc->hb;
493   shake_done(&cc->c, buf, h->ops->c->hashsz);
494   return (buf);
495 }
496
497 static void shake_ghdestroy(ghash *h)
498   { shake_ghctx *cc = (shake_ghctx *)h; BURN(cc); S_DESTROY(cc); }
499
500 static ghash *shake_ghcopy(ghash *h)
501 {
502   shake_ghctx *cc = (shake_ghctx *)h;
503   shake_ghctx *hc = S_CREATE(shake_ghctx);
504   *hc = *cc;
505   return (&hc->h);
506 }
507
508 static ghash *shake128_ghinit(void)
509 {
510   shake_ghctx *cc = S_CREATE(shake_ghctx);
511   cc->h.ops = &shake128_ghops;
512   shake128_init(&cc->c);
513   return (&cc->h);
514 }
515
516 static ghash *shake256_ghinit(void)
517 {
518   shake_ghctx *cc = S_CREATE(shake_ghctx);
519   cc->h.ops = &shake256_ghops;
520   shake256_init(&cc->c);
521   return (&cc->h);
522 }
523
524 const gchash
525   shake128 = { "shake128", SHAKE128_HASHSZ, shake128_ghinit, 168 },
526   shake256 = { "shake256", SHAKE256_HASHSZ, shake256_ghinit, 136 };
527
528 static const ghash_ops
529   shake128_ghops = { &shake128, shake_ghhash, shake_ghdone,
530                      shake_ghdestroy, shake_ghcopy },
531   shake256_ghops = { &shake256, shake_ghhash, shake_ghdone,
532                      shake_ghdestroy, shake_ghcopy };
533
534 /* --- Cipher interface --- */
535
536 typedef struct shake_gcctx {
537   gcipher gc;
538   shake_ctx c;
539 } shake_gcctx;
540
541 static const gcipher_ops shake128_gcops, shake256_gcops;
542
543 static void shake_gcencdec(gcipher *c, const void *s, void *d, size_t sz)
544   { shake_gcctx *cc = (shake_gcctx *)c; shake_mask(&cc->c, s, d, sz); }
545
546 static void shake_gcdestroy(gcipher *c)
547   { shake_gcctx *cc = (shake_gcctx *)c; BURN(*cc); S_DESTROY(cc); }
548
549 static const gcipher_ops
550   shake128_gcops = { &shake128_xof, shake_gcencdec, shake_gcencdec,
551                      shake_gcdestroy, 0, 0 },
552   shake256_gcops = { &shake256_xof, shake_gcencdec, shake_gcencdec,
553                      shake_gcdestroy, 0, 0 };
554
555 static gcipher *shake128_gcinit(const void *k, size_t sz)
556 {
557   shake_gcctx *cc = S_CREATE(shake_gcctx);
558   cc->gc.ops = &shake128_gcops;
559   shake128_init(&cc->c); shake_hash(&cc->c, k, sz); shake_xof(&cc->c);
560   return (&cc->gc);
561 }
562
563 static gcipher *shake256_gcinit(const void *k, size_t sz)
564 {
565   shake_gcctx *cc = S_CREATE(shake_gcctx);
566   cc->gc.ops = &shake256_gcops;
567   shake256_init(&cc->c); shake_hash(&cc->c, k, sz); shake_xof(&cc->c);
568   return (&cc->gc);
569 }
570
571 const gccipher
572   shake128_xof = { "shake128-xof", shake128_keysz, 0, shake128_gcinit },
573   shake256_xof = { "shake256-xof", shake256_keysz, 0, shake256_gcinit };
574
575 /* --- Random generator interface --- */
576
577 typedef struct shake_grctx {
578   grand gr;
579   shake_ctx c;
580 } shake_grctx;
581
582 static int shake_grmisc(grand *r, unsigned op, ...)
583 {
584   int rc = 0;
585   switch (op) {
586     case GRAND_CHECK: rc = 0; break;
587     default: GRAND_BADOP; break;
588   }
589   return (rc);
590 }
591
592 static void shake_grdestroy(grand *r)
593   { shake_grctx *cc = (shake_grctx *)r; BURN(cc); S_DESTROY(cc); }
594
595 static octet shake_grbyte(grand *r)
596 {
597   shake_grctx *cc = (shake_grctx *)r;
598   octet o;
599   shake_get(&cc->c, &o, 1);
600   return (o);
601 }
602
603 static uint32 shake_grword(grand *r)
604 {
605   shake_grctx *cc = (shake_grctx *)r;
606   octet b[4];
607   shake_get(&cc->c, &b, 4);
608   return (LOAD32(b));
609 }
610
611 static void shake_grfill(grand *r, void *p, size_t sz)
612   { shake_grctx *cc = (shake_grctx *)r; shake_get(&cc->c, p, sz); }
613
614 static const grand_ops
615   shake128_grops = { "shake128", GRAND_CRYPTO, 0,
616                      shake_grmisc, shake_grdestroy, shake_grword,
617                      shake_grbyte, shake_grword, grand_defaultrange,
618                      shake_grfill },
619   shake256_grops = { "shake256", GRAND_CRYPTO, 0,
620                      shake_grmisc, shake_grdestroy, shake_grword,
621                      shake_grbyte, shake_grword, grand_defaultrange,
622                      shake_grfill },
623   cshake128_grops = { "cshake128", GRAND_CRYPTO, 0,
624                       shake_grmisc, shake_grdestroy, shake_grword,
625                       shake_grbyte, shake_grword, grand_defaultrange,
626                       shake_grfill },
627   cshake256_grops = { "cshake256", GRAND_CRYPTO, 0,
628                       shake_grmisc, shake_grdestroy, shake_grword,
629                       shake_grbyte, shake_grword, grand_defaultrange,
630                       shake_grfill };
631
632 /* --- @shake{128,256}_rand@ --- *
633  *
634  * Arguments:   @const void *k@ = pointer to seed material
635  *              @size_t sz@ = size of the seed
636  *
637  * Returns:     A pseudorandom generator with the given seed.
638  */
639
640 grand *shake128_rand(const void *k, size_t sz)
641 {
642   shake_grctx *cc = S_CREATE(shake_grctx);
643   cc->gr.ops = &shake128_grops;
644   shake128_init(&cc->c); shake_hash(&cc->c, k, sz); shake_xof(&cc->c);
645   return (&cc->gr);
646 }
647
648 grand *shake256_rand(const void *k, size_t sz)
649 {
650   shake_grctx *cc = S_CREATE(shake_grctx);
651   cc->gr.ops = &shake256_grops;
652   shake256_init(&cc->c); shake_hash(&cc->c, k, sz); shake_xof(&cc->c);
653   return (&cc->gr);
654 }
655
656 /* --- @cshake{128,256}_rand@ --- *
657  *
658  * Arguments:   @const void *func@ = function name
659  *              @size_t fsz@ = length of function name
660  *              @const void *perso@ = personalization string
661  *              @size_t psz@ = length of personalization string
662  *              @const void *k@ = pointer to seed material
663  *              @size_t sz@ = size of the seed
664  *
665  * Returns:     A pseudorandom generator with the given seed.
666  */
667
668 grand *cshake128_rand(const void *func, size_t fsz,
669                       const void *perso, size_t psz,
670                       const void *k, size_t sz)
671 {
672   shake_grctx *cc = S_CREATE(shake_grctx);
673   cc->gr.ops = &cshake128_grops;
674   cshake128_init(&cc->c, func, fsz, perso, psz);
675   shake_hash(&cc->c, k, sz); shake_xof(&cc->c);
676   return (&cc->gr);
677 }
678
679 grand *cshake256_rand(const void *func, size_t fsz,
680                       const void *perso, size_t psz,
681                       const void *k, size_t sz)
682 {
683   shake_grctx *cc = S_CREATE(shake_grctx);
684   cc->gr.ops = &cshake256_grops;
685   cshake256_init(&cc->c, func, fsz, perso, psz);
686   shake_hash(&cc->c, k, sz); shake_xof(&cc->c);
687   return (&cc->gr);
688 }
689
690 /*----- The KMAC variable-length PRF --------------------------------------*/
691
692 typedef shake_ctx kmac_ctx;
693
694 /* --- @kmac{128,256}_init@ --- *
695  *
696  * Arguments:   @kmac_ctx *ctx@ = pointer to context to fill in
697  *              @const char *perso@ = personalization string, or null
698  *              @size_t psz@ = length of personalization string
699  *              @const void *k@ = pointer to key material
700  *              @size_t sz@ = size of key material
701  *
702  * Returns:     ---
703  *
704  * Use:         Sets up a KMAC context.  Use @kmac_hash@ to feed in the input
705  *              message.
706  */
707
708 static void init_kmac(kmac_ctx *ctx,
709                       unsigned c0, const void *perso, size_t psz,
710                       const void *k, size_t sz)
711 {
712   init_shake(ctx, c0, "KMAC", 4, perso, psz);
713   bytepad_before(ctx); stringenc(ctx, k, sz); bytepad_after(ctx);
714 }
715
716 void kmac128_init(kmac_ctx *ctx, const void *perso, size_t psz,
717                   const void *k, size_t sz)
718   { init_kmac(ctx, 128, perso, psz, k, sz); }
719
720 void kmac256_init(kmac_ctx *ctx, const void *perso, size_t psz,
721                   const void *k, size_t sz)
722   { init_kmac(ctx, 256, perso, psz, k, sz); }
723
724 /* --- @kmac_xof@ --- *
725  *
726  * Arguments:   @kmac_ctx *ctx@ = pointer to context
727  *
728  * Returns:     ---
729  *
730  * Use:         Marks the end of the message to be processed.  The output can
731  *              be read using @kmac_get@.
732  */
733
734 void kmac_xof(kmac_ctx *ctx)
735   { rightenc_sz(ctx, 0); shake_xof(ctx); }
736
737 /* --- @kmac_done@ --- *
738  *
739  * Arguments:   @kmac_ctx *ctx@ = pointer to context
740  *              @void *h@ = where to put the tag
741  *              @size_t hsz@ = size of tag to produce
742  *
743  * Returns:     ---
744  *
745  * Use:         Marks the end of the message to be processed and returns a
746  *              tag.  Note that the tag value is dependent on the output
747  *              size.
748  */
749
750 void kmac_done(kmac_ctx *ctx, void *h, size_t hsz)
751   { rightenc_sz(ctx, 8*hsz); shake_done(ctx, h, hsz); }
752
753 /* --- MAC interface --- */
754
755 typedef struct kmac_ghctx {
756   ghash h;
757   kmac_ctx c;
758   octet hb[KMAC256_TAGSZ];
759 } kmac_ghctx;
760
761 typedef struct kmac_gmctx {
762   gmac m;
763   kmac_ctx c;
764   const ghash_ops *hops;
765 } kmac_gmctx;
766
767 static const ghash_ops kmac128_ghops, kmac256_ghops;
768 static const gmac_ops kmac128_gmops, kmac256_gmops;
769
770 static void kmac_ghhash(ghash *h, const void *p, size_t sz)
771   { kmac_ghctx *cc = (kmac_ghctx *)h; kmac_hash(&cc->c, p, sz); }
772
773 static octet *kmac_ghdone(ghash *h, void *buf)
774 {
775   kmac_ghctx *cc = (kmac_ghctx *)h;
776   if (!buf) buf = cc->hb;
777   kmac_done(&cc->c, buf, cc->h.ops->c->hashsz);
778   return (buf);
779 }
780
781 static void kmac_ghdestroy(ghash *h)
782   { kmac_ghctx *cc = (kmac_ghctx *)h; BURN(cc); S_DESTROY(cc); }
783
784 static ghash *kmac_ghcopy(ghash *h)
785 {
786   kmac_ghctx *cc = (kmac_ghctx *)h;
787   kmac_ghctx *hc = S_CREATE(kmac_ghctx);
788   *hc = *cc;
789   return (&hc->h);
790 }
791
792 static ghash *kmac_ghinit(void)
793   { assert(((void)"Attempt to instantiate an unkeyed MAC", 0)); return (0); }
794
795 static ghash *kmac_gminit(gmac *m)
796 {
797   kmac_gmctx *cc = (kmac_gmctx *)m;
798   kmac_ghctx *hc = S_CREATE(kmac_ghctx);
799   hc->h.ops = cc->hops;
800   hc->c = cc->c;
801   return (&hc->h);
802 }
803
804 static void kmac_gmdestroy(gmac *m)
805   { kmac_gmctx *cc = (kmac_gmctx *)m; BURN(cc); S_DESTROY(cc); }
806
807 static gmac *kmac128_gmkey(const void *k, size_t sz)
808 {
809   kmac_gmctx *cc = S_CREATE(kmac_gmctx);
810   cc->m.ops = &kmac128_gmops; cc->hops = &kmac128_ghops;
811   kmac128_init(&cc->c, 0, 0, k, sz);
812   return (&cc->m);
813 }
814
815 static gmac *kmac256_gmkey(const void *k, size_t sz)
816 {
817   kmac_gmctx *cc = S_CREATE(kmac_gmctx);
818   cc->m.ops = &kmac256_gmops; cc->hops = &kmac256_ghops;
819   kmac256_init(&cc->c, 0, 0, k, sz);
820   return (&cc->m);
821 }
822
823 static const gchash
824   kmac128_ghcls = { "kmac128", KMAC128_TAGSZ, kmac_ghinit, 168 },
825   kmac256_ghcls = { "kmac256", KMAC256_TAGSZ, kmac_ghinit, 136 };
826
827 const gcmac
828   kmac128 = { "kmac128", KMAC128_TAGSZ, kmac128_keysz, kmac128_gmkey },
829   kmac256 = { "kmac256", KMAC256_TAGSZ, kmac256_keysz, kmac256_gmkey };
830
831 static const ghash_ops
832   kmac128_ghops = { &kmac128_ghcls, kmac_ghhash, kmac_ghdone,
833                     kmac_ghdestroy, kmac_ghcopy },
834   kmac256_ghops = { &kmac256_ghcls, kmac_ghhash, kmac_ghdone,
835                     kmac_ghdestroy, kmac_ghcopy };
836
837 static const gmac_ops
838   kmac128_gmops = { &kmac128, kmac_gminit, kmac_gmdestroy },
839   kmac256_gmops = { &kmac256, kmac_gminit, kmac_gmdestroy };
840
841 /* --- Random generator XOF interface --- */
842
843 typedef struct kmac_grctx {
844   grand gr;
845   kmac_ctx k, c;
846 } kmac_grctx;
847
848 static int kmac_grmisc(grand *r, unsigned op, ...)
849 {
850   kmac_grctx *cc = (kmac_grctx *)r;
851   int rc = 0;
852   octet buf[64];
853   va_list ap;
854   int i;
855   uint32 u;
856   grand *rr;
857   const void *p;
858   size_t sz;
859
860   va_start(ap, op);
861   switch (op) {
862     case GRAND_CHECK:
863       op = va_arg(ap, unsigned);
864       switch (op) {
865         case GRAND_SEEDINT: case GRAND_SEEDUINT32:
866         case GRAND_SEEDBLOCK: case GRAND_SEEDRAND:
867           rc = 1; break;
868         default:
869           rc = 0; break;
870       }
871       break;
872     case GRAND_SEEDINT:
873       i = va_arg(ap, int); STORE32_L(buf, i); p = buf; sz = 4; goto seed;
874     case GRAND_SEEDUINT32:
875       u = va_arg(ap, uint32); STORE32_L(buf, u); p = buf; sz = 4; goto seed;
876     case GRAND_SEEDRAND:
877       rr = va_arg(ap, grand *);
878       p = buf; sz = (200 - cc->c.h.r)/2; GR_FILL(rr, buf, sz); goto seed;
879     case GRAND_SEEDBLOCK:
880       p = va_arg(ap, const void *); sz = va_arg(ap, size_t);
881     seed:
882       cc->c = cc->k;
883       kmac_hash(&cc->c, p, sz);
884       kmac_xof(&cc->c);
885       break;
886     default: GRAND_BADOP; break;
887   }
888   return (rc);
889 }
890
891 static void kmac_grdestroy(grand *r)
892   { kmac_grctx *cc = (kmac_grctx *)r; BURN(cc); S_DESTROY(cc); }
893
894 static octet kmac_grbyte(grand *r)
895 {
896   kmac_grctx *cc = (kmac_grctx *)r;
897   octet o;
898   kmac_get(&cc->c, &o, 1);
899   return (o);
900 }
901
902 static uint32 kmac_grword(grand *r)
903 {
904   kmac_grctx *cc = (kmac_grctx *)r;
905   octet b[4];
906   kmac_get(&cc->c, &b, 4);
907   return (LOAD32(b));
908 }
909
910 static void kmac_grfill(grand *r, void *p, size_t sz)
911   { kmac_grctx *cc = (kmac_grctx *)r; kmac_get(&cc->c, p, sz); }
912
913 static const grand_ops
914   kmac128_grops = { "kmac128", GRAND_CRYPTO, 0,
915                     kmac_grmisc, kmac_grdestroy, kmac_grword,
916                     kmac_grbyte, kmac_grword, grand_defaultrange,
917                     kmac_grfill },
918   kmac256_grops = { "kmac256", GRAND_CRYPTO, 0,
919                     kmac_grmisc, kmac_grdestroy, kmac_grword,
920                     kmac_grbyte, kmac_grword, grand_defaultrange,
921                     kmac_grfill };
922
923 /* --- @kmac{128,256}_rand@ --- *
924  *
925  * Arguments:   @const void *perso@ = personalization string, or null
926  *              @size_t psz@ = length of personalization string
927  *              @const void *k@ = pointer to seed material
928  *              @size_t sz@ = size of the seed
929  *
930  * Returns:     A pseudorandom generator with the given key.
931  *
932  * Use:         The generator processes an empty message by default, but this
933  *              can be changed by seeding it.
934  */
935
936 grand *kmac128_rand(const void *perso, size_t psz, const void *k, size_t sz)
937 {
938   kmac_grctx *cc = S_CREATE(kmac_grctx);
939   cc->gr.ops = &kmac128_grops;
940   kmac128_init(&cc->k, perso, psz, k, sz);
941   cc->c = cc->k; kmac_xof(&cc->c);
942   return (&cc->gr);
943 }
944
945 grand *kmac256_rand(const void *perso, size_t psz, const void *k, size_t sz)
946 {
947   kmac_grctx *cc = S_CREATE(kmac_grctx);
948   cc->gr.ops = &kmac256_grops;
949   kmac256_init(&cc->k, perso, psz, k, sz);
950   cc->c = cc->k; kmac_xof(&cc->c);
951   return (&cc->gr);
952 }
953
954 /*----- Test rig ----------------------------------------------------------*/
955
956 #ifdef TEST_RIG
957
958 #include <stdio.h>
959
960 #include <mLib/report.h>
961 #include <mLib/testrig.h>
962
963 HASHES(HASH_VERIFYX)
964
965 static int vrf_sha3_mct(void (*initfn)(sha3_ctx *),
966                         int n, dstr *in, dstr *out)
967 {
968   sha3_ctx ctx;
969   dstr d = DSTR_INIT;
970   int ok = 1;
971   int i;
972
973   if (in->len != out->len) die(1, "inconsistent lengths");
974   dstr_ensure(&d, out->len); d.len = out->len;
975   memcpy(d.buf, in->buf, in->len);
976   for (i = 0; i < n; i++) {
977     initfn(&ctx);
978     sha3_hash(&ctx, d.buf, d.len);
979     sha3_done(&ctx, d.buf);
980   }
981
982   if (memcmp(d.buf, out->buf, out->len) != 0) {
983     ok = 0;
984     printf("\nfail\n\tsteps = %d\n\tinput = ", n);
985     type_hex.dump(in, stdout);
986     printf("\n\texpected = ");
987     type_hex.dump(out, stdout);
988     fputs("\n\tcomputed = ", stdout);
989     type_hex.dump(&d, stdout);
990     putchar('\n');
991   }
992
993   dstr_destroy(&d);
994   return (ok);
995 }
996
997 #define VRF_MCT(PRE, pre, name)                                         \
998   static int vrf_##pre##_mct(dstr *v)                                   \
999     { return (vrf_sha3_mct(pre##_init, *(int *)v[0].buf, &v[1], &v[2])); }
1000 HASHES(VRF_MCT)
1001 #undef VRF_MCT
1002
1003 static int vrf_shaky(void (*initfn)(shake_ctx *,
1004                                     const void *, size_t,
1005                                     const void *, size_t),
1006                      dstr *func, dstr *perso,
1007                      dstr *m, dstr *want)
1008 {
1009   shake_ctx ctx;
1010   dstr d = DSTR_INIT;
1011   int ok = 1;
1012   int i;
1013   const int *ip;
1014   size_t sz;
1015   octet *p;
1016   static const int szs[] = { 1, 7, 192, -1, 0 };
1017
1018   dstr_ensure(&d, want->len); d.len = want->len;
1019   for (ip = szs; *ip; ip++) {
1020     initfn(&ctx,
1021            func ? func->buf : 0, func ? func->len : 0,
1022            perso ? perso->buf : 0, perso ? perso->len : 0);
1023     p = (octet *)m->buf; sz = m->len;
1024     i = (*ip == -1 || *ip > sz) ? sz : *ip;
1025     while (sz) {
1026       if (i > sz) i = sz;
1027       shake_hash(&ctx, p, i);
1028       p += i; sz -= i;
1029     }
1030     shake_xof(&ctx);
1031
1032     p = (octet *)d.buf; sz = d.len;
1033     i = (*ip == -1 || *ip > sz) ? sz : *ip;
1034     while (sz) {
1035       if (i > sz) i = sz;
1036       shake_get(&ctx, p, i);
1037       p += i; sz -= i;
1038     }
1039
1040     if (memcmp(d.buf, want->buf, want->len) != 0) {
1041       ok = 0;
1042       printf("\nfail (get):\n\tstep = %i\n\tinput = ", *ip);
1043       type_hex.dump(m, stdout);
1044       if (func) printf("\n\tfunction = `%s'", func->buf);
1045       if (perso) printf("\n\tperso = `%s'", perso->buf);
1046       printf("\n\texpected = ");
1047       type_hex.dump(want, stdout);
1048       fputs("\n\tcomputed = ", stdout);
1049       type_hex.dump(&d, stdout);
1050       putchar('\n');
1051     }
1052
1053     initfn(&ctx,
1054            func ? func->buf : 0, func ? func->len : 0,
1055            perso ? perso->buf : 0, perso ? perso->len : 0);
1056     p = (octet *)m->buf; sz = m->len;
1057     i = (*ip == -1 || *ip > sz) ? sz : *ip;
1058     while (sz) {
1059       if (i > sz) i = sz;
1060       shake_hash(&ctx, p, i);
1061       p += i; sz -= i;
1062     }
1063     shake_xof(&ctx);
1064
1065     memset(d.buf, 0, d.len);
1066     p = (octet *)d.buf; sz = d.len;
1067     i = (*ip == -1 || *ip > sz) ? sz : *ip;
1068     while (sz) {
1069       if (i > sz) i = sz;
1070       shake_mask(&ctx, p, p, i);
1071       p += i; sz -= i;
1072     }
1073
1074     if (memcmp(d.buf, want->buf, want->len) != 0) {
1075       ok = 0;
1076       printf("\nfail (mask):\n\tstep = %i\n\tinput = ", *ip);
1077       type_hex.dump(m, stdout);
1078       if (func) printf("\n\tfunction = `%s'", func->buf);
1079       if (perso) printf("\n\tperso = `%s'", perso->buf);
1080       printf("\n\texpected = ");
1081       type_hex.dump(want, stdout);
1082       fputs("\n\tcomputed = ", stdout);
1083       type_hex.dump(&d, stdout);
1084       putchar('\n');
1085     }
1086   }
1087
1088   dstr_destroy(&d);
1089   return (ok);
1090 }
1091
1092 static int vrf_cshake128(dstr *v)
1093 {
1094   return (vrf_shaky(cshake128_init, &v[0], &v[1], &v[2], &v[3]));
1095 }
1096
1097 static int vrf_cshake256(dstr *v)
1098 {
1099   return (vrf_shaky(cshake256_init, &v[0], &v[1], &v[2], &v[3]));
1100 }
1101
1102 static void shake128_init_adaptor(shake_ctx *ctx,
1103                                   const void *func, size_t fsz,
1104                                   const void *perso, size_t psz)
1105   { assert(!fsz); assert(!psz); shake128_init(ctx);}
1106
1107 static void shake256_init_adaptor(shake_ctx *ctx,
1108                                   const void *func, size_t fsz,
1109                                   const void *perso, size_t psz)
1110   { assert(!fsz); assert(!psz); shake256_init(ctx);}
1111
1112 static int vrf_shake128(dstr *v)
1113   { return (vrf_shaky(shake128_init_adaptor, 0, 0, &v[0], &v[1])); }
1114
1115 static int vrf_shake256(dstr *v)
1116   { return (vrf_shaky(shake256_init_adaptor, 0, 0, &v[0], &v[1])); }
1117
1118 static int vrf_kmac(void (*initfn)(kmac_ctx *, const void *, size_t,
1119                                    const void *, size_t),
1120                     dstr *perso, int tsz,
1121                     dstr *k, dstr *m, dstr *want)
1122 {
1123   kmac_ctx ctx;
1124   dstr d = DSTR_INIT;
1125   int ok = 1;
1126
1127   if (tsz && tsz != want->len) die(1, "inconsistent tag length request");
1128   dstr_ensure(&d, want->len); d.len = want->len;
1129   initfn(&ctx, perso->buf, perso->len, k->buf, k->len);
1130   kmac_hash(&ctx, m->buf, m->len);
1131   if (tsz) kmac_done(&ctx, d.buf, tsz);
1132   else { kmac_xof(&ctx); kmac_get(&ctx, d.buf, d.len); }
1133
1134   if (memcmp(d.buf, want->buf, want->len) != 0) {
1135     ok = 0;
1136     printf("\nfail");
1137     printf("\n\tperso = `%s'", perso->buf);
1138     printf("\n\ttag size = %d", tsz);
1139     printf("\n\tkey = "); type_hex.dump(k, stdout);
1140     printf("\n\tinput = "); type_hex.dump(m, stdout);
1141     printf("\n\texpected = "); type_hex.dump(want, stdout);
1142     fputs("\n\tcomputed = ", stdout); type_hex.dump(&d, stdout);
1143     putchar('\n');
1144   }
1145
1146   dstr_destroy(&d);
1147   return (ok);
1148 }
1149
1150 static int vrf_kmac128(dstr *v)
1151 {
1152   return (vrf_kmac(kmac128_init, &v[0], *(int *)v[1].buf,
1153                    &v[2], &v[3], &v[4]));
1154 }
1155
1156 static int vrf_kmac256(dstr *v)
1157 {
1158   return (vrf_kmac(kmac256_init, &v[0], *(int *)v[1].buf,
1159                    &v[2], &v[3], &v[4]));
1160 }
1161
1162 static const test_chunk defs[] = {
1163   HASHES(HASH_TESTDEFSX)
1164 #define VRF_MCTDEF(PRE, pre, name)                                      \
1165   { name "-mct", vrf_##pre##_mct,                                       \
1166     { &type_int, &type_hex, &type_hex, 0 } },
1167   HASHES(VRF_MCTDEF)
1168 #undef VRF_MCTDEF
1169   { "shake128", vrf_shake128, { &type_hex, &type_hex, 0 } },
1170   { "shake256", vrf_shake256, { &type_hex, &type_hex, 0 } },
1171   { "cshake128", vrf_cshake128,
1172     { &type_string, &type_string, &type_hex, &type_hex, 0 } },
1173   { "cshake256", vrf_cshake256,
1174     { &type_string, &type_string, &type_hex, &type_hex, 0 } },
1175   { "kmac128", vrf_kmac128,
1176     { &type_string, &type_int, &type_hex, &type_hex, &type_hex, 0 } },
1177   { "kmac256", vrf_kmac256,
1178     { &type_string, &type_int, &type_hex, &type_hex, &type_hex, 0 } },
1179   { 0, 0, { 0 } }
1180 };
1181
1182 int main(int argc, char *argv[])
1183 {
1184   test_run(argc, argv, defs, SRCDIR"/t/sha3");
1185   return (0);
1186 }
1187
1188 #endif
1189
1190 /*----- That's all, folks -------------------------------------------------*/