Make `ChaCha20::get_single_block` return a full, single block
[rust-lightning] / lightning / src / crypto / 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 // 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
10 // licenses.
11
12 #[cfg(not(fuzzing))]
13 mod real_chacha {
14         use core::cmp;
15         use core::convert::TryInto;
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 ::core::ops::Add for u32x4 {
21                 type Output = u32x4;
22                 #[inline]
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))
28                 }
29         }
30         impl ::core::ops::Sub for u32x4 {
31                 type Output = u32x4;
32                 #[inline]
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))
38                 }
39         }
40         impl ::core::ops::BitXor for u32x4 {
41                 type Output = u32x4;
42                 #[inline]
43                 fn bitxor(self, rhs: u32x4) -> u32x4 {
44                         u32x4(self.0 ^ rhs.0, self.1 ^ rhs.1, self.2 ^ rhs.2, self.3 ^ rhs.3)
45                 }
46         }
47         impl ::core::ops::Shr<u8> for u32x4 {
48                 type Output = u32x4;
49                 #[inline]
50                 fn shr(self, shr: u8) -> u32x4 {
51                         u32x4(self.0 >> shr, self.1 >> shr, self.2 >> shr, self.3 >> shr)
52                 }
53         }
54         impl ::core::ops::Shl<u8> for u32x4 {
55                 type Output = u32x4;
56                 #[inline]
57                 fn shl(self, shl: u8) -> u32x4 {
58                         u32x4(self.0 << shl, self.1 << shl, self.2 << shl, self.3 << shl)
59                 }
60         }
61         impl u32x4 {
62                 #[inline]
63                 fn from_bytes(bytes: &[u8]) -> Self {
64                         assert_eq!(bytes.len(), 4*4);
65                         Self (
66                                 u32::from_le_bytes(bytes[0*4..1*4].try_into().expect("len is 4")),
67                                 u32::from_le_bytes(bytes[1*4..2*4].try_into().expect("len is 4")),
68                                 u32::from_le_bytes(bytes[2*4..3*4].try_into().expect("len is 4")),
69                                 u32::from_le_bytes(bytes[3*4..4*4].try_into().expect("len is 4")),
70                         )
71                 }
72         }
73
74         const BLOCK_SIZE: usize = 64;
75
76         #[derive(Clone,Copy)]
77         struct ChaChaState {
78                 a: u32x4,
79                 b: u32x4,
80                 c: u32x4,
81                 d: u32x4
82         }
83
84         #[derive(Copy)]
85         pub struct ChaCha20 {
86                 state  : ChaChaState,
87                 output : [u8; BLOCK_SIZE],
88                 offset : usize,
89         }
90
91         impl Clone for ChaCha20 { fn clone(&self) -> ChaCha20 { *self } }
92
93         macro_rules! swizzle {
94                 ($b: expr, $c: expr, $d: expr) => {{
95                         let u32x4(b10, b11, b12, b13) = $b;
96                         $b = u32x4(b11, b12, b13, b10);
97                         let u32x4(c10, c11, c12, c13) = $c;
98                         $c = u32x4(c12, c13,c10, c11);
99                         let u32x4(d10, d11, d12, d13) = $d;
100                         $d = u32x4(d13, d10, d11, d12);
101                 }}
102         }
103
104         macro_rules! state_to_buffer {
105                 ($state: expr, $output: expr) => {{
106                         let u32x4(a1, a2, a3, a4) = $state.a;
107                         let u32x4(b1, b2, b3, b4) = $state.b;
108                         let u32x4(c1, c2, c3, c4) = $state.c;
109                         let u32x4(d1, d2, d3, d4) = $state.d;
110                         let lens = [
111                                 a1,a2,a3,a4,
112                                 b1,b2,b3,b4,
113                                 c1,c2,c3,c4,
114                                 d1,d2,d3,d4
115                         ];
116                         for i in 0..lens.len() {
117                                 $output[i*4..(i+1)*4].copy_from_slice(&lens[i].to_le_bytes());
118                         }
119                 }}
120         }
121
122         macro_rules! round{
123                 ($state: expr) => {{
124                         $state.a = $state.a + $state.b;
125                         rotate!($state.d, $state.a, 16);
126                         $state.c = $state.c + $state.d;
127                         rotate!($state.b, $state.c, 12);
128                         $state.a = $state.a + $state.b;
129                         rotate!($state.d, $state.a, 8);
130                         $state.c = $state.c + $state.d;
131                         rotate!($state.b, $state.c, 7);
132                 }}
133         }
134
135         macro_rules! rotate {
136                 ($a: expr, $b: expr, $rot: expr) => {{
137                         let v = $a ^ $b;
138                         let r = 32 - $rot;
139                         let right = v >> r;
140                         $a = (v << $rot) ^ right
141                 }}
142         }
143
144         impl ChaCha20 {
145                 pub fn new(key: &[u8], nonce: &[u8]) -> ChaCha20 {
146                         assert!(key.len() == 16 || key.len() == 32);
147                         assert!(nonce.len() == 8 || nonce.len() == 12);
148
149                         ChaCha20{ state: ChaCha20::expand(key, nonce), output: [0u8; BLOCK_SIZE], offset: 64 }
150                 }
151
152                 /// Get one block from a ChaCha stream.
153                 pub fn get_single_block(key: &[u8; 32], nonce: &[u8; 16]) -> [u8; 64] {
154                         let mut chacha = ChaCha20 { state: ChaCha20::expand(key, nonce), output: [0u8; BLOCK_SIZE], offset: 64 };
155                         chacha.update();
156                         chacha.output
157                 }
158
159                 /// Encrypts `src` into `dest` using a single block from a ChaCha stream. Passing `dest` as
160                 /// `src` in a second call will decrypt it.
161                 pub fn encrypt_single_block(
162                         key: &[u8; 32], nonce: &[u8; 16], dest: &mut [u8], src: &[u8]
163                 ) {
164                         debug_assert_eq!(dest.len(), src.len());
165                         debug_assert!(dest.len() <= 32);
166
167                         let block = ChaCha20::get_single_block(key, nonce);
168                         for i in 0..dest.len() {
169                                 dest[i] = block[i] ^ src[i];
170                         }
171                 }
172
173                 /// Same as `encrypt_single_block` only operates on a fixed-size input in-place.
174                 pub fn encrypt_single_block_in_place(
175                         key: &[u8; 32], nonce: &[u8; 16], bytes: &mut [u8; 32]
176                 ) {
177                         let block = ChaCha20::get_single_block(key, nonce);
178                         for i in 0..bytes.len() {
179                                 bytes[i] = block[i] ^ bytes[i];
180                         }
181                 }
182
183                 fn expand(key: &[u8], nonce: &[u8]) -> ChaChaState {
184                         let constant = match key.len() {
185                                 16 => b"expand 16-byte k",
186                                 32 => b"expand 32-byte k",
187                                 _  => unreachable!(),
188                         };
189                         ChaChaState {
190                                 a: u32x4::from_bytes(&constant[0..16]),
191                                 b: u32x4::from_bytes(&key[0..16]),
192                                 c: if key.len() == 16 {
193                                         u32x4::from_bytes(&key[0..16])
194                                 } else {
195                                         u32x4::from_bytes(&key[16..32])
196                                 },
197                                 d: if nonce.len() == 16 {
198                                         u32x4::from_bytes(&nonce[0..16])
199                                 } else if nonce.len() == 12 {
200                                         let mut nonce4 = [0; 4*4];
201                                         nonce4[4..].copy_from_slice(nonce);
202                                         u32x4::from_bytes(&nonce4)
203                                 } else {
204                                         let mut nonce4 = [0; 4*4];
205                                         nonce4[8..].copy_from_slice(nonce);
206                                         u32x4::from_bytes(&nonce4)
207                                 }
208                         }
209                 }
210
211                 // put the the next BLOCK_SIZE keystream bytes into self.output
212                 fn update(&mut self) {
213                         let mut state = self.state;
214
215                         for _ in 0..10 {
216                                 round!(state);
217                                 swizzle!(state.b, state.c, state.d);
218                                 round!(state);
219                                 swizzle!(state.d, state.c, state.b);
220                         }
221                         state.a = state.a + self.state.a;
222                         state.b = state.b + self.state.b;
223                         state.c = state.c + self.state.c;
224                         state.d = state.d + self.state.d;
225
226                         state_to_buffer!(state, self.output);
227
228                         self.state.d = self.state.d + u32x4(1, 0, 0, 0);
229                         let u32x4(c12, _, _, _) = self.state.d;
230                         if c12 == 0 {
231                                 // we could increment the other counter word with an 8 byte nonce
232                                 // but other implementations like boringssl have this same
233                                 // limitation
234                                 panic!("counter is exhausted");
235                         }
236
237                         self.offset = 0;
238                 }
239
240                 #[inline] // Useful cause input may be 0s on stack that should be optimized out
241                 pub fn process(&mut self, input: &[u8], output: &mut [u8]) {
242                         assert!(input.len() == output.len());
243                         let len = input.len();
244                         let mut i = 0;
245                         while i < len {
246                                 // If there is no keystream available in the output buffer,
247                                 // generate the next block.
248                                 if self.offset == BLOCK_SIZE {
249                                         self.update();
250                                 }
251
252                                 // Process the min(available keystream, remaining input length).
253                                 let count = cmp::min(BLOCK_SIZE - self.offset, len - i);
254                                 // explicitly assert lengths to avoid bounds checks:
255                                 assert!(output.len() >= i + count);
256                                 assert!(input.len() >= i + count);
257                                 assert!(self.output.len() >= self.offset + count);
258                                 for j in 0..count {
259                                         output[i + j] = input[i + j] ^ self.output[self.offset + j];
260                                 }
261                                 i += count;
262                                 self.offset += count;
263                         }
264                 }
265
266                 pub fn process_in_place(&mut self, input_output: &mut [u8]) {
267                         let len = input_output.len();
268                         let mut i = 0;
269                         while i < len {
270                                 // If there is no keystream available in the output buffer,
271                                 // generate the next block.
272                                 if self.offset == BLOCK_SIZE {
273                                         self.update();
274                                 }
275
276                                 // Process the min(available keystream, remaining input length).
277                                 let count = cmp::min(BLOCK_SIZE - self.offset, len - i);
278                                 // explicitly assert lengths to avoid bounds checks:
279                                 assert!(input_output.len() >= i + count);
280                                 assert!(self.output.len() >= self.offset + count);
281                                 for j in 0..count {
282                                         input_output[i + j] ^= self.output[self.offset + j];
283                                 }
284                                 i += count;
285                                 self.offset += count;
286                         }
287                 }
288
289                 #[cfg(test)]
290                 pub fn seek_to_block(&mut self, block_offset: u32) {
291                         self.state.d.0 = block_offset;
292                         self.update();
293                 }
294         }
295 }
296 #[cfg(not(fuzzing))]
297 pub use self::real_chacha::ChaCha20;
298
299 #[cfg(fuzzing)]
300 mod fuzzy_chacha {
301         pub struct ChaCha20 {}
302
303         impl ChaCha20 {
304                 pub fn new(key: &[u8], nonce: &[u8]) -> ChaCha20 {
305                         assert!(key.len() == 16 || key.len() == 32);
306                         assert!(nonce.len() == 8 || nonce.len() == 12);
307                         Self {}
308                 }
309
310                 pub fn get_single_block(_key: &[u8; 32], _nonce: &[u8; 16]) -> [u8; 32] {
311                         [0; 32]
312                 }
313
314                 pub fn encrypt_single_block(
315                         _key: &[u8; 32], _nonce: &[u8; 16], dest: &mut [u8], src: &[u8]
316                 ) {
317                         debug_assert_eq!(dest.len(), src.len());
318                         debug_assert!(dest.len() <= 32);
319                 }
320
321                 pub fn encrypt_single_block_in_place(
322                         _key: &[u8; 32], _nonce: &[u8; 16], _bytes: &mut [u8; 32]
323                 ) {}
324
325                 pub fn process(&mut self, input: &[u8], output: &mut [u8]) {
326                         output.copy_from_slice(input);
327                 }
328
329                 pub fn process_in_place(&mut self, _input_output: &mut [u8]) {}
330         }
331 }
332 #[cfg(fuzzing)]
333 pub use self::fuzzy_chacha::ChaCha20;
334
335 #[cfg(test)]
336 mod test {
337         use alloc::vec;
338         use alloc::vec::{Vec};
339         use core::convert::TryInto;
340         use core::iter::repeat;
341
342         use super::ChaCha20;
343
344         #[test]
345         fn test_chacha20_256_tls_vectors() {
346                 struct TestVector {
347                         key:   [u8; 32],
348                         nonce: [u8; 8],
349                         keystream: Vec<u8>,
350                 }
351                 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
352                 let test_vectors = vec!(
353                         TestVector{
354                                 key: [
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, 0x00,
359                                 ],
360                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
361                                 keystream: vec!(
362                                         0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
363                                         0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
364                                         0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
365                                         0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
366                                         0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
367                                         0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
368                                         0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
369                                         0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
370                                 ),
371                         }, TestVector{
372                                 key: [
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, 0x01,
377                                 ],
378                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
379                                 keystream: vec!(
380                                         0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96,
381                                         0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96,
382                                         0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 0xd2, 0x60,
383                                         0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41,
384                                         0xbb, 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2,
385                                         0xa5, 0xd1, 0xe7, 0xe2, 0x0d, 0x42, 0xaf, 0x2c,
386                                         0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 0x81,
387                                         0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63,
388                                 ),
389                         }, TestVector{
390                                 key: [
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,
395                                 ],
396                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
397                                 keystream: vec!(
398                                         0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5,
399                                         0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a,
400                                         0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13,
401                                         0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31,
402                                         0xe8, 0x5a, 0x05, 0x02, 0x78, 0xa7, 0x08, 0x45,
403                                         0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b,
404                                         0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e,
405                                         0x44, 0x5f, 0x41, 0xe3,
406                                 ),
407                         }, TestVector{
408                                 key: [
409                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413                                 ],
414                                 nonce: [ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
415                                 keystream: vec!(
416                                         0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
417                                         0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
418                                         0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
419                                         0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
420                                         0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
421                                         0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
422                                         0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
423                                         0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
424                                 ),
425                         }, TestVector{
426                                 key: [
427                                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
428                                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
429                                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
430                                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
431                                 ],
432                                 nonce: [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
433                                 keystream: vec!(
434                                         0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69,
435                                         0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75,
436                                         0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93,
437                                         0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1,
438                                         0x34, 0xa4, 0x54, 0x7b, 0x73, 0x3b, 0x46, 0x41,
439                                         0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69,
440                                         0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1,
441                                         0x59, 0x16, 0x15, 0x5c, 0x2b, 0xe8, 0x24, 0x1a,
442                                         0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94,
443                                         0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66,
444                                         0x89, 0xde, 0x95, 0x26, 0x49, 0x86, 0xd9, 0x58,
445                                         0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd,
446                                         0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56,
447                                         0x3e, 0xb9, 0xb3, 0xa4, 0xa4, 0x72, 0xf8, 0x2e,
448                                         0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e,
449                                         0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7,
450                                         0x9d, 0xb9, 0xd4, 0xf7, 0xc7, 0xa8, 0x99, 0x15,
451                                         0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3,
452                                         0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a,
453                                         0x97, 0xa5, 0xf5, 0x76, 0xfe, 0x06, 0x40, 0x25,
454                                         0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5,
455                                         0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69,
456                                         0x59, 0x66, 0x09, 0x96, 0x54, 0x6c, 0xc9, 0xc4,
457                                         0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7,
458                                         0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79,
459                                         0xe5, 0xc5, 0x36, 0x0c, 0x33, 0x17, 0x16, 0x6a,
460                                         0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a,
461                                         0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2,
462                                         0xcc, 0xb2, 0x7d, 0x5a, 0xaa, 0xe0, 0xad, 0x7a,
463                                         0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09,
464                                         0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a,
465                                         0x6d, 0xeb, 0x3a, 0xb7, 0x8f, 0xab, 0x78, 0xc9,
466                                 ),
467                         },
468                 );
469
470                 for tv in test_vectors.iter() {
471                         let mut c = ChaCha20::new(&tv.key, &tv.nonce);
472                         let input: Vec<u8> = repeat(0).take(tv.keystream.len()).collect();
473                         let mut output: Vec<u8> = repeat(0).take(input.len()).collect();
474                         c.process(&input[..], &mut output[..]);
475                         assert_eq!(output, tv.keystream);
476                 }
477         }
478
479         #[test]
480         fn test_chacha20_256_tls_vectors_96_nonce() {
481                 struct TestVector {
482                         key:   [u8; 32],
483                         nonce: [u8; 12],
484                         keystream: Vec<u8>,
485                 }
486                 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
487                 let test_vectors = vec!(
488                         TestVector{
489                                 key: [
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, 0x00,
494                                 ],
495                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
496                                 keystream: vec!(
497                                         0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
498                                         0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
499                                         0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
500                                         0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
501                                         0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
502                                         0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
503                                         0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
504                                         0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
505                                 ),
506                         }, TestVector{
507                                 key: [
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, 0x01,
512                                 ],
513                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
514                                 keystream: vec!(
515                                         0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96,
516                                         0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96,
517                                         0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 0xd2, 0x60,
518                                         0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41,
519                                         0xbb, 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2,
520                                         0xa5, 0xd1, 0xe7, 0xe2, 0x0d, 0x42, 0xaf, 0x2c,
521                                         0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 0x81,
522                                         0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63,
523                                 ),
524                         }, TestVector{
525                                 key: [
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,
530                                 ],
531                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
532                                 keystream: vec!(
533                                         0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5,
534                                         0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a,
535                                         0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13,
536                                         0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31,
537                                         0xe8, 0x5a, 0x05, 0x02, 0x78, 0xa7, 0x08, 0x45,
538                                         0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b,
539                                         0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e,
540                                         0x44, 0x5f, 0x41, 0xe3,
541                                 ),
542                         }, TestVector{
543                                 key: [
544                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548                                 ],
549                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
550                                 keystream: vec!(
551                                         0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
552                                         0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
553                                         0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
554                                         0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
555                                         0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
556                                         0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
557                                         0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
558                                         0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
559                                 ),
560                         }, TestVector{
561                                 key: [
562                                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
563                                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
564                                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
565                                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
566                                 ],
567                                 nonce: [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
568                                 keystream: vec!(
569                                         0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69,
570                                         0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75,
571                                         0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93,
572                                         0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1,
573                                         0x34, 0xa4, 0x54, 0x7b, 0x73, 0x3b, 0x46, 0x41,
574                                         0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69,
575                                         0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1,
576                                         0x59, 0x16, 0x15, 0x5c, 0x2b, 0xe8, 0x24, 0x1a,
577                                         0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94,
578                                         0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66,
579                                         0x89, 0xde, 0x95, 0x26, 0x49, 0x86, 0xd9, 0x58,
580                                         0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd,
581                                         0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56,
582                                         0x3e, 0xb9, 0xb3, 0xa4, 0xa4, 0x72, 0xf8, 0x2e,
583                                         0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e,
584                                         0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7,
585                                         0x9d, 0xb9, 0xd4, 0xf7, 0xc7, 0xa8, 0x99, 0x15,
586                                         0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3,
587                                         0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a,
588                                         0x97, 0xa5, 0xf5, 0x76, 0xfe, 0x06, 0x40, 0x25,
589                                         0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5,
590                                         0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69,
591                                         0x59, 0x66, 0x09, 0x96, 0x54, 0x6c, 0xc9, 0xc4,
592                                         0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7,
593                                         0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79,
594                                         0xe5, 0xc5, 0x36, 0x0c, 0x33, 0x17, 0x16, 0x6a,
595                                         0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a,
596                                         0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2,
597                                         0xcc, 0xb2, 0x7d, 0x5a, 0xaa, 0xe0, 0xad, 0x7a,
598                                         0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09,
599                                         0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a,
600                                         0x6d, 0xeb, 0x3a, 0xb7, 0x8f, 0xab, 0x78, 0xc9,
601                                 ),
602                         },
603                 );
604
605                 for tv in test_vectors.iter() {
606                         let mut c = ChaCha20::new(&tv.key, &tv.nonce);
607                         let input: Vec<u8> = repeat(0).take(tv.keystream.len()).collect();
608                         let mut output: Vec<u8> = repeat(0).take(input.len()).collect();
609                         c.process(&input[..], &mut output[..]);
610                         assert_eq!(output, tv.keystream);
611                 }
612         }
613
614         #[test]
615         fn get_single_block() {
616                 // Test that `get_single_block` (which takes a 16-byte nonce) is equivalent to getting a block
617                 // using a 12-byte nonce, with the block starting at the counter offset given by the remaining 4
618                 // bytes.
619                 let key = [
620                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
621                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
622                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
623                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
624                 ];
625                 let nonce_16bytes = [
626                         0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b
627                 ];
628                 let counter_pos = &nonce_16bytes[..4];
629                 let nonce_12bytes = &nonce_16bytes[4..];
630
631                 // Initialize a ChaCha20 instance with its counter starting at 0.
632                 let mut chacha20 = ChaCha20::new(&key, nonce_12bytes);
633                 // Seek its counter to the block at counter_pos.
634                 chacha20.seek_to_block(u32::from_le_bytes(counter_pos.try_into().unwrap()));
635                 let mut block_bytes = [0; 64];
636                 chacha20.process_in_place(&mut block_bytes);
637
638                 assert_eq!(ChaCha20::get_single_block(&key, &nonce_16bytes), block_bytes);
639         }
640
641         #[test]
642         fn encrypt_single_block() {
643                 let key = [
644                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
645                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
646                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
647                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
648                 ];
649                 let nonce = [
650                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
651                         0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
652                 ];
653                 let bytes = [1; 32];
654
655                 let mut encrypted_bytes = [0; 32];
656                 ChaCha20::encrypt_single_block(&key, &nonce, &mut encrypted_bytes, &bytes);
657
658                 let mut decrypted_bytes = [0; 32];
659                 ChaCha20::encrypt_single_block(&key, &nonce, &mut decrypted_bytes, &encrypted_bytes);
660
661                 assert_eq!(bytes, decrypted_bytes);
662         }
663
664         #[test]
665         fn encrypt_single_block_in_place() {
666                 let key = [
667                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
668                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
669                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
670                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
671                 ];
672                 let nonce = [
673                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
674                         0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
675                 ];
676                 let unencrypted_bytes = [1; 32];
677                 let mut bytes = unencrypted_bytes;
678
679                 ChaCha20::encrypt_single_block_in_place(&key, &nonce, &mut bytes);
680                 assert_ne!(bytes, unencrypted_bytes);
681
682                 ChaCha20::encrypt_single_block_in_place(&key, &nonce, &mut bytes);
683                 assert_eq!(bytes, unencrypted_bytes);
684         }
685 }