chiark / gitweb /
Merge branch '2.3.x'
[catacomb] / symm / poly1305.h
1 /* -*-c-*-
2  *
3  * Poly1305 message authentication code
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 /*----- Notes on Poly1305 -------------------------------------------------*
29  *
30  * The Poly1305 message authentication code was designed by Daniel Bernstein
31  * in 2004.  It's a heavily performance-engineered Carter--Wegman MAC, based
32  * on polynomial evaluation in %$\F = \mathrm{GF}(2^{130} - 5)$%.  Some of
33  * the performance engineering is out-of-date, being there to support
34  * implementation techniques which are no longer relevant, but it still runs
35  * very quickly.
36  *
37  * The key %$r$% is an element of %$\F$%.  Messages are encoded as a sequence
38  * %$m_0, m_1, \ldots, m_{n-1}$% of of elements of %$\F$%.  A raw hash is
39  * calculated as %$h_0 = \sum_{0\le i<n} m_0 r^{n-i}$%.  Finally, the raw
40  * hash is masked for output by adding to its canonical representative a mask
41  * value %$s$% modulo %$2^{128}$% and encoding the result as an octet string.
42  *
43  * As originally presented, Poly1305 generated the output mask by encrypting
44  * a nonce using AES.  This has since been separated from the design, so that
45  * Poly1305 stands on its own.  Poly1305 is highly key-agile, and most modern
46  * uses simply generate a fresh pseudorandom key and mask for each message.
47  * Note that both key and mask must be (at least) pseudorandom.
48  */
49
50 #ifndef CATACOMB_POLY1305_H
51 #define CATACOMB_POLY1305_H
52
53 #ifdef __cplusplus
54   extern "C" {
55 #endif
56
57 /*----- Header files ------------------------------------------------------*/
58
59 #include <mLib/bits.h>
60
61 #ifndef CATACOMB_KEYSZ_H
62 #  include "keysz.h"
63 #endif
64
65 /*----- Constants ---------------------------------------------------------*/
66
67 extern const octet poly1305_keysz[];
68
69 #define POLY1305_BLKSZ 16u
70 #define POLY1305_KEYSZ 16u
71 #define POLY1305_MASKSZ 16u
72 #define POLY1305_TAGSZ 16u
73
74 /*----- Data structures ---------------------------------------------------*/
75
76 typedef struct poly1305_key {
77   union {
78     struct { uint32 r0, r1, r2, r3, r4, rr1, rr2, rr3, rr4; } p26;
79     struct { uint16 r[12]; } p11;
80   } u;
81 } poly1305_key;
82
83 typedef struct poly1305_ctx {
84   poly1305_key k;
85   union {
86     struct { uint32 s0, s1, s2, s3, s4; uint32 h[5]; } p26;
87     struct { uint16 s[12], h[12]; } p11;
88   } u;
89   unsigned long count;
90   unsigned nbuf;
91   octet buf[16];
92 } poly1305_ctx;
93
94 /*----- Functions provided ------------------------------------------------*/
95
96 /* --- @poly1305_keyinit@ --- *
97  *
98  * Arguments:   @poly1305_key *key@ = key structure to fill in
99  *              @const void *k@ = pointer to key material
100  *              @size_t ksz@ = length of key (must be @POLY1305_KEYSZ == 16@)
101  *
102  * Returns:     ---
103  *
104  * Use:         Records a Poly1305 key and performs (minimal)
105  *              precomputations.
106  */
107
108 extern void poly1305_keyinit(poly1305_key */*key*/,
109                              const void */*k*/, size_t /*sz*/);
110
111 /* --- @poly1305_macinit@ --- *
112  *
113  * Arguments:   @poly1305_ctx *ctx@ = MAC context to fill in
114  *              @const poly1305_key *key@ = pointer to key structure to use
115  *              @const void *iv@ = pointer to mask string
116  *
117  * Returns:     ---
118  *
119  * Use:         Initializes a MAC context for use.  The key can be discarded
120  *              at any time.
121  *
122  *              It is permitted for @iv@ to be null, though it is not then
123  *              possible to complete the MAC computation on @ctx@.  The
124  *              resulting context may still be useful, e.g., as an operand to
125  *              @poly1305_concat@.
126  */
127
128 extern void poly1305_macinit(poly1305_ctx */*ctx*/,
129                              const poly1305_key */*key*/,
130                              const void */*iv*/);
131
132 /* --- @poly1305_copy@ --- *
133  *
134  * Arguments:   @poly1305_ctx *to@ = destination context
135  *              @const poly1305_ctx *from@ = source context
136  *
137  * Returns:     ---
138  *
139  * Use:         Duplicates a Poly1305 MAC context.  The destination need not
140  *              have been initialized.  Both contexts can be used
141  *              independently afterwards.
142  */
143
144 extern void poly1305_copy(poly1305_ctx */*to*/,
145                           const poly1305_ctx */*from*/);
146
147 /* --- @poly1305_hash@ --- *
148  *
149  * Arguments:   @poly1305_ctx *ctx@ = MAC context to update
150  *              @const void *p@ = pointer to message data
151  *              @size_t sz@ = length of message data
152  *
153  * Returns:     ---
154  *
155  * Use:         Processes a chunk of message.  The message pieces may have
156  *              arbitrary lengths, and may be empty.
157  */
158
159 extern void poly1305_hash(poly1305_ctx */*ctx*/,
160                           const void */*p*/, size_t /*sz*/);
161
162 /* --- @poly1305_flush@ --- *
163  *
164  * Arguments:   @poly1305_ctx *ctx@ = MAC context to flush
165  *
166  * Returns:     ---
167  *
168  * Use:         Forces any buffered message data in the context to be
169  *              processed.  This has no effect if the message processed so
170  *              far is a whole number of blocks.  Flushing is performed
171  *              automatically by @poly1305_done@, but it may be necessary to
172  *              force it by hand when using @poly1305_concat@.
173  *
174  *              Flushing a partial block has an observable effect on the
175  *              computation: the resulting state is (with high probability)
176  *              dissimilar to any state reachable with a message which is a
177  *              whole number of blocks long.
178  */
179
180 extern void poly1305_flush(poly1305_ctx */*ctx*/);
181
182 /* --- @poly1305_flushzero@ --- *
183  *
184  * Arguments:   @poly1305_ctx *ctx@ = MAC context to flush
185  *
186  * Returns:     ---
187  *
188  * Use:         Forces any buffered message data in the context to be
189  *              processed, by hashing between zero and fifteen additional
190  *              zero bytes.  Like @poly1305_flush@, this has no effect if the
191  *              the message processed so far is a whole number of blocks.
192  *              Unlike @poly1305_flush@, the behaviour if the message is not
193  *              a whole number of blocks is equivalent to actually hashing
194  *              some extra data.
195  */
196
197 extern void poly1305_flushzero(poly1305_ctx */*ctx*/);
198
199 /* --- @poly1305_concat@ --- *
200  *
201  * Arguments:   @poly1305_ctx *ctx@ = destination context
202  *              @const poly1305_ctx *prefix, *suffix@ = two operand contexts
203  *
204  * Returns:     ---
205  *
206  * Use:         The two operand contexts @prefix@ and @suffix@ represent
207  *              processing of two messages %$m$% and %$m'$%; the effect is to
208  *              set @ctx@ to the state corresponding to their concatenation
209  *              %$m \cat m'$%.
210  *
211  *              All three contexts must have been initialized using the same
212  *              key value (though not necessarily from the same key
213  *              structure).  The mask values associated with the input
214  *              contexts are irrelevant.  The @prefix@ message %$m$% must be
215  *              a whole number of blocks long: this can be arranged by
216  *              flushing the context.  The @suffix@ message need not be a
217  *              whole number of blocks long.  All of the contexts remain
218  *              operational and can be used independently afterwards.
219  */
220
221 extern void poly1305_concat(poly1305_ctx */*ctx*/,
222                             const poly1305_ctx */*prefix*/,
223                             const poly1305_ctx */*suffix*/);
224
225 /* --- @poly1305_done@ --- *
226  *
227  * Arguments:   @poly1305_ctx *ctx@ = MAC context to finish
228  *              @void *h@ = buffer to write the tag to
229  *
230  * Returns:     ---
231  *
232  * Use:         Completes a Poly1305 MAC tag computation.
233  */
234
235 extern void poly1305_done(poly1305_ctx */*ctx*/, void */*h*/);
236
237 /*----- That's all, folks -------------------------------------------------*/
238
239 #ifdef __cplusplus
240   }
241 #endif
242
243 #endif