ecc: Fix ec_mulm_25519.
[libgcrypt.git] / cipher / poly1305.c
1 /* poly1305.c  -  Poly1305 internals and generic implementation
2  * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser general Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /* The code is based on public-domain Poly1305 implementation by
21  * Andrew Moon at
22  *  https://github.com/floodyberry/poly1305-opt
23  */
24
25 #include <config.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "types.h"
31 #include "g10lib.h"
32 #include "cipher.h"
33 #include "bufhelp.h"
34 #include "poly1305-internal.h"
35
36
37 static const char *selftest (void);
38 \f
39
40
41 #ifdef POLY1305_USE_SSE2
42
43 void _gcry_poly1305_amd64_sse2_init_ext(void *state, const poly1305_key_t *key)
44                                        OPS_FUNC_ABI;
45 unsigned int _gcry_poly1305_amd64_sse2_finish_ext(void *state, const byte *m,
46                                                   size_t remaining,
47                                                   byte mac[16]) OPS_FUNC_ABI;
48 unsigned int _gcry_poly1305_amd64_sse2_blocks(void *ctx, const byte *m,
49                                               size_t bytes) OPS_FUNC_ABI;
50
51 static const poly1305_ops_t poly1305_amd64_sse2_ops = {
52   POLY1305_SSE2_BLOCKSIZE,
53   _gcry_poly1305_amd64_sse2_init_ext,
54   _gcry_poly1305_amd64_sse2_blocks,
55   _gcry_poly1305_amd64_sse2_finish_ext
56 };
57
58 #else  /* !POLY1305_USE_SSE2 */
59
60 static OPS_FUNC_ABI void poly1305_init_ext_ref32
61 /**/                (void *state, const poly1305_key_t *key);
62 static OPS_FUNC_ABI unsigned int poly1305_blocks_ref32
63 /**/                (void *state, const byte *m, size_t bytes);
64 static OPS_FUNC_ABI unsigned int poly1305_finish_ext_ref32
65 /**/                (void *state, const byte * m,
66                      size_t remaining, byte mac[POLY1305_TAGLEN]);
67
68 static const poly1305_ops_t poly1305_default_ops = {
69   POLY1305_REF_BLOCKSIZE,
70   poly1305_init_ext_ref32,
71   poly1305_blocks_ref32,
72   poly1305_finish_ext_ref32
73 };
74
75 #endif /* !POLY1305_USE_SSE2 */
76
77
78 #ifdef POLY1305_USE_AVX2
79
80 void _gcry_poly1305_amd64_avx2_init_ext(void *state, const poly1305_key_t *key)
81                                        OPS_FUNC_ABI;
82 unsigned int _gcry_poly1305_amd64_avx2_finish_ext(void *state, const byte *m,
83                                                   size_t remaining,
84                                                   byte mac[16]) OPS_FUNC_ABI;
85 unsigned int _gcry_poly1305_amd64_avx2_blocks(void *ctx, const byte *m,
86                                               size_t bytes) OPS_FUNC_ABI;
87
88 static const poly1305_ops_t poly1305_amd64_avx2_ops = {
89   POLY1305_AVX2_BLOCKSIZE,
90   _gcry_poly1305_amd64_avx2_init_ext,
91   _gcry_poly1305_amd64_avx2_blocks,
92   _gcry_poly1305_amd64_avx2_finish_ext
93 };
94
95 #endif
96
97
98 #ifdef POLY1305_USE_NEON
99
100 void _gcry_poly1305_armv7_neon_init_ext(void *state, const poly1305_key_t *key)
101                                        OPS_FUNC_ABI;
102 unsigned int _gcry_poly1305_armv7_neon_finish_ext(void *state, const byte *m,
103                                                   size_t remaining,
104                                                   byte mac[16]) OPS_FUNC_ABI;
105 unsigned int _gcry_poly1305_armv7_neon_blocks(void *ctx, const byte *m,
106                                               size_t bytes) OPS_FUNC_ABI;
107
108 static const poly1305_ops_t poly1305_armv7_neon_ops = {
109   POLY1305_NEON_BLOCKSIZE,
110   _gcry_poly1305_armv7_neon_init_ext,
111   _gcry_poly1305_armv7_neon_blocks,
112   _gcry_poly1305_armv7_neon_finish_ext
113 };
114
115 #endif
116
117
118 /* Reference unoptimized poly1305 implementation using 32 bit * 32 bit = 64 bit
119  * multiplication and 64 bit addition.
120  */
121
122 typedef struct poly1305_state_ref32_s
123 {
124   u32 r[5];
125   u32 h[5];
126   u32 pad[4];
127   byte final;
128 } poly1305_state_ref32_t;
129
130
131 #ifndef POLY1305_USE_SSE2
132 static OPS_FUNC_ABI void
133 poly1305_init_ext_ref32 (void *state, const poly1305_key_t * key)
134 {
135   poly1305_state_ref32_t *st = (poly1305_state_ref32_t *) state;
136
137   gcry_assert (sizeof (*st) + POLY1305_STATE_ALIGNMENT <=
138                sizeof (((poly1305_context_t *) 0)->state));
139
140   /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
141   st->r[0] = (buf_get_le32 (&key->b[0])) & 0x3ffffff;
142   st->r[1] = (buf_get_le32 (&key->b[3]) >> 2) & 0x3ffff03;
143   st->r[2] = (buf_get_le32 (&key->b[6]) >> 4) & 0x3ffc0ff;
144   st->r[3] = (buf_get_le32 (&key->b[9]) >> 6) & 0x3f03fff;
145   st->r[4] = (buf_get_le32 (&key->b[12]) >> 8) & 0x00fffff;
146
147   /* h = 0 */
148   st->h[0] = 0;
149   st->h[1] = 0;
150   st->h[2] = 0;
151   st->h[3] = 0;
152   st->h[4] = 0;
153
154   /* save pad for later */
155   st->pad[0] = buf_get_le32 (&key->b[16]);
156   st->pad[1] = buf_get_le32 (&key->b[20]);
157   st->pad[2] = buf_get_le32 (&key->b[24]);
158   st->pad[3] = buf_get_le32 (&key->b[28]);
159
160   st->final = 0;
161 }
162 #endif /* !POLY1305_USE_SSE2 */
163
164
165 #ifndef POLY1305_USE_SSE2
166 static OPS_FUNC_ABI unsigned int
167 poly1305_blocks_ref32 (void *state, const byte * m, size_t bytes)
168 {
169   poly1305_state_ref32_t *st = (poly1305_state_ref32_t *) state;
170   const u32 hibit = (st->final) ? 0 : (1 << 24);        /* 1 << 128 */
171   u32 r0, r1, r2, r3, r4;
172   u32 s1, s2, s3, s4;
173   u32 h0, h1, h2, h3, h4;
174   u64 d0, d1, d2, d3, d4;
175   u32 c;
176
177   r0 = st->r[0];
178   r1 = st->r[1];
179   r2 = st->r[2];
180   r3 = st->r[3];
181   r4 = st->r[4];
182
183   s1 = r1 * 5;
184   s2 = r2 * 5;
185   s3 = r3 * 5;
186   s4 = r4 * 5;
187
188   h0 = st->h[0];
189   h1 = st->h[1];
190   h2 = st->h[2];
191   h3 = st->h[3];
192   h4 = st->h[4];
193
194   while (bytes >= POLY1305_REF_BLOCKSIZE)
195     {
196       /* h += m[i] */
197       h0 += (buf_get_le32 (m + 0)) & 0x3ffffff;
198       h1 += (buf_get_le32 (m + 3) >> 2) & 0x3ffffff;
199       h2 += (buf_get_le32 (m + 6) >> 4) & 0x3ffffff;
200       h3 += (buf_get_le32 (m + 9) >> 6) & 0x3ffffff;
201       h4 += (buf_get_le32 (m + 12) >> 8) | hibit;
202
203       /* h *= r */
204       d0 =
205         ((u64) h0 * r0) + ((u64) h1 * s4) +
206         ((u64) h2 * s3) + ((u64) h3 * s2) + ((u64) h4 * s1);
207       d1 =
208         ((u64) h0 * r1) + ((u64) h1 * r0) +
209         ((u64) h2 * s4) + ((u64) h3 * s3) + ((u64) h4 * s2);
210       d2 =
211         ((u64) h0 * r2) + ((u64) h1 * r1) +
212         ((u64) h2 * r0) + ((u64) h3 * s4) + ((u64) h4 * s3);
213       d3 =
214         ((u64) h0 * r3) + ((u64) h1 * r2) +
215         ((u64) h2 * r1) + ((u64) h3 * r0) + ((u64) h4 * s4);
216       d4 =
217         ((u64) h0 * r4) + ((u64) h1 * r3) +
218         ((u64) h2 * r2) + ((u64) h3 * r1) + ((u64) h4 * r0);
219
220       /* (partial) h %= p */
221       c = (u32) (d0 >> 26);
222       h0 = (u32) d0 & 0x3ffffff;
223       d1 += c;
224       c = (u32) (d1 >> 26);
225       h1 = (u32) d1 & 0x3ffffff;
226       d2 += c;
227       c = (u32) (d2 >> 26);
228       h2 = (u32) d2 & 0x3ffffff;
229       d3 += c;
230       c = (u32) (d3 >> 26);
231       h3 = (u32) d3 & 0x3ffffff;
232       d4 += c;
233       c = (u32) (d4 >> 26);
234       h4 = (u32) d4 & 0x3ffffff;
235       h0 += c * 5;
236       c = (h0 >> 26);
237       h0 = h0 & 0x3ffffff;
238       h1 += c;
239
240       m += POLY1305_REF_BLOCKSIZE;
241       bytes -= POLY1305_REF_BLOCKSIZE;
242     }
243
244   st->h[0] = h0;
245   st->h[1] = h1;
246   st->h[2] = h2;
247   st->h[3] = h3;
248   st->h[4] = h4;
249
250   return (16 * sizeof (u32) + 5 * sizeof (u64) + 5 * sizeof (void *));
251 }
252 #endif /* !POLY1305_USE_SSE2 */
253
254
255 #ifndef POLY1305_USE_SSE2
256 static OPS_FUNC_ABI unsigned int
257 poly1305_finish_ext_ref32 (void *state, const byte * m,
258                            size_t remaining, byte mac[POLY1305_TAGLEN])
259 {
260   poly1305_state_ref32_t *st = (poly1305_state_ref32_t *) state;
261   u32 h0, h1, h2, h3, h4, c;
262   u32 g0, g1, g2, g3, g4;
263   u64 f;
264   u32 mask;
265   unsigned int burn = 0;
266
267   /* process the remaining block */
268   if (remaining)
269     {
270       byte final[POLY1305_REF_BLOCKSIZE] = { 0 };
271       size_t i;
272       for (i = 0; i < remaining; i++)
273         final[i] = m[i];
274       final[remaining] = 1;
275       st->final = 1;
276       burn = poly1305_blocks_ref32 (st, final, POLY1305_REF_BLOCKSIZE);
277     }
278
279   /* fully carry h */
280   h0 = st->h[0];
281   h1 = st->h[1];
282   h2 = st->h[2];
283   h3 = st->h[3];
284   h4 = st->h[4];
285
286   c = h1 >> 26;
287   h1 = h1 & 0x3ffffff;
288   h2 += c;
289   c = h2 >> 26;
290   h2 = h2 & 0x3ffffff;
291   h3 += c;
292   c = h3 >> 26;
293   h3 = h3 & 0x3ffffff;
294   h4 += c;
295   c = h4 >> 26;
296   h4 = h4 & 0x3ffffff;
297   h0 += c * 5;
298   c = h0 >> 26;
299   h0 = h0 & 0x3ffffff;
300   h1 += c;
301
302   /* compute h + -p */
303   g0 = h0 + 5;
304   c = g0 >> 26;
305   g0 &= 0x3ffffff;
306   g1 = h1 + c;
307   c = g1 >> 26;
308   g1 &= 0x3ffffff;
309   g2 = h2 + c;
310   c = g2 >> 26;
311   g2 &= 0x3ffffff;
312   g3 = h3 + c;
313   c = g3 >> 26;
314   g3 &= 0x3ffffff;
315   g4 = h4 + c - (1 << 26);
316
317   /* select h if h < p, or h + -p if h >= p */
318   mask = (g4 >> ((sizeof (u32) * 8) - 1)) - 1;
319   g0 &= mask;
320   g1 &= mask;
321   g2 &= mask;
322   g3 &= mask;
323   g4 &= mask;
324   mask = ~mask;
325   h0 = (h0 & mask) | g0;
326   h1 = (h1 & mask) | g1;
327   h2 = (h2 & mask) | g2;
328   h3 = (h3 & mask) | g3;
329   h4 = (h4 & mask) | g4;
330
331   /* h = h % (2^128) */
332   h0 = ((h0) | (h1 << 26)) & 0xffffffff;
333   h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff;
334   h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
335   h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
336
337   /* mac = (h + pad) % (2^128) */
338   f = (u64) h0 + st->pad[0];
339   h0 = (u32) f;
340   f = (u64) h1 + st->pad[1] + (f >> 32);
341   h1 = (u32) f;
342   f = (u64) h2 + st->pad[2] + (f >> 32);
343   h2 = (u32) f;
344   f = (u64) h3 + st->pad[3] + (f >> 32);
345   h3 = (u32) f;
346
347   buf_put_le32 (mac + 0, h0);
348   buf_put_le32 (mac + 4, h1);
349   buf_put_le32 (mac + 8, h2);
350   buf_put_le32 (mac + 12, h3);
351
352   /* zero out the state */
353   st->h[0] = 0;
354   st->h[1] = 0;
355   st->h[2] = 0;
356   st->h[3] = 0;
357   st->h[4] = 0;
358   st->r[0] = 0;
359   st->r[1] = 0;
360   st->r[2] = 0;
361   st->r[3] = 0;
362   st->r[4] = 0;
363   st->pad[0] = 0;
364   st->pad[1] = 0;
365   st->pad[2] = 0;
366   st->pad[3] = 0;
367
368   /* burn_stack */
369   return (13 * sizeof (u32) + sizeof (u64) +
370           POLY1305_REF_BLOCKSIZE + 6 * sizeof (void *)) + burn;
371 }
372 #endif /* !POLY1305_USE_SSE2*/
373
374
375 \f
376
377
378 static inline void *
379 poly1305_get_state (poly1305_context_t * ctx)
380 {
381   byte *c = ctx->state;
382   c += POLY1305_STATE_ALIGNMENT - 1;
383   c -= (uintptr_t) c & (POLY1305_STATE_ALIGNMENT - 1);
384   return c;
385 }
386
387
388 static void
389 poly1305_init (poly1305_context_t * ctx, const poly1305_key_t * key)
390 {
391   void *state = poly1305_get_state (ctx);
392
393   ctx->leftover = 0;
394
395   ctx->ops->init_ext (state, key);
396 }
397
398
399 void
400 _gcry_poly1305_update (poly1305_context_t * ctx, const byte * m, size_t bytes)
401 {
402   void *state = poly1305_get_state (ctx);
403   unsigned int burn = 0;
404   size_t block_size = ctx->ops->block_size;
405
406   /* handle leftover */
407   if (ctx->leftover)
408     {
409       size_t want = (block_size - ctx->leftover);
410       if (want > bytes)
411         want = bytes;
412       buf_cpy (ctx->buffer + ctx->leftover, m, want);
413       bytes -= want;
414       m += want;
415       ctx->leftover += want;
416       if (ctx->leftover < block_size)
417         return;
418       burn = ctx->ops->blocks (state, ctx->buffer, block_size);
419       ctx->leftover = 0;
420     }
421
422   /* process full blocks */
423   if (bytes >= block_size)
424     {
425       size_t want = (bytes & ~(block_size - 1));
426       burn = ctx->ops->blocks (state, m, want);
427       m += want;
428       bytes -= want;
429     }
430
431   /* store leftover */
432   if (bytes)
433     {
434       buf_cpy (ctx->buffer + ctx->leftover, m, bytes);
435       ctx->leftover += bytes;
436     }
437
438   if (burn)
439     _gcry_burn_stack (burn);
440 }
441
442
443 void
444 _gcry_poly1305_finish (poly1305_context_t * ctx, byte mac[POLY1305_TAGLEN])
445 {
446   void *state = poly1305_get_state (ctx);
447   unsigned int burn;
448
449   burn = ctx->ops->finish_ext (state, ctx->buffer, ctx->leftover, mac);
450
451   _gcry_burn_stack (burn);
452 }
453
454
455 gcry_err_code_t
456 _gcry_poly1305_init (poly1305_context_t * ctx, const byte * key,
457                      size_t keylen)
458 {
459   static int initialized;
460   static const char *selftest_failed;
461   poly1305_key_t keytmp;
462   unsigned int features = _gcry_get_hw_features ();
463
464   if (!initialized)
465     {
466       initialized = 1;
467       selftest_failed = selftest ();
468       if (selftest_failed)
469         log_error ("Poly1305 selftest failed (%s)\n", selftest_failed);
470     }
471
472   if (keylen != POLY1305_KEYLEN)
473     return GPG_ERR_INV_KEYLEN;
474
475   if (selftest_failed)
476     return GPG_ERR_SELFTEST_FAILED;
477
478 #ifdef POLY1305_USE_SSE2
479   ctx->ops = &poly1305_amd64_sse2_ops;
480 #else
481   ctx->ops = &poly1305_default_ops;
482 #endif
483
484 #ifdef POLY1305_USE_AVX2
485   if (features & HWF_INTEL_AVX2)
486     ctx->ops = &poly1305_amd64_avx2_ops;
487 #endif
488 #ifdef POLY1305_USE_NEON
489   if (features & HWF_ARM_NEON)
490     ctx->ops = &poly1305_armv7_neon_ops;
491 #endif
492   (void)features;
493
494   buf_cpy (keytmp.b, key, POLY1305_KEYLEN);
495   poly1305_init (ctx, &keytmp);
496
497   wipememory (&keytmp, sizeof (keytmp));
498
499   return 0;
500 }
501
502
503 static void
504 poly1305_auth (byte mac[POLY1305_TAGLEN], const byte * m, size_t bytes,
505                const byte * key)
506 {
507   poly1305_context_t ctx;
508
509   memset (&ctx, 0, sizeof (ctx));
510
511   _gcry_poly1305_init (&ctx, key, POLY1305_KEYLEN);
512   _gcry_poly1305_update (&ctx, m, bytes);
513   _gcry_poly1305_finish (&ctx, mac);
514
515   wipememory (&ctx, sizeof (ctx));
516 }
517
518
519 static const char *
520 selftest (void)
521 {
522   /* example from nacl */
523   static const byte nacl_key[POLY1305_KEYLEN] = {
524     0xee, 0xa6, 0xa7, 0x25, 0x1c, 0x1e, 0x72, 0x91,
525     0x6d, 0x11, 0xc2, 0xcb, 0x21, 0x4d, 0x3c, 0x25,
526     0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23, 0x4e, 0x65,
527     0x2d, 0x65, 0x1f, 0xa4, 0xc8, 0xcf, 0xf8, 0x80,
528   };
529
530   static const byte nacl_msg[131] = {
531     0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73,
532     0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce,
533     0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4,
534     0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a,
535     0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b,
536     0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72,
537     0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2,
538     0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38,
539     0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a,
540     0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae,
541     0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea,
542     0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda,
543     0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde,
544     0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3,
545     0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6,
546     0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74,
547     0xe3, 0x55, 0xa5
548   };
549
550   static const byte nacl_mac[16] = {
551     0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5,
552     0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9
553   };
554
555   /* generates a final value of (2^130 - 2) == 3 */
556   static const byte wrap_key[POLY1305_KEYLEN] = {
557     0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
560     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561   };
562
563   static const byte wrap_msg[16] = {
564     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
565     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
566   };
567
568   static const byte wrap_mac[16] = {
569     0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571   };
572
573   /* mac of the macs of messages of length 0 to 256, where the key and messages
574    * have all their values set to the length
575    */
576   static const byte total_key[POLY1305_KEYLEN] = {
577     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
578     0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9,
579     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
580     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
581   };
582
583   static const byte total_mac[16] = {
584     0x64, 0xaf, 0xe2, 0xe8, 0xd6, 0xad, 0x7b, 0xbd,
585     0xd2, 0x87, 0xf9, 0x7c, 0x44, 0x62, 0x3d, 0x39
586   };
587
588   poly1305_context_t ctx;
589   poly1305_context_t total_ctx;
590   byte all_key[POLY1305_KEYLEN];
591   byte all_msg[256];
592   byte mac[16];
593   size_t i, j;
594
595   memset (&ctx, 0, sizeof (ctx));
596   memset (&total_ctx, 0, sizeof (total_ctx));
597
598   memset (mac, 0, sizeof (mac));
599   poly1305_auth (mac, nacl_msg, sizeof (nacl_msg), nacl_key);
600   if (memcmp (nacl_mac, mac, sizeof (nacl_mac)) != 0)
601     return "Poly1305 test 1 failed.";
602
603   /* SSE2/AVX have a 32 byte block size, but also support 64 byte blocks, so
604    * make sure everything still works varying between them */
605   memset (mac, 0, sizeof (mac));
606   _gcry_poly1305_init (&ctx, nacl_key, POLY1305_KEYLEN);
607   _gcry_poly1305_update (&ctx, nacl_msg + 0, 32);
608   _gcry_poly1305_update (&ctx, nacl_msg + 32, 64);
609   _gcry_poly1305_update (&ctx, nacl_msg + 96, 16);
610   _gcry_poly1305_update (&ctx, nacl_msg + 112, 8);
611   _gcry_poly1305_update (&ctx, nacl_msg + 120, 4);
612   _gcry_poly1305_update (&ctx, nacl_msg + 124, 2);
613   _gcry_poly1305_update (&ctx, nacl_msg + 126, 1);
614   _gcry_poly1305_update (&ctx, nacl_msg + 127, 1);
615   _gcry_poly1305_update (&ctx, nacl_msg + 128, 1);
616   _gcry_poly1305_update (&ctx, nacl_msg + 129, 1);
617   _gcry_poly1305_update (&ctx, nacl_msg + 130, 1);
618   _gcry_poly1305_finish (&ctx, mac);
619   if (memcmp (nacl_mac, mac, sizeof (nacl_mac)) != 0)
620     return "Poly1305 test 2 failed.";
621
622   memset (mac, 0, sizeof (mac));
623   poly1305_auth (mac, wrap_msg, sizeof (wrap_msg), wrap_key);
624   if (memcmp (wrap_mac, mac, sizeof (nacl_mac)) != 0)
625     return "Poly1305 test 3 failed.";
626
627   _gcry_poly1305_init (&total_ctx, total_key, POLY1305_KEYLEN);
628   for (i = 0; i < 256; i++)
629     {
630       /* set key and message to 'i,i,i..' */
631       for (j = 0; j < sizeof (all_key); j++)
632         all_key[j] = i;
633       for (j = 0; j < i; j++)
634         all_msg[j] = i;
635       poly1305_auth (mac, all_msg, i, all_key);
636       _gcry_poly1305_update (&total_ctx, mac, 16);
637     }
638   _gcry_poly1305_finish (&total_ctx, mac);
639   if (memcmp (total_mac, mac, sizeof (total_mac)) != 0)
640     return "Poly1305 test 4 failed.";
641
642   return NULL;
643 }