use super ::{
AlgorithmName, Buffer, BufferKindUser, ExtendableOutputCore, FixedOutputCore, OutputS
izeUser,
Reset, UpdateCore, XofReaderCoreWrapper,
};
use crate ::{
ExtendableOutput, ExtendableOutputReset, FixedOutput, FixedOutputReset, HashMarker, Update,
};
use block_buffer::BlockBuffer;
use core::fmt;
use crypto_common::{
typenum::{IsLess, Le, NonZero, U256},
BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output,
};
#[ cfg(feature = "mac" )]
use crate ::MacMarker;
#[ cfg(feature = "oid" )]
use const_oid::{AssociatedOid, ObjectIdentifier};
/// Wrapper around [`BufferKindUser`].
///
/// It handles data buffering and implements the slice-based traits.
#[ derive(Clone, Default)]
pub struct CoreWrapper<T>
where
T: BufferKindUser,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
core: T,
buffer: BlockBuffer<T::BlockSize, T::BufferKind>,
}
impl <T> HashMarker for CoreWrapper<T>
where
T: BufferKindUser + HashMarker,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
}
#[ cfg(feature = "mac" )]
#[ cfg_attr(docsrs, doc(cfg(feature = "mac" )))]
impl <T> MacMarker for CoreWrapper<T>
where
T: BufferKindUser + MacMarker,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
}
// this blanket impl is needed for HMAC
impl <T> BlockSizeUser for CoreWrapper<T>
where
T: BufferKindUser + HashMarker,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
type BlockSize = T::BlockSize;
}
impl <T> CoreWrapper<T>
where
T: BufferKindUser,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
/// Create new wrapper from `core`.
#[ inline]
pub fn from_core(core: T) -> Self {
let buffer = Default::default();
Self { core, buffer }
}
/// Decompose wrapper into inner parts.
#[ inline]
pub fn decompose(self ) -> (T, Buffer<T>) {
let Self { core, buffer } = self ;
(core, buffer)
}
}
impl <T> KeySizeUser for CoreWrapper<T>
where
T: BufferKindUser + KeySizeUser,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
type KeySize = T::KeySize;
}
impl <T> KeyInit for CoreWrapper<T>
where
T: BufferKindUser + KeyInit,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
#[ inline]
fn new(key: &Key<Self >) -> Self {
Self {
core: T::new(key),
buffer: Default::default(),
}
}
#[ inline]
fn new_from_slice(key: &[u8]) -> Result<Self , InvalidLength> {
Ok(Self {
core: T::new_from_slice(key)?,
buffer: Default::default(),
})
}
}
impl <T> fmt::Debug for CoreWrapper<T>
where
T: BufferKindUser + AlgorithmName,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
#[ inline]
fn fmt(&self , f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
T::write_alg_name(f)?;
f.write_str(" { .. }" )
}
}
impl <T> Reset for CoreWrapper<T>
where
T: BufferKindUser + Reset,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
#[ inline]
fn reset(&mut self ) {
self .core.reset();
self .buffer.reset();
}
}
impl <T> Update for CoreWrapper<T>
where
T: BufferKindUser + UpdateCore,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
#[ inline]
fn update(&mut self , input: &[u8]) {
let Self { core, buffer } = self ;
buffer.digest_blocks(input, |blocks| core.update_blocks(blocks));
}
}
impl <T> OutputSizeUser for CoreWrapper<T>
where
T: BufferKindUser + OutputSizeUser,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
type OutputSize = T::OutputSize;
}
impl <T> FixedOutput for CoreWrapper<T>
where
T: FixedOutputCore,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
#[ inline]
fn finalize_into(mut self , out: &mut Output<Self >) {
let Self { core, buffer } = &mut self ;
core.finalize_fixed_core(buffer, out);
}
}
impl <T> FixedOutputReset for CoreWrapper<T>
where
T: FixedOutputCore + Reset,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
#[ inline]
fn finalize_into_reset(&mut self , out: &mut Output<Self >) {
let Self { core, buffer } = self ;
core.finalize_fixed_core(buffer, out);
core.reset();
buffer.reset();
}
}
impl <T> ExtendableOutput for CoreWrapper<T>
where
T: ExtendableOutputCore,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
<T::ReaderCore as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<T::ReaderCore as BlockSizeUser>::BlockSize, U256>: NonZero,
{
type Reader = XofReaderCoreWrapper<T::ReaderCore>;
#[ inline]
fn finalize_xof(self ) -> Self ::Reader {
let (mut core, mut buffer) = self .decompose();
let core = core.finalize_xof_core(&mut buffer);
let buffer = Default::default();
Self ::Reader { core, buffer }
}
}
impl <T> ExtendableOutputReset for CoreWrapper<T>
where
T: ExtendableOutputCore + Reset,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
<T::ReaderCore as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<T::ReaderCore as BlockSizeUser>::BlockSize, U256>: NonZero,
{
#[ inline]
fn finalize_xof_reset(&mut self ) -> Self ::Reader {
let Self { core, buffer } = self ;
let reader_core = core.finalize_xof_core(buffer);
core.reset();
buffer.reset();
let buffer = Default::default();
Self ::Reader {
core: reader_core,
buffer,
}
}
}
#[ cfg(feature = "oid" )]
#[ cfg_attr(docsrs, doc(cfg(feature = "oid" )))]
impl <T> AssociatedOid for CoreWrapper<T>
where
T: BufferKindUser + AssociatedOid,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
const OID: ObjectIdentifier = T::OID;
}
#[ cfg(feature = "std" )]
#[ cfg_attr(docsrs, doc(cfg(feature = "std" )))]
impl <T> std::io::Write for CoreWrapper<T>
where
T: BufferKindUser + UpdateCore,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
#[ inline]
fn write(&mut self , buf: &[u8]) -> std::io::Result<usize> {
Update::update(self , buf);
Ok(buf.len())
}
#[ inline]
fn flush(&mut self ) -> std::io::Result<()> {
Ok(())
}
}
/// A proxy trait to a core type implemented by [`CoreWrapper`]
// TODO: replace with an inherent associated type on stabilization:
// https://github.com/rust-lang/rust/issues/8995
pub trait CoreProxy: sealed::Sealed {
/// Type wrapped by [`CoreWrapper`].
type Core;
}
mod sealed {
pub trait Sealed {}
}
impl <T> sealed::Sealed for CoreWrapper<T>
where
T: BufferKindUser,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
}
impl <T> CoreProxy for CoreWrapper<T>
where
T: BufferKindUser,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
type Core = T;
}
Messung V0.5 in Prozent C=74 H=98 G=86
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-19)
¤
*© Formatika GbR, Deutschland