Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions digest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub mod core_api;
mod digest;
#[cfg(feature = "mac")]
mod mac;
mod xof_fixed;

#[cfg(feature = "core-api")]
pub use block_buffer;
Expand All @@ -70,6 +71,7 @@ pub use crypto_common::{InnerInit, InvalidLength, Key, KeyInit};
pub use crypto_common::{Output, OutputSizeUser, Reset, array, typenum, typenum::consts};
#[cfg(feature = "mac")]
pub use mac::{CtOutput, Mac, MacError, MacMarker};
pub use xof_fixed::XofFixedWrapper;

use core::fmt;

Expand Down
146 changes: 146 additions & 0 deletions digest/src/xof_fixed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
use core::fmt;
use core::marker::PhantomData;

use crypto_common::array::ArraySize;
use crypto_common::hazmat::SerializableState;
use crypto_common::{BlockSizeUser, KeyInit, KeySizeUser, OutputSizeUser, Reset};

use crate::{
CustomizedInit, ExtendableOutput, ExtendableOutputReset, FixedOutput, FixedOutputReset,
HashMarker, Update,
};

/// Wrapper around [`ExtendableOutput`] types adding [`OutputSizeUser`] with the given size of `S`.
pub struct XofFixedWrapper<T: ExtendableOutput, S: ArraySize> {
hash: T,
size: PhantomData<S>,
}

impl<T: ExtendableOutput + Clone, S: ArraySize> Clone for XofFixedWrapper<T, S> {
fn clone(&self) -> Self {
Self {
hash: self.hash.clone(),
size: PhantomData,
}
}
}

impl<T: ExtendableOutput + fmt::Debug, S: ArraySize> fmt::Debug for XofFixedWrapper<T, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("XofFixedWrapper")
.field("hash", &self.hash)
.field("_size", &self.size)
.finish()
}
}

impl<T: ExtendableOutput + Default, S: ArraySize> Default for XofFixedWrapper<T, S> {
fn default() -> Self {
Self {
hash: Default::default(),
size: PhantomData,
}
}
}

impl<T: ExtendableOutput + HashMarker, S: ArraySize> HashMarker for XofFixedWrapper<T, S> {}

#[cfg(feature = "mac")]
impl<T: ExtendableOutput + crate::MacMarker, S: ArraySize> crate::MacMarker
for XofFixedWrapper<T, S>
{
}

// this blanket impl is needed for HMAC
impl<T: ExtendableOutput + BlockSizeUser, S: ArraySize> BlockSizeUser for XofFixedWrapper<T, S> {
type BlockSize = T::BlockSize;
}

impl<T: ExtendableOutput + KeySizeUser, S: ArraySize> KeySizeUser for XofFixedWrapper<T, S> {
type KeySize = T::KeySize;
}

impl<T: ExtendableOutput + KeyInit, S: ArraySize> KeyInit for XofFixedWrapper<T, S> {
fn new(key: &crypto_common::Key<Self>) -> Self {
Self {
hash: T::new(key),
size: PhantomData,
}
}
}

impl<T: ExtendableOutput + Reset, S: ArraySize> Reset for XofFixedWrapper<T, S> {
fn reset(&mut self) {
self.hash.reset();
}
}

impl<T: ExtendableOutput + Update, S: ArraySize> Update for XofFixedWrapper<T, S> {
fn update(&mut self, data: &[u8]) {
self.hash.update(data)
}
}

impl<T: ExtendableOutput, S: ArraySize> OutputSizeUser for XofFixedWrapper<T, S> {
type OutputSize = S;
}

impl<T: ExtendableOutput + Update, S: ArraySize> FixedOutput for XofFixedWrapper<T, S> {
fn finalize_into(self, out: &mut crypto_common::Output<Self>) {
self.hash.finalize_xof_into(out);
}
}

impl<T: ExtendableOutputReset, S: ArraySize> FixedOutputReset for XofFixedWrapper<T, S> {
fn finalize_into_reset(&mut self, out: &mut crypto_common::Output<Self>) {
self.hash.finalize_xof_reset_into(out);
}
}

impl<T: ExtendableOutput, S: ArraySize> ExtendableOutput for XofFixedWrapper<T, S> {
type Reader = T::Reader;

fn finalize_xof(self) -> Self::Reader {
self.hash.finalize_xof()
}
}

impl<T: ExtendableOutputReset, S: ArraySize> ExtendableOutputReset for XofFixedWrapper<T, S> {
fn finalize_xof_reset(&mut self) -> Self::Reader {
self.hash.finalize_xof_reset()
}
}

#[cfg(feature = "zeroize")]
impl<T: ExtendableOutput + zeroize::ZeroizeOnDrop, S: ArraySize> zeroize::ZeroizeOnDrop
for XofFixedWrapper<T, S>
{
}

impl<T: ExtendableOutput + CustomizedInit, S: ArraySize> CustomizedInit for XofFixedWrapper<T, S> {
fn new_customized(customization: &[u8]) -> Self {
Self {
hash: T::new_customized(customization),
size: PhantomData,
}
}
}

impl<T: ExtendableOutput + SerializableState, S: ArraySize> SerializableState
for XofFixedWrapper<T, S>
{
type SerializedStateSize = T::SerializedStateSize;

fn serialize(&self) -> crypto_common::hazmat::SerializedState<Self> {
self.hash.serialize()
}

fn deserialize(
serialized_state: &crypto_common::hazmat::SerializedState<Self>,
) -> Result<Self, crypto_common::hazmat::DeserializeStateError> {
T::deserialize(serialized_state).map(|hash| Self {
hash,
size: PhantomData,
})
}
}