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