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.
12 #[cfg(not(feature = "fuzztarget"))]
15 use util::byte_utils::{slice_to_le32, le32_to_array};
16 use crypto::symmetriccipher::SynchronousStreamCipher;
18 #[derive(Clone, Copy, PartialEq, Eq)]
19 #[allow(non_camel_case_types)]
20 struct u32x4(pub u32, pub u32, pub u32, pub u32);
21 impl ::std::ops::Add for u32x4 {
23 fn add(self, rhs: u32x4) -> u32x4 {
24 u32x4(self.0.wrapping_add(rhs.0),
25 self.1.wrapping_add(rhs.1),
26 self.2.wrapping_add(rhs.2),
27 self.3.wrapping_add(rhs.3))
30 impl ::std::ops::Sub for u32x4 {
32 fn sub(self, rhs: u32x4) -> u32x4 {
33 u32x4(self.0.wrapping_sub(rhs.0),
34 self.1.wrapping_sub(rhs.1),
35 self.2.wrapping_sub(rhs.2),
36 self.3.wrapping_sub(rhs.3))
39 impl ::std::ops::BitXor for u32x4 {
41 fn bitxor(self, rhs: u32x4) -> u32x4 {
42 u32x4(self.0 ^ rhs.0, self.1 ^ rhs.1, self.2 ^ rhs.2, self.3 ^ rhs.3)
45 impl ::std::ops::Shr<u32x4> for u32x4 {
47 fn shr(self, rhs: u32x4) -> u32x4 {
48 u32x4(self.0 >> rhs.0, self.1 >> rhs.1, self.2 >> rhs.2, self.3 >> rhs.3)
51 impl ::std::ops::Shl<u32x4> for u32x4 {
53 fn shl(self, rhs: u32x4) -> u32x4 {
54 u32x4(self.0 << rhs.0, self.1 << rhs.1, self.2 << rhs.2, self.3 << rhs.3)
73 impl Clone for ChaCha20 { fn clone(&self) -> ChaCha20 { *self } }
75 macro_rules! swizzle {
76 ($b: expr, $c: expr, $d: expr) => {{
77 let u32x4(b10, b11, b12, b13) = $b;
78 $b = u32x4(b11, b12, b13, b10);
79 let u32x4(c10, c11, c12, c13) = $c;
80 $c = u32x4(c12, c13,c10, c11);
81 let u32x4(d10, d11, d12, d13) = $d;
82 $d = u32x4(d13, d10, d11, d12);
86 macro_rules! state_to_buffer {
87 ($state: expr, $output: expr) => {{
88 let u32x4(a1, a2, a3, a4) = $state.a;
89 let u32x4(b1, b2, b3, b4) = $state.b;
90 let u32x4(c1, c2, c3, c4) = $state.c;
91 let u32x4(d1, d2, d3, d4) = $state.d;
98 for i in 0..lens.len() {
99 $output[i*4..(i+1)*4].copy_from_slice(&le32_to_array(lens[i]));
106 $state.a = $state.a + $state.b;
107 rotate!($state.d, $state.a, S16);
108 $state.c = $state.c + $state.d;
109 rotate!($state.b, $state.c, S12);
110 $state.a = $state.a + $state.b;
111 rotate!($state.d, $state.a, S8);
112 $state.c = $state.c + $state.d;
113 rotate!($state.b, $state.c, S7);
117 macro_rules! rotate {
118 ($a: expr, $b: expr, $c:expr) => {{
122 $a = (v << $c) ^ right
126 const S32:u32x4 = u32x4(32, 32, 32, 32);
127 const S16:u32x4 = u32x4(16, 16, 16, 16);
128 const S12:u32x4 = u32x4(12, 12, 12, 12);
129 const S8:u32x4 = u32x4(8, 8, 8, 8);
130 const S7:u32x4 = u32x4(7, 7, 7, 7);
133 pub fn new(key: &[u8], nonce: &[u8]) -> ChaCha20 {
134 assert!(key.len() == 16 || key.len() == 32);
135 assert!(nonce.len() == 8 || nonce.len() == 12);
137 ChaCha20{ state: ChaCha20::expand(key, nonce), output: [0u8; 64], offset: 64 }
140 fn expand(key: &[u8], nonce: &[u8]) -> ChaChaState {
141 let constant = match key.len() {
142 16 => b"expand 16-byte k",
143 32 => b"expand 32-byte k",
148 slice_to_le32(&constant[0..4]),
149 slice_to_le32(&constant[4..8]),
150 slice_to_le32(&constant[8..12]),
151 slice_to_le32(&constant[12..16])
154 slice_to_le32(&key[0..4]),
155 slice_to_le32(&key[4..8]),
156 slice_to_le32(&key[8..12]),
157 slice_to_le32(&key[12..16])
159 c: if key.len() == 16 {
161 slice_to_le32(&key[0..4]),
162 slice_to_le32(&key[4..8]),
163 slice_to_le32(&key[8..12]),
164 slice_to_le32(&key[12..16])
168 slice_to_le32(&key[16..20]),
169 slice_to_le32(&key[20..24]),
170 slice_to_le32(&key[24..28]),
171 slice_to_le32(&key[28..32])
174 d: if nonce.len() == 16 {
176 slice_to_le32(&nonce[0..4]),
177 slice_to_le32(&nonce[4..8]),
178 slice_to_le32(&nonce[8..12]),
179 slice_to_le32(&nonce[12..16])
181 } else if nonce.len() == 12 {
184 slice_to_le32(&nonce[0..4]),
185 slice_to_le32(&nonce[4..8]),
186 slice_to_le32(&nonce[8..12])
192 slice_to_le32(&nonce[0..4]),
193 slice_to_le32(&nonce[4..8])
199 // put the the next 64 keystream bytes into self.output
200 fn update(&mut self) {
201 let mut state = self.state;
205 swizzle!(state.b, state.c, state.d);
207 swizzle!(state.d, state.c, state.b);
209 state.a = state.a + self.state.a;
210 state.b = state.b + self.state.b;
211 state.c = state.c + self.state.c;
212 state.d = state.d + self.state.d;
214 state_to_buffer!(state, self.output);
216 self.state.d = self.state.d + u32x4(1, 0, 0, 0);
217 let u32x4(c12, _, _, _) = self.state.d;
219 // we could increment the other counter word with an 8 byte nonce
220 // but other implementations like boringssl have this same
222 panic!("counter is exhausted");
229 impl SynchronousStreamCipher for ChaCha20 {
230 fn process(&mut self, input: &[u8], output: &mut [u8]) {
231 assert!(input.len() == output.len());
232 let len = input.len();
235 // If there is no keystream available in the output buffer,
236 // generate the next block.
237 if self.offset == 64 {
241 // Process the min(available keystream, remaining input length).
242 let count = cmp::min(64 - self.offset, len - i);
243 // explicitly assert lengths to avoid bounds checks:
244 assert!(output.len() >= i + count);
245 assert!(input.len() >= i + count);
246 assert!(self.output.len() >= self.offset + count);
248 output[i + j] = input[i + j] ^ self.output[self.offset + j];
251 self.offset += count;
256 #[cfg(not(feature = "fuzztarget"))]
257 pub use self::real_chacha::ChaCha20;
259 #[cfg(feature = "fuzztarget")]
261 use crypto::symmetriccipher::SynchronousStreamCipher;
263 pub struct ChaCha20 {}
266 pub fn new(key: &[u8], nonce: &[u8]) -> ChaCha20 {
267 assert!(key.len() == 16 || key.len() == 32);
268 assert!(nonce.len() == 8 || nonce.len() == 12);
273 impl SynchronousStreamCipher for ChaCha20 {
274 fn process(&mut self, input: &[u8], output: &mut [u8]) {
275 output.copy_from_slice(input);
279 #[cfg(feature = "fuzztarget")]
280 pub use self::fuzzy_chacha::ChaCha20;
284 use std::iter::repeat;
287 use crypto::symmetriccipher::SynchronousStreamCipher;
290 fn test_chacha20_256_tls_vectors() {
296 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
297 let test_vectors = vec!(
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
307 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
308 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
309 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
310 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
311 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
312 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
313 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
314 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
323 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
325 0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96,
326 0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96,
327 0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 0xd2, 0x60,
328 0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41,
329 0xbb, 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2,
330 0xa5, 0xd1, 0xe7, 0xe2, 0x0d, 0x42, 0xaf, 0x2c,
331 0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 0x81,
332 0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63,
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, 0x01 ],
343 0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5,
344 0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a,
345 0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13,
346 0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31,
347 0xe8, 0x5a, 0x05, 0x02, 0x78, 0xa7, 0x08, 0x45,
348 0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b,
349 0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e,
350 0x44, 0x5f, 0x41, 0xe3,
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, 0x00,
359 nonce: [ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
361 0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
362 0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
363 0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
364 0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
365 0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
366 0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
367 0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
368 0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
372 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
373 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
374 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
375 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
377 nonce: [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
379 0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69,
380 0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75,
381 0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93,
382 0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1,
383 0x34, 0xa4, 0x54, 0x7b, 0x73, 0x3b, 0x46, 0x41,
384 0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69,
385 0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1,
386 0x59, 0x16, 0x15, 0x5c, 0x2b, 0xe8, 0x24, 0x1a,
387 0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94,
388 0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66,
389 0x89, 0xde, 0x95, 0x26, 0x49, 0x86, 0xd9, 0x58,
390 0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd,
391 0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56,
392 0x3e, 0xb9, 0xb3, 0xa4, 0xa4, 0x72, 0xf8, 0x2e,
393 0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e,
394 0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7,
395 0x9d, 0xb9, 0xd4, 0xf7, 0xc7, 0xa8, 0x99, 0x15,
396 0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3,
397 0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a,
398 0x97, 0xa5, 0xf5, 0x76, 0xfe, 0x06, 0x40, 0x25,
399 0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5,
400 0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69,
401 0x59, 0x66, 0x09, 0x96, 0x54, 0x6c, 0xc9, 0xc4,
402 0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7,
403 0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79,
404 0xe5, 0xc5, 0x36, 0x0c, 0x33, 0x17, 0x16, 0x6a,
405 0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a,
406 0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2,
407 0xcc, 0xb2, 0x7d, 0x5a, 0xaa, 0xe0, 0xad, 0x7a,
408 0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09,
409 0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a,
410 0x6d, 0xeb, 0x3a, 0xb7, 0x8f, 0xab, 0x78, 0xc9,
415 for tv in test_vectors.iter() {
416 let mut c = ChaCha20::new(&tv.key, &tv.nonce);
417 let input: Vec<u8> = repeat(0).take(tv.keystream.len()).collect();
418 let mut output: Vec<u8> = repeat(0).take(input.len()).collect();
419 c.process(&input[..], &mut output[..]);
420 assert_eq!(output, tv.keystream);
425 fn test_chacha20_256_tls_vectors_96_nonce() {
431 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
432 let test_vectors = vec!(
435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
437 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
442 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
443 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
444 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
445 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
446 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
447 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
448 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
449 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
458 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
460 0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96,
461 0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96,
462 0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 0xd2, 0x60,
463 0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41,
464 0xbb, 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2,
465 0xa5, 0xd1, 0xe7, 0xe2, 0x0d, 0x42, 0xaf, 0x2c,
466 0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 0x81,
467 0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63,
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, 0x01 ],
478 0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5,
479 0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a,
480 0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13,
481 0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31,
482 0xe8, 0x5a, 0x05, 0x02, 0x78, 0xa7, 0x08, 0x45,
483 0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b,
484 0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e,
485 0x44, 0x5f, 0x41, 0xe3,
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, 0x00,
494 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
496 0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
497 0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
498 0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
499 0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
500 0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
501 0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
502 0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
503 0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
507 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
508 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
509 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
510 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
512 nonce: [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
514 0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69,
515 0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75,
516 0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93,
517 0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1,
518 0x34, 0xa4, 0x54, 0x7b, 0x73, 0x3b, 0x46, 0x41,
519 0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69,
520 0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1,
521 0x59, 0x16, 0x15, 0x5c, 0x2b, 0xe8, 0x24, 0x1a,
522 0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94,
523 0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66,
524 0x89, 0xde, 0x95, 0x26, 0x49, 0x86, 0xd9, 0x58,
525 0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd,
526 0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56,
527 0x3e, 0xb9, 0xb3, 0xa4, 0xa4, 0x72, 0xf8, 0x2e,
528 0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e,
529 0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7,
530 0x9d, 0xb9, 0xd4, 0xf7, 0xc7, 0xa8, 0x99, 0x15,
531 0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3,
532 0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a,
533 0x97, 0xa5, 0xf5, 0x76, 0xfe, 0x06, 0x40, 0x25,
534 0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5,
535 0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69,
536 0x59, 0x66, 0x09, 0x96, 0x54, 0x6c, 0xc9, 0xc4,
537 0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7,
538 0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79,
539 0xe5, 0xc5, 0x36, 0x0c, 0x33, 0x17, 0x16, 0x6a,
540 0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a,
541 0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2,
542 0xcc, 0xb2, 0x7d, 0x5a, 0xaa, 0xe0, 0xad, 0x7a,
543 0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09,
544 0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a,
545 0x6d, 0xeb, 0x3a, 0xb7, 0x8f, 0xab, 0x78, 0xc9,
550 for tv in test_vectors.iter() {
551 let mut c = ChaCha20::new(&tv.key, &tv.nonce);
552 let input: Vec<u8> = repeat(0).take(tv.keystream.len()).collect();
553 let mut output: Vec<u8> = repeat(0).take(input.len()).collect();
554 c.process(&input[..], &mut output[..]);
555 assert_eq!(output, tv.keystream);