crypto_api_chachapoly/
poly1305.rs

1use crate::core::poly1305::{ poly1305_init, poly1305_update, poly1305_finish };
2use crypto_api::{
3    mac::{ MacInfo, Mac },
4    rng::{ SecureRng, SecKeyGen }
5};
6use std::error::Error;
7
8
9/// The size of a Poly1305 key (256 bits/32 bytes)
10pub const POLY1305_KEY: usize = 32;
11/// The size of a ChaChaPoly authentication tag
12pub const POLY1305_TAG: usize = 16;
13
14
15/// An implementation of [Poly1305](https://tools.ietf.org/html/rfc8439)
16pub struct Poly1305;
17impl Poly1305 {
18    /// Creates a `Mac` instance with `Poly1305` as underlying algorithm
19    pub fn mac() -> Box<dyn Mac> {
20        Box::new(Self)
21    }
22    
23    /// A helper function for the ChachaPoly-IETF AEAD construction
24    pub(in crate) fn chachapoly_auth(tag: &mut[u8], ad: &[u8], data: &[u8], foot: &[u8], key: &[u8]) {
25        // Init Poly1305
26        let (mut r, mut s, mut u, mut a) = (vec![0; 5], vec![0; 4], vec![0; 5], vec![0; 5]);
27        poly1305_init(&mut r, &mut s, &mut u, key);
28        
29        // Process AD, data and the footer
30        poly1305_update(&mut a, &r, &u, ad, false);
31        poly1305_update(&mut a, &r, &u, data, false);
32        poly1305_update(&mut a, &r, &u, foot, true);
33        poly1305_finish(tag, &mut a, &mut s);
34    }
35}
36impl SecKeyGen for Poly1305 {
37    fn new_sec_key(&self, buf: &mut[u8], rng: &mut dyn SecureRng) -> Result<usize, Box<dyn Error + 'static>> {
38        // Verify input
39        vfy_keygen!(POLY1305_KEY => buf);
40        
41        // Generate key
42        rng.random(&mut buf[..POLY1305_KEY])?;
43        Ok(POLY1305_KEY)
44    }
45}
46impl Mac for Poly1305 {
47    fn info(&self) -> MacInfo {
48        MacInfo {
49            name: "Poly1305", is_otm: true,
50            mac_len: POLY1305_TAG,
51            mac_len_r: POLY1305_TAG..(POLY1305_TAG + 1),
52            key_len_r: POLY1305_KEY..(POLY1305_KEY + 1)
53        }
54    }
55    
56    fn auth(&self, buf: &mut[u8], data: &[u8], key: &[u8]) -> Result<usize, Box<dyn Error + 'static>> {
57        // Verify input
58        vfy_auth!(key => [POLY1305_KEY], => [buf, POLY1305_TAG]);
59        
60        // Authenticate data
61        let (mut r, mut s, mut u, mut a) = (vec![0; 5], vec![0; 4], vec![0; 5], vec![0; 5]);
62        poly1305_init(&mut r, &mut s, &mut u, key);
63        poly1305_update(&mut a, &r, &u, data, true);
64        poly1305_finish(buf, &mut a, &s);
65        
66        Ok(POLY1305_TAG)
67    }
68}