use core::fmt;
use tc_block_cipher::{BlockCipher, BlockCipherInit, BlockError, CipherDirection, InitError};
use crate::ThreefishParams;
#[cfg(not(feature = "rustcrypto"))]
use crate::ThreefishPortableEngine as Backend;
#[cfg(feature = "rustcrypto")]
use crate::ThreefishRustCryptoEngine as Backend;
pub struct ThreefishEngine<const WORDS: usize> {
inner: Backend<WORDS>,
}
impl<const WORDS: usize> ThreefishEngine<WORDS> {
pub const fn new() -> Self {
Self {
inner: Backend::new(),
}
}
}
impl<const WORDS: usize> Default for ThreefishEngine<WORDS> {
fn default() -> Self {
Self::new()
}
}
impl<const WORDS: usize> fmt::Display for ThreefishEngine<WORDS> {
fn fmt(&self, output: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(output)
}
}
impl<const WORDS: usize> BlockCipher for ThreefishEngine<WORDS> {
type Error = BlockError;
fn block_size(&self) -> usize {
self.inner.block_size()
}
fn process_block(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, BlockError> {
self.inner.process_block(input, output)
}
}
impl<P: ThreefishParams + ?Sized, const WORDS: usize> BlockCipherInit<P>
for ThreefishEngine<WORDS>
{
type Error = InitError;
fn init(&mut self, direction: CipherDirection, params: &P) -> Result<(), InitError> {
self.inner.init(direction, params)
}
}
pub type Threefish256Engine = ThreefishEngine<4>;
pub type Threefish512Engine = ThreefishEngine<8>;
pub type Threefish1024Engine = ThreefishEngine<16>;