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