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