Commit | Line | Data |
---|---|---|
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 |