GitHub CI: update list of container images
[tinc] / src / chacha-poly1305 / chacha.c
1 /*
2 chacha-merged.c version 20080118
3 D. J. Bernstein
4 Public domain.
5 */
6
7 #include "../system.h"
8
9 #include "chacha.h"
10
11 typedef struct chacha_ctx chacha_ctx;
12
13 #define U8C(v) (v##U)
14 #define U32C(v) (v##U)
15
16 #define U8V(v) ((uint8_t)(v) & U8C(0xFF))
17 #define U32V(v) ((uint32_t)(v) & U32C(0xFFFFFFFF))
18
19 #define ROTL32(v, n) \
20         (U32V((v) << (n)) | ((v) >> (32 - (n))))
21
22 #define U8TO32_LITTLE(p) \
23         (((uint32_t)((p)[0])      ) | \
24          ((uint32_t)((p)[1]) <<  8) | \
25          ((uint32_t)((p)[2]) << 16) | \
26          ((uint32_t)((p)[3]) << 24))
27
28 #define U32TO8_LITTLE(p, v) \
29         do { \
30                 (p)[0] = U8V((v)      ); \
31                 (p)[1] = U8V((v) >>  8); \
32                 (p)[2] = U8V((v) >> 16); \
33                 (p)[3] = U8V((v) >> 24); \
34         } while (0)
35
36 #define ROTATE(v,c) (ROTL32(v,c))
37 #define XOR(v,w) ((v) ^ (w))
38 #define PLUS(v,w) (U32V((v) + (w)))
39 #define PLUSONE(v) (PLUS((v),1))
40
41 #define QUARTERROUND(a,b,c,d) \
42         a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
43         c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
44         a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
45         c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
46
47 static const char sigma[16] = "expand 32-byte k";
48 static const char tau[16] = "expand 16-byte k";
49
50 void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits) {
51         const char *constants;
52
53         x->input[4] = U8TO32_LITTLE(k + 0);
54         x->input[5] = U8TO32_LITTLE(k + 4);
55         x->input[6] = U8TO32_LITTLE(k + 8);
56         x->input[7] = U8TO32_LITTLE(k + 12);
57
58         if(kbits == 256) {      /* recommended */
59                 k += 16;
60                 constants = sigma;
61         } else {                /* kbits == 128 */
62                 constants = tau;
63         }
64
65         x->input[8] = U8TO32_LITTLE(k + 0);
66         x->input[9] = U8TO32_LITTLE(k + 4);
67         x->input[10] = U8TO32_LITTLE(k + 8);
68         x->input[11] = U8TO32_LITTLE(k + 12);
69         x->input[0] = U8TO32_LITTLE(constants + 0);
70         x->input[1] = U8TO32_LITTLE(constants + 4);
71         x->input[2] = U8TO32_LITTLE(constants + 8);
72         x->input[3] = U8TO32_LITTLE(constants + 12);
73 }
74
75 void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter) {
76         x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
77         x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
78         x->input[14] = U8TO32_LITTLE(iv + 0);
79         x->input[15] = U8TO32_LITTLE(iv + 4);
80 }
81
82 void
83 chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes) {
84         uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
85         uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
86         uint8_t *ctarget = NULL;
87         uint8_t tmp[64];
88         uint32_t i;
89
90         if(!bytes) {
91                 return;
92         }
93
94         j0 = x->input[0];
95         j1 = x->input[1];
96         j2 = x->input[2];
97         j3 = x->input[3];
98         j4 = x->input[4];
99         j5 = x->input[5];
100         j6 = x->input[6];
101         j7 = x->input[7];
102         j8 = x->input[8];
103         j9 = x->input[9];
104         j10 = x->input[10];
105         j11 = x->input[11];
106         j12 = x->input[12];
107         j13 = x->input[13];
108         j14 = x->input[14];
109         j15 = x->input[15];
110
111         for(;;) {
112                 if(bytes < 64) {
113                         for(i = 0; i < bytes; ++i) {
114                                 tmp[i] = m[i];
115                         }
116
117                         m = tmp;
118                         ctarget = c;
119                         c = tmp;
120                 }
121
122                 x0 = j0;
123                 x1 = j1;
124                 x2 = j2;
125                 x3 = j3;
126                 x4 = j4;
127                 x5 = j5;
128                 x6 = j6;
129                 x7 = j7;
130                 x8 = j8;
131                 x9 = j9;
132                 x10 = j10;
133                 x11 = j11;
134                 x12 = j12;
135                 x13 = j13;
136                 x14 = j14;
137                 x15 = j15;
138
139                 for(i = 20; i > 0; i -= 2) {
140                         QUARTERROUND(x0, x4, x8, x12)
141                         QUARTERROUND(x1, x5, x9, x13)
142                         QUARTERROUND(x2, x6, x10, x14)
143                         QUARTERROUND(x3, x7, x11, x15)
144                         QUARTERROUND(x0, x5, x10, x15)
145                         QUARTERROUND(x1, x6, x11, x12)
146                         QUARTERROUND(x2, x7, x8, x13)
147                         QUARTERROUND(x3, x4, x9, x14)
148                 }
149
150                 x0 = PLUS(x0, j0);
151                 x1 = PLUS(x1, j1);
152                 x2 = PLUS(x2, j2);
153                 x3 = PLUS(x3, j3);
154                 x4 = PLUS(x4, j4);
155                 x5 = PLUS(x5, j5);
156                 x6 = PLUS(x6, j6);
157                 x7 = PLUS(x7, j7);
158                 x8 = PLUS(x8, j8);
159                 x9 = PLUS(x9, j9);
160                 x10 = PLUS(x10, j10);
161                 x11 = PLUS(x11, j11);
162                 x12 = PLUS(x12, j12);
163                 x13 = PLUS(x13, j13);
164                 x14 = PLUS(x14, j14);
165                 x15 = PLUS(x15, j15);
166
167                 x0 = XOR(x0, U8TO32_LITTLE(m + 0));
168                 x1 = XOR(x1, U8TO32_LITTLE(m + 4));
169                 x2 = XOR(x2, U8TO32_LITTLE(m + 8));
170                 x3 = XOR(x3, U8TO32_LITTLE(m + 12));
171                 x4 = XOR(x4, U8TO32_LITTLE(m + 16));
172                 x5 = XOR(x5, U8TO32_LITTLE(m + 20));
173                 x6 = XOR(x6, U8TO32_LITTLE(m + 24));
174                 x7 = XOR(x7, U8TO32_LITTLE(m + 28));
175                 x8 = XOR(x8, U8TO32_LITTLE(m + 32));
176                 x9 = XOR(x9, U8TO32_LITTLE(m + 36));
177                 x10 = XOR(x10, U8TO32_LITTLE(m + 40));
178                 x11 = XOR(x11, U8TO32_LITTLE(m + 44));
179                 x12 = XOR(x12, U8TO32_LITTLE(m + 48));
180                 x13 = XOR(x13, U8TO32_LITTLE(m + 52));
181                 x14 = XOR(x14, U8TO32_LITTLE(m + 56));
182                 x15 = XOR(x15, U8TO32_LITTLE(m + 60));
183
184                 j12 = PLUSONE(j12);
185
186                 if(!j12) {
187                         j13 = PLUSONE(j13);
188                         /* stopping at 2^70 bytes per nonce is user's responsibility */
189                 }
190
191                 U32TO8_LITTLE(c + 0, x0);
192                 U32TO8_LITTLE(c + 4, x1);
193                 U32TO8_LITTLE(c + 8, x2);
194                 U32TO8_LITTLE(c + 12, x3);
195                 U32TO8_LITTLE(c + 16, x4);
196                 U32TO8_LITTLE(c + 20, x5);
197                 U32TO8_LITTLE(c + 24, x6);
198                 U32TO8_LITTLE(c + 28, x7);
199                 U32TO8_LITTLE(c + 32, x8);
200                 U32TO8_LITTLE(c + 36, x9);
201                 U32TO8_LITTLE(c + 40, x10);
202                 U32TO8_LITTLE(c + 44, x11);
203                 U32TO8_LITTLE(c + 48, x12);
204                 U32TO8_LITTLE(c + 52, x13);
205                 U32TO8_LITTLE(c + 56, x14);
206                 U32TO8_LITTLE(c + 60, x15);
207
208                 if(bytes <= 64) {
209                         if(bytes < 64) {
210                                 for(i = 0; i < bytes; ++i) {
211                                         ctarget[i] = c[i];
212                                 }
213                         }
214
215                         x->input[12] = j12;
216                         x->input[13] = j13;
217                         return;
218                 }
219
220                 bytes -= 64;
221                 c += 64;
222                 m += 64;
223         }
224 }