Use `crate::prelude::*` rather than specific imports
[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
16         #[derive(Clone, Copy, PartialEq, Eq)]
17         #[allow(non_camel_case_types)]
18         struct u32x4(pub u32, pub u32, pub u32, pub u32);
19         impl ::core::ops::Add for u32x4 {
20                 type Output = u32x4;
21                 #[inline]
22                 fn add(self, rhs: u32x4) -> u32x4 {
23                         u32x4(self.0.wrapping_add(rhs.0),
24                               self.1.wrapping_add(rhs.1),
25                               self.2.wrapping_add(rhs.2),
26                               self.3.wrapping_add(rhs.3))
27                 }
28         }
29         impl ::core::ops::Sub for u32x4 {
30                 type Output = u32x4;
31                 #[inline]
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))
37                 }
38         }
39         impl ::core::ops::BitXor for u32x4 {
40                 type Output = u32x4;
41                 #[inline]
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)
44                 }
45         }
46         impl ::core::ops::Shr<u8> for u32x4 {
47                 type Output = u32x4;
48                 #[inline]
49                 fn shr(self, shr: u8) -> u32x4 {
50                         u32x4(self.0 >> shr, self.1 >> shr, self.2 >> shr, self.3 >> shr)
51                 }
52         }
53         impl ::core::ops::Shl<u8> for u32x4 {
54                 type Output = u32x4;
55                 #[inline]
56                 fn shl(self, shl: u8) -> u32x4 {
57                         u32x4(self.0 << shl, self.1 << shl, self.2 << shl, self.3 << shl)
58                 }
59         }
60         impl u32x4 {
61                 #[inline]
62                 fn from_bytes(bytes: &[u8]) -> Self {
63                         assert_eq!(bytes.len(), 4*4);
64                         Self (
65                                 u32::from_le_bytes(bytes[0*4..1*4].try_into().expect("len is 4")),
66                                 u32::from_le_bytes(bytes[1*4..2*4].try_into().expect("len is 4")),
67                                 u32::from_le_bytes(bytes[2*4..3*4].try_into().expect("len is 4")),
68                                 u32::from_le_bytes(bytes[3*4..4*4].try_into().expect("len is 4")),
69                         )
70                 }
71         }
72
73         const BLOCK_SIZE: usize = 64;
74
75         #[derive(Clone,Copy)]
76         struct ChaChaState {
77                 a: u32x4,
78                 b: u32x4,
79                 c: u32x4,
80                 d: u32x4
81         }
82
83         #[derive(Copy)]
84         pub struct ChaCha20 {
85                 state  : ChaChaState,
86                 output : [u8; BLOCK_SIZE],
87                 offset : usize,
88         }
89
90         impl Clone for ChaCha20 { fn clone(&self) -> ChaCha20 { *self } }
91
92         macro_rules! swizzle {
93                 ($b: expr, $c: expr, $d: expr) => {{
94                         let u32x4(b10, b11, b12, b13) = $b;
95                         $b = u32x4(b11, b12, b13, b10);
96                         let u32x4(c10, c11, c12, c13) = $c;
97                         $c = u32x4(c12, c13,c10, c11);
98                         let u32x4(d10, d11, d12, d13) = $d;
99                         $d = u32x4(d13, d10, d11, d12);
100                 }}
101         }
102
103         macro_rules! state_to_buffer {
104                 ($state: expr, $output: expr) => {{
105                         let u32x4(a1, a2, a3, a4) = $state.a;
106                         let u32x4(b1, b2, b3, b4) = $state.b;
107                         let u32x4(c1, c2, c3, c4) = $state.c;
108                         let u32x4(d1, d2, d3, d4) = $state.d;
109                         let lens = [
110                                 a1,a2,a3,a4,
111                                 b1,b2,b3,b4,
112                                 c1,c2,c3,c4,
113                                 d1,d2,d3,d4
114                         ];
115                         for i in 0..lens.len() {
116                                 $output[i*4..(i+1)*4].copy_from_slice(&lens[i].to_le_bytes());
117                         }
118                 }}
119         }
120
121         macro_rules! round{
122                 ($state: expr) => {{
123                         $state.a = $state.a + $state.b;
124                         rotate!($state.d, $state.a, 16);
125                         $state.c = $state.c + $state.d;
126                         rotate!($state.b, $state.c, 12);
127                         $state.a = $state.a + $state.b;
128                         rotate!($state.d, $state.a, 8);
129                         $state.c = $state.c + $state.d;
130                         rotate!($state.b, $state.c, 7);
131                 }}
132         }
133
134         macro_rules! rotate {
135                 ($a: expr, $b: expr, $rot: expr) => {{
136                         let v = $a ^ $b;
137                         let r = 32 - $rot;
138                         let right = v >> r;
139                         $a = (v << $rot) ^ right
140                 }}
141         }
142
143         impl ChaCha20 {
144                 pub fn new(key: &[u8], nonce: &[u8]) -> ChaCha20 {
145                         assert!(key.len() == 16 || key.len() == 32);
146                         assert!(nonce.len() == 8 || nonce.len() == 12);
147
148                         ChaCha20{ state: ChaCha20::expand(key, nonce), output: [0u8; BLOCK_SIZE], offset: 64 }
149                 }
150
151                 /// Get one block from a ChaCha stream.
152                 pub fn get_single_block(key: &[u8; 32], nonce: &[u8; 16]) -> [u8; 32] {
153                         let mut chacha = ChaCha20 { state: ChaCha20::expand(key, nonce), output: [0u8; BLOCK_SIZE], offset: 64 };
154                         let mut chacha_bytes = [0; 32];
155                         chacha.process_in_place(&mut chacha_bytes);
156                         chacha_bytes
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 core::iter::repeat;
338
339         use crate::prelude::*;
340
341         use super::ChaCha20;
342
343         #[test]
344         fn test_chacha20_256_tls_vectors() {
345                 struct TestVector {
346                         key:   [u8; 32],
347                         nonce: [u8; 8],
348                         keystream: Vec<u8>,
349                 }
350                 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
351                 let test_vectors = vec!(
352                         TestVector{
353                                 key: [
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,
358                                 ],
359                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
360                                 keystream: vec!(
361                                         0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
362                                         0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
363                                         0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
364                                         0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
365                                         0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
366                                         0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
367                                         0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
368                                         0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
369                                 ),
370                         }, TestVector{
371                                 key: [
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, 0x01,
376                                 ],
377                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
378                                 keystream: vec!(
379                                         0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96,
380                                         0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96,
381                                         0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 0xd2, 0x60,
382                                         0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41,
383                                         0xbb, 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2,
384                                         0xa5, 0xd1, 0xe7, 0xe2, 0x0d, 0x42, 0xaf, 0x2c,
385                                         0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 0x81,
386                                         0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63,
387                                 ),
388                         }, TestVector{
389                                 key: [
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,
394                                 ],
395                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
396                                 keystream: vec!(
397                                         0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5,
398                                         0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a,
399                                         0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13,
400                                         0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31,
401                                         0xe8, 0x5a, 0x05, 0x02, 0x78, 0xa7, 0x08, 0x45,
402                                         0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b,
403                                         0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e,
404                                         0x44, 0x5f, 0x41, 0xe3,
405                                 ),
406                         }, TestVector{
407                                 key: [
408                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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                                 ],
413                                 nonce: [ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
414                                 keystream: vec!(
415                                         0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
416                                         0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
417                                         0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
418                                         0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
419                                         0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
420                                         0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
421                                         0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
422                                         0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
423                                 ),
424                         }, TestVector{
425                                 key: [
426                                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
427                                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
428                                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
429                                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
430                                 ],
431                                 nonce: [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
432                                 keystream: vec!(
433                                         0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69,
434                                         0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75,
435                                         0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93,
436                                         0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1,
437                                         0x34, 0xa4, 0x54, 0x7b, 0x73, 0x3b, 0x46, 0x41,
438                                         0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69,
439                                         0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1,
440                                         0x59, 0x16, 0x15, 0x5c, 0x2b, 0xe8, 0x24, 0x1a,
441                                         0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94,
442                                         0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66,
443                                         0x89, 0xde, 0x95, 0x26, 0x49, 0x86, 0xd9, 0x58,
444                                         0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd,
445                                         0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56,
446                                         0x3e, 0xb9, 0xb3, 0xa4, 0xa4, 0x72, 0xf8, 0x2e,
447                                         0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e,
448                                         0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7,
449                                         0x9d, 0xb9, 0xd4, 0xf7, 0xc7, 0xa8, 0x99, 0x15,
450                                         0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3,
451                                         0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a,
452                                         0x97, 0xa5, 0xf5, 0x76, 0xfe, 0x06, 0x40, 0x25,
453                                         0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5,
454                                         0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69,
455                                         0x59, 0x66, 0x09, 0x96, 0x54, 0x6c, 0xc9, 0xc4,
456                                         0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7,
457                                         0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79,
458                                         0xe5, 0xc5, 0x36, 0x0c, 0x33, 0x17, 0x16, 0x6a,
459                                         0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a,
460                                         0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2,
461                                         0xcc, 0xb2, 0x7d, 0x5a, 0xaa, 0xe0, 0xad, 0x7a,
462                                         0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09,
463                                         0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a,
464                                         0x6d, 0xeb, 0x3a, 0xb7, 0x8f, 0xab, 0x78, 0xc9,
465                                 ),
466                         },
467                 );
468
469                 for tv in test_vectors.iter() {
470                         let mut c = ChaCha20::new(&tv.key, &tv.nonce);
471                         let input: Vec<u8> = repeat(0).take(tv.keystream.len()).collect();
472                         let mut output: Vec<u8> = repeat(0).take(input.len()).collect();
473                         c.process(&input[..], &mut output[..]);
474                         assert_eq!(output, tv.keystream);
475                 }
476         }
477
478         #[test]
479         fn test_chacha20_256_tls_vectors_96_nonce() {
480                 struct TestVector {
481                         key:   [u8; 32],
482                         nonce: [u8; 12],
483                         keystream: Vec<u8>,
484                 }
485                 // taken from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
486                 let test_vectors = vec!(
487                         TestVector{
488                                 key: [
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,
493                                 ],
494                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
495                                 keystream: vec!(
496                                         0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
497                                         0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
498                                         0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
499                                         0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
500                                         0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
501                                         0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
502                                         0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
503                                         0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
504                                 ),
505                         }, TestVector{
506                                 key: [
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, 0x01,
511                                 ],
512                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
513                                 keystream: vec!(
514                                         0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96,
515                                         0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96,
516                                         0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 0xd2, 0x60,
517                                         0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41,
518                                         0xbb, 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2,
519                                         0xa5, 0xd1, 0xe7, 0xe2, 0x0d, 0x42, 0xaf, 0x2c,
520                                         0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 0x81,
521                                         0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63,
522                                 ),
523                         }, TestVector{
524                                 key: [
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,
529                                 ],
530                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ],
531                                 keystream: vec!(
532                                         0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5,
533                                         0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a,
534                                         0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13,
535                                         0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31,
536                                         0xe8, 0x5a, 0x05, 0x02, 0x78, 0xa7, 0x08, 0x45,
537                                         0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b,
538                                         0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e,
539                                         0x44, 0x5f, 0x41, 0xe3,
540                                 ),
541                         }, TestVector{
542                                 key: [
543                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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                                 ],
548                                 nonce: [ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
549                                 keystream: vec!(
550                                         0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
551                                         0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
552                                         0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
553                                         0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
554                                         0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
555                                         0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
556                                         0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
557                                         0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
558                                 ),
559                         }, TestVector{
560                                 key: [
561                                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
562                                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
563                                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
564                                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
565                                 ],
566                                 nonce: [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ],
567                                 keystream: vec!(
568                                         0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69,
569                                         0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75,
570                                         0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93,
571                                         0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1,
572                                         0x34, 0xa4, 0x54, 0x7b, 0x73, 0x3b, 0x46, 0x41,
573                                         0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69,
574                                         0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1,
575                                         0x59, 0x16, 0x15, 0x5c, 0x2b, 0xe8, 0x24, 0x1a,
576                                         0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94,
577                                         0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66,
578                                         0x89, 0xde, 0x95, 0x26, 0x49, 0x86, 0xd9, 0x58,
579                                         0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd,
580                                         0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56,
581                                         0x3e, 0xb9, 0xb3, 0xa4, 0xa4, 0x72, 0xf8, 0x2e,
582                                         0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e,
583                                         0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7,
584                                         0x9d, 0xb9, 0xd4, 0xf7, 0xc7, 0xa8, 0x99, 0x15,
585                                         0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3,
586                                         0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a,
587                                         0x97, 0xa5, 0xf5, 0x76, 0xfe, 0x06, 0x40, 0x25,
588                                         0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5,
589                                         0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69,
590                                         0x59, 0x66, 0x09, 0x96, 0x54, 0x6c, 0xc9, 0xc4,
591                                         0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7,
592                                         0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79,
593                                         0xe5, 0xc5, 0x36, 0x0c, 0x33, 0x17, 0x16, 0x6a,
594                                         0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a,
595                                         0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2,
596                                         0xcc, 0xb2, 0x7d, 0x5a, 0xaa, 0xe0, 0xad, 0x7a,
597                                         0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09,
598                                         0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a,
599                                         0x6d, 0xeb, 0x3a, 0xb7, 0x8f, 0xab, 0x78, 0xc9,
600                                 ),
601                         },
602                 );
603
604                 for tv in test_vectors.iter() {
605                         let mut c = ChaCha20::new(&tv.key, &tv.nonce);
606                         let input: Vec<u8> = repeat(0).take(tv.keystream.len()).collect();
607                         let mut output: Vec<u8> = repeat(0).take(input.len()).collect();
608                         c.process(&input[..], &mut output[..]);
609                         assert_eq!(output, tv.keystream);
610                 }
611         }
612
613         #[test]
614         fn get_single_block() {
615                 // Test that `get_single_block` (which takes a 16-byte nonce) is equivalent to getting a block
616                 // using a 12-byte nonce, with the block starting at the counter offset given by the remaining 4
617                 // bytes.
618                 let key = [
619                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
620                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
621                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
622                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
623                 ];
624                 let nonce_16bytes = [
625                         0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b
626                 ];
627                 let counter_pos = &nonce_16bytes[..4];
628                 let nonce_12bytes = &nonce_16bytes[4..];
629
630                 // Initialize a ChaCha20 instance with its counter starting at 0.
631                 let mut chacha20 = ChaCha20::new(&key, nonce_12bytes);
632                 // Seek its counter to the block at counter_pos.
633                 chacha20.seek_to_block(u32::from_le_bytes(counter_pos.try_into().unwrap()));
634                 let mut block_bytes = [0; 32];
635                 chacha20.process_in_place(&mut block_bytes);
636
637                 assert_eq!(ChaCha20::get_single_block(&key, &nonce_16bytes), block_bytes);
638         }
639
640         #[test]
641         fn encrypt_single_block() {
642                 let key = [
643                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
644                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
645                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
646                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
647                 ];
648                 let nonce = [
649                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
650                         0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
651                 ];
652                 let bytes = [1; 32];
653
654                 let mut encrypted_bytes = [0; 32];
655                 ChaCha20::encrypt_single_block(&key, &nonce, &mut encrypted_bytes, &bytes);
656
657                 let mut decrypted_bytes = [0; 32];
658                 ChaCha20::encrypt_single_block(&key, &nonce, &mut decrypted_bytes, &encrypted_bytes);
659
660                 assert_eq!(bytes, decrypted_bytes);
661         }
662
663         #[test]
664         fn encrypt_single_block_in_place() {
665                 let key = [
666                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
667                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
668                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
669                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
670                 ];
671                 let nonce = [
672                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
673                         0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
674                 ];
675                 let unencrypted_bytes = [1; 32];
676                 let mut bytes = unencrypted_bytes;
677
678                 ChaCha20::encrypt_single_block_in_place(&key, &nonce, &mut bytes);
679                 assert_ne!(bytes, unencrypted_bytes);
680
681                 ChaCha20::encrypt_single_block_in_place(&key, &nonce, &mut bytes);
682                 assert_eq!(bytes, unencrypted_bytes);
683         }
684 }