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.
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.
14 #[cfg(not(feature = "fuzztarget"))]
17 use util::byte_utils::{slice_to_le32, le32_to_array};
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 {
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))
31 impl ::std::ops::Sub for 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))
40 impl ::std::ops::BitXor for 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)
46 impl ::std::ops::Shr<u32x4> for 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)
52 impl ::std::ops::Shl<u32x4> for 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)
59 const BLOCK_SIZE: usize = 64;
72 output : [u8; BLOCK_SIZE],
76 impl Clone for ChaCha20 { fn clone(&self) -> ChaCha20 { *self } }
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);
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;
101 for i in 0..lens.len() {
102 $output[i*4..(i+1)*4].copy_from_slice(&le32_to_array(lens[i]));
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);
120 macro_rules! rotate {
121 ($a: expr, $b: expr, $c:expr) => {{
125 $a = (v << $c) ^ right
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);
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);
140 ChaCha20{ state: ChaCha20::expand(key, nonce), output: [0u8; BLOCK_SIZE], offset: 64 }
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",
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])
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])
162 c: if key.len() == 16 {
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])
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])
177 d: if nonce.len() == 16 {
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])
184 } else if nonce.len() == 12 {
187 slice_to_le32(&nonce[0..4]),
188 slice_to_le32(&nonce[4..8]),
189 slice_to_le32(&nonce[8..12])
195 slice_to_le32(&nonce[0..4]),
196 slice_to_le32(&nonce[4..8])
202 // put the the next BLOCK_SIZE keystream bytes into self.output
203 fn update(&mut self) {
204 let mut state = self.state;
208 swizzle!(state.b, state.c, state.d);
210 swizzle!(state.d, state.c, state.b);
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;
217 state_to_buffer!(state, self.output);
219 self.state.d = self.state.d + u32x4(1, 0, 0, 0);
220 let u32x4(c12, _, _, _) = self.state.d;
222 // we could increment the other counter word with an 8 byte nonce
223 // but other implementations like boringssl have this same
225 panic!("counter is exhausted");
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();
237 // If there is no keystream available in the output buffer,
238 // generate the next block.
239 if self.offset == BLOCK_SIZE {
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);
250 output[i + j] = input[i + j] ^ self.output[self.offset + j];
253 self.offset += count;
257 pub fn process_in_place(&mut self, input_output: &mut [u8]) {
258 let len = input_output.len();
261 // If there is no keystream available in the output buffer,
262 // generate the next block.
263 if self.offset == BLOCK_SIZE {
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);
273 input_output[i + j] ^= self.output[self.offset + j];
276 self.offset += count;
281 #[cfg(not(feature = "fuzztarget"))]
282 pub use self::real_chacha::ChaCha20;
284 #[cfg(feature = "fuzztarget")]
286 pub struct 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);
295 pub fn process(&mut self, input: &[u8], output: &mut [u8]) {
296 output.copy_from_slice(input);
299 pub fn process_in_place(&mut self, _input_output: &mut [u8]) {}
302 #[cfg(feature = "fuzztarget")]
303 pub use self::fuzzy_chacha::ChaCha20;
305 pub(crate) struct ChaChaReader<'a, R: io::Read> {
306 pub chacha: &'a mut ChaCha20,
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)?;
313 self.chacha.process_in_place(&mut dest[0..res]);
321 use std::iter::repeat;
326 fn test_chacha20_256_tls_vectors() {
332 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
333 let test_vectors = vec!(
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,
341 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
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,
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,
359 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
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,
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,
377 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
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,
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,
395 nonce: [ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
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,
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,
413 nonce: [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
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,
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);
461 fn test_chacha20_256_tls_vectors_96_nonce() {
467 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
468 let test_vectors = vec!(
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,
476 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
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,
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,
494 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
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,
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,
512 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
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,
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,
530 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
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,
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,
548 nonce: [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
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,
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);