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