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 // 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
14 #[cfg(not(feature = "fuzztarget"))]
17 use core::convert::TryInto;
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 {
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 ::core::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 ::core::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 ::core::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 ::core::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 fn from_bytes(bytes: &[u8]) -> Self {
60 assert_eq!(bytes.len(), 4*4);
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")),
70 const BLOCK_SIZE: usize = 64;
83 output : [u8; BLOCK_SIZE],
87 impl Clone for ChaCha20 { fn clone(&self) -> ChaCha20 { *self } }
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);
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;
112 for i in 0..lens.len() {
113 $output[i*4..(i+1)*4].copy_from_slice(&lens[i].to_le_bytes());
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);
131 macro_rules! rotate {
132 ($a: expr, $b: expr, $c:expr) => {{
136 $a = (v << $c) ^ right
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);
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);
151 ChaCha20{ state: ChaCha20::expand(key, nonce), output: [0u8; BLOCK_SIZE], offset: 64 }
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",
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])
166 u32x4::from_bytes(&key[16..32])
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)
175 let mut nonce4 = [0; 4*4];
176 nonce4[8..].copy_from_slice(nonce);
177 u32x4::from_bytes(&nonce4)
182 // put the the next BLOCK_SIZE keystream bytes into self.output
183 fn update(&mut self) {
184 let mut state = self.state;
188 swizzle!(state.b, state.c, state.d);
190 swizzle!(state.d, state.c, state.b);
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;
197 state_to_buffer!(state, self.output);
199 self.state.d = self.state.d + u32x4(1, 0, 0, 0);
200 let u32x4(c12, _, _, _) = self.state.d;
202 // we could increment the other counter word with an 8 byte nonce
203 // but other implementations like boringssl have this same
205 panic!("counter is exhausted");
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();
217 // If there is no keystream available in the output buffer,
218 // generate the next block.
219 if self.offset == BLOCK_SIZE {
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);
230 output[i + j] = input[i + j] ^ self.output[self.offset + j];
233 self.offset += count;
237 pub fn process_in_place(&mut self, input_output: &mut [u8]) {
238 let len = input_output.len();
241 // If there is no keystream available in the output buffer,
242 // generate the next block.
243 if self.offset == BLOCK_SIZE {
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);
253 input_output[i + j] ^= self.output[self.offset + j];
256 self.offset += count;
261 #[cfg(not(feature = "fuzztarget"))]
262 pub use self::real_chacha::ChaCha20;
264 #[cfg(feature = "fuzztarget")]
266 pub struct 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);
275 pub fn process(&mut self, input: &[u8], output: &mut [u8]) {
276 output.copy_from_slice(input);
279 pub fn process_in_place(&mut self, _input_output: &mut [u8]) {}
282 #[cfg(feature = "fuzztarget")]
283 pub use self::fuzzy_chacha::ChaCha20;
285 pub(crate) struct ChaChaReader<'a, R: io::Read> {
286 pub chacha: &'a mut ChaCha20,
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)?;
293 self.chacha.process_in_place(&mut dest[0..res]);
302 use core::iter::repeat;
307 fn test_chacha20_256_tls_vectors() {
313 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
314 let test_vectors = vec!(
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,
322 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
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,
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,
340 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
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,
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,
358 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
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,
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,
376 nonce: [ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
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,
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,
394 nonce: [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
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,
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);
442 fn test_chacha20_256_tls_vectors_96_nonce() {
448 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
449 let test_vectors = vec!(
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,
457 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
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,
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,
475 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
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,
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,
493 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
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,
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,
511 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
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,
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,
529 nonce: [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
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,
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);