2 chacha-merged.c version 20080118
7 /* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */
10 #include <sys/types.h>
12 #include <crypto/chacha20/chacha.h>
17 typedef struct chacha_ctx chacha_ctx;
20 #define U32C(v) (v##U)
22 #define U8V(v) ((u8)(v) & U8C(0xFF))
23 #define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
25 #define ROTL32(v, n) \
26 (U32V((v) << (n)) | ((v) >> (32 - (n))))
28 #define U8TO32_LITTLE(p) \
30 ((u32)((p)[1]) << 8) | \
31 ((u32)((p)[2]) << 16) | \
32 ((u32)((p)[3]) << 24))
34 #define U32TO8_LITTLE(p, v) \
37 (p)[1] = U8V((v) >> 8); \
38 (p)[2] = U8V((v) >> 16); \
39 (p)[3] = U8V((v) >> 24); \
42 #define ROTATE(v,c) (ROTL32(v,c))
43 #define XOR(v,w) ((v) ^ (w))
44 #define PLUS(v,w) (U32V((v) + (w)))
45 #define PLUSONE(v) (PLUS((v),1))
47 #define QUARTERROUND(a,b,c,d) \
48 a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
49 c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
50 a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
51 c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
53 static const char sigma[16] = "expand 32-byte k";
54 static const char tau[16] = "expand 16-byte k";
57 chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
59 const char *constants;
61 x->input[4] = U8TO32_LITTLE(k + 0);
62 x->input[5] = U8TO32_LITTLE(k + 4);
63 x->input[6] = U8TO32_LITTLE(k + 8);
64 x->input[7] = U8TO32_LITTLE(k + 12);
65 if (kbits == 256) { /* recommended */
68 } else { /* kbits == 128 */
71 x->input[8] = U8TO32_LITTLE(k + 0);
72 x->input[9] = U8TO32_LITTLE(k + 4);
73 x->input[10] = U8TO32_LITTLE(k + 8);
74 x->input[11] = U8TO32_LITTLE(k + 12);
75 x->input[0] = U8TO32_LITTLE(constants + 0);
76 x->input[1] = U8TO32_LITTLE(constants + 4);
77 x->input[2] = U8TO32_LITTLE(constants + 8);
78 x->input[3] = U8TO32_LITTLE(constants + 12);
82 chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
84 #ifndef CHACHA_NONCE0_CTR128
85 x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
86 x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
87 x->input[14] = U8TO32_LITTLE(iv + 0);
88 x->input[15] = U8TO32_LITTLE(iv + 4);
92 x->input[12] = U8TO32_LITTLE(counter + 0);
93 x->input[13] = U8TO32_LITTLE(counter + 4);
94 x->input[14] = U8TO32_LITTLE(counter + 8);
95 x->input[15] = U8TO32_LITTLE(counter + 12);
99 #ifdef CHACHA_NONCE0_CTR128
101 chacha_ctrsave(const chacha_ctx *x, u8 *counter)
103 U32TO8_LITTLE(counter + 0, x->input[12]);
104 U32TO8_LITTLE(counter + 4, x->input[13]);
105 U32TO8_LITTLE(counter + 8, x->input[14]);
106 U32TO8_LITTLE(counter + 12, x->input[15]);
111 chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
113 u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
114 u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
140 #ifndef KEYSTREAM_ONLY
141 for (i = 0;i < bytes;++i) tmp[i] = m[i];
163 for (i = 20;i > 0;i -= 2) {
164 QUARTERROUND( x0, x4, x8,x12)
165 QUARTERROUND( x1, x5, x9,x13)
166 QUARTERROUND( x2, x6,x10,x14)
167 QUARTERROUND( x3, x7,x11,x15)
168 QUARTERROUND( x0, x5,x10,x15)
169 QUARTERROUND( x1, x6,x11,x12)
170 QUARTERROUND( x2, x7, x8,x13)
171 QUARTERROUND( x3, x4, x9,x14)
190 #ifndef KEYSTREAM_ONLY
191 x0 = XOR(x0,U8TO32_LITTLE(m + 0));
192 x1 = XOR(x1,U8TO32_LITTLE(m + 4));
193 x2 = XOR(x2,U8TO32_LITTLE(m + 8));
194 x3 = XOR(x3,U8TO32_LITTLE(m + 12));
195 x4 = XOR(x4,U8TO32_LITTLE(m + 16));
196 x5 = XOR(x5,U8TO32_LITTLE(m + 20));
197 x6 = XOR(x6,U8TO32_LITTLE(m + 24));
198 x7 = XOR(x7,U8TO32_LITTLE(m + 28));
199 x8 = XOR(x8,U8TO32_LITTLE(m + 32));
200 x9 = XOR(x9,U8TO32_LITTLE(m + 36));
201 x10 = XOR(x10,U8TO32_LITTLE(m + 40));
202 x11 = XOR(x11,U8TO32_LITTLE(m + 44));
203 x12 = XOR(x12,U8TO32_LITTLE(m + 48));
204 x13 = XOR(x13,U8TO32_LITTLE(m + 52));
205 x14 = XOR(x14,U8TO32_LITTLE(m + 56));
206 x15 = XOR(x15,U8TO32_LITTLE(m + 60));
212 #ifndef CHACHA_NONCE0_CTR128
213 /* stopping at 2^70 bytes per nonce is user's responsibility */
224 U32TO8_LITTLE(c + 0,x0);
225 U32TO8_LITTLE(c + 4,x1);
226 U32TO8_LITTLE(c + 8,x2);
227 U32TO8_LITTLE(c + 12,x3);
228 U32TO8_LITTLE(c + 16,x4);
229 U32TO8_LITTLE(c + 20,x5);
230 U32TO8_LITTLE(c + 24,x6);
231 U32TO8_LITTLE(c + 28,x7);
232 U32TO8_LITTLE(c + 32,x8);
233 U32TO8_LITTLE(c + 36,x9);
234 U32TO8_LITTLE(c + 40,x10);
235 U32TO8_LITTLE(c + 44,x11);
236 U32TO8_LITTLE(c + 48,x12);
237 U32TO8_LITTLE(c + 52,x13);
238 U32TO8_LITTLE(c + 56,x14);
239 U32TO8_LITTLE(c + 60,x15);
243 for (i = 0;i < bytes;++i) ctarget[i] = c[i];
247 #ifdef CHACHA_NONCE0_CTR128
255 #ifndef KEYSTREAM_ONLY