chiark / gitweb /
Release 2.4.3.
[catacomb] / symm / chacha-core.h
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
98  * updated.  This is the same as Salsa20, only without the final permutation.
99  */
100 #define CHACHA_FFWD(z, y) do {                                          \
101   int _i;                                                               \
102   for (_i = 0; _i < 16; _i++) (z)[_i] += (y)[_i];                       \
103 } while (0)
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