chiark / gitweb /
debian/control: Don't require `valgrind' on `armel'.
[catacomb] / symm / salsa20.h
1 /* -*-c-*-
2  *
3  * Salsa20 stream cipher
4  *
5  * (c) 2015 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 #ifndef CATACOMB_SALSA20_H
29 #define CATACOMB_SALSA20_H
30
31 #ifdef __cplusplus
32   extern "C" {
33 #endif
34
35 /*----- Header files ------------------------------------------------------*/
36
37 #include <mLib/bits.h>
38
39 #ifndef CATACOMB_GCIPHER_H
40 #  include "gcipher.h"
41 #endif
42
43 #ifndef CATACOMB_GRAND_H
44 #  include "grand.h"
45 #endif
46
47 /*----- Constants ---------------------------------------------------------*/
48
49 #define SALSA20_NONCESZ 8u
50 #define SALSA20_IETF_NONCESZ 12u
51 #define SALSA20_KEYSZ 32u
52 #define SALSA20_OUTSZ 64u
53
54 #define HSALSA20_INSZ 16u
55 #define HSALSA20_OUTSZ 32u
56
57 #define XSALSA20_NONCESZ 24u
58 #define XSALSA20_KEYSZ SALSA20_KEYSZ
59 #define XSALSA20_OUTSZ SALSA20_OUTSZ
60
61 /*----- Data structures ---------------------------------------------------*/
62
63 typedef uint32 salsa20_matrix[16];
64
65 typedef struct salsa20_ctx {
66   salsa20_matrix a;
67   octet buf[SALSA20_OUTSZ];
68   size_t bufi;
69 } salsa20_ctx;
70
71 #define XSALSA20_DEFCTX(name)                                           \
72   typedef struct name { salsa20_ctx s; salsa20_matrix k; } name
73 XSALSA20_DEFCTX(xsalsa20_ctx);
74 XSALSA20_DEFCTX(xsalsa2012_ctx);
75 XSALSA20_DEFCTX(xsalsa208_ctx);
76
77 /*----- The Salsa20 stream cipher -----------------------------------------*/
78
79 /* --- @salsa20_init@ --- *
80  *
81  * Arguments:   @salsa20_ctx *ctx@ = context to fill in
82  *              @const void *key@ = pointer to key material
83  *              @size_t ksz@ = size of key (either 32 or 16)
84  *              @const void *nonce@ = initial nonce, or null
85  *
86  * Returns:     ---
87  *
88  * Use:         Initializes a Salsa20 context ready for use.
89  */
90
91 extern void salsa20_init(salsa20_ctx */*ctx*/,
92                          const void */*key*/, size_t /*ksz*/,
93                          const void */*nonce*/);
94
95 /* --- @salsa20_setnonce{,_ietf}@ --- *
96  *
97  * Arguments:   @salsa20_ctx *ctx@ = pointer to context
98  *              @const void *nonce@ = the nonce (@SALSA20_NONCESZ@ or
99  *                      @SALSA20_IETF_NONCESZ@ bytes)
100  *
101  * Returns:     ---
102  *
103  * Use:         Set a new nonce in the context @ctx@, e.g., for processing a
104  *              different message.  The stream position is reset to zero (see
105  *              @salsa20_seek@ etc.).
106  */
107
108 extern void salsa20_setnonce(salsa20_ctx */*ctx*/, const void */*nonce*/);
109 extern void salsa20_setnonce_ietf(salsa20_ctx */*ctx*/,
110                                   const void */*nonce*/);
111
112 /* --- @salsa20_seek{,u64,_ietf}@ --- *
113  *
114  * Arguments:   @salsa20_ctx *ctx@ = pointer to context
115  *              @unsigned long i@, @kludge64 i@ = new position to set
116  *
117  * Returns:     ---
118  *
119  * Use:         Sets a new stream position, in units of Salsa20 output
120  *              blocks, which are @SALSA20_OUTSZ@ bytes each.  Byte
121  *              granularity can be achieved by calling @salsa20_encrypt@
122  *              appropriately.
123  */
124
125 extern void salsa20_seek(salsa20_ctx */*ctx*/, unsigned long /*i*/);
126 extern void salsa20_seeku64(salsa20_ctx */*ctx*/, kludge64 /*i*/);
127 extern void salsa20_seek_ietf(salsa20_ctx */*ctx*/, uint32 /*i*/);
128
129 /* --- @salsa20_tell{,u64,_ietf}@ --- *
130  *
131  * Arguments:   @salsa20_ctx *ctx@ = pointer to context
132  *
133  * Returns:     The current position in the output stream, in blocks,
134  *              rounding upwards.
135  */
136
137 extern unsigned long salsa20_tell(salsa20_ctx */*ctx*/);
138 extern kludge64 salsa20_tellu64(salsa20_ctx */*ctx*/);
139 extern uint32 salsa20_tell_ietf(salsa20_ctx */*ctx*/);
140
141 /* --- @salsa20{,12,8}_encrypt@ --- *
142  *
143  * Arguments:   @salsa20_ctx *ctx@ = pointer to context
144  *              @const void *src@ = source buffer (or null)
145  *              @void *dest@ = destination buffer (or null)
146  *              @size_t sz@ = size of the buffers
147  *
148  * Returns:     ---
149  *
150  * Use:         Encrypts or decrypts @sz@ bytes of data from @src@ to @dest@.
151  *              Salsa20 works by XORing plaintext with a keystream, so
152  *              encryption and decryption are the same operation.  If @dest@
153  *              is null then ignore @src@ and skip @sz@ bytes of the
154  *              keystream.  If @src@ is null, then just write the keystream
155  *              to @dest@.
156  */
157
158 extern void salsa20_encrypt(salsa20_ctx */*ctx*/,
159                             const void */*src*/, void */*dest*/,
160                             size_t /*sz*/);
161 extern void salsa2012_encrypt(salsa20_ctx */*ctx*/,
162                               const void */*src*/, void */*dest*/,
163                               size_t /*sz*/);
164 extern void salsa208_encrypt(salsa20_ctx */*ctx*/,
165                               const void */*src*/, void */*dest*/,
166                               size_t /*sz*/);
167
168 /*----- The HSalsa20 pseudorandom function --------------------------------*/
169
170 /* --- @hsalsa20{,12,8}_prf@ --- *
171  *
172  * Arguments:   @salsa20_ctx *ctx@ = pointer to context
173  *              @const void *src@ = the input (@HSALSA20_INSZ@ bytes)
174  *              @void *dest@ = the output (@HSALSA20_OUTSZ@ bytes)
175  *
176  * Returns:     ---
177  *
178  * Use:         Apply the HSalsa20/r pseudorandom function to @src@, writing
179  *              the result to @out@.
180  */
181
182 extern void hsalsa20_prf(salsa20_ctx */*ctx*/,
183                          const void */*src*/, void */*dest*/);
184 extern void hsalsa2012_prf(salsa20_ctx */*ctx*/,
185                            const void */*src*/, void */*dest*/);
186 extern void hsalsa208_prf(salsa20_ctx */*ctx*/,
187                           const void */*src*/, void */*dest*/);
188
189 /*----- The XSalsa20 stream cipher ----------------------------------------*/
190
191 /* --- @xsalsa20{,12,8}_init@ --- *
192  *
193  * Arguments:   @xsalsa20R_ctx *ctx@ = the context to fill in
194  *              @const void *key@ = pointer to key material
195  *              @size_t ksz@ = size of key (either 32 or 16)
196  *              @const void *nonce@ = initial nonce, or null
197  *
198  * Returns:     ---
199  *
200  * Use:         Initializes an XSalsa20/r context ready for use.
201  *
202  *              There is a different function for each number of rounds,
203  *              unlike for plain Salsa20.
204  */
205
206 extern void xsalsa20_init(xsalsa20_ctx */*ctx*/,
207                           const void */*key*/, size_t /*ksz*/,
208                           const void */*nonce*/);
209 extern void xsalsa2012_init(xsalsa2012_ctx */*ctx*/,
210                             const void */*key*/, size_t /*ksz*/,
211                             const void */*nonce*/);
212 extern void xsalsa208_init(xsalsa208_ctx */*ctx*/,
213                            const void */*key*/, size_t /*ksz*/,
214                            const void */*nonce*/);
215
216 /* --- @xsalsa20{,12,8}_setnonce@ --- *
217  *
218  * Arguments:   @xsalsa20R_ctx *ctx@ = pointer to context
219  *              @const void *nonce@ = the nonce (@XSALSA20_NONCESZ@ bytes)
220  *
221  * Returns:     ---
222  *
223  * Use:         Set a new nonce in the context @ctx@, e.g., for processing a
224  *              different message.  The stream position is reset to zero (see
225  *              @salsa20_seek@ etc.).
226  *
227  *              There is a different function for each number of rounds,
228  *              unlike for plain Salsa20.
229  */
230
231 extern void xsalsa20_setnonce(xsalsa20_ctx */*ctx*/,
232                               const void */*nonce*/);
233 extern void xsalsa2012_setnonce(xsalsa2012_ctx */*ctx*/,
234                                 const void */*nonce*/);
235 extern void xsalsa208_setnonce(xsalsa208_ctx */*ctx*/,
236                                const void */*nonce*/);
237
238 /* --- @xsalsa20{,12,8}_seek@, @xsalsa20{,12,8}_seeku64@ --- *
239  *
240  * Arguments:   @xsalsa20R_ctx *ctx@ = pointer to context
241  *              @unsigned long i@, @kludge64 i@ = new position to set
242  *
243  * Returns:     ---
244  *
245  * Use:         Sets a new stream position, in units of Salsa20 output
246  *              blocks, which are @XSALSA20_OUTSZ@ bytes each.  Byte
247  *              granularity can be achieved by calling @xsalsa20R_encrypt@
248  *              appropriately.
249  *
250  *              There is a different function for each number of rounds,
251  *              unlike for plain Salsa20, because the context structures are
252  *              different.
253  */
254
255 extern void xsalsa20_seek(xsalsa20_ctx */*ctx*/, unsigned long /*i*/);
256 extern void xsalsa2012_seek(xsalsa2012_ctx */*ctx*/, unsigned long /*i*/);
257 extern void xsalsa208_seek(xsalsa208_ctx */*ctx*/, unsigned long /*i*/);
258 extern void xsalsa20_seeku64(xsalsa20_ctx */*ctx*/, kludge64 /*i*/);
259 extern void xsalsa2012_seeku64(xsalsa2012_ctx */*ctx*/, kludge64 /*i*/);
260 extern void xsalsa208_seeku64(xsalsa208_ctx */*ctx*/, kludge64 /*i*/);
261
262 /* --- @xsalsa20{,12,8}_tell@, @xsalsa20{,12,8}_tellu64@ --- *
263  *
264  * Arguments:   @salsa20_ctx *ctx@ = pointer to context
265  *
266  * Returns:     The current position in the output stream, in blocks,
267  *              rounding upwards.
268  *
269  *              There is a different function for each number of rounds,
270  *              unlike for plain Salsa20, because the context structures are
271  *              different.
272  */
273
274 extern unsigned long xsalsa20_tell(xsalsa20_ctx */*ctx*/);
275 extern unsigned long xsalsa2012_tell(xsalsa2012_ctx */*ctx*/);
276 extern unsigned long xsalsa208_tell(xsalsa208_ctx */*ctx*/);
277 extern kludge64 xsalsa20_tellu64(xsalsa20_ctx */*ctx*/);
278 extern kludge64 xsalsa2012_tellu64(xsalsa2012_ctx */*ctx*/);
279 extern kludge64 xsalsa208_tellu64(xsalsa208_ctx */*ctx*/);
280
281 /* --- @xsalsa20{,12,8}_encrypt@ --- *
282  *
283  * Arguments:   @xsalsa20R_ctx *ctx@ = pointer to context
284  *              @const void *src@ = source buffer (or null)
285  *              @void *dest@ = destination buffer (or null)
286  *              @size_t sz@ = size of the buffers
287  *
288  * Returns:     ---
289  *
290  * Use:         Encrypts or decrypts @sz@ bytes of data from @src@ to @dest@.
291  *              XSalsa20 works by XORing plaintext with a keystream, so
292  *              encryption and decryption are the same operation.  If @dest@
293  *              is null then ignore @src@ and skip @sz@ bytes of the
294  *              keystream.  If @src@ is null, then just write the keystream
295  *              to @dest@.
296  */
297
298 extern void xsalsa20_encrypt(xsalsa20_ctx */*ctx*/,
299                             const void */*src*/, void */*dest*/,
300                             size_t /*sz*/);
301 extern void xsalsa2012_encrypt(xsalsa2012_ctx */*ctx*/,
302                               const void */*src*/, void */*dest*/,
303                               size_t /*sz*/);
304 extern void xsalsa208_encrypt(xsalsa208_ctx */*ctx*/,
305                               const void */*src*/, void */*dest*/,
306                               size_t /*sz*/);
307
308 /*----- Generic cipher interface ------------------------------------------*/
309
310 extern const octet salsa20_keysz[];
311 #define salsa2012_keysz salsa20_keysz
312 #define salsa208_keysz salsa20_keysz
313 #define salsa20_ietf_keysz salsa20_keysz
314 #define salsa2012_ietf_keysz salsa20_keysz
315 #define salsa208_ietf_keysz salsa20_keysz
316 #define xsalsa20_keysz salsa20_keysz
317 #define xsalsa2012_keysz salsa20_keysz
318 #define xsalsa208_keysz salsa20_keysz
319
320 extern const gccipher salsa20, salsa2012, salsa208;
321 extern const gccipher salsa20_ietf, salsa2012_ietf, salsa208_ietf;
322 extern const gccipher xsalsa20, xsalsa2012, xsalsa208;
323
324 /*----- Generic random number generator interface -------------------------*/
325
326 /* --- @salsa20{,12,8}{,_ietf}_rand@, @xsalsa20{,12,8}{,_ietf}_rand@ --- *
327  *
328  * Arguments:           @const void *k@ = pointer to key material
329  *                      @size_t ksz@ = size of key material
330  *                      @const void *n@ = pointer to nonce or null
331  *                              (@SALSA20_NONCESZ@, @SALSA20_IETF_NONCESZ@,
332  *                              or @XSALSA20_NONCESZ@)
333  *
334  * Returns:             Pointer to generic random number generator instance.
335  *
336  * Use:                 Creates a random number interface wrapper around
337  *                      the Salsa20/r or XSalsa20/r stream ciphers.
338  */
339
340 extern grand *salsa20_rand(const void */*k*/, size_t /*ksz*/,
341                            const void */*n*/);
342 extern grand *salsa2012_rand(const void */*k*/, size_t /*ksz*/,
343                              const void */*n*/);
344 extern grand *salsa208_rand(const void */*k*/, size_t /*ksz*/,
345                             const void */*n*/);
346 extern grand *salsa20_ietf_rand(const void */*k*/, size_t /*ksz*/,
347                                 const void */*n*/);
348 extern grand *salsa2012_ietf_rand(const void */*k*/, size_t /*ksz*/,
349                                   const void */*n*/);
350 extern grand *salsa208_ietf_rand(const void */*k*/, size_t /*ksz*/,
351                                  const void */*n*/);
352 extern grand *xsalsa20_rand(const void */*k*/, size_t /*ksz*/,
353                             const void */*n*/);
354 extern grand *xsalsa2012_rand(const void */*k*/, size_t /*ksz*/,
355                               const void */*n*/);
356 extern grand *xsalsa208_rand(const void */*k*/, size_t /*ksz*/,
357                              const void */*n*/);
358
359 enum {
360   SALSA20_SEEK = GRAND_SPECIFIC('S'),   /* @unsigned long pos@ */
361   SALSA20_SEEKU64,                      /* @kludge64 pos@ */
362   SALSA20_TELL,                         /* @unsigned long *pos@ */
363   SALSA20_TELLU64                       /* @kludge64 *pos@ */
364 };
365
366 /*----- That's all, folks -------------------------------------------------*/
367
368 #ifdef __cplusplus
369   }
370 #endif
371
372 #endif