2 chacha-merged.c version 20080118
7 /* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */
12 typedef unsigned char u8
;
13 typedef unsigned int u32
;
14 typedef unsigned int u_int
;
17 #define U32C(v) (v##U)
19 #define U8V(v) ((u8)(v) & U8C(0xFF))
20 #define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
22 #define ROTL32(v, n) \
23 (U32V((v) << (n)) | ((v) >> (32 - (n))))
25 #define U8TO32_LITTLE(p) \
27 ((u32)((p)[1]) << 8) | \
28 ((u32)((p)[2]) << 16) | \
29 ((u32)((p)[3]) << 24))
31 #define U32TO8_LITTLE(p, v) \
34 (p)[1] = U8V((v) >> 8); \
35 (p)[2] = U8V((v) >> 16); \
36 (p)[3] = U8V((v) >> 24); \
39 #define ROTATE(v,c) (ROTL32(v,c))
40 #define XOR(v,w) ((v) ^ (w))
41 #define PLUS(v,w) (U32V((v) + (w)))
42 #define PLUSONE(v) (PLUS((v),1))
44 #define QUARTERROUND(a,b,c,d) \
45 a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
46 c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
47 a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
48 c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
50 static const char sigma
[16] = "expand 32-byte k";
51 static const char tau
[16] = "expand 16-byte k";
54 chacha_keysetup(chacha_ctx_t
*x
,const u8
*k
,u32 kbits
,u32 ivbits
)
56 const char *constants
;
58 x
->chacha_input
[4] = U8TO32_LITTLE(k
+ 0);
59 x
->chacha_input
[5] = U8TO32_LITTLE(k
+ 4);
60 x
->chacha_input
[6] = U8TO32_LITTLE(k
+ 8);
61 x
->chacha_input
[7] = U8TO32_LITTLE(k
+ 12);
62 if (kbits
== 256) { /* recommended */
65 } else { /* kbits == 128 */
68 x
->chacha_input
[8] = U8TO32_LITTLE(k
+ 0);
69 x
->chacha_input
[9] = U8TO32_LITTLE(k
+ 4);
70 x
->chacha_input
[10] = U8TO32_LITTLE(k
+ 8);
71 x
->chacha_input
[11] = U8TO32_LITTLE(k
+ 12);
72 x
->chacha_input
[0] = U8TO32_LITTLE(constants
+ 0);
73 x
->chacha_input
[1] = U8TO32_LITTLE(constants
+ 4);
74 x
->chacha_input
[2] = U8TO32_LITTLE(constants
+ 8);
75 x
->chacha_input
[3] = U8TO32_LITTLE(constants
+ 12);
79 chacha_ivsetup(chacha_ctx_t
*x
,const u8
*iv
)
81 x
->chacha_input
[12] = 0;
82 x
->chacha_input
[13] = 0;
83 x
->chacha_input
[14] = U8TO32_LITTLE(iv
+ 0);
84 x
->chacha_input
[15] = U8TO32_LITTLE(iv
+ 4);
88 chacha_encrypt_bytes(chacha_ctx_t
*x
,const u8
*m
,u8
*c
,u32 bytes
)
90 u32 x0
, x1
, x2
, x3
, x4
, x5
, x6
, x7
, x8
, x9
, x10
, x11
, x12
, x13
, x14
, x15
;
91 u32 j0
, j1
, j2
, j3
, j4
, j5
, j6
, j7
, j8
, j9
, j10
, j11
, j12
, j13
, j14
, j15
;
98 j0
= x
->chacha_input
[0];
99 j1
= x
->chacha_input
[1];
100 j2
= x
->chacha_input
[2];
101 j3
= x
->chacha_input
[3];
102 j4
= x
->chacha_input
[4];
103 j5
= x
->chacha_input
[5];
104 j6
= x
->chacha_input
[6];
105 j7
= x
->chacha_input
[7];
106 j8
= x
->chacha_input
[8];
107 j9
= x
->chacha_input
[9];
108 j10
= x
->chacha_input
[10];
109 j11
= x
->chacha_input
[11];
110 j12
= x
->chacha_input
[12];
111 j13
= x
->chacha_input
[13];
112 j14
= x
->chacha_input
[14];
113 j15
= x
->chacha_input
[15];
117 for (i
= 0;i
< bytes
;++i
) tmp
[i
] = m
[i
];
138 for (i
= 20;i
> 0;i
-= 2) {
139 QUARTERROUND( x0
, x4
, x8
,x12
)
140 QUARTERROUND( x1
, x5
, x9
,x13
)
141 QUARTERROUND( x2
, x6
,x10
,x14
)
142 QUARTERROUND( x3
, x7
,x11
,x15
)
143 QUARTERROUND( x0
, x5
,x10
,x15
)
144 QUARTERROUND( x1
, x6
,x11
,x12
)
145 QUARTERROUND( x2
, x7
, x8
,x13
)
146 QUARTERROUND( x3
, x4
, x9
,x14
)
165 #ifndef KEYSTREAM_ONLY
166 x0
= XOR(x0
,U8TO32_LITTLE(m
+ 0));
167 x1
= XOR(x1
,U8TO32_LITTLE(m
+ 4));
168 x2
= XOR(x2
,U8TO32_LITTLE(m
+ 8));
169 x3
= XOR(x3
,U8TO32_LITTLE(m
+ 12));
170 x4
= XOR(x4
,U8TO32_LITTLE(m
+ 16));
171 x5
= XOR(x5
,U8TO32_LITTLE(m
+ 20));
172 x6
= XOR(x6
,U8TO32_LITTLE(m
+ 24));
173 x7
= XOR(x7
,U8TO32_LITTLE(m
+ 28));
174 x8
= XOR(x8
,U8TO32_LITTLE(m
+ 32));
175 x9
= XOR(x9
,U8TO32_LITTLE(m
+ 36));
176 x10
= XOR(x10
,U8TO32_LITTLE(m
+ 40));
177 x11
= XOR(x11
,U8TO32_LITTLE(m
+ 44));
178 x12
= XOR(x12
,U8TO32_LITTLE(m
+ 48));
179 x13
= XOR(x13
,U8TO32_LITTLE(m
+ 52));
180 x14
= XOR(x14
,U8TO32_LITTLE(m
+ 56));
181 x15
= XOR(x15
,U8TO32_LITTLE(m
+ 60));
187 /* stopping at 2^70 bytes per nonce is user's responsibility */
190 U32TO8_LITTLE(c
+ 0,x0
);
191 U32TO8_LITTLE(c
+ 4,x1
);
192 U32TO8_LITTLE(c
+ 8,x2
);
193 U32TO8_LITTLE(c
+ 12,x3
);
194 U32TO8_LITTLE(c
+ 16,x4
);
195 U32TO8_LITTLE(c
+ 20,x5
);
196 U32TO8_LITTLE(c
+ 24,x6
);
197 U32TO8_LITTLE(c
+ 28,x7
);
198 U32TO8_LITTLE(c
+ 32,x8
);
199 U32TO8_LITTLE(c
+ 36,x9
);
200 U32TO8_LITTLE(c
+ 40,x10
);
201 U32TO8_LITTLE(c
+ 44,x11
);
202 U32TO8_LITTLE(c
+ 48,x12
);
203 U32TO8_LITTLE(c
+ 52,x13
);
204 U32TO8_LITTLE(c
+ 56,x14
);
205 U32TO8_LITTLE(c
+ 60,x15
);
209 for (i
= 0;i
< bytes
;++i
) ctarget
[i
] = c
[i
];
211 x
->chacha_input
[12] = j12
;
212 x
->chacha_input
[13] = j13
;
217 #ifndef KEYSTREAM_ONLY