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