1use futures::{AsyncWrite, io::{self, AsyncRead, AsyncReadExt, AsyncWriteExt}};
2use std::{pin::Pin, task::{Context, Poll}};
3
4fn cha_cha_quarter_round(
5 state: &mut [u32; 16],
6 a_index: usize,
7 b_index: usize,
8 c_index: usize,
9 d_index: usize,
10) {
11 let mut a = state[a_index];
12 let mut b = state[b_index];
13 let mut c = state[c_index];
14 let mut d = state[d_index];
15
16 a = a.wrapping_add(b);
17 d = d ^ a;
18 d = d.rotate_left(16);
19
20 c = c.wrapping_add(d);
21 b = b ^ c;
22 b = b.rotate_left(12);
23
24 a = a.wrapping_add(b);
25 d = d ^ a;
26 d = d.rotate_left(8);
27
28 c = c.wrapping_add(d);
29 b = b ^ c;
30 b = b.rotate_left(7);
31
32 state[a_index] = a;
33 state[b_index] = b;
34 state[c_index] = c;
35 state[d_index] = d;
36}
37
38fn cha_cha_20_block(key: &[u8; 32], counter: u32, nonce: &[u8; 12]) -> [u8; 64] {
39 let mut key_words = [0u32; 8];
40 for i in 0..8 {
41 key_words[i] = u32::from_le_bytes([
42 key[4*i],
43 key[4*i + 1],
44 key[4*i + 2],
45 key[4*i + 3],
46 ]);
47 }
48
49 let mut nonce_words = [0u32; 3];
50 for i in 0..3 {
51 nonce_words[i] = u32::from_le_bytes([
52 nonce[4*i],
53 nonce[4*i + 1],
54 nonce[4*i + 2],
55 nonce[4*i + 3],
56 ]);
57 }
58
59 let [k0,k1,k2,k3,k4,k5,k6,k7] = key_words;
60 let [n0,n1,n2] = nonce_words;
61
62 let mut state: [u32; 16] = [
63 0x6170_7865, 0x3320_646e, 0x7962_2d32, 0x6b20_6574,
64 k0, k1, k2, k3, k4, k5, k6, k7,
65 counter,
66 n0, n1, n2,
67 ];
68
69 let mut working_state = state;
70
71 for _ in 0..10 {
72 cha_cha_quarter_round(&mut working_state, 0, 4, 8, 12);
73 cha_cha_quarter_round(&mut working_state, 1, 5, 9, 13);
74 cha_cha_quarter_round(&mut working_state, 2, 6, 10, 14);
75 cha_cha_quarter_round(&mut working_state, 3, 7, 11, 15);
76
77 cha_cha_quarter_round(&mut working_state, 0, 5, 10, 15);
78 cha_cha_quarter_round(&mut working_state, 1, 6, 11, 12);
79 cha_cha_quarter_round(&mut working_state, 2, 7, 8, 13);
80 cha_cha_quarter_round(&mut working_state, 3, 4, 9, 14);
81 }
82
83 for i in 0..16 {
84 state[i] = state[i].wrapping_add(working_state[i]);
85 }
86
87 let mut out = [0u8; 64];
88 for (i, word) in state.iter().enumerate() {
89 out[4*i..4*i+4].copy_from_slice(&word.to_le_bytes());
90 }
91 out
92}
93
94pub async fn cha_cha_20_encrypt<R, W>(
95 key: &[u8; 32],
96 mut counter: u32,
97 nonce: &[u8; 12],
98 mut reader: R,
99 mut writer: W,
100) -> io::Result<()>
101 where
102 R: AsyncRead + Unpin,
103 W: AsyncWrite + Unpin
104{
105 let mut buf = [0u8; 4096];
106 let mut block_off = 0usize;
107 let mut keystream = [0u8; 64];
108
109 loop {
110 let n = reader.read(&mut buf).await?;
111 if n == 0 { break; }
112
113 let mut i = 0;
114 while i < n {
115 if block_off == 0 {
116 keystream = cha_cha_20_block(key, counter, nonce);
117 }
118 let take = core::cmp::min(64 - block_off, n - i);
119 for j in 0..take {
120 buf[i + j] ^= keystream[block_off + j];
121 }
122 i += take;
123 block_off += take;
124 if block_off == 64 {
125 block_off = 0;
126 counter = counter.wrapping_add(1);
127 }
128 }
129 writer.write_all(&buf[..n]).await?;
130 }
131 writer.flush().await?;
132 Ok(())
133}
134
135
136#[derive(Clone, Copy)]
137struct Poly1305 {
138 accumulator: [u32; 5],
139 r: [u32; 4],
140 s: [u32; 4],
141 buffer: [u8; 16],
142 buffer_len: usize,
143}
144
145impl Poly1305 {
146 pub fn new(key: &[u8; 32]) -> Self {
147 let mut r = [0u32; 4];
148 let mut s = [0u32; 4];
149 for i in 0..4 {
150 let j = 4 * i;
151 r[i] = u32::from_le_bytes([key[j], key[j + 1], key[j + 2], key[j + 3]]);
152 s[i] = u32::from_le_bytes([
153 key[16 + j],
154 key[16 + j + 1],
155 key[16 + j + 2],
156 key[16 + j + 3],
157 ]);
158 }
159 r[0] &= 0x0fffffff;
160 r[1] &= 0x0ffffffc;
161 r[2] &= 0x0ffffffc;
162 r[3] &= 0x0ffffffc;
163
164 Self {
165 accumulator: [0; 5],
166 r,
167 s,
168 buffer: [0; 16],
169 buffer_len: 0,
170 }
171 }
172
173 pub fn update(&mut self, mut data: &[u8]) {
174 while !data.is_empty() {
175 let to_copy = std::cmp::min(16 - self.buffer_len, data.len());
176 self.buffer[self.buffer_len..self.buffer_len + to_copy]
177 .copy_from_slice(&data[0..to_copy]);
178 self.buffer_len += to_copy;
179 data = &data[to_copy..];
180
181 if self.buffer_len == 16 {
182 let mut block = [0u32; 4];
183 for i in 0..4 {
184 let j = 4 * i;
185 block[i] = u32::from_le_bytes([
186 self.buffer[j],
187 self.buffer[j + 1],
188 self.buffer[j + 2],
189 self.buffer[j + 3],
190 ]);
191 }
192 let extended_block = [block[0], block[1], block[2], block[3], 1];
193 self.accumulator = poly1305_add(self.accumulator, extended_block);
194 poly1305_mul(&mut self.accumulator, self.r);
195 self.buffer_len = 0;
196 }
197 }
198 }
199
200 pub fn finalize(mut self) -> [u8; 16] {
201 if self.buffer_len > 0 {
202 self.buffer[self.buffer_len] = 1;
203 for i in self.buffer_len + 1..16 {
204 self.buffer[i] = 0;
205 }
206 let mut block = [0u32; 4];
207 for i in 0..4 {
208 let j = 4 * i;
209 block[i] = u32::from_le_bytes([
210 self.buffer[j],
211 self.buffer[j + 1],
212 self.buffer[j + 2],
213 self.buffer[j + 3],
214 ]);
215 }
216 let extended_block = [block[0], block[1], block[2], block[3], 0];
217 self.accumulator = poly1305_add(self.accumulator, extended_block);
218 poly1305_mul(&mut self.accumulator, self.r);
219 }
220 self.accumulator = poly1305_mod(self.accumulator);
221 let extended_s = [self.s[0], self.s[1], self.s[2], self.s[3], 0];
222 self.accumulator = poly1305_add(self.accumulator, extended_s);
223 let mut out = [0u8; 16];
224 for (i, limb) in self.accumulator[..4].iter().enumerate() {
225 out[4 * i..4 * i + 4].copy_from_slice(&limb.to_le_bytes());
226 }
227 out
228 }
229}
230
231pub async fn poly1305_mac_async<R: AsyncRead + Unpin>(
232 key: &[u8; 32],
233 mut reader: R,
234) -> io::Result<[u8; 16]> {
235 let mut state = Poly1305::new(key);
236 let mut buf = [0u8; 1024];
237 loop {
238 let n = reader.read(&mut buf).await?;
239 if n == 0 {
240 break;
241 }
242 state.update(&buf[0..n]);
243 }
244 Ok(state.finalize())
245}
246
247fn poly1305_mul(h: &mut [u32; 5], r: [u32; 4]) {
249 let r0: u64 = r[0] as u64;
251 let r1: u64 = r[1] as u64;
252 let r2: u64 = r[2] as u64;
253 let r3: u64 = r[3] as u64;
254
255 let h0: u64 = h[0] as u64;
256 let h1: u64 = h[1] as u64;
257 let h2: u64 = h[2] as u64;
258 let h3: u64 = h[3] as u64;
259 let h4: u64 = h[4] as u64;
260
261 let rr0 = (r0 >> 2) * 5; let rr1 = (r1 >> 2) * 5; let rr2 = (r2 >> 2) * 5; let rr3 = (r3 >> 2) * 5; let x0: u64 = h0 * r0 + h1 * rr3 + h2 * rr2 + h3 * rr1 + h4 * rr0;
268 let x1 = h0 * r1 + h1 * r0 + h2 * rr3 + h3 * rr2 + h4 * rr1;
269 let x2 = h0 * r2 + h1 * r1 + h2 * r0 + h3 * rr3 + h4 * rr2;
270 let x3 = h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * rr3;
271 let x4 = h4 * (r0 & 3); let msb: u64 = x4 + (x3 >> 32);
275 let mut u = (msb >> 2) * 5; u += x0 & 0xffffffff;
277 h[0] = (u & 0xffffffff) as u32;
278 u >>= 32;
279 u += (x1 & 0xffffffff) + (x0 >> 32);
280 h[1] = (u & 0xffffffff) as u32;
281 u >>= 32;
282 u += (x2 & 0xffffffff) + (x1 >> 32);
283 h[2] = (u & 0xffffffff) as u32;
284 u >>= 32;
285 u += (x3 & 0xffffffff) + (x2 >> 32);
286 h[3] = (u & 0xffffffff) as u32;
287 u >>= 32;
288 u += msb & 3 ;
289 h[4] = u as u32;
290}
291
292fn poly1305_add(a: [u32; 5], b: [u32; 5]) -> [u32; 5] {
293 let mut temp: u64 = 0;
294 let mut result: [u32; 5] = Default::default();
295
296 for i in 0..5 {
298 temp += a[i] as u64 + b[i] as u64;
299 result[i] = temp as u32;
300 temp >>= 32;
301 }
302
303 result
304}
305
306fn poly1305_mod(a: [u32; 5]) -> [u32; 5] {
307 if a[4] < 3 {
308 return a;
309 }
310
311 let low_p = 0xfffffffffffffffffffffffffffffffbu128;
312 let low_a: u128 =
313 a[0] as u128
314 | ((a[1] as u128) << 32)
315 | ((a[2] as u128) << 64)
316 | ((a[3] as u128) << 96);
317 if a[4] == 3 && low_p > low_a {
318 return a;
319 }
320 if a[4] == 3 && low_p == low_a {
321 return [0, 0, 0, 0, 0];
322 }
323
324 let mut hi_a = a[4];
325 let low_result = if low_a >= low_p {
326 low_a - low_p
327 } else {
328 hi_a -= 1;
329 !low_p + 1 + low_a
330 };
331
332 let bytes = low_result.to_le_bytes();
333 let low_result = [
334 u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]),
335 u32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]),
336 u32::from_le_bytes([bytes[8], bytes[9], bytes[10], bytes[11]]),
337 u32::from_le_bytes([bytes[12], bytes[13], bytes[14], bytes[15]]),
338 ];
339 [
340 low_result[0],
341 low_result[1],
342 low_result[2],
343 low_result[3],
344 hi_a - 3,
345 ]
346}
347
348pub fn poly1305_key_gen(key: &[u8; 32], nonce: &[u8; 12]) -> [u8; 32] {
349 let counter = 0;
350 let block = &cha_cha_20_block(key, counter, nonce)[..32];
351 let mut result: [u8; 32] = [0; 32];
352 result.copy_from_slice(block);
353 result
354}
355
356struct TeeReader<'a, R: AsyncRead + Unpin> {
357 reader: R,
358 poly: &'a mut Poly1305,
359 cipher_len: u64,
360}
361
362impl<'a, R: AsyncRead + Unpin> TeeReader<'a, R> {
363 fn new(reader: R, poly: &'a mut Poly1305) -> Self {
364 Self {
365 reader,
366 poly,
367 cipher_len: 0,
368 }
369 }
370}
371
372impl<'a, R: AsyncRead + Unpin> AsyncRead for TeeReader<'a, R> {
373 fn poll_read(
374 mut self: Pin<&mut Self>,
375 cx: &mut Context<'_>,
376 buf: &mut [u8],
377 ) -> Poll<io::Result<usize>> {
378 let n = futures::ready!(Pin::new(&mut self.reader).poll_read(cx, buf))?;
379 if n > 0 {
380 self.poly.update(&buf[..n]);
381 self.cipher_len += n as u64;
382 }
383 Poll::Ready(Ok(n))
384 }
385}
386
387struct TeeWriter<'a, W: AsyncWrite + Unpin> {
388 writer: W,
389 poly: &'a mut Poly1305,
390 cipher_len: u64,
391}
392
393impl<'a, W: AsyncWrite + Unpin> TeeWriter<'a, W> {
394 fn new(writer: W, poly: &'a mut Poly1305) -> Self {
395 Self {
396 writer,
397 poly,
398 cipher_len: 0,
399 }
400 }
401}
402
403impl<'a, W: AsyncWrite + Unpin> AsyncWrite for TeeWriter<'a, W> {
404 fn poll_write(
405 mut self: Pin<&mut Self>,
406 cx: &mut Context<'_>,
407 buf: &[u8],
408 ) -> Poll<io::Result<usize>> {
409 let n = futures::ready!(Pin::new(&mut self.writer).poll_write(cx, buf))?;
410 self.poly.update(&buf[..n]);
411 self.cipher_len += n as u64;
412 Poll::Ready(Ok(n))
413 }
414
415 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
416 Pin::new(&mut self.writer).poll_flush(cx)
417 }
418
419 fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
420 Pin::new(&mut self.writer).poll_close(cx)
421 }
422}
423
424
425pub async fn cha_cha_20_aead_encrypt<R: AsyncRead + Unpin, W: AsyncWrite + Unpin>(
426 aad: &[u8],
427 key: &[u8; 32],
428 nonce: [u8; 12],
429 reader: R,
430 mut writer: W,
431) -> io::Result<[u8; 16]> {
432 let otk = poly1305_key_gen(key, &nonce);
433 let mut poly = Poly1305::new(&otk);
434
435 poly.update(aad);
436 let aad_pad = (16 - aad.len() % 16) % 16;
437 if aad_pad > 0 {
438 let zero_pad = [0u8; 16];
439 poly.update(&zero_pad[..aad_pad]);
440 }
441
442 let mut tee_writer = TeeWriter::new(&mut writer, &mut poly);
443 cha_cha_20_encrypt(key, 1u32, &nonce, reader, &mut tee_writer).await?;
444
445 let cipher_len = tee_writer.cipher_len;
446 let cipher_pad = (16 - (cipher_len as usize % 16)) % 16;
447 tee_writer.flush().await?;
448 if cipher_pad > 0 {
449 let zero_pad = [0u8; 16];
450 poly.update(&zero_pad[..cipher_pad]);
451 }
452
453 let aad_len_bytes: [u8; 8] = (aad.len() as u64).to_le_bytes();
454 let cipher_len_bytes: [u8; 8] = cipher_len.to_le_bytes();
455 poly.update(&aad_len_bytes);
456 poly.update(&cipher_len_bytes);
457
458 let tag = poly.finalize();
459 Ok(tag)
460}
461
462pub async fn cha_cha_20_aead_decrypt_verify<R, W>(
463 aad: &[u8],
464 key: &[u8; 32],
465 nonce: [u8; 12],
466 reader: R,
467 writer: W,
468 expected_tag: [u8; 16],
469) -> io::Result<()>
470where
471 R: AsyncRead + Unpin,
472 W: AsyncWrite + Unpin
473{
474 let otk = poly1305_key_gen(key, &nonce);
475 let mut poly = Poly1305::new(&otk);
476
477 poly.update(aad);
478 let aad_pad = (16 - aad.len() % 16) % 16;
479 if aad_pad != 0 {
480 let zero_pad = [0u8; 16];
481 poly.update(&zero_pad[..aad_pad]);
482 }
483
484 let mut tee_reader = TeeReader::new(reader, &mut poly);
485 cha_cha_20_encrypt(key, 1u32, &nonce, &mut tee_reader, writer).await?;
486
487 let cipher_len = tee_reader.cipher_len;
488 let c_pad = (16 - (cipher_len as usize % 16)) % 16;
489 if c_pad != 0 {
490 let zero_pad = [0u8; 16];
491 poly.update(&zero_pad[..c_pad]);
492 }
493
494 let aad_len_le = (aad.len() as u64).to_le_bytes();
495 let c_len_le = (cipher_len as u64).to_le_bytes();
496 poly.update(&aad_len_le);
497 poly.update(&c_len_le);
498
499 let tag = poly.finalize();
500 let mut diff: u8 = 0;
501 for i in 0..16 {
502 diff |= tag[i] ^ expected_tag[i];
503 }
504 if diff != 0 {
505 return Err(io::Error::new(io::ErrorKind::InvalidData, "AEAD tag mismatch"));
506 }
507
508 Ok(())
509}
510
511
512#[cfg(test)]
513mod tests {
514 use futures::executor::block_on;
515
516 use super::*;
517
518 const PLAIN_TEXT_1:&[u8] = &[
519 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e,
520 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20,
521 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20,
522 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66,
523 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e,
524 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20,
525 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, 0x63, 0x72,
526 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
527 0x74, 0x2e
528 ];
529
530 const CIPHER_TEXT1: &[u8] = &[
531 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef,
532 0x7e, 0xc2, 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, 0xa9, 0xe2, 0xb5, 0xa7,
533 0x36, 0xee, 0x62, 0xd6, 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, 0x82, 0xfa,
534 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b, 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29,
535 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36, 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77,
536 0x8b, 0x8c, 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, 0xfa, 0xb3, 0x24, 0xe4,
537 0xfa, 0xd6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc, 0x3f, 0xf4,
538 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b,
539 0x61, 0x16,
540 ];
541
542 const AAD1: [u8; 12] = [
543 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
544 ];
545
546 const KEY1: [u8; 32] = [
547 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d,
548 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
549 0x9c, 0x9d, 0x9e, 0x9f,
550 ];
551
552 const IV1: [u8; 8] = [0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47];
553 const TAG1: [u8; 16] = [
554 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60,
555 0x06, 0x91,
556 ];
557
558
559 #[test]
560 fn test_cha_cha_quarter_round() {
561 let mut state: [u32; 16] = [
562 0x879531e0, 0xc5ecf37d, 0x516461b1, 0xc9a62f8a, 0x44c20ef3, 0x3390af7f, 0xd9fc690b,
563 0x2a5f714c, 0x53372767, 0xb00a5631, 0x974c541a, 0x359e9963, 0x5c971061, 0x3d631689,
564 0x2098d9d6, 0x91dbd320,
565 ];
566
567 cha_cha_quarter_round(&mut state, 2, 7, 8, 13);
568
569 assert_eq!(
570 state,
571 [
572 0x879531e0, 0xc5ecf37d, 0xbdb886dc, 0xc9a62f8a, 0x44c20ef3, 0x3390af7f, 0xd9fc690b,
573 0xcfacafd2, 0xe46bea80, 0xb00a5631, 0x974c541a, 0x359e9963, 0x5c971061, 0xccc07c79,
574 0x2098d9d6, 0x91dbd320
575 ]
576 );
577 }
578
579 #[test]
580 fn test_cha_cha_20_block() {
581 let key: [u8; 32] = [
582 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
583 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
584 0x1f,
585 ];
586 let nonce: [u8; 12] = [0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0];
587
588 let state: &[u8] = &cha_cha_20_block(&key, 1u32, &nonce);
589 let expected: &[u8] = &[
590 0x10u8, 0xf1, 0xe7, 0xe4, 0xd1, 0x3b, 0x59, 0x15, 0x50, 0x0f, 0xdd, 0x1f, 0xa3, 0x20,
591 0x71, 0xc4, 0xc7u8, 0xd1, 0xf4, 0xc7, 0x33, 0xc0, 0x68, 0x03, 0x04, 0x22, 0xaa, 0x9a,
592 0xc3, 0xd4, 0x6c, 0x4e, 0xd2u8, 0x82, 0x64, 0x46, 0x07, 0x9f, 0xaa, 0x09, 0x14, 0xc2,
593 0xd7, 0x05, 0xd9, 0x8b, 0x02, 0xa2, 0xb5u8, 0x12, 0x9c, 0xd1, 0xde, 0x16, 0x4e, 0xb9,
594 0xcb, 0xd0, 0x83, 0xe8, 0xa2, 0x50, 0x3c, 0x4e,
595 ];
596
597 assert_eq!(state, expected);
598 }
599
600 #[test]
601 fn test_cha_cha_20_encrypt() {
602 let key: [u8; 32] = [
603 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
604 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
605 0x1f,
606 ];
607 let nonce: [u8; 12] = [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0];
608
609 let mut cipher_text = vec![];
610 block_on(
611 cha_cha_20_encrypt(&key, 1, &nonce, PLAIN_TEXT_1, &mut cipher_text)
612 ).unwrap();
613 let expected: &[u8] = &[
614 0x6e, 0x2e, 0x35, 0x9a, 0x25, 0x68, 0xf9, 0x80, 0x41, 0xba, 0x07, 0x28, 0xdd, 0x0d,
615 0x69, 0x81, 0xe9, 0x7e, 0x7a, 0xec, 0x1d, 0x43, 0x60, 0xc2, 0x0a, 0x27, 0xaf, 0xcc,
616 0xfd, 0x9f, 0xae, 0x0b, 0xf9, 0x1b, 0x65, 0xc5, 0x52, 0x47, 0x33, 0xab, 0x8f, 0x59,
617 0x3d, 0xab, 0xcd, 0x62, 0xb3, 0x57, 0x16, 0x39, 0xd6, 0x24, 0xe6, 0x51, 0x52, 0xab,
618 0x8f, 0x53, 0x0c, 0x35, 0x9f, 0x08, 0x61, 0xd8, 0x07, 0xca, 0x0d, 0xbf, 0x50, 0x0d,
619 0x6a, 0x61, 0x56, 0xa3, 0x8e, 0x08, 0x8a, 0x22, 0xb6, 0x5e, 0x52, 0xbc, 0x51, 0x4d,
620 0x16, 0xcc, 0xf8, 0x06, 0x81, 0x8c, 0xe9, 0x1a, 0xb7, 0x79, 0x37, 0x36, 0x5a, 0xf9,
621 0x0b, 0xbf, 0x74, 0xa3, 0x5b, 0xe6, 0xb4, 0x0b, 0x8e, 0xed, 0xf2, 0x78, 0x5e, 0x42,
622 0x87, 0x4d,
623 ];
624
625 assert_eq!(&cipher_text, expected);
626 }
627
628 #[test]
629 fn test_poly1305_mac() {
630 let key_material: [u8; 32] = [
631 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33, 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5,
632 0x06, 0xa8, 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd, 0x4a, 0xbf, 0xf6, 0xaf,
633 0x41, 0x49, 0xf5, 0x1b,
634 ];
635 let message:&[u8] = &[
636 0x43u8, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x20,
637 0x46, 0x6f, 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68,
638 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70,
639 ];
640
641 let tag = block_on(
642 poly1305_mac_async(&key_material, message)
643 ).unwrap();
644 let expected: &[u8] = &[
645 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6, 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01,
646 0x27, 0xa9,
647 ];
648
649 assert_eq!(tag, expected);
650 }
651
652 #[test]
653 fn test_poly1305_key_generation() {
654 let nonce: [u8; 12] = [
655 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
656 ];
657 let result: [u8; 32] = poly1305_key_gen(&KEY1, &nonce);
658 let expected: [u8; 32] = [
659 0x8a, 0xd5, 0xa0, 0x8b, 0x90, 0x5f, 0x81, 0xcc, 0x81, 0x50, 0x40, 0x27, 0x4a, 0xb2,
660 0x94, 0x71, 0xa8, 0x33, 0xb6, 0x37, 0xe3, 0xfd, 0x0d, 0xa5, 0x08, 0xdb, 0xb8, 0xe2,
661 0xfd, 0xd1, 0xa6, 0x46,
662 ];
663
664 assert_eq!(&result, &expected);
665 }
666
667 #[test]
668 fn test_cha_cha_20_aead_encrypt() {
669 let constant: [u8; 4] = [0x07, 0x00, 0x00, 0x00];
670 let mut constant_and_iv: [u8; 12] = [0; 12];
671 constant_and_iv[..4].copy_from_slice(&constant);
672 constant_and_iv[4..].copy_from_slice(&IV1);
673
674 let mut cipher_text = vec![];
675 let tag = block_on(
676 cha_cha_20_aead_encrypt(
677 &AAD1,
678 &KEY1,
679 constant_and_iv,
680 PLAIN_TEXT_1,
681 &mut cipher_text
682 )
683 ).unwrap();
684
685 assert_eq!(&cipher_text, CIPHER_TEXT1);
686 assert_eq!(tag, TAG1);
687 }
688
689 #[test]
690 fn test_cha_cha_20_aead_decrypt() {
691 let constant: [u8; 4] = [0x07, 0x00, 0x00, 0x00];
692 let mut constant_and_iv: [u8; 12] = [0; 12];
693 constant_and_iv[..4].copy_from_slice(&constant);
694 constant_and_iv[4..].copy_from_slice(&IV1);
695
696 let mut plain_text = vec![];
697 block_on(cha_cha_20_aead_decrypt_verify(
698 &AAD1,
699 &KEY1,
700 constant_and_iv,
701 CIPHER_TEXT1,
702 &mut plain_text,
703 TAG1
704 ))
705 .unwrap();
706
707 assert_eq!(&plain_text, PLAIN_TEXT_1);
708 }
710
711 #[test]
712 fn test_poly1305_mac_2() {
713 let otk = [
714 0xfd, 0x72, 0xb9, 0xc9, 0x9a, 0xa1, 0x50, 0x9c, 0xd4, 0x7e, 0x72, 0x27, 0x0a, 0xc2,
715 0xbf, 0x07, 0xc9, 0x21, 0x98, 0xb5, 0x77, 0xfc, 0x73, 0xaa, 0x0f, 0x36, 0x3c, 0xf6,
716 0x38, 0xd3, 0xa6, 0xd7,
717 ];
718 let message: &[u8] = &[
719 0x17, 0x03, 0x03, 0x03, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720 0x00, 0x00, 0x6e, 0xc9, 0x75, 0x08, 0x7a, 0x1a, 0x86, 0x19, 0x66, 0x0f, 0x02, 0x13,
721 0x67, 0x92, 0x64, 0x11, 0xe8, 0xbb, 0x85, 0x8f, 0xab, 0xd2, 0xad, 0xf5, 0xfe, 0xa9,
722 0xfe, 0xb5, 0x35, 0x4f, 0x81, 0xc1, 0x21, 0xe3, 0xf3, 0x02, 0xe1, 0x2a, 0xbc, 0x55,
723 0xa8, 0xd5, 0xa7, 0x08, 0xcd, 0x0e, 0xa9, 0x7d, 0x27, 0x78, 0x8b, 0xe8, 0xf3, 0x7a,
724 0x6d, 0x44, 0x8c, 0x92, 0xbc, 0x16, 0x13, 0xe5, 0x59, 0x94, 0x9a, 0xde, 0xe0, 0x14,
725 0x29, 0xd4, 0xf6, 0x44, 0x20, 0xb1, 0xa7, 0xc3, 0xb7, 0x7d, 0xa9, 0x91, 0xd5, 0x2a,
726 0xa8, 0x0f, 0x90, 0xfc, 0x38, 0x01, 0x27, 0xa4, 0x6b, 0x16, 0xdb, 0x75, 0x0b, 0x06,
727 0x7a, 0x13, 0xbb, 0xf2, 0x95, 0xbb, 0x2e, 0x07, 0x81, 0x92, 0xe1, 0x05, 0x42, 0xd6,
728 0x2e, 0xda, 0xb8, 0xb8, 0x65, 0x95, 0xc7, 0x36, 0x1e, 0x68, 0x17, 0x0c, 0xf3, 0x57,
729 0xdf, 0x2f, 0x60, 0x32, 0x36, 0xdc, 0x57, 0x98, 0x46, 0x22, 0x3c, 0x9f, 0x2d, 0xb6,
730 0xd2, 0x7c, 0xbf, 0x70, 0xe1, 0x82, 0xb5, 0x2e, 0x92, 0xb3, 0x04, 0x3d, 0x17, 0x81,
731 0xde, 0x37, 0x59, 0xa4, 0x12, 0xf2, 0x55, 0xf0, 0x95, 0x82, 0x03, 0xaa, 0x52, 0x89,
732 0xe8, 0x71, 0x70, 0xf7, 0x5a, 0x5f, 0x5c, 0x0d, 0x34, 0x52, 0xc4, 0xb4, 0x65, 0xb6,
733 0x5f, 0x99, 0xf2, 0x0e, 0x02, 0x1e, 0x24, 0xcb, 0xdc, 0x1d, 0xd2, 0xb7, 0x3c, 0x8a,
734 0x4a, 0x64, 0x3a, 0x76, 0xa8, 0x99, 0x60, 0x38, 0x78, 0x53, 0x7e, 0x85, 0xf6, 0x20,
735 0xb7, 0xf4, 0x7d, 0x0a, 0x6c, 0x9c, 0x4d, 0x18, 0xea, 0xa8, 0xdf, 0xf6, 0x18, 0x86,
736 0xab, 0x5a, 0x8a, 0x9e, 0xdf, 0x13, 0xa0, 0x14, 0x0f, 0xae, 0x33, 0x9c, 0x70, 0x0a,
737 0x68, 0x24, 0xc3, 0x34, 0x06, 0x08, 0xe4, 0xdc, 0x1d, 0xeb, 0xa9, 0x49, 0xf4, 0x72,
738 0x9f, 0xd5, 0x4c, 0xaa, 0xa8, 0xf7, 0xc2, 0x3f, 0xf0, 0xd8, 0x0e, 0xe9, 0x1e, 0xb1,
739 0x21, 0x04, 0x98, 0x3e, 0x4c, 0x8e, 0xa1, 0x5c, 0x1a, 0x69, 0x8e, 0x7a, 0x6c, 0x06,
740 0xaa, 0x43, 0xbd, 0x5f, 0x56, 0x24, 0x98, 0xd7, 0x12, 0xd3, 0x1c, 0x2e, 0x6c, 0xd9,
741 0x35, 0x25, 0x28, 0x51, 0xae, 0x4d, 0x62, 0x83, 0xb4, 0x69, 0x36, 0x31, 0xde, 0x8e,
742 0x92, 0x91, 0xc8, 0xd6, 0x28, 0xad, 0x2e, 0x57, 0xe5, 0x74, 0x99, 0x30, 0xc6, 0x30,
743 0x35, 0x55, 0x72, 0x7f, 0x0c, 0xed, 0x5b, 0x75, 0x68, 0x75, 0x51, 0xf8, 0x52, 0x52,
744 0xeb, 0xc2, 0xcc, 0xd7, 0x38, 0xad, 0x3c, 0xb6, 0x23, 0x76, 0xf8, 0xd0, 0x37, 0xb7,
745 0x73, 0x79, 0x07, 0x8a, 0x4a, 0x3e, 0x81, 0xce, 0xfc, 0x44, 0x9b, 0xbc, 0x0c, 0xf4,
746 0x7f, 0x51, 0xae, 0x3b, 0x6a, 0xe5, 0x0d, 0x3c, 0x58, 0xf8, 0xbd, 0x98, 0x98, 0xa2,
747 0xc9, 0x99, 0x44, 0x54, 0x3b, 0x1c, 0x4c, 0x7f, 0x7e, 0xba, 0x85, 0x31, 0x0f, 0x60,
748 0x72, 0xdf, 0x70, 0x7d, 0xf1, 0x2b, 0xe4, 0xdd, 0x76, 0x27, 0x7d, 0x26, 0x58, 0xe8,
749 0x50, 0x3b, 0x24, 0xd2, 0xce, 0xf3, 0xb7, 0x34, 0x93, 0xe6, 0xcd, 0x13, 0x82, 0x29,
750 0xa6, 0x96, 0x01, 0xaf, 0xa9, 0xa8, 0xbf, 0x46, 0x65, 0xbb, 0x24, 0x2b, 0x3b, 0x89,
751 0x1d, 0xfd, 0x4b, 0x90, 0x93, 0xf6, 0x00, 0xb0, 0x1f, 0x6d, 0x99, 0xdd, 0xb0, 0xc1,
752 0x92, 0x75, 0x3a, 0xa6, 0xcd, 0x42, 0xaa, 0x38, 0x5d, 0xe6, 0x5d, 0xbd, 0x5d, 0x92,
753 0x4f, 0x4b, 0x3c, 0x33, 0x7a, 0x6f, 0xc3, 0xc9, 0xc7, 0x06, 0x86, 0x4a, 0x5c, 0xe2,
754 0xbe, 0xeb, 0x63, 0xf9, 0x16, 0x43, 0xd0, 0x56, 0xcc, 0x3e, 0xc5, 0xa5, 0x78, 0xca,
755 0xd6, 0x0d, 0xd5, 0x78, 0xac, 0x5a, 0xea, 0x09, 0x68, 0xe9, 0x5a, 0x16, 0x3c, 0x83,
756 0xf1, 0xbb, 0x34, 0x72, 0xc3, 0x85, 0xf2, 0x51, 0x64, 0x08, 0x74, 0x58, 0xc5, 0xc2,
757 0xf1, 0xfc, 0x48, 0x55, 0x83, 0x8d, 0x87, 0x87, 0xf6, 0x0c, 0x35, 0xc4, 0x43, 0xe4,
758 0x98, 0xdf, 0x63, 0x5f, 0xce, 0x8e, 0xac, 0x67, 0x65, 0x1c, 0xc2, 0xd8, 0xac, 0xb0,
759 0xd9, 0xa2, 0xf5, 0xfd, 0x2f, 0xb5, 0xf2, 0xe5, 0x7e, 0x90, 0xc9, 0x5f, 0x8e, 0x76,
760 0x48, 0x89, 0xb1, 0x30, 0x83, 0x94, 0x2f, 0x52, 0x7a, 0x00, 0x9b, 0xe0, 0xb2, 0x6c,
761 0x98, 0xe0, 0x65, 0x50, 0x7d, 0xa1, 0x00, 0xa0, 0xba, 0x9b, 0x38, 0x5d, 0xaa, 0xca,
762 0x9f, 0x57, 0x0f, 0x4f, 0x12, 0x01, 0x72, 0x87, 0xb6, 0xfb, 0xab, 0x23, 0xf1, 0x93,
763 0xe8, 0x42, 0xa1, 0xfd, 0x23, 0x64, 0xd8, 0x0b, 0xc6, 0xaf, 0x76, 0x38, 0x13, 0xe2,
764 0xe8, 0x76, 0x19, 0x5d, 0xdd, 0xe7, 0x7a, 0xe5, 0xf4, 0x5d, 0xe8, 0xf7, 0x98, 0x7b,
765 0x88, 0x1f, 0xd6, 0x12, 0x0a, 0xbc, 0xa0, 0x6a, 0x5b, 0x26, 0x9c, 0x88, 0x7f, 0x0b,
766 0xf5, 0x9f, 0x3d, 0x88, 0xf4, 0x9d, 0x5a, 0x76, 0xe9, 0x05, 0x30, 0x01, 0x27, 0x2a,
767 0x30, 0x5d, 0xf5, 0x55, 0xa1, 0x79, 0xaf, 0xa0, 0x64, 0xf6, 0xad, 0x5a, 0x89, 0x12,
768 0x56, 0xa1, 0xee, 0x33, 0x4a, 0x96, 0xb7, 0x4f, 0x43, 0xcf, 0x31, 0x00, 0xf5, 0x59,
769 0xb7, 0xef, 0xea, 0x97, 0xce, 0x77, 0x0b, 0xdf, 0x11, 0xe3, 0xc2, 0xf4, 0x0f, 0x36,
770 0xc0, 0xbf, 0xf2, 0x44, 0x69, 0x88, 0x82, 0x11, 0xac, 0xe0, 0x79, 0x82, 0x6e, 0x17,
771 0xef, 0x72, 0x39, 0x08, 0xa4, 0xd9, 0x5a, 0x17, 0x29, 0x6f, 0xcb, 0xb0, 0x66, 0x51,
772 0xd8, 0xe8, 0xa4, 0x29, 0xe1, 0x6c, 0x05, 0x5e, 0x92, 0x2f, 0x01, 0xfd, 0x70, 0x9c,
773 0x78, 0xb2, 0xae, 0xdb, 0xb2, 0xbc, 0x1f, 0x0b, 0x75, 0x57, 0xca, 0xac, 0x87, 0x49,
774 0x26, 0x88, 0x69, 0x90, 0x89, 0xd0, 0x0a, 0x16, 0x9d, 0xae, 0xf6, 0xc7, 0xd2, 0x32,
775 0x5a, 0x96, 0x6d, 0x34, 0x54, 0xca, 0xb1, 0x09, 0x7a, 0xc2, 0xc1, 0xac, 0x17, 0x54,
776 0x8d, 0xfe, 0x33, 0xac, 0xf7, 0xe7, 0xc4, 0xc1, 0x74, 0x39, 0xc2, 0x92, 0x88, 0x26,
777 0x5e, 0x6d, 0x42, 0x6c, 0x5f, 0x7c, 0x4b, 0x1f, 0x72, 0x11, 0xbe, 0xfb, 0x36, 0xfb,
778 0x85, 0xce, 0xd2, 0x19, 0x6a, 0xe7, 0x65, 0x6e, 0x76, 0x55, 0x96, 0x5a, 0x4e, 0x9e,
779 0xdc, 0xa9, 0x60, 0x2b, 0x5c, 0x5d, 0x36, 0xca, 0xfb, 0x4f, 0x6b, 0xd9, 0x8d, 0xde,
780 0x9f, 0xe0, 0x3c, 0xc6, 0xf4, 0xe4, 0xa3, 0x2a, 0x83, 0x33, 0xd0, 0x8b, 0x90, 0xe0,
781 0x18, 0xa6, 0xa3, 0x08, 0x9b, 0x1d, 0xd2, 0x5b, 0x2d, 0x5b, 0x6b, 0xef, 0x3f, 0x7c,
782 0xec, 0xbd, 0xe9, 0x43, 0xa9, 0xc0, 0x98, 0xfc, 0x46, 0x49, 0x8e, 0x99, 0x5a, 0xc9,
783 0xa1, 0x9c, 0xdd, 0xae, 0x7a, 0xd7, 0x30, 0xed, 0xf3, 0x88, 0x47, 0xf5, 0x48, 0xde,
784 0x2e, 0x79, 0x91, 0xeb, 0x35, 0x60, 0x1e, 0x1b, 0x09, 0x45, 0xfb, 0x87, 0x67, 0xb2,
785 0x87, 0x94, 0x76, 0x72, 0x48, 0x7b, 0x3f, 0x28, 0x11, 0xdd, 0xe1, 0x07, 0x88, 0x08,
786 0x75, 0x9f, 0x17, 0x6a, 0x9f, 0xa7, 0x22, 0x63, 0x59, 0x21, 0x61, 0xaa, 0xc2, 0x10,
787 0xdf, 0x00, 0xfc, 0xef, 0xf7, 0x99, 0xc7, 0x26, 0xcc, 0x5f, 0x8a, 0x19, 0x0b, 0x4f,
788 0x6c, 0x93, 0x61, 0x87, 0x2a, 0xf2, 0x99, 0x5d, 0xc8, 0x14, 0xbd, 0xa2, 0xa5, 0x8c,
789 0x21, 0x5e, 0xc3, 0xd9, 0x08, 0xe5, 0xa3, 0x6d, 0xd0, 0x1c, 0xdf, 0xad, 0xb8, 0xc5,
790 0xd3, 0xd7, 0xa6, 0xf7, 0xc4, 0x7c, 0xd3, 0xf2, 0x3b, 0x55, 0x34, 0x63, 0x1b, 0x64,
791 0xb5, 0xf1, 0xf2, 0x73, 0x68, 0x6e, 0x99, 0x08, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00,
792 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x03, 0x00, 0x00,
793 0x00, 0x00, 0x00, 0x00,
794 ];
795 let tag = block_on(poly1305_mac_async( &otk, message)).unwrap();
796 let expected_tag = &[
797 0x45, 0x6b, 0x78, 0xfc, 0x85, 0x68, 0xbd, 0x62, 0x07, 0x1e, 0x6b, 0x32, 0x9c, 0x23,
798 0xfb, 0x50,
799 ];
800 assert_eq!(&tag as &[u8], expected_tag);
801 }
802
803 #[test]
804 fn test_poly1305_mac_3() {
805 let otk = [
806 0x50, 0xd7, 0x07, 0xbc, 0xa8, 0xe5, 0x35, 0x3d, 0x3d, 0xb1, 0x01, 0xf6, 0x78, 0x10,
807 0xb7, 0x3f, 0x7d, 0x92, 0x02, 0xd8, 0xe4, 0xbd, 0x11, 0x8f, 0xd7, 0xca, 0x44, 0x68,
808 0x54, 0x56, 0xe6, 0x6f,
809 ];
810 let message: &[u8] = &[
811 0x17, 0x03, 0x03, 0x05, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
812 0x00, 0x00, 0xde, 0x6c, 0xea, 0x98, 0x72, 0x1c, 0xb8, 0xfc, 0x60, 0xec, 0x26, 0xec,
813 0x15, 0x50, 0x27, 0x0c, 0x43, 0x29, 0x6b, 0x4c, 0x9a, 0x67, 0x9e, 0xe1, 0x7b, 0x88,
814 0xfd, 0x73, 0xae, 0xbf, 0xc8, 0x43, 0xd9, 0xcd, 0x74, 0x8c, 0x4e, 0xd2, 0xd9, 0x8d,
815 0x01, 0x18, 0x63, 0xd9, 0x36, 0xef, 0x81, 0xf6, 0x7a, 0x7e, 0xf0, 0x3a, 0x8f, 0x27,
816 0xac, 0x81, 0xf1, 0x8d, 0xee, 0xbd, 0x2c, 0xb9, 0xe7, 0x9a, 0xb0, 0x2c, 0xad, 0xe7,
817 0x98, 0x9d, 0x16, 0x9d, 0x76, 0xda, 0x78, 0xac, 0x58, 0x26, 0x0b, 0x27, 0xd5, 0x3b,
818 0x66, 0xa4, 0xab, 0x7c, 0x8d, 0x36, 0x2b, 0x9d, 0x12, 0xe3, 0x30, 0x11, 0x9c, 0x49,
819 0xa6, 0xbc, 0x0a, 0xae, 0x31, 0x7d, 0x6f, 0xa8, 0x24, 0x5c, 0x9f, 0xe7, 0xd6, 0x65,
820 0x91, 0x72, 0x89, 0xb4, 0xbc, 0x19, 0x16, 0xe2, 0x3b, 0xe4, 0xcb, 0x5d, 0xb1, 0x4a,
821 0x3b, 0x57, 0x8f, 0x22, 0x2a, 0x6d, 0x87, 0x62, 0x9a, 0xf9, 0x3f, 0x0c, 0x09, 0x7f,
822 0x0f, 0x80, 0x53, 0x9d, 0x4e, 0x15, 0xb9, 0x29, 0xd5, 0x75, 0x97, 0x9e, 0x01, 0xa5,
823 0x7c, 0x8a, 0x0b, 0xf2, 0xf2, 0xfb, 0x7d, 0xcd, 0xa5, 0x0d, 0x76, 0x02, 0xd6, 0x6c,
824 0x43, 0x0b, 0xf2, 0x74, 0xc1, 0x75, 0xc2, 0xc3, 0xe9, 0x25, 0xce, 0xf8, 0x0d, 0xc6,
825 0x0a, 0xd2, 0xe4, 0xef, 0xa3, 0xb7, 0xed, 0x92, 0x58, 0x51, 0xfc, 0xc6, 0x0d, 0x0e,
826 0x8f, 0xe1, 0xbe, 0xde, 0x6c, 0x01, 0xb5, 0x03, 0x4f, 0xbb, 0x47, 0x76, 0xf2, 0x04,
827 0x44, 0xb5, 0x93, 0x83, 0x58, 0xad, 0x06, 0x3e, 0x95, 0x39, 0xbc, 0x16, 0xc9, 0xe7,
828 0x17, 0x45, 0xce, 0xc0, 0x79, 0x0f, 0x50, 0x74, 0x8d, 0x5a, 0xf6, 0xc4, 0xe2, 0xfd,
829 0x97, 0xf2, 0x49, 0x86, 0x75, 0x93, 0x8d, 0x9e, 0xbc, 0x23, 0x04, 0x0e, 0x76, 0x2a,
830 0xf1, 0x66, 0xbd, 0xef, 0xe8, 0xd0, 0xc1, 0xcb, 0xd6, 0x8f, 0x21, 0x6f, 0xfc, 0xd4,
831 0xd2, 0xed, 0x7b, 0xc4, 0x3a, 0x5d, 0xe7, 0x3c, 0xca, 0xa4, 0x56, 0x18, 0x65, 0x42,
832 0x5a, 0x78, 0xf4, 0x4a, 0xe1, 0x31, 0xfe, 0x68, 0xfd, 0xd5, 0x85, 0x10, 0xa6, 0x88,
833 0x45, 0x99, 0xa5, 0x95, 0xd3, 0x3a, 0xe4, 0x6b, 0xd3, 0x03, 0x84, 0xdc, 0xd2, 0x56,
834 0x01, 0x5c, 0xfc, 0x52, 0x1f, 0x47, 0xca, 0x3a, 0xf6, 0x49, 0xf6, 0x24, 0xc8, 0x4d,
835 0xfb, 0x69, 0x06, 0x00, 0xd5, 0x12, 0x6b, 0xcb, 0x98, 0xab, 0x51, 0xe5, 0xcc, 0xbf,
836 0x4d, 0xe9, 0x60, 0x80, 0x8d, 0x41, 0x64, 0x95, 0x36, 0x94, 0x65, 0x4a, 0x04, 0x58,
837 0xc3, 0xf3, 0x43, 0x54, 0xce, 0x11, 0xe3, 0x95, 0xdb, 0x95, 0xfe, 0x51, 0x08, 0x51,
838 0x07, 0x37, 0xef, 0x50, 0xca, 0x20, 0x39, 0x2d, 0xce, 0xed, 0x4e, 0x59, 0x68, 0x38,
839 0x8e, 0x3b, 0xb1, 0xde, 0x21, 0x56, 0xe8, 0xb0, 0x81, 0xb3, 0xcc, 0x66, 0x94, 0x1d,
840 0xeb, 0x40, 0xe6, 0xb5, 0x2d, 0x79, 0x47, 0x35, 0x4e, 0x85, 0x45, 0xb0, 0x62, 0x4b,
841 0x01, 0xb7, 0xe4, 0x0b, 0x8f, 0x77, 0x5a, 0x39, 0x32, 0x58, 0xd1, 0xd4, 0xd1, 0xe7,
842 0xc8, 0x18, 0xd0, 0x75, 0x44, 0x7a, 0x43, 0x41, 0xbe, 0x0e, 0xca, 0xf5, 0x38, 0x9f,
843 0xdd, 0x1b, 0x47, 0x62, 0x30, 0xee, 0xee, 0x16, 0x7b, 0x32, 0xbc, 0xe3, 0x55, 0x70,
844 0x0a, 0xcf, 0xe4, 0xf9, 0x65, 0x01, 0xf4, 0x9e, 0x4a, 0x82, 0x68, 0xe0, 0x62, 0x1a,
845 0xac, 0x14, 0x3c, 0x1b, 0x94, 0x0e, 0xd3, 0x85, 0xa2, 0x1d, 0x61, 0x08, 0xad, 0x5a,
846 0x9c, 0x5e, 0xdc, 0x81, 0x9c, 0x7b, 0xf2, 0xe4, 0x7f, 0x25, 0x53, 0x47, 0x31, 0x66,
847 0x4d, 0xbd, 0x80, 0x36, 0x6f, 0xa1, 0x33, 0x80, 0x05, 0x5b, 0x79, 0xe0, 0x86, 0x5f,
848 0x3c, 0x08, 0xe7, 0x5e, 0x02, 0x7f, 0x42, 0x92, 0xe3, 0x31, 0xf0, 0x6f, 0xbf, 0x91,
849 0x54, 0x12, 0xa9, 0x6e, 0xe4, 0x48, 0xed, 0x75, 0x78, 0x8f, 0x66, 0x59, 0x00, 0xcd,
850 0x0a, 0x5a, 0xeb, 0x62, 0xe7, 0x82, 0x61, 0x21, 0xed, 0xc0, 0xd5, 0xc5, 0x08, 0xf6,
851 0x9a, 0x4c, 0xd0, 0x01, 0x0f, 0xe0, 0xe2, 0x3f, 0xd2, 0xf8, 0x15, 0xc9, 0x91, 0x74,
852 0xec, 0x9a, 0x36, 0x73, 0x71, 0x1a, 0xb4, 0x8c, 0x3a, 0xe3, 0x31, 0xaf, 0xdd, 0xb8,
853 0xc2, 0xef, 0x3b, 0x61, 0xe3, 0x6f, 0x1f, 0xea, 0x28, 0xb3, 0x38, 0x77, 0x03, 0x3d,
854 0x20, 0xa9, 0x79, 0x68, 0x27, 0x68, 0x41, 0x18, 0xea, 0x58, 0xaf, 0xc5, 0x38, 0xae,
855 0xca, 0x56, 0x81, 0x55, 0xec, 0xa6, 0x59, 0xa0, 0xf0, 0x7a, 0x8d, 0xf2, 0x05, 0x17,
856 0xd0, 0x93, 0x47, 0x1f, 0x6a, 0x77, 0xc6, 0x60, 0xdb, 0xb5, 0x60, 0x38, 0xe1, 0xd9,
857 0xf3, 0xc3, 0xae, 0x0a, 0x16, 0x5c, 0x46, 0xd9, 0xdf, 0xf6, 0x8a, 0xa1, 0x6a, 0x09,
858 0x89, 0xac, 0xaa, 0x53, 0xa0, 0x4c, 0x0e, 0x6b, 0x3b, 0x0c, 0x9c, 0x6d, 0xaa, 0xb4,
859 0xef, 0x09, 0x00, 0x63, 0x14, 0xa1, 0xda, 0xef, 0x4a, 0x0b, 0xe9, 0xd6, 0x22, 0x51,
860 0xd5, 0x9b, 0x71, 0xca, 0xd9, 0xbd, 0x43, 0x9b, 0x1e, 0x8b, 0x45, 0x20, 0xb0, 0x94,
861 0x4a, 0x81, 0x62, 0xc2, 0x0d, 0x48, 0x89, 0xd2, 0x33, 0xf8, 0xed, 0xa8, 0x7d, 0xc1,
862 0x10, 0x02, 0x57, 0x83, 0x4a, 0x32, 0x1e, 0x35, 0xf3, 0xf4, 0x6c, 0xb3, 0x01, 0x47,
863 0x3d, 0xe4, 0xb4, 0xc1, 0x7a, 0xfe, 0x19, 0x0f, 0x3a, 0x8c, 0x6f, 0xa7, 0x1d, 0xf0,
864 0x32, 0x80, 0x7f, 0x92, 0x4c, 0x49, 0xc4, 0xb0, 0x41, 0x08, 0xb2, 0x2f, 0x22, 0x3f,
865 0x6d, 0xcc, 0xa3, 0xd0, 0x3a, 0xe7, 0x11, 0x14, 0x5a, 0x57, 0x3f, 0xb3, 0xc8, 0x2b,
866 0x79, 0xe9, 0x53, 0x94, 0x34, 0x74, 0x26, 0x07, 0x85, 0x06, 0x96, 0x4c, 0x93, 0x63,
867 0x1e, 0x11, 0x18, 0xe8, 0x86, 0x19, 0x2e, 0x82, 0xbe, 0x17, 0x6b, 0x37, 0xba, 0x6d,
868 0x1a, 0xa0, 0x68, 0x20, 0x54, 0x12, 0xff, 0x88, 0xbc, 0x4b, 0x87, 0x45, 0x9d, 0x03,
869 0x06, 0x11, 0x57, 0x4d, 0x25, 0x41, 0x3a, 0x5f, 0x11, 0x21, 0x2f, 0xeb, 0xd6, 0xdc,
870 0x34, 0xda, 0xfd, 0x4c, 0xe0, 0xe9, 0x6c, 0xce, 0x35, 0xed, 0x87, 0xf0, 0x6c, 0xda,
871 0xb0, 0x77, 0x3a, 0x24, 0x33, 0xea, 0x88, 0xaf, 0x15, 0x98, 0xef, 0xeb, 0xab, 0xc1,
872 0xc1, 0xf3, 0x8b, 0x9f, 0xbe, 0xdb, 0x34, 0x29, 0x14, 0xf5, 0x9d, 0x58, 0xd1, 0x53,
873 0x4c, 0xbb, 0xc0, 0x1f, 0xc1, 0x7a, 0x2d, 0x94, 0x2a, 0x86, 0xcc, 0x24, 0x95, 0x42,
874 0x69, 0xea, 0x72, 0x22, 0x1d, 0xbd, 0x19, 0xd7, 0x5e, 0xb3, 0xd0, 0x5f, 0xb3, 0xa9,
875 0x4d, 0x52, 0xa0, 0x9a, 0xb0, 0xe3, 0xde, 0x14, 0x2d, 0xf1, 0x3f, 0x82, 0x82, 0x39,
876 0x9f, 0xee, 0x78, 0xa8, 0xec, 0x33, 0x0c, 0x01, 0x9a, 0xdf, 0xcf, 0xb3, 0x54, 0x02,
877 0x2e, 0xcc, 0x58, 0x0b, 0xfd, 0x0e, 0xe3, 0xac, 0x12, 0x0f, 0x8b, 0x87, 0x0a, 0xad,
878 0x1e, 0x4b, 0x1d, 0x45, 0x3e, 0x6c, 0x4c, 0x7d, 0xff, 0x55, 0xb4, 0x81, 0xaa, 0x0b,
879 0xf0, 0x75, 0x32, 0xa8, 0x32, 0x4d, 0x11, 0xf2, 0xb6, 0x58, 0x42, 0xac, 0x37, 0x6b,
880 0x78, 0xe3, 0x93, 0x3a, 0xaf, 0x26, 0x59, 0x3c, 0xa2, 0x81, 0xab, 0xbc, 0x2c, 0x42,
881 0x87, 0xa7, 0x41, 0x55, 0xb1, 0xe2, 0xa3, 0xf1, 0x0a, 0xa8, 0xd8, 0x11, 0xe8, 0xd7,
882 0xb8, 0x03, 0x44, 0xab, 0xa6, 0x66, 0x98, 0x3c, 0x90, 0x17, 0x88, 0xdd, 0xe7, 0x9c,
883 0x1a, 0x27, 0xba, 0xce, 0x04, 0x3d, 0x34, 0x74, 0xd1, 0xe1, 0x5b, 0x41, 0x5e, 0x2c,
884 0x75, 0x30, 0x03, 0xf6, 0x85, 0x17, 0xbb, 0xb8, 0xfb, 0xb7, 0x7a, 0xf9, 0xb7, 0xc2,
885 0x51, 0x29, 0xe5, 0xc5, 0xf8, 0x0b, 0x86, 0x60, 0x7f, 0x7a, 0x81, 0xe6, 0x0b, 0x23,
886 0xdf, 0xd2, 0x60, 0x1c, 0xbc, 0xaf, 0x2e, 0x6f, 0x1d, 0xd5, 0x81, 0x5e, 0x0e, 0xd0,
887 0x07, 0x54, 0x81, 0x29, 0x30, 0xa0, 0x28, 0xa5, 0xe8, 0x48, 0x9d, 0xea, 0x1d, 0xc5,
888 0x60, 0xff, 0xc3, 0xac, 0x1b, 0x0b, 0xa2, 0xbc, 0x14, 0x63, 0x2b, 0x52, 0xea, 0x5d,
889 0x8c, 0x48, 0xdb, 0x63, 0x72, 0x4b, 0x1b, 0x2c, 0x27, 0xfd, 0x0d, 0x51, 0xa4, 0x28,
890 0xec, 0xe2, 0xc2, 0x21, 0xbe, 0x51, 0x77, 0x58, 0x5f, 0x45, 0x81, 0x7e, 0x62, 0x4a,
891 0x07, 0x5f, 0xd2, 0x2d, 0xa2, 0x4f, 0x18, 0x74, 0x63, 0x1a, 0xae, 0x43, 0x09, 0x5d,
892 0xfb, 0x1e, 0x5d, 0xfb, 0x5a, 0xff, 0x10, 0x41, 0x92, 0xb9, 0xd4, 0x26, 0x01, 0x1c,
893 0x45, 0xd1, 0x5c, 0xb1, 0x62, 0x08, 0xad, 0x60, 0x6e, 0xce, 0xdf, 0x27, 0x49, 0x2f,
894 0xb2, 0x00, 0x59, 0x5b, 0x36, 0x0f, 0xe9, 0xdf, 0xc2, 0xd1, 0xc4, 0x32, 0x84, 0x55,
895 0x07, 0x22, 0x5d, 0x91, 0x53, 0x9f, 0xef, 0x13, 0xe6, 0x07, 0xb8, 0x85, 0xbb, 0x9f,
896 0xc7, 0xda, 0x09, 0x3a, 0x68, 0x8d, 0xc9, 0x9f, 0xcd, 0x76, 0xdb, 0x73, 0x6b, 0x57,
897 0x36, 0x3a, 0xbf, 0xc5, 0x97, 0xcb, 0x85, 0xd1, 0x25, 0xc4, 0x10, 0x07, 0x0c, 0x2c,
898 0x6f, 0x1e, 0x11, 0x46, 0xc8, 0xbb, 0x10, 0x95, 0x35, 0x1e, 0x39, 0x27, 0x05, 0x6e,
899 0x91, 0x0d, 0xb5, 0xa6, 0x66, 0xe4, 0xcf, 0xa5, 0xac, 0x4d, 0x2b, 0x48, 0xfd, 0x2d,
900 0x94, 0x4a, 0x84, 0xde, 0xf6, 0x67, 0x63, 0xa5, 0x4a, 0x53, 0x1d, 0x74, 0x6e, 0xe8,
901 0xf0, 0xc5, 0x9c, 0x87, 0xec, 0x30, 0xa9, 0x34, 0x3d, 0x89, 0x52, 0x37, 0x84, 0xa9,
902 0x20, 0x4e, 0xed, 0x89, 0xaa, 0xb3, 0x2e, 0xec, 0x03, 0x38, 0x33, 0xe1, 0x03, 0x35,
903 0x0a, 0xc7, 0xc0, 0x4c, 0x43, 0x36, 0x8e, 0x38, 0xa8, 0xe9, 0xbc, 0x03, 0x42, 0x86,
904 0xaf, 0x14, 0xda, 0x1a, 0x20, 0xca, 0xc6, 0xdc, 0xb8, 0xb5, 0xf7, 0x9e, 0x39, 0x7c,
905 0x9a, 0x43, 0xee, 0xbb, 0x53, 0xe0, 0x6d, 0xa0, 0xef, 0xa7, 0x00, 0xf1, 0x48, 0xc4,
906 0x7d, 0xb2, 0x60, 0xb2, 0x14, 0xaf, 0x7f, 0x24, 0x83, 0x81, 0x40, 0xff, 0xc2, 0x1a,
907 0x0d, 0xe8, 0xaf, 0x8c, 0x6d, 0xdf, 0x6d, 0xfc, 0x90, 0x2a, 0x92, 0xb4, 0xd5, 0x21,
908 0xe5, 0xb4, 0xf2, 0x93, 0xb5, 0x2f, 0x64, 0x45, 0x95, 0xdb, 0x01, 0x87, 0x21, 0x1d,
909 0xa8, 0x44, 0xcb, 0x26, 0x14, 0x1d, 0xd5, 0x1b, 0xd3, 0x7f, 0xf6, 0x11, 0x4e, 0x01,
910 0xa8, 0xa3, 0xb8, 0x90, 0xb3, 0x05, 0xf6, 0xc1, 0x00, 0x0d, 0xd5, 0x5a, 0x48, 0xe9,
911 0x7f, 0x19, 0x43, 0xc4, 0x8b, 0xbb, 0x0b, 0xb2, 0xd0, 0x3c, 0x7f, 0x0d, 0x6c, 0xbd,
912 0xbe, 0xba, 0xee, 0x40, 0x04, 0x93, 0xf7, 0x1f, 0x97, 0xa9, 0x9b, 0xef, 0x0e, 0x18,
913 0x0b, 0x82, 0xfe, 0xe5, 0x7b, 0x0a, 0xc5, 0x1b, 0x02, 0x89, 0x4e, 0x6a, 0x62, 0x69,
914 0x1f, 0x95, 0xa3, 0xb0, 0xeb, 0x87, 0x11, 0xa3, 0x5f, 0xa4, 0x33, 0xbd, 0xeb, 0xd1,
915 0xc2, 0x91, 0x0c, 0xf8, 0x7f, 0x73, 0xa7, 0x48, 0xdd, 0x1c, 0x32, 0x69, 0x1b, 0xbc,
916 0xb8, 0x6d, 0x91, 0xc3, 0xb9, 0x59, 0x1b, 0xf1, 0x0d, 0xbe, 0x20, 0x1f, 0xc3, 0x37,
917 0x91, 0x8c, 0x15, 0xeb, 0xbb, 0xc4, 0xaa, 0xc5, 0x8a, 0xa3, 0xf3, 0x30, 0xad, 0xab,
918 0x48, 0x5a, 0xb9, 0x4d, 0x08, 0xcc, 0x36, 0x7e, 0x8b, 0x01, 0x0b, 0x01, 0xed, 0xfd,
919 0xaa, 0x17, 0x50, 0x4f, 0x28, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
920 0x00, 0x00, 0xdd, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
921 ];
922 let tag = block_on(
923 poly1305_mac_async(&otk, message)
924 ).unwrap();
925 let expected_tag = &[
926 0x78, 0xfb, 0xe0, 0x05, 0xdb, 0xff, 0x31, 0xf6, 0xdf, 0xdf, 0xe4, 0x58, 0x7b, 0x4d,
927 0xbe, 0x8e,
928 ];
929 assert_eq!(&tag as &[u8], expected_tag);
930 }
931
932 #[test]
933 fn test_poly1305_mod() {
934 let a: [u32; 5] = [0x2dde68f6, 0x672041f6, 0xf0a01508, 0x1ed7f726, 0x04];
935 assert_eq!(
936 poly1305_mod(a),
937 [0x2dde68fb, 0x672041f6, 0xf0a01508, 0x1ed7f726, 0x0]
938 );
939
940 let a: [u32; 5] = [0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03];
941 assert_eq!(poly1305_mod(a), [0x4, 0, 0, 0, 0]);
942
943 let a: [u32; 5] = [0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x04];
944 assert_eq!(poly1305_mod(a), [0x4, 0, 0, 0, 0x1]);
945
946 let a: [u32; 5] = [0xfffffffa, 0xffffffff, 0xffffffff, 0xffffffff, 0x03];
947 assert_eq!(
948 poly1305_mod(a),
949 [0xfffffffa, 0xffffffff, 0xffffffff, 0xffffffff, 0x3]
950 );
951
952 let a: [u32; 5] = [0xfffffffb, 0xffffffff, 0xffffffff, 0xffffffff, 0x03];
953 assert_eq!(poly1305_mod(a), [0, 0, 0, 0, 0]);
954
955 let a: [u32; 5] = [0xfffffffc, 0xffffffff, 0xffffffff, 0xffffffff, 0x03];
956 assert_eq!(poly1305_mod(a), [1, 0, 0, 0, 0]);
957 }
958
959 #[test]
960 fn test_cha_cha_20_encrypt_empty() {
961 let key: [u8; 32] = [0; 32];
962 let nonce: [u8; 12] = [0; 12];
963 let plaintext: &[u8] = &[];
964 let mut result = vec![];
965 block_on(
966 cha_cha_20_encrypt(&key, 1, &nonce, plaintext, &mut result)
967 ).unwrap();
968 assert_eq!(result, &[]);
969 }
970
971 #[test]
972 fn test_cha_cha_20_encrypt_large() {
973 let key: [u8; 32] = [0; 32];
974 let nonce: [u8; 12] = [0; 12];
975 let plaintext: Vec<u8> = vec![0; 1024]; let mut result = vec![];
977 block_on(
978 cha_cha_20_encrypt(&key, 1, &nonce, plaintext.as_slice(), &mut result)
979 ).unwrap();
980 assert_eq!(result.len(), 1024);
981 }
982
983 #[test]
984 fn test_poly1305_mac_async_small_chunks() {
985 let key: [u8; 32] = [0; 32];
986 let mut message: &[u8] = &[0; 32];
987 let tag = block_on(
988 poly1305_mac_async(&key, &mut message)
989 ).unwrap();
990 let expected:&[u8] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
991 assert_eq!(&tag, expected);
992 }
993
994 #[test]
995 fn test_cha_cha_20_aead_decrypt_tampered() {
996 let key: [u8; 32] = [0; 32];
997 let nonce: [u8; 12] = [0; 12];
998 let plaintext: &[u8] = b"test";
999 let aad: &[u8] = b"aad";
1000 let mut ciphertext = vec![];
1001 let expected_tag = block_on(
1002 cha_cha_20_aead_encrypt(aad, &key, nonce, plaintext, &mut ciphertext)
1003 ).unwrap();
1004 ciphertext[0] ^= 1; let mut plain_text = vec![];
1006 let result = block_on(
1007 cha_cha_20_aead_decrypt_verify(aad, &key, nonce, ciphertext.as_slice(), &mut plain_text, expected_tag)
1008 );
1009 assert!(matches!(result, Err(err) if err.kind() == io::ErrorKind::InvalidData));
1010 }
1011
1012 #[test]
1013 fn test_cha_cha_20_aead_decrypt_wrong_tag() {
1014 let key: [u8; 32] = [0; 32];
1015 let nonce: [u8; 12] = [0; 12];
1016 let plaintext: &[u8] = b"test";
1017 let aad: &[u8] = b"aad";
1018 let mut ciphertext = vec![];
1019 let tag = block_on(
1020 cha_cha_20_aead_encrypt(aad, &key, nonce, plaintext, &mut ciphertext)
1021 ).unwrap();
1022 let mut wrong_tag = tag;
1023 wrong_tag[0] ^= 1;
1024 let mut plain_text = vec![];
1025 let result = block_on(
1026 cha_cha_20_aead_decrypt_verify(aad, &key, nonce,
1027 ciphertext.as_slice(), &mut plain_text, wrong_tag)
1028 );
1029 assert!(matches!(result, Err(err) if err.kind() == io::ErrorKind::InvalidData));
1030 }
1031
1032 #[test]
1033 fn test_cha_cha_20_encrypt_reader_error() {
1034 struct FailingReader;
1035 impl AsyncRead for FailingReader {
1036 fn poll_read(self: std::pin::Pin<&mut Self>, _cx: &mut std::task::Context<'_>, _buf: &mut [u8]) -> std::task::Poll<io::Result<usize>> {
1037 std::task::Poll::Ready(Err(io::Error::new(io::ErrorKind::Other, "read error")))
1038 }
1039 }
1040 let key: [u8; 32] = [0; 32];
1041 let nonce: [u8; 12] = [0; 12];
1042 let mut cipher1 = vec![];
1043 let result = block_on(
1044 cha_cha_20_encrypt(&key, 1, &nonce, FailingReader, &mut cipher1),
1045 );
1046 assert!(result.is_err());
1047 }
1048
1049 #[test]
1050 fn test_cha_cha_20_key_sensitivity() {
1051 let key1: [u8; 32] = [0; 32];
1052 let key2: [u8; 32] = [1; 32];
1053 let nonce: [u8; 12] = [0; 12];
1054 let plaintext: &[u8] = b"test";
1055 let mut cipher1 = vec![];
1056 block_on(
1057 cha_cha_20_encrypt(&key1, 1, &nonce, plaintext, &mut cipher1)
1058 ).unwrap();
1059 let mut cipher2 = vec![];
1060 block_on(
1061 cha_cha_20_encrypt(&key2, 1, &nonce, plaintext, &mut cipher2)
1062 ).unwrap();
1063 assert_ne!(cipher1, cipher2);
1064 }
1065
1066 #[test]
1067 fn test_cha_cha_20_nonce_reuse() {
1068 let key: [u8; 32] = [0; 32];
1069 let nonce1: [u8; 12] = [0; 12];
1070 let nonce2: [u8; 12] = [1; 12];
1071 let block1 = cha_cha_20_block(&key, 1, &nonce1);
1072 let block2 = cha_cha_20_block(&key, 1, &nonce2);
1073 assert_ne!(block1, block2);
1074 }
1075
1076 #[test]
1077 fn test_cha_cha_20_block_counter_zero() {
1078 let key: [u8; 32] = [
1079 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1080 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1081 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1082 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
1083 ];
1084 let nonce: [u8; 12] = [0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00];
1085 let block = cha_cha_20_block(&key, 0, &nonce);
1086 let expected: [u8; 64] = [
1087 138, 220, 145, 253, 159, 244, 240, 245, 27, 15, 173, 80, 255, 21, 214, 55,
1088 228, 14, 253, 162, 6, 204, 82, 199, 131, 167, 66, 0, 80, 60, 21, 130,
1089 205, 152, 51, 54, 125, 10, 84, 213, 125, 60, 158, 153, 143, 73, 14, 230,
1090 156, 163, 76, 31, 249, 233, 57, 167, 85, 132, 197, 45, 105, 10, 53, 212
1091 ];
1092 assert_eq!(block, expected);
1093 }
1094
1095 #[test]
1096 fn test_cha_cha_20_encrypt_counter_max() {
1097 let key: [u8; 32] = [
1098 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1099 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1100 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1101 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
1102 ];
1103 let nonce: [u8; 12] = [0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00];
1104 let plaintext: [u8; 64] = [0; 64];
1105 let mut result = vec![];
1106 block_on(
1107 cha_cha_20_encrypt(&key, u32::MAX, &nonce, &plaintext[..], &mut result)
1108 ).unwrap();
1109 let expected: [u8; 64] = [
1110 255, 41, 65, 184, 215, 64, 246, 203, 181, 9, 54, 191, 153, 126, 189, 82,
1111 24, 203, 16, 141, 197, 63, 65, 198, 72, 65, 208, 33, 129, 103, 67, 12,
1112 160, 59, 119, 12, 167, 76, 203, 100, 42, 40, 25, 77, 29, 237, 210, 237,
1113 19, 21, 30, 37, 236, 93, 127, 174, 182, 208, 96, 191, 183, 230, 177, 70
1114 ];
1115 assert_eq!(result, expected);
1116 }
1117
1118 #[test]
1119 fn test_poly1305_mac_empty() {
1120 let key: [u8; 32] = [
1121 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
1122 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
1123 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
1124 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b,
1125 ];
1126 let message:&[u8] = &[];
1127 let tag = block_on(
1128 poly1305_mac_async(&key, message)
1129 ).unwrap();
1130 let expected: [u8; 16] = [1, 3, 128, 138, 251, 13, 178, 253, 74, 191, 246, 175, 65, 73, 245, 27];
1131 assert_eq!(tag, expected);
1132 }
1133
1134 #[test]
1135 fn test_poly1305_mac_16_bytes() {
1136 let key: [u8; 32] = [
1137 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
1138 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
1139 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
1140 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b,
1141 ];
1142 let message:&[u8] = &[
1143 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
1144 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
1145 ];
1146 let tag = block_on(
1147 poly1305_mac_async(&key, message)
1148 ).unwrap();
1149 let expected: [u8; 16] = [253, 134, 28, 113, 132, 249, 143, 69, 220, 109, 91, 77, 198, 192, 129, 228];
1150 assert_eq!(tag, expected);
1151 }
1152
1153 #[test]
1154 fn test_cha_cha_20_aead_encrypt_empty() {
1155 let key: [u8; 32] = [
1156 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
1157 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
1158 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
1159 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
1160 ];
1161 let nonce: [u8; 12] = [0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47];
1162 let plaintext: [u8; 0] = [];
1163 let aad: [u8; 0] = [];
1164 let mut ciphertext = vec![];
1165 let tag = block_on(
1166 cha_cha_20_aead_encrypt(&aad, &key, nonce, &plaintext[..], &mut ciphertext)
1167 ).unwrap();
1168 let expected_tag: [u8; 16] = [
1169 160, 120, 77, 122, 71, 22, 243, 254, 180, 246, 78, 127, 75, 57, 191, 4
1170 ];
1171 assert_eq!(ciphertext, &[]);
1172 assert_eq!(tag, expected_tag);
1173 }
1174
1175 #[test]
1176 fn test_cha_cha_20_aead_encrypt_aad_16_bytes() {
1177 let key: [u8; 32] = [
1178 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
1179 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
1180 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
1181 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
1182 ];
1183 let nonce: [u8; 12] = [0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47];
1184 let plaintext: [u8; 4] = [0x74, 0x65, 0x73, 0x74]; let aad: [u8; 16] = [
1186 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
1187 0xc4, 0xc5, 0xc6, 0xc7, 0x00, 0x00, 0x00, 0x00,
1188 ];
1189 let mut ciphertext = vec![];
1190 let tag = block_on(
1191 cha_cha_20_aead_encrypt(&aad, &key, nonce, &plaintext[..], &mut ciphertext)
1192 ).unwrap();
1193 let expected_ciphertext: [u8; 4] = [0xeb, 0x1e, 0x9a, 0x29];
1194 let expected_tag: [u8; 16] = [105, 124, 51, 142, 40, 75, 123, 86, 47, 48, 217, 240, 118, 71, 195, 224];
1195 assert_eq!(ciphertext, expected_ciphertext);
1196 assert_eq!(tag, expected_tag);
1197 }
1198
1199 #[test]
1200 fn test_cha_cha_20_encrypt_small_chunks() {
1201 let key: [u8; 32] = [
1202 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1203 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1204 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1205 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
1206 ];
1207 let nonce: [u8; 12] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00];
1208 let plaintext: &[u8] = b"test message";
1209 let mut result = vec![];
1210 block_on(
1211 cha_cha_20_encrypt(&key, 1, &nonce, plaintext, &mut result)
1212 ).unwrap();
1213 let expected: [u8; 12] = [86, 42, 34, 135, 96, 118, 188, 146, 92, 191, 64, 10];
1214 assert_eq!(&result, &expected[..]);
1215 }
1216}