3 chacha-merged.c version 20080118
18 #define LOAD32_LE(SRC) get_unaligned_le32(SRC)
20 #define STORE32_LE(DST, W) store32_le((DST), (W))
23 store32_le(uint8_t dst
[4], uint32_t w
)
25 dst
[0] = (uint8_t) w
; w
>>= 8;
26 dst
[1] = (uint8_t) w
; w
>>= 8;
27 dst
[2] = (uint8_t) w
; w
>>= 8;
32 #define ROTL32(X, B) rotl32((X), (B))
33 static inline uint32_t
34 rotl32(const uint32_t x
, const int b
)
36 return (x
<< b
) | (x
>> (32 - b
));
39 typedef struct chacha_ctx chacha_ctx
;
41 #define U32C(v) (v##U)
43 #define U32V(v) ((uint32_t)(v) &U32C(0xFFFFFFFF))
45 #define ROTATE(v, c) (ROTL32(v, c))
46 #define XOR(v, w) ((v) ^ (w))
47 #define PLUS(v, w) (U32V((v) + (w)))
48 #define PLUSONE(v) (PLUS((v), 1))
50 #define QUARTERROUND(a, b, c, d) \
52 d = ROTATE(XOR(d, a), 16); \
54 b = ROTATE(XOR(b, c), 12); \
56 d = ROTATE(XOR(d, a), 8); \
58 b = ROTATE(XOR(b, c), 7);
61 chacha_keysetup(chacha_ctx
*ctx
, const uint8_t *k
)
63 ctx
->input
[0] = U32C(0x61707865);
64 ctx
->input
[1] = U32C(0x3320646e);
65 ctx
->input
[2] = U32C(0x79622d32);
66 ctx
->input
[3] = U32C(0x6b206574);
67 ctx
->input
[4] = LOAD32_LE(k
+ 0);
68 ctx
->input
[5] = LOAD32_LE(k
+ 4);
69 ctx
->input
[6] = LOAD32_LE(k
+ 8);
70 ctx
->input
[7] = LOAD32_LE(k
+ 12);
71 ctx
->input
[8] = LOAD32_LE(k
+ 16);
72 ctx
->input
[9] = LOAD32_LE(k
+ 20);
73 ctx
->input
[10] = LOAD32_LE(k
+ 24);
74 ctx
->input
[11] = LOAD32_LE(k
+ 28);
78 chacha_ivsetup(chacha_ctx
*ctx
, const uint8_t *iv
, const uint8_t *counter
)
80 ctx
->input
[12] = counter
== NULL
? 0 : LOAD32_LE(counter
+ 0);
81 ctx
->input
[13] = counter
== NULL
? 0 : LOAD32_LE(counter
+ 4);
82 ctx
->input
[14] = LOAD32_LE(iv
+ 0);
83 ctx
->input
[15] = LOAD32_LE(iv
+ 4);
87 chacha20_encrypt_bytes(chacha_ctx
*ctx
, const uint8_t *m
, uint8_t *c
,
88 unsigned long long bytes
)
90 uint32_t x0
, x1
, x2
, x3
, x4
, x5
, x6
, x7
, x8
, x9
, x10
, x11
, x12
, x13
, x14
,
92 uint32_t j0
, j1
, j2
, j3
, j4
, j5
, j6
, j7
, j8
, j9
, j10
, j11
, j12
, j13
, j14
,
94 uint8_t *ctarget
= NULL
;
99 return; /* LCOV_EXCL_LINE */
111 j10
= ctx
->input
[10];
112 j11
= ctx
->input
[11];
113 j12
= ctx
->input
[12];
114 j13
= ctx
->input
[13];
115 j14
= ctx
->input
[14];
116 j15
= ctx
->input
[15];
121 for (i
= 0; i
< bytes
; ++i
) {
144 for (i
= 20; i
> 0; i
-= 2) {
145 QUARTERROUND(x0
, x4
, x8
, x12
)
146 QUARTERROUND(x1
, x5
, x9
, x13
)
147 QUARTERROUND(x2
, x6
, x10
, x14
)
148 QUARTERROUND(x3
, x7
, x11
, x15
)
149 QUARTERROUND(x0
, x5
, x10
, x15
)
150 QUARTERROUND(x1
, x6
, x11
, x12
)
151 QUARTERROUND(x2
, x7
, x8
, x13
)
152 QUARTERROUND(x3
, x4
, x9
, x14
)
164 x10
= PLUS(x10
, j10
);
165 x11
= PLUS(x11
, j11
);
166 x12
= PLUS(x12
, j12
);
167 x13
= PLUS(x13
, j13
);
168 x14
= PLUS(x14
, j14
);
169 x15
= PLUS(x15
, j15
);
171 x0
= XOR(x0
, LOAD32_LE(m
+ 0));
172 x1
= XOR(x1
, LOAD32_LE(m
+ 4));
173 x2
= XOR(x2
, LOAD32_LE(m
+ 8));
174 x3
= XOR(x3
, LOAD32_LE(m
+ 12));
175 x4
= XOR(x4
, LOAD32_LE(m
+ 16));
176 x5
= XOR(x5
, LOAD32_LE(m
+ 20));
177 x6
= XOR(x6
, LOAD32_LE(m
+ 24));
178 x7
= XOR(x7
, LOAD32_LE(m
+ 28));
179 x8
= XOR(x8
, LOAD32_LE(m
+ 32));
180 x9
= XOR(x9
, LOAD32_LE(m
+ 36));
181 x10
= XOR(x10
, LOAD32_LE(m
+ 40));
182 x11
= XOR(x11
, LOAD32_LE(m
+ 44));
183 x12
= XOR(x12
, LOAD32_LE(m
+ 48));
184 x13
= XOR(x13
, LOAD32_LE(m
+ 52));
185 x14
= XOR(x14
, LOAD32_LE(m
+ 56));
186 x15
= XOR(x15
, LOAD32_LE(m
+ 60));
189 /* LCOV_EXCL_START */
195 STORE32_LE(c
+ 0, x0
);
196 STORE32_LE(c
+ 4, x1
);
197 STORE32_LE(c
+ 8, x2
);
198 STORE32_LE(c
+ 12, x3
);
199 STORE32_LE(c
+ 16, x4
);
200 STORE32_LE(c
+ 20, x5
);
201 STORE32_LE(c
+ 24, x6
);
202 STORE32_LE(c
+ 28, x7
);
203 STORE32_LE(c
+ 32, x8
);
204 STORE32_LE(c
+ 36, x9
);
205 STORE32_LE(c
+ 40, x10
);
206 STORE32_LE(c
+ 44, x11
);
207 STORE32_LE(c
+ 48, x12
);
208 STORE32_LE(c
+ 52, x13
);
209 STORE32_LE(c
+ 56, x14
);
210 STORE32_LE(c
+ 60, x15
);
214 for (i
= 0; i
< (unsigned int) bytes
; ++i
) {
215 ctarget
[i
] = c
[i
]; /* ctarget cannot be NULL */
218 ctx
->input
[12] = j12
;
219 ctx
->input
[13] = j13
;
229 void chacha20_encrypt_msg(void *msg
, size_t len
, const void *nonce
, const void *key
)
231 struct chacha_ctx ctx
;
233 chacha_keysetup(&ctx
, key
);
234 chacha_ivsetup(&ctx
, nonce
, NULL
);
235 chacha20_encrypt_bytes(&ctx
, msg
, msg
, len
);