use core::marker::PhantomData;
use common::{Block, ParBlocksSizeUser, array::ArraySize};
use super::{
TweakBlockCipherDecBackend, TweakBlockCipherDecClosure, TweakBlockCipherDecrypt,
TweakBlockCipherEncBackend, TweakBlockCipherEncrypt, TweakSizeUser,
};
use crate::{
BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherDecrypt, BlockCipherEncBackend,
BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, consts::U1,
tweak::TweakBlockCipherEncClosure,
};
#[derive(Debug, Clone)]
pub struct ZeroTweak<C: TweakSizeUser + BlockSizeUser>(pub C);
impl<C: TweakSizeUser + BlockSizeUser> BlockSizeUser for ZeroTweak<C> {
type BlockSize = C::BlockSize;
}
impl<C: TweakBlockCipherEncrypt> BlockCipherEncrypt for ZeroTweak<C> {
#[inline]
fn encrypt_with_backend(&self, f: impl BlockCipherEncClosure<BlockSize = Self::BlockSize>) {
self.0.encrypt_with_backend(ClosureWrapper {
f,
_pd: PhantomData,
});
}
}
impl<C: TweakBlockCipherDecrypt> BlockCipherDecrypt for ZeroTweak<C> {
#[inline]
fn decrypt_with_backend(&self, f: impl BlockCipherDecClosure<BlockSize = Self::BlockSize>) {
self.0.decrypt_with_backend(ClosureWrapper {
f,
_pd: PhantomData,
});
}
}
struct ClosureWrapper<TS: ArraySize, BS: ArraySize, F> {
f: F,
_pd: PhantomData<(TS, BS)>,
}
impl<TS: ArraySize, BS: ArraySize, F> BlockSizeUser for ClosureWrapper<TS, BS, F> {
type BlockSize = BS;
}
impl<TS: ArraySize, BS: ArraySize, F> TweakSizeUser for ClosureWrapper<TS, BS, F> {
type TweakSize = TS;
}
impl<TS: ArraySize, BS: ArraySize, F> TweakBlockCipherEncClosure for ClosureWrapper<TS, BS, F>
where
F: BlockCipherEncClosure<BlockSize = BS>,
{
#[inline]
fn call<B: TweakBlockCipherEncBackend<BlockSize = BS, TweakSize = TS>>(self, backend: &B) {
self.f.call(&BackendWrapper {
backend,
_pd: PhantomData,
});
}
}
impl<TS: ArraySize, BS: ArraySize, F> TweakBlockCipherDecClosure for ClosureWrapper<TS, BS, F>
where
F: BlockCipherDecClosure<BlockSize = BS>,
{
#[inline]
fn call<B: TweakBlockCipherDecBackend<BlockSize = BS, TweakSize = TS>>(self, backend: &B) {
self.f.call(&BackendWrapper {
backend,
_pd: PhantomData,
});
}
}
struct BackendWrapper<'a, BS: ArraySize, B> {
backend: &'a B,
_pd: PhantomData<BS>,
}
impl<BS: ArraySize, B> BlockSizeUser for BackendWrapper<'_, BS, B> {
type BlockSize = BS;
}
impl<BS: ArraySize, B> ParBlocksSizeUser for BackendWrapper<'_, BS, B> {
type ParBlocksSize = U1;
}
impl<BS: ArraySize, B> BlockCipherEncBackend for BackendWrapper<'_, BS, B>
where
B: TweakBlockCipherEncBackend<BlockSize = BS>,
{
#[inline]
fn encrypt_block(&self, block: inout::InOut<'_, '_, Block<Self>>) {
self.backend.encrypt_block_inout(&Default::default(), block);
}
}
impl<BS: ArraySize, B> BlockCipherDecBackend for BackendWrapper<'_, BS, B>
where
B: TweakBlockCipherDecBackend<BlockSize = BS>,
{
#[inline]
fn decrypt_block(&self, block: inout::InOut<'_, '_, Block<Self>>) {
self.backend.decrypt_block_inout(&Default::default(), block);
}
}