retail-mac 0.1.0

Implementation of Retail Message Authentication Code (Retail MAC)
Documentation
#![no_std]
#![doc = include_str!("../README.md")]
#![doc(
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg",
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg"
)]
#![cfg_attr(docsrs, feature(doc_cfg))]

pub use digest::{self, Key, KeyInit, Mac};

/// Block-level implementation.
pub mod block_api;

use block_api::RetailMacCore;
use cipher::{AlgorithmName, BlockCipherDecrypt, BlockCipherEncrypt, KeySizeUser};
use core::{fmt, ops::Mul};
use digest::{
    InvalidLength,
    array::ArraySize,
    block_api::CoreProxy,
    block_api::SmallBlockSizeUser,
    typenum::{Prod, U2},
};

digest::buffer_fixed!(
    /// Generic Retail MAC instance.
    #[derive(Clone)]
    pub struct RetailMac<C: BlockCipherEncrypt + BlockCipherDecrypt + SmallBlockSizeUser>(RetailMacCore<C>);
    impl: ResetMacTraits;
);

impl<C> KeySizeUser for RetailMac<C>
where
    C: BlockCipherEncrypt + BlockCipherDecrypt + SmallBlockSizeUser,
    <C as SmallBlockSizeUser>::_BlockSize: Mul<U2>,
    Prod<<C as SmallBlockSizeUser>::_BlockSize, U2>: ArraySize,
{
    type KeySize = Prod<<C as SmallBlockSizeUser>::_BlockSize, U2>;
}

impl<C> KeyInit for RetailMac<C>
where
    C: BlockCipherEncrypt + BlockCipherDecrypt + SmallBlockSizeUser + KeyInit,
    <C as SmallBlockSizeUser>::_BlockSize: Mul<U2>,
    Prod<<C as SmallBlockSizeUser>::_BlockSize, U2>: ArraySize,
{
    #[inline(always)]
    fn new(key: &Key<Self>) -> Self {
        Self {
            core: KeyInit::new(key),
            buffer: Default::default(),
        }
    }

    #[inline(always)]
    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
        KeyInit::new_from_slice(key).map(|core| Self {
            core,
            buffer: Default::default(),
        })
    }
}

impl<C> AlgorithmName for RetailMac<C>
where
    C: BlockCipherEncrypt + BlockCipherDecrypt + SmallBlockSizeUser + AlgorithmName,
{
    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
        <Self as CoreProxy>::Core::write_alg_name(f)
    }
}