ascon_prng/
mac.rs

1use ascon::State;
2use digest::{
3    block_buffer::Eager,
4    core_api::{
5        AlgorithmName, BlockSizeUser, BufferKindUser, CoreWrapper, FixedOutputCore, UpdateCore,
6    },
7    crypto_common::{KeyInit, KeySizeUser},
8    MacMarker, OutputSizeUser,
9};
10use typenum::consts::{U16, U32};
11
12use crate::{compress, extract};
13
14#[derive(Clone, Debug)]
15pub struct AsconMacCore {
16    state: State,
17}
18
19pub type AsconMac = CoreWrapper<AsconMacCore>;
20
21impl KeySizeUser for AsconMacCore {
22    type KeySize = U16;
23}
24
25impl AlgorithmName for AsconMacCore {
26    fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
27        f.write_str("Ascon-Mac")
28    }
29}
30
31impl KeyInit for AsconMacCore {
32    #[inline(always)]
33    fn new(key: &digest::Key<Self>) -> Self {
34        const IV: u64 = 0x00000080008c8080;
35        Self {
36            state: crate::init(IV, key),
37        }
38    }
39}
40
41impl BlockSizeUser for AsconMacCore {
42    type BlockSize = U32;
43}
44
45impl BufferKindUser for AsconMacCore {
46    type BufferKind = Eager;
47}
48
49impl UpdateCore for AsconMacCore {
50    fn update_blocks(&mut self, blocks: &[digest::core_api::Block<Self>]) {
51        blocks.iter().for_each(|b| compress(&mut self.state, b, 0));
52    }
53}
54
55impl OutputSizeUser for AsconMacCore {
56    type OutputSize = U16;
57}
58
59impl FixedOutputCore for AsconMacCore {
60    fn finalize_fixed_core(
61        &mut self,
62        buffer: &mut digest::core_api::Buffer<Self>,
63        out: &mut digest::Output<Self>,
64    ) {
65        buffer.digest_pad(0x01, &[], |block| {
66            compress(&mut self.state, block, 1);
67        });
68        extract(&self.state, out);
69    }
70}
71
72impl MacMarker for AsconMacCore {}
73
74#[cfg(test)]
75mod tests {
76    use digest::Mac;
77
78    use super::AsconMac;
79
80    #[test]
81    fn round_trip() {
82        let input = b"This is our great input sequence";
83
84        let mut mac = AsconMac::new(b"0123456789abcdef".into());
85        mac.update(input);
86        let output = mac.finalize().into_bytes();
87
88        assert_eq!(
89            &output[..],
90            &[53, 224, 223, 219, 242, 104, 181, 209, 23, 144, 216, 69, 242, 73, 137, 139]
91        );
92
93        let mut mac = AsconMac::new(b"0123456789abcdef".into());
94        mac.update(input);
95        mac.verify(&output).unwrap();
96    }
97}