Merge branch '2.5.x'
[catacomb] / symm / chacha-core.h
CommitLineData
55d81656
MW
1/* -*-c-*-
2 *
3 * ChaCha core definitions
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_CHACHA_CORE_H
29#define CATACOMB_CHACHA_CORE_H
30
31#ifdef __cplusplus
32 extern "C" {
33#endif
34
35/*----- Header files ------------------------------------------------------*/
36
37#include <mLib/bits.h>
38#include <mLib/macros.h>
39
40#ifndef CATACOMB_CHACHA_H
41# include "chacha.h"
42#endif
43
44#ifndef CATACOMB_SALSA20_CORE_H
45# include "salsa20-core.h"
46#endif
47
48/*----- Magic constants ---------------------------------------------------*/
49
50/* The magic ChaCha constants are the same as the Salsa20 ones. For 256-bit
51 * keys ...
52 */
53#define CHACHA_A256 SALSA20_A256 /* e x p a */
54#define CHACHA_B256 SALSA20_B256 /* n d 3 */
55#define CHACHA_C256 SALSA20_C256 /* 2 - b y */
56#define CHACHA_D256 SALSA20_D256 /* t e k */
57
58/* ... and for 128-bit keys ... */
59#define CHACHA_A128 SALSA20_A128 /* e x p a */
60#define CHACHA_B128 SALSA20_B128 /* n d 1 */
61#define CHACHA_C128 SALSA20_C128 /* 6 - b y */
62#define CHACHA_D128 SALSA20_D128 /* t e k */
63
64/* ... and for 80-bit keys, for completeness's sake. */
65#define CHACHA_A80 SALSA20_A80 /* e x p a */
66#define CHACHA_B80 SALSA20_B80 /* n d 1 */
67#define CHACHA_C80 SALSA20_C80 /* 0 - b y */
68#define CHACHA_D80 SALSA20_D80 /* t e k */
69
70/*----- The ChaCha core function ------------------------------------------*/
71
72/* The ChaCha quarter round. Read from the matrix @y@ at indices @a@, @b@,
73 * @c@, and @d@; and write to the corresponding elements of @z@.
74 */
75#define CHACHA_QR(z, y, a, b, c, d) do { \
76 (z)[a] = (y)[a] + (y)[b]; (z)[d] = ROL32((y)[d] ^ (z)[a], 16); \
77 (z)[c] = (y)[c] + (z)[d]; (z)[b] = ROL32((y)[b] ^ (z)[c], 12); \
78 (z)[a] = (z)[a] + (z)[b]; (z)[d] = ROL32((z)[d] ^ (z)[a], 8); \
79 (z)[c] = (z)[c] + (z)[d]; (z)[b] = ROL32((z)[b] ^ (z)[c], 7); \
80} while (0)
81
82/* The ChaCha double-round. Read from matrix @y@, writing the result to
83 * @z@.
84 */
85#define CHACHA_DR(z, y) do { \
86 CHACHA_QR(z, y, 0, 4, 8, 12); \
87 CHACHA_QR(z, y, 1, 5, 9, 13); \
88 CHACHA_QR(z, y, 2, 6, 10, 14); \
89 CHACHA_QR(z, y, 3, 7, 11, 15); \
90 CHACHA_QR(z, z, 0, 5, 10, 15); \
91 CHACHA_QR(z, z, 1, 6, 11, 12); \
92 CHACHA_QR(z, z, 2, 7, 8, 13); \
93 CHACHA_QR(z, z, 3, 4, 9, 14); \
94} while (0)
95
96/* The ChaCha feedforward step, used at the end of the core function. Here,
97 * @y@ contains the original input matrix; @z@ contains the final one, and is
a4c2e267 98 * updated. This is the same as Salsa20, only without the final permutation.
55d81656 99 */
a4c2e267
MW
100#define CHACHA_FFWD(z, y) do { \
101 int _i; \
102 for (_i = 0; _i < 16; _i++) (z)[_i] += (y)[_i]; \
103} while (0)
55d81656
MW
104
105/* Various numbers of rounds, unrolled. Read from @y@, and write to @z@. */
106#define CHACHA_4R(z, y) \
107 do { CHACHA_DR(z, y); CHACHA_DR(z, z); } while (0)
108#define CHACHA_8R(z, y) \
109 do { CHACHA_4R(z, y); CHACHA_4R(z, z); } while (0)
110#define CHACHA_12R(z, y) \
111 do { CHACHA_8R(z, y); CHACHA_4R(z, z); } while (0)
112#define CHACHA_20R(z, y) \
113 do { CHACHA_12R(z, y); CHACHA_8R(z, z); } while (0)
114
115/* Apply @n@ (must be even) rounds, rolled. (This seems to be faster,
116 * probably because it fits in cache better). Read from @y@, and write to
117 * @z@.
118 */
119#define CHACHA_nR(z, y, n) do { \
120 int _i; \
121 CHACHA_DR(z, y); \
122 for (_i = 0; _i < (n)/2 - 1; _i++) CHACHA_DR(z, z); \
123} while (0)
124
125/* Step the counter in the Chacha state matrix @a@. */
126#define CHACHA_STEP(a) \
127 do { (a)[12] = U32((a)[12] + 1); (a)[13] += !(a)[12]; } while (0)
128
129/*----- Variants and naming -----------------------------------------------*/
130
131/* Common numbers of rounds, for which we generate definitions. */
132#define CHACHA_VARS(_) _(8) _(12) _(20)
133
134/*----- That's all, folks -------------------------------------------------*/
135
136#ifdef __cplusplus
137 }
138#endif
139
140#endif