]> git.bitcoin.ninja Git - rust-lightning/blob - lightning/src/util/chacha20.rs
Drop requirement that all ChannelKeys expose revocaion_basepoint
[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         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 std::iter::repeat;
322
323         use super::ChaCha20;
324
325         #[test]
326         fn test_chacha20_256_tls_vectors() {
327                 struct TestVector {
328                         key:   [u8; 32],
329                         nonce: [u8; 8],
330                         keystream: Vec<u8>,
331                 };
332                 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
333                 let test_vectors = vec!(
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, 0x00 ],
342                                 keystream: vec!(
343                                         0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
344                                         0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
345                                         0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
346                                         0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
347                                         0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
348                                         0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
349                                         0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
350                                         0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
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, 0x01,
358                                 ],
359                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
360                                 keystream: vec!(
361                                         0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96,
362                                         0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96,
363                                         0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 0xd2, 0x60,
364                                         0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41,
365                                         0xbb, 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2,
366                                         0xa5, 0xd1, 0xe7, 0xe2, 0x0d, 0x42, 0xaf, 0x2c,
367                                         0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 0x81,
368                                         0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63,
369                                 ),
370                         }, TestVector{
371                                 key: [
372                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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                                 ],
377                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
378                                 keystream: vec!(
379                                         0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5,
380                                         0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a,
381                                         0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13,
382                                         0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31,
383                                         0xe8, 0x5a, 0x05, 0x02, 0x78, 0xa7, 0x08, 0x45,
384                                         0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b,
385                                         0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e,
386                                         0x44, 0x5f, 0x41, 0xe3,
387                                 ),
388                         }, TestVector{
389                                 key: [
390                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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                                 ],
395                                 nonce: [ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
396                                 keystream: vec!(
397                                         0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
398                                         0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
399                                         0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
400                                         0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
401                                         0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
402                                         0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
403                                         0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
404                                         0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
405                                 ),
406                         }, TestVector{
407                                 key: [
408                                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
409                                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
410                                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
411                                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
412                                 ],
413                                 nonce: [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
414                                 keystream: vec!(
415                                         0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69,
416                                         0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75,
417                                         0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93,
418                                         0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1,
419                                         0x34, 0xa4, 0x54, 0x7b, 0x73, 0x3b, 0x46, 0x41,
420                                         0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69,
421                                         0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1,
422                                         0x59, 0x16, 0x15, 0x5c, 0x2b, 0xe8, 0x24, 0x1a,
423                                         0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94,
424                                         0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66,
425                                         0x89, 0xde, 0x95, 0x26, 0x49, 0x86, 0xd9, 0x58,
426                                         0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd,
427                                         0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56,
428                                         0x3e, 0xb9, 0xb3, 0xa4, 0xa4, 0x72, 0xf8, 0x2e,
429                                         0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e,
430                                         0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7,
431                                         0x9d, 0xb9, 0xd4, 0xf7, 0xc7, 0xa8, 0x99, 0x15,
432                                         0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3,
433                                         0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a,
434                                         0x97, 0xa5, 0xf5, 0x76, 0xfe, 0x06, 0x40, 0x25,
435                                         0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5,
436                                         0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69,
437                                         0x59, 0x66, 0x09, 0x96, 0x54, 0x6c, 0xc9, 0xc4,
438                                         0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7,
439                                         0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79,
440                                         0xe5, 0xc5, 0x36, 0x0c, 0x33, 0x17, 0x16, 0x6a,
441                                         0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a,
442                                         0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2,
443                                         0xcc, 0xb2, 0x7d, 0x5a, 0xaa, 0xe0, 0xad, 0x7a,
444                                         0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09,
445                                         0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a,
446                                         0x6d, 0xeb, 0x3a, 0xb7, 0x8f, 0xab, 0x78, 0xc9,
447                                 ),
448                         },
449                 );
450
451                 for tv in test_vectors.iter() {
452                         let mut c = ChaCha20::new(&tv.key, &tv.nonce);
453                         let input: Vec<u8> = repeat(0).take(tv.keystream.len()).collect();
454                         let mut output: Vec<u8> = repeat(0).take(input.len()).collect();
455                         c.process(&input[..], &mut output[..]);
456                         assert_eq!(output, tv.keystream);
457                 }
458         }
459
460         #[test]
461         fn test_chacha20_256_tls_vectors_96_nonce() {
462                 struct TestVector {
463                         key:   [u8; 32],
464                         nonce: [u8; 12],
465                         keystream: Vec<u8>,
466                 };
467                 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
468                 let test_vectors = vec!(
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, 0x00 ],
477                                 keystream: vec!(
478                                         0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
479                                         0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
480                                         0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
481                                         0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
482                                         0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
483                                         0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
484                                         0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
485                                         0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
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, 0x01,
493                                 ],
494                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
495                                 keystream: vec!(
496                                         0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96,
497                                         0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96,
498                                         0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 0xd2, 0x60,
499                                         0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41,
500                                         0xbb, 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2,
501                                         0xa5, 0xd1, 0xe7, 0xe2, 0x0d, 0x42, 0xaf, 0x2c,
502                                         0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 0x81,
503                                         0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63,
504                                 ),
505                         }, TestVector{
506                                 key: [
507                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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                                 ],
512                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
513                                 keystream: vec!(
514                                         0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5,
515                                         0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a,
516                                         0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13,
517                                         0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31,
518                                         0xe8, 0x5a, 0x05, 0x02, 0x78, 0xa7, 0x08, 0x45,
519                                         0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b,
520                                         0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e,
521                                         0x44, 0x5f, 0x41, 0xe3,
522                                 ),
523                         }, TestVector{
524                                 key: [
525                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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                                 ],
530                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
531                                 keystream: vec!(
532                                         0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
533                                         0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
534                                         0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
535                                         0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
536                                         0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
537                                         0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
538                                         0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
539                                         0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
540                                 ),
541                         }, TestVector{
542                                 key: [
543                                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
544                                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
545                                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
546                                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
547                                 ],
548                                 nonce: [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
549                                 keystream: vec!(
550                                         0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69,
551                                         0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75,
552                                         0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93,
553                                         0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1,
554                                         0x34, 0xa4, 0x54, 0x7b, 0x73, 0x3b, 0x46, 0x41,
555                                         0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69,
556                                         0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1,
557                                         0x59, 0x16, 0x15, 0x5c, 0x2b, 0xe8, 0x24, 0x1a,
558                                         0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94,
559                                         0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66,
560                                         0x89, 0xde, 0x95, 0x26, 0x49, 0x86, 0xd9, 0x58,
561                                         0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd,
562                                         0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56,
563                                         0x3e, 0xb9, 0xb3, 0xa4, 0xa4, 0x72, 0xf8, 0x2e,
564                                         0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e,
565                                         0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7,
566                                         0x9d, 0xb9, 0xd4, 0xf7, 0xc7, 0xa8, 0x99, 0x15,
567                                         0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3,
568                                         0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a,
569                                         0x97, 0xa5, 0xf5, 0x76, 0xfe, 0x06, 0x40, 0x25,
570                                         0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5,
571                                         0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69,
572                                         0x59, 0x66, 0x09, 0x96, 0x54, 0x6c, 0xc9, 0xc4,
573                                         0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7,
574                                         0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79,
575                                         0xe5, 0xc5, 0x36, 0x0c, 0x33, 0x17, 0x16, 0x6a,
576                                         0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a,
577                                         0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2,
578                                         0xcc, 0xb2, 0x7d, 0x5a, 0xaa, 0xe0, 0xad, 0x7a,
579                                         0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09,
580                                         0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a,
581                                         0x6d, 0xeb, 0x3a, 0xb7, 0x8f, 0xab, 0x78, 0xc9,
582                                 ),
583                         },
584                 );
585
586                 for tv in test_vectors.iter() {
587                         let mut c = ChaCha20::new(&tv.key, &tv.nonce);
588                         let input: Vec<u8> = repeat(0).take(tv.keystream.len()).collect();
589                         let mut output: Vec<u8> = repeat(0).take(input.len()).collect();
590                         c.process(&input[..], &mut output[..]);
591                         assert_eq!(output, tv.keystream);
592                 }
593         }
594 }