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 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 ::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 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]);
322 use core::iter::repeat;
327 fn test_chacha20_256_tls_vectors() {
333 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
334 let test_vectors = vec!(
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
344 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
345 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
346 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
347 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
348 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
349 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
350 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
351 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
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, 0x00,
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
360 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
362 0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96,
363 0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96,
364 0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 0xd2, 0x60,
365 0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41,
366 0xbb, 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2,
367 0xa5, 0xd1, 0xe7, 0xe2, 0x0d, 0x42, 0xaf, 0x2c,
368 0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 0x81,
369 0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
380 0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5,
381 0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a,
382 0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13,
383 0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31,
384 0xe8, 0x5a, 0x05, 0x02, 0x78, 0xa7, 0x08, 0x45,
385 0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b,
386 0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e,
387 0x44, 0x5f, 0x41, 0xe3,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 nonce: [ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
398 0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
399 0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
400 0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
401 0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
402 0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
403 0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
404 0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
405 0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
409 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
410 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
411 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
412 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
414 nonce: [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
416 0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69,
417 0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75,
418 0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93,
419 0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1,
420 0x34, 0xa4, 0x54, 0x7b, 0x73, 0x3b, 0x46, 0x41,
421 0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69,
422 0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1,
423 0x59, 0x16, 0x15, 0x5c, 0x2b, 0xe8, 0x24, 0x1a,
424 0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94,
425 0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66,
426 0x89, 0xde, 0x95, 0x26, 0x49, 0x86, 0xd9, 0x58,
427 0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd,
428 0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56,
429 0x3e, 0xb9, 0xb3, 0xa4, 0xa4, 0x72, 0xf8, 0x2e,
430 0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e,
431 0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7,
432 0x9d, 0xb9, 0xd4, 0xf7, 0xc7, 0xa8, 0x99, 0x15,
433 0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3,
434 0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a,
435 0x97, 0xa5, 0xf5, 0x76, 0xfe, 0x06, 0x40, 0x25,
436 0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5,
437 0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69,
438 0x59, 0x66, 0x09, 0x96, 0x54, 0x6c, 0xc9, 0xc4,
439 0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7,
440 0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79,
441 0xe5, 0xc5, 0x36, 0x0c, 0x33, 0x17, 0x16, 0x6a,
442 0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a,
443 0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2,
444 0xcc, 0xb2, 0x7d, 0x5a, 0xaa, 0xe0, 0xad, 0x7a,
445 0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09,
446 0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a,
447 0x6d, 0xeb, 0x3a, 0xb7, 0x8f, 0xab, 0x78, 0xc9,
452 for tv in test_vectors.iter() {
453 let mut c = ChaCha20::new(&tv.key, &tv.nonce);
454 let input: Vec<u8> = repeat(0).take(tv.keystream.len()).collect();
455 let mut output: Vec<u8> = repeat(0).take(input.len()).collect();
456 c.process(&input[..], &mut output[..]);
457 assert_eq!(output, tv.keystream);
462 fn test_chacha20_256_tls_vectors_96_nonce() {
468 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
469 let test_vectors = vec!(
472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
479 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
480 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
481 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
482 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
483 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
484 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
485 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
486 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
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, 0x00,
493 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
495 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
497 0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96,
498 0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96,
499 0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 0xd2, 0x60,
500 0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41,
501 0xbb, 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2,
502 0xa5, 0xd1, 0xe7, 0xe2, 0x0d, 0x42, 0xaf, 0x2c,
503 0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 0x81,
504 0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63,
508 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
509 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
515 0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5,
516 0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a,
517 0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13,
518 0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31,
519 0xe8, 0x5a, 0x05, 0x02, 0x78, 0xa7, 0x08, 0x45,
520 0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b,
521 0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e,
522 0x44, 0x5f, 0x41, 0xe3,
526 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
528 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
529 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
533 0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
534 0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
535 0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
536 0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
537 0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
538 0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
539 0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
540 0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
544 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
545 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
546 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
547 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
549 nonce: [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
551 0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69,
552 0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75,
553 0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93,
554 0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1,
555 0x34, 0xa4, 0x54, 0x7b, 0x73, 0x3b, 0x46, 0x41,
556 0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69,
557 0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1,
558 0x59, 0x16, 0x15, 0x5c, 0x2b, 0xe8, 0x24, 0x1a,
559 0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94,
560 0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66,
561 0x89, 0xde, 0x95, 0x26, 0x49, 0x86, 0xd9, 0x58,
562 0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd,
563 0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56,
564 0x3e, 0xb9, 0xb3, 0xa4, 0xa4, 0x72, 0xf8, 0x2e,
565 0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e,
566 0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7,
567 0x9d, 0xb9, 0xd4, 0xf7, 0xc7, 0xa8, 0x99, 0x15,
568 0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3,
569 0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a,
570 0x97, 0xa5, 0xf5, 0x76, 0xfe, 0x06, 0x40, 0x25,
571 0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5,
572 0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69,
573 0x59, 0x66, 0x09, 0x96, 0x54, 0x6c, 0xc9, 0xc4,
574 0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7,
575 0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79,
576 0xe5, 0xc5, 0x36, 0x0c, 0x33, 0x17, 0x16, 0x6a,
577 0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a,
578 0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2,
579 0xcc, 0xb2, 0x7d, 0x5a, 0xaa, 0xe0, 0xad, 0x7a,
580 0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09,
581 0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a,
582 0x6d, 0xeb, 0x3a, 0xb7, 0x8f, 0xab, 0x78, 0xc9,
587 for tv in test_vectors.iter() {
588 let mut c = ChaCha20::new(&tv.key, &tv.nonce);
589 let input: Vec<u8> = repeat(0).take(tv.keystream.len()).collect();
590 let mut output: Vec<u8> = repeat(0).take(input.len()).collect();
591 c.process(&input[..], &mut output[..]);
592 assert_eq!(output, tv.keystream);