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