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