2 /* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */
5 chacha-merged.c version 20080118
14 #include "crypto_stream_chacha20.h"
24 typedef struct chacha_ctx chacha_ctx;
27 #define U32C(v) (v##U)
29 #define U8V(v) ((u8)(v) & U8C(0xFF))
30 #define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
32 #define ROTL32(v, n) \
33 (U32V((v) << (n)) | ((v) >> (32 - (n))))
35 #define U8TO32_LITTLE(p) \
37 ((u32)((p)[1]) << 8) | \
38 ((u32)((p)[2]) << 16) | \
39 ((u32)((p)[3]) << 24))
41 #define U32TO8_LITTLE(p, v) \
44 (p)[1] = U8V((v) >> 8); \
45 (p)[2] = U8V((v) >> 16); \
46 (p)[3] = U8V((v) >> 24); \
49 #define ROTATE(v,c) (ROTL32(v,c))
50 #define XOR(v,w) ((v) ^ (w))
51 #define PLUS(v,w) (U32V((v) + (w)))
52 #define PLUSONE(v) (PLUS((v),1))
54 #define QUARTERROUND(a,b,c,d) \
55 a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
56 c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
57 a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
58 c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
60 static const unsigned char sigma[16] = {
61 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'
65 chacha_keysetup(chacha_ctx *x, const u8 *k)
67 const unsigned char *constants;
69 x->input[4] = U8TO32_LITTLE(k + 0);
70 x->input[5] = U8TO32_LITTLE(k + 4);
71 x->input[6] = U8TO32_LITTLE(k + 8);
72 x->input[7] = U8TO32_LITTLE(k + 12);
75 x->input[8] = U8TO32_LITTLE(k + 0);
76 x->input[9] = U8TO32_LITTLE(k + 4);
77 x->input[10] = U8TO32_LITTLE(k + 8);
78 x->input[11] = U8TO32_LITTLE(k + 12);
79 x->input[0] = U8TO32_LITTLE(constants + 0);
80 x->input[1] = U8TO32_LITTLE(constants + 4);
81 x->input[2] = U8TO32_LITTLE(constants + 8);
82 x->input[3] = U8TO32_LITTLE(constants + 12);
86 chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
88 x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
89 x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
90 x->input[14] = U8TO32_LITTLE(iv + 0);
91 x->input[15] = U8TO32_LITTLE(iv + 4);
95 chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, unsigned long long bytes)
97 u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
98 u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
104 return; /* LCOV_EXCL_LINE */
125 for (i = 0; i < bytes; ++i) {
148 for (i = 20; i > 0; i -= 2) {
149 QUARTERROUND(x0, x4, x8, x12)
150 QUARTERROUND(x1, x5, x9, x13)
151 QUARTERROUND(x2, x6, x10, x14)
152 QUARTERROUND(x3, x7, x11, x15)
153 QUARTERROUND(x0, x5, x10, x15)
154 QUARTERROUND(x1, x6, x11, x12)
155 QUARTERROUND(x2, x7, x8, x13)
156 QUARTERROUND(x3, x4, x9, x14)
168 x10 = PLUS(x10, j10);
169 x11 = PLUS(x11, j11);
170 x12 = PLUS(x12, j12);
171 x13 = PLUS(x13, j13);
172 x14 = PLUS(x14, j14);
173 x15 = PLUS(x15, j15);
175 x0 = XOR(x0, U8TO32_LITTLE(m + 0));
176 x1 = XOR(x1, U8TO32_LITTLE(m + 4));
177 x2 = XOR(x2, U8TO32_LITTLE(m + 8));
178 x3 = XOR(x3, U8TO32_LITTLE(m + 12));
179 x4 = XOR(x4, U8TO32_LITTLE(m + 16));
180 x5 = XOR(x5, U8TO32_LITTLE(m + 20));
181 x6 = XOR(x6, U8TO32_LITTLE(m + 24));
182 x7 = XOR(x7, U8TO32_LITTLE(m + 28));
183 x8 = XOR(x8, U8TO32_LITTLE(m + 32));
184 x9 = XOR(x9, U8TO32_LITTLE(m + 36));
185 x10 = XOR(x10, U8TO32_LITTLE(m + 40));
186 x11 = XOR(x11, U8TO32_LITTLE(m + 44));
187 x12 = XOR(x12, U8TO32_LITTLE(m + 48));
188 x13 = XOR(x13, U8TO32_LITTLE(m + 52));
189 x14 = XOR(x14, U8TO32_LITTLE(m + 56));
190 x15 = XOR(x15, U8TO32_LITTLE(m + 60));
193 /* LCOV_EXCL_START */
199 U32TO8_LITTLE(c + 0, x0);
200 U32TO8_LITTLE(c + 4, x1);
201 U32TO8_LITTLE(c + 8, x2);
202 U32TO8_LITTLE(c + 12, x3);
203 U32TO8_LITTLE(c + 16, x4);
204 U32TO8_LITTLE(c + 20, x5);
205 U32TO8_LITTLE(c + 24, x6);
206 U32TO8_LITTLE(c + 28, x7);
207 U32TO8_LITTLE(c + 32, x8);
208 U32TO8_LITTLE(c + 36, x9);
209 U32TO8_LITTLE(c + 40, x10);
210 U32TO8_LITTLE(c + 44, x11);
211 U32TO8_LITTLE(c + 48, x12);
212 U32TO8_LITTLE(c + 52, x13);
213 U32TO8_LITTLE(c + 56, x14);
214 U32TO8_LITTLE(c + 60, x15);
218 for (i = 0; i < (unsigned int) bytes; ++i) {
233 crypto_stream_chacha20_ref(unsigned char *c, unsigned long long clen,
234 const unsigned char *n, const unsigned char *k)
236 struct chacha_ctx ctx;
241 (void) sizeof(int[crypto_stream_chacha20_KEYBYTES == 256 / 8 ? 1 : -1]);
242 chacha_keysetup(&ctx, k);
243 chacha_ivsetup(&ctx, n, NULL);
245 chacha_encrypt_bytes(&ctx, c, c, clen);
246 sodium_memzero(&ctx, sizeof ctx);
252 crypto_stream_chacha20_ref_xor_ic(unsigned char *c, const unsigned char *m,
253 unsigned long long mlen,
254 const unsigned char *n, uint64_t ic,
255 const unsigned char *k)
257 struct chacha_ctx ctx;
265 ic_high = U32V(ic >> 32);
267 U32TO8_LITTLE(&ic_bytes[0], ic_low);
268 U32TO8_LITTLE(&ic_bytes[4], ic_high);
269 chacha_keysetup(&ctx, k);
270 chacha_ivsetup(&ctx, n, ic_bytes);
271 chacha_encrypt_bytes(&ctx, m, c, mlen);
272 sodium_memzero(&ctx, sizeof ctx);
273 sodium_memzero(ic_bytes, sizeof ic_bytes);