crypto_async_rs/
cha_cha_poly_async.rs

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
247// Multiplies h and r, put the result in h
248fn poly1305_mul(h: &mut [u32; 5], r: [u32; 4]) {
249    // These would fit in 32 bits, but we need 64 bit multiplications
250    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; // lose 2 bottom bits...
262    let rr1 = (r1 >> 2) * 5; // 2 bottom bits already cleared
263    let rr2 = (r2 >> 2) * 5; // 2 bottom bits already cleared
264    let rr3 = (r3 >> 2) * 5; // 2 bottom bits already cleared
265
266    // school book modular multiplication (without carry propagation)
267    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); // ...recover those 2 bits
272
273    // carry propagation (put the result back in h)
274    let msb: u64 = x4 + (x3 >> 32);
275    let mut u = (msb >> 2) * 5; // lose 2 bottom bits...
276    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 /* ...recover them */;
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    //Compute R = A + B
297    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        // assert_eq!(&tag, &expected_tag);
709    }
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]; // 16 blocks
976        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; // Tamper
1005        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]; // "test"
1185        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}