Steal rust-crypto's ChaCha20 implementation wholesale
[rust-lightning] / src / util / chacha20.rs
1 // This file was stolen from rust-crypto.
2 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
3 // file at the top-level directory of this distribution and at
4 // http://rust-lang.org/COPYRIGHT.
5
6 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
7 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
8 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
9 // option. This file may not be copied, modified, or distributed
10 // except according to those terms.
11
12 #[cfg(not(feature = "fuzztarget"))]
13 mod real_chacha {
14         use std::cmp;
15         use util::byte_utils::{slice_to_le32, le32_to_array};
16         use crypto::symmetriccipher::SynchronousStreamCipher;
17
18         #[derive(Clone, Copy, PartialEq, Eq)]
19         #[allow(non_camel_case_types)]
20         struct u32x4(pub u32, pub u32, pub u32, pub u32);
21         impl ::std::ops::Add for u32x4 {
22                 type Output = u32x4;
23                 fn add(self, rhs: u32x4) -> u32x4 {
24                         u32x4(self.0.wrapping_add(rhs.0),
25                               self.1.wrapping_add(rhs.1),
26                               self.2.wrapping_add(rhs.2),
27                               self.3.wrapping_add(rhs.3))
28                 }
29         }
30         impl ::std::ops::Sub for u32x4 {
31                 type Output = u32x4;
32                 fn sub(self, rhs: u32x4) -> u32x4 {
33                         u32x4(self.0.wrapping_sub(rhs.0),
34                               self.1.wrapping_sub(rhs.1),
35                               self.2.wrapping_sub(rhs.2),
36                               self.3.wrapping_sub(rhs.3))
37                 }
38         }
39         impl ::std::ops::BitXor for u32x4 {
40                 type Output = u32x4;
41                 fn bitxor(self, rhs: u32x4) -> u32x4 {
42                         u32x4(self.0 ^ rhs.0, self.1 ^ rhs.1, self.2 ^ rhs.2, self.3 ^ rhs.3)
43                 }
44         }
45         impl ::std::ops::Shr<u32x4> for u32x4 {
46                 type Output = u32x4;
47                 fn shr(self, rhs: u32x4) -> u32x4 {
48                         u32x4(self.0 >> rhs.0, self.1 >> rhs.1, self.2 >> rhs.2, self.3 >> rhs.3)
49                 }
50         }
51         impl ::std::ops::Shl<u32x4> for u32x4 {
52                 type Output = u32x4;
53                 fn shl(self, rhs: u32x4) -> u32x4 {
54                         u32x4(self.0 << rhs.0, self.1 << rhs.1, self.2 << rhs.2, self.3 << rhs.3)
55                 }
56         }
57
58         #[derive(Clone,Copy)]
59         struct ChaChaState {
60                 a: u32x4,
61                 b: u32x4,
62                 c: u32x4,
63                 d: u32x4
64         }
65
66         #[derive(Copy)]
67         pub struct ChaCha20 {
68                 state  : ChaChaState,
69                 output : [u8; 64],
70                 offset : usize,
71         }
72
73         impl Clone for ChaCha20 { fn clone(&self) -> ChaCha20 { *self } }
74
75         macro_rules! swizzle {
76                 ($b: expr, $c: expr, $d: expr) => {{
77                         let u32x4(b10, b11, b12, b13) = $b;
78                         $b = u32x4(b11, b12, b13, b10);
79                         let u32x4(c10, c11, c12, c13) = $c;
80                         $c = u32x4(c12, c13,c10, c11);
81                         let u32x4(d10, d11, d12, d13) = $d;
82                         $d = u32x4(d13, d10, d11, d12);
83                 }}
84         }
85
86         macro_rules! state_to_buffer {
87                 ($state: expr, $output: expr) => {{
88                         let u32x4(a1, a2, a3, a4) = $state.a;
89                         let u32x4(b1, b2, b3, b4) = $state.b;
90                         let u32x4(c1, c2, c3, c4) = $state.c;
91                         let u32x4(d1, d2, d3, d4) = $state.d;
92                         let lens = [
93                                 a1,a2,a3,a4,
94                                 b1,b2,b3,b4,
95                                 c1,c2,c3,c4,
96                                 d1,d2,d3,d4
97                         ];
98                         for i in 0..lens.len() {
99                                 $output[i*4..(i+1)*4].copy_from_slice(&le32_to_array(lens[i]));
100                         }
101                 }}
102         }
103
104         macro_rules! round{
105                 ($state: expr) => {{
106                         $state.a = $state.a + $state.b;
107                         rotate!($state.d, $state.a, S16);
108                         $state.c = $state.c + $state.d;
109                         rotate!($state.b, $state.c, S12);
110                         $state.a = $state.a + $state.b;
111                         rotate!($state.d, $state.a, S8);
112                         $state.c = $state.c + $state.d;
113                         rotate!($state.b, $state.c, S7);
114                 }}
115         }
116
117         macro_rules! rotate {
118                 ($a: expr, $b: expr, $c:expr) => {{
119                         let v = $a ^ $b;
120                         let r = S32 - $c;
121                         let right = v >> r;
122                         $a = (v << $c) ^ right
123                 }}
124         }
125
126         const S32:u32x4 = u32x4(32, 32, 32, 32);
127         const S16:u32x4 = u32x4(16, 16, 16, 16);
128         const S12:u32x4 = u32x4(12, 12, 12, 12);
129         const S8:u32x4 = u32x4(8, 8, 8, 8);
130         const S7:u32x4 = u32x4(7, 7, 7, 7);
131
132         impl ChaCha20 {
133                 pub fn new(key: &[u8], nonce: &[u8]) -> ChaCha20 {
134                         assert!(key.len() == 16 || key.len() == 32);
135                         assert!(nonce.len() == 8 || nonce.len() == 12);
136
137                         ChaCha20{ state: ChaCha20::expand(key, nonce), output: [0u8; 64], offset: 64 }
138                 }
139
140                 fn expand(key: &[u8], nonce: &[u8]) -> ChaChaState {
141                         let constant = match key.len() {
142                                 16 => b"expand 16-byte k",
143                                 32 => b"expand 32-byte k",
144                                 _  => unreachable!(),
145                         };
146                         ChaChaState {
147                                 a: u32x4(
148                                         slice_to_le32(&constant[0..4]),
149                                         slice_to_le32(&constant[4..8]),
150                                         slice_to_le32(&constant[8..12]),
151                                         slice_to_le32(&constant[12..16])
152                                 ),
153                                 b: u32x4(
154                                         slice_to_le32(&key[0..4]),
155                                         slice_to_le32(&key[4..8]),
156                                         slice_to_le32(&key[8..12]),
157                                         slice_to_le32(&key[12..16])
158                                 ),
159                                 c: if key.len() == 16 {
160                                         u32x4(
161                                                 slice_to_le32(&key[0..4]),
162                                                 slice_to_le32(&key[4..8]),
163                                                 slice_to_le32(&key[8..12]),
164                                                 slice_to_le32(&key[12..16])
165                                         )
166                                 } else {
167                                         u32x4(
168                                                 slice_to_le32(&key[16..20]),
169                                                 slice_to_le32(&key[20..24]),
170                                                 slice_to_le32(&key[24..28]),
171                                                 slice_to_le32(&key[28..32])
172                                         )
173                                 },
174                                 d: if nonce.len() == 16 {
175                                         u32x4(
176                                                 slice_to_le32(&nonce[0..4]),
177                                                 slice_to_le32(&nonce[4..8]),
178                                                 slice_to_le32(&nonce[8..12]),
179                                                 slice_to_le32(&nonce[12..16])
180                                         )
181                                 } else if nonce.len() == 12 {
182                                         u32x4(
183                                                 0,
184                                                 slice_to_le32(&nonce[0..4]),
185                                                 slice_to_le32(&nonce[4..8]),
186                                                 slice_to_le32(&nonce[8..12])
187                                         )
188                                 } else {
189                                         u32x4(
190                                                 0,
191                                                 0,
192                                                 slice_to_le32(&nonce[0..4]),
193                                                 slice_to_le32(&nonce[4..8])
194                                         )
195                                 }
196                         }
197                 }
198
199                 // put the the next 64 keystream bytes into self.output
200                 fn update(&mut self) {
201                         let mut state = self.state;
202
203                         for _ in 0..10 {
204                                 round!(state);
205                                 swizzle!(state.b, state.c, state.d);
206                                 round!(state);
207                                 swizzle!(state.d, state.c, state.b);
208                         }
209                         state.a = state.a + self.state.a;
210                         state.b = state.b + self.state.b;
211                         state.c = state.c + self.state.c;
212                         state.d = state.d + self.state.d;
213
214                         state_to_buffer!(state, self.output);
215
216                         self.state.d = self.state.d + u32x4(1, 0, 0, 0);
217                         let u32x4(c12, _, _, _) = self.state.d;
218                         if c12 == 0 {
219                                 // we could increment the other counter word with an 8 byte nonce
220                                 // but other implementations like boringssl have this same
221                                 // limitation
222                                 panic!("counter is exhausted");
223                         }
224
225                         self.offset = 0;
226                 }
227         }
228
229         impl SynchronousStreamCipher for ChaCha20 {
230                 fn process(&mut self, input: &[u8], output: &mut [u8]) {
231                         assert!(input.len() == output.len());
232                         let len = input.len();
233                         let mut i = 0;
234                         while i < len {
235                                 // If there is no keystream available in the output buffer,
236                                 // generate the next block.
237                                 if self.offset == 64 {
238                                         self.update();
239                                 }
240
241                                 // Process the min(available keystream, remaining input length).
242                                 let count = cmp::min(64 - self.offset, len - i);
243                                 // explicitly assert lengths to avoid bounds checks:
244                                 assert!(output.len() >= i + count);
245                                 assert!(input.len() >= i + count);
246                                 assert!(self.output.len() >= self.offset + count);
247                                 for j in 0..count {
248                                         output[i + j] = input[i + j] ^ self.output[self.offset + j];
249                                 }
250                                 i += count;
251                                 self.offset += count;
252                         }
253                 }
254         }
255 }
256 #[cfg(not(feature = "fuzztarget"))]
257 pub use self::real_chacha::ChaCha20;
258
259 #[cfg(feature = "fuzztarget")]
260 mod fuzzy_chacha {
261         use crypto::symmetriccipher::SynchronousStreamCipher;
262
263         pub struct ChaCha20 {}
264
265         impl ChaCha20 {
266                 pub fn new(key: &[u8], nonce: &[u8]) -> ChaCha20 {
267                         assert!(key.len() == 16 || key.len() == 32);
268                         assert!(nonce.len() == 8 || nonce.len() == 12);
269                         Self {}
270                 }
271         }
272
273         impl SynchronousStreamCipher for ChaCha20 {
274                 fn process(&mut self, input: &[u8], output: &mut [u8]) {
275                         output.copy_from_slice(input);
276                 }
277         }
278 }
279 #[cfg(feature = "fuzztarget")]
280 pub use self::fuzzy_chacha::ChaCha20;
281
282 #[cfg(test)]
283 mod test {
284         use std::iter::repeat;
285
286         use super::ChaCha20;
287         use crypto::symmetriccipher::SynchronousStreamCipher;
288
289         #[test]
290         fn test_chacha20_256_tls_vectors() {
291                 struct TestVector {
292                         key:   [u8; 32],
293                         nonce: [u8; 8],
294                         keystream: Vec<u8>,
295                 };
296                 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
297                 let test_vectors = vec!(
298                         TestVector{
299                                 key: [
300                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304                                 ],
305                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
306                                 keystream: vec!(
307                                         0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
308                                         0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
309                                         0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
310                                         0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
311                                         0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
312                                         0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
313                                         0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
314                                         0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
315                                 ),
316                         }, TestVector{
317                                 key: [
318                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
322                                 ],
323                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
324                                 keystream: vec!(
325                                         0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96,
326                                         0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96,
327                                         0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 0xd2, 0x60,
328                                         0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41,
329                                         0xbb, 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2,
330                                         0xa5, 0xd1, 0xe7, 0xe2, 0x0d, 0x42, 0xaf, 0x2c,
331                                         0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 0x81,
332                                         0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63,
333                                 ),
334                         }, TestVector{
335                                 key: [
336                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340                                 ],
341                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
342                                 keystream: vec!(
343                                         0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5,
344                                         0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a,
345                                         0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13,
346                                         0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31,
347                                         0xe8, 0x5a, 0x05, 0x02, 0x78, 0xa7, 0x08, 0x45,
348                                         0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b,
349                                         0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e,
350                                         0x44, 0x5f, 0x41, 0xe3,
351                                 ),
352                         }, TestVector{
353                                 key: [
354                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358                                 ],
359                                 nonce: [ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
360                                 keystream: vec!(
361                                         0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
362                                         0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
363                                         0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
364                                         0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
365                                         0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
366                                         0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
367                                         0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
368                                         0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
369                                 ),
370                         }, TestVector{
371                                 key: [
372                                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
373                                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
374                                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
375                                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
376                                 ],
377                                 nonce: [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
378                                 keystream: vec!(
379                                         0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69,
380                                         0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75,
381                                         0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93,
382                                         0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1,
383                                         0x34, 0xa4, 0x54, 0x7b, 0x73, 0x3b, 0x46, 0x41,
384                                         0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69,
385                                         0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1,
386                                         0x59, 0x16, 0x15, 0x5c, 0x2b, 0xe8, 0x24, 0x1a,
387                                         0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94,
388                                         0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66,
389                                         0x89, 0xde, 0x95, 0x26, 0x49, 0x86, 0xd9, 0x58,
390                                         0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd,
391                                         0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56,
392                                         0x3e, 0xb9, 0xb3, 0xa4, 0xa4, 0x72, 0xf8, 0x2e,
393                                         0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e,
394                                         0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7,
395                                         0x9d, 0xb9, 0xd4, 0xf7, 0xc7, 0xa8, 0x99, 0x15,
396                                         0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3,
397                                         0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a,
398                                         0x97, 0xa5, 0xf5, 0x76, 0xfe, 0x06, 0x40, 0x25,
399                                         0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5,
400                                         0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69,
401                                         0x59, 0x66, 0x09, 0x96, 0x54, 0x6c, 0xc9, 0xc4,
402                                         0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7,
403                                         0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79,
404                                         0xe5, 0xc5, 0x36, 0x0c, 0x33, 0x17, 0x16, 0x6a,
405                                         0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a,
406                                         0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2,
407                                         0xcc, 0xb2, 0x7d, 0x5a, 0xaa, 0xe0, 0xad, 0x7a,
408                                         0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09,
409                                         0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a,
410                                         0x6d, 0xeb, 0x3a, 0xb7, 0x8f, 0xab, 0x78, 0xc9,
411                                 ),
412                         },
413                 );
414
415                 for tv in test_vectors.iter() {
416                         let mut c = ChaCha20::new(&tv.key, &tv.nonce);
417                         let input: Vec<u8> = repeat(0).take(tv.keystream.len()).collect();
418                         let mut output: Vec<u8> = repeat(0).take(input.len()).collect();
419                         c.process(&input[..], &mut output[..]);
420                         assert_eq!(output, tv.keystream);
421                 }
422         }
423
424         #[test]
425         fn test_chacha20_256_tls_vectors_96_nonce() {
426                 struct TestVector {
427                         key:   [u8; 32],
428                         nonce: [u8; 12],
429                         keystream: Vec<u8>,
430                 };
431                 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
432                 let test_vectors = vec!(
433                         TestVector{
434                                 key: [
435                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
437                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
438                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
439                                 ],
440                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
441                                 keystream: vec!(
442                                         0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
443                                         0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
444                                         0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
445                                         0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
446                                         0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
447                                         0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
448                                         0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
449                                         0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
450                                 ),
451                         }, TestVector{
452                                 key: [
453                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
455                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
456                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
457                                 ],
458                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
459                                 keystream: vec!(
460                                         0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96,
461                                         0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96,
462                                         0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 0xd2, 0x60,
463                                         0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41,
464                                         0xbb, 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2,
465                                         0xa5, 0xd1, 0xe7, 0xe2, 0x0d, 0x42, 0xaf, 0x2c,
466                                         0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 0x81,
467                                         0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63,
468                                 ),
469                         }, TestVector{
470                                 key: [
471                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475                                 ],
476                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
477                                 keystream: vec!(
478                                         0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5,
479                                         0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a,
480                                         0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13,
481                                         0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31,
482                                         0xe8, 0x5a, 0x05, 0x02, 0x78, 0xa7, 0x08, 0x45,
483                                         0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b,
484                                         0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e,
485                                         0x44, 0x5f, 0x41, 0xe3,
486                                 ),
487                         }, TestVector{
488                                 key: [
489                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
493                                 ],
494                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
495                                 keystream: vec!(
496                                         0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
497                                         0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
498                                         0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
499                                         0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
500                                         0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
501                                         0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
502                                         0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
503                                         0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
504                                 ),
505                         }, TestVector{
506                                 key: [
507                                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
508                                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
509                                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
510                                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
511                                 ],
512                                 nonce: [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
513                                 keystream: vec!(
514                                         0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69,
515                                         0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75,
516                                         0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93,
517                                         0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1,
518                                         0x34, 0xa4, 0x54, 0x7b, 0x73, 0x3b, 0x46, 0x41,
519                                         0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69,
520                                         0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1,
521                                         0x59, 0x16, 0x15, 0x5c, 0x2b, 0xe8, 0x24, 0x1a,
522                                         0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94,
523                                         0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66,
524                                         0x89, 0xde, 0x95, 0x26, 0x49, 0x86, 0xd9, 0x58,
525                                         0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd,
526                                         0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56,
527                                         0x3e, 0xb9, 0xb3, 0xa4, 0xa4, 0x72, 0xf8, 0x2e,
528                                         0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e,
529                                         0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7,
530                                         0x9d, 0xb9, 0xd4, 0xf7, 0xc7, 0xa8, 0x99, 0x15,
531                                         0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3,
532                                         0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a,
533                                         0x97, 0xa5, 0xf5, 0x76, 0xfe, 0x06, 0x40, 0x25,
534                                         0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5,
535                                         0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69,
536                                         0x59, 0x66, 0x09, 0x96, 0x54, 0x6c, 0xc9, 0xc4,
537                                         0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7,
538                                         0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79,
539                                         0xe5, 0xc5, 0x36, 0x0c, 0x33, 0x17, 0x16, 0x6a,
540                                         0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a,
541                                         0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2,
542                                         0xcc, 0xb2, 0x7d, 0x5a, 0xaa, 0xe0, 0xad, 0x7a,
543                                         0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09,
544                                         0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a,
545                                         0x6d, 0xeb, 0x3a, 0xb7, 0x8f, 0xab, 0x78, 0xc9,
546                                 ),
547                         },
548                 );
549
550                 for tv in test_vectors.iter() {
551                         let mut c = ChaCha20::new(&tv.key, &tv.nonce);
552                         let input: Vec<u8> = repeat(0).take(tv.keystream.len()).collect();
553                         let mut output: Vec<u8> = repeat(0).take(input.len()).collect();
554                         c.process(&input[..], &mut output[..]);
555                         assert_eq!(output, tv.keystream);
556                 }
557         }
558 }