Skip to content

Commit 2596277

Browse files
authored
digest: add XofFixedWrapper (#1815)
1 parent ad1c1ac commit 2596277

2 files changed

Lines changed: 148 additions & 0 deletions

File tree

digest/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ pub mod core_api;
5555
mod digest;
5656
#[cfg(feature = "mac")]
5757
mod mac;
58+
mod xof_fixed;
5859

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

7476
use core::fmt;
7577

digest/src/xof_fixed.rs

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
use core::fmt;
2+
use core::marker::PhantomData;
3+
4+
use crypto_common::array::ArraySize;
5+
use crypto_common::hazmat::SerializableState;
6+
use crypto_common::{BlockSizeUser, KeyInit, KeySizeUser, OutputSizeUser, Reset};
7+
8+
use crate::{
9+
CustomizedInit, ExtendableOutput, ExtendableOutputReset, FixedOutput, FixedOutputReset,
10+
HashMarker, Update,
11+
};
12+
13+
/// Wrapper around [`ExtendableOutput`] types adding [`OutputSizeUser`] with the given size of `S`.
14+
pub struct XofFixedWrapper<T: ExtendableOutput, S: ArraySize> {
15+
hash: T,
16+
size: PhantomData<S>,
17+
}
18+
19+
impl<T: ExtendableOutput + Clone, S: ArraySize> Clone for XofFixedWrapper<T, S> {
20+
fn clone(&self) -> Self {
21+
Self {
22+
hash: self.hash.clone(),
23+
size: PhantomData,
24+
}
25+
}
26+
}
27+
28+
impl<T: ExtendableOutput + fmt::Debug, S: ArraySize> fmt::Debug for XofFixedWrapper<T, S> {
29+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30+
f.debug_struct("XofFixedWrapper")
31+
.field("hash", &self.hash)
32+
.field("_size", &self.size)
33+
.finish()
34+
}
35+
}
36+
37+
impl<T: ExtendableOutput + Default, S: ArraySize> Default for XofFixedWrapper<T, S> {
38+
fn default() -> Self {
39+
Self {
40+
hash: Default::default(),
41+
size: PhantomData,
42+
}
43+
}
44+
}
45+
46+
impl<T: ExtendableOutput + HashMarker, S: ArraySize> HashMarker for XofFixedWrapper<T, S> {}
47+
48+
#[cfg(feature = "mac")]
49+
impl<T: ExtendableOutput + crate::MacMarker, S: ArraySize> crate::MacMarker
50+
for XofFixedWrapper<T, S>
51+
{
52+
}
53+
54+
// this blanket impl is needed for HMAC
55+
impl<T: ExtendableOutput + BlockSizeUser, S: ArraySize> BlockSizeUser for XofFixedWrapper<T, S> {
56+
type BlockSize = T::BlockSize;
57+
}
58+
59+
impl<T: ExtendableOutput + KeySizeUser, S: ArraySize> KeySizeUser for XofFixedWrapper<T, S> {
60+
type KeySize = T::KeySize;
61+
}
62+
63+
impl<T: ExtendableOutput + KeyInit, S: ArraySize> KeyInit for XofFixedWrapper<T, S> {
64+
fn new(key: &crypto_common::Key<Self>) -> Self {
65+
Self {
66+
hash: T::new(key),
67+
size: PhantomData,
68+
}
69+
}
70+
}
71+
72+
impl<T: ExtendableOutput + Reset, S: ArraySize> Reset for XofFixedWrapper<T, S> {
73+
fn reset(&mut self) {
74+
self.hash.reset();
75+
}
76+
}
77+
78+
impl<T: ExtendableOutput + Update, S: ArraySize> Update for XofFixedWrapper<T, S> {
79+
fn update(&mut self, data: &[u8]) {
80+
self.hash.update(data)
81+
}
82+
}
83+
84+
impl<T: ExtendableOutput, S: ArraySize> OutputSizeUser for XofFixedWrapper<T, S> {
85+
type OutputSize = S;
86+
}
87+
88+
impl<T: ExtendableOutput + Update, S: ArraySize> FixedOutput for XofFixedWrapper<T, S> {
89+
fn finalize_into(self, out: &mut crypto_common::Output<Self>) {
90+
self.hash.finalize_xof_into(out);
91+
}
92+
}
93+
94+
impl<T: ExtendableOutputReset, S: ArraySize> FixedOutputReset for XofFixedWrapper<T, S> {
95+
fn finalize_into_reset(&mut self, out: &mut crypto_common::Output<Self>) {
96+
self.hash.finalize_xof_reset_into(out);
97+
}
98+
}
99+
100+
impl<T: ExtendableOutput, S: ArraySize> ExtendableOutput for XofFixedWrapper<T, S> {
101+
type Reader = T::Reader;
102+
103+
fn finalize_xof(self) -> Self::Reader {
104+
self.hash.finalize_xof()
105+
}
106+
}
107+
108+
impl<T: ExtendableOutputReset, S: ArraySize> ExtendableOutputReset for XofFixedWrapper<T, S> {
109+
fn finalize_xof_reset(&mut self) -> Self::Reader {
110+
self.hash.finalize_xof_reset()
111+
}
112+
}
113+
114+
#[cfg(feature = "zeroize")]
115+
impl<T: ExtendableOutput + zeroize::ZeroizeOnDrop, S: ArraySize> zeroize::ZeroizeOnDrop
116+
for XofFixedWrapper<T, S>
117+
{
118+
}
119+
120+
impl<T: ExtendableOutput + CustomizedInit, S: ArraySize> CustomizedInit for XofFixedWrapper<T, S> {
121+
fn new_customized(customization: &[u8]) -> Self {
122+
Self {
123+
hash: T::new_customized(customization),
124+
size: PhantomData,
125+
}
126+
}
127+
}
128+
129+
impl<T: ExtendableOutput + SerializableState, S: ArraySize> SerializableState
130+
for XofFixedWrapper<T, S>
131+
{
132+
type SerializedStateSize = T::SerializedStateSize;
133+
134+
fn serialize(&self) -> crypto_common::hazmat::SerializedState<Self> {
135+
self.hash.serialize()
136+
}
137+
138+
fn deserialize(
139+
serialized_state: &crypto_common::hazmat::SerializedState<Self>,
140+
) -> Result<Self, crypto_common::hazmat::DeserializeStateError> {
141+
T::deserialize(serialized_state).map(|hash| Self {
142+
hash,
143+
size: PhantomData,
144+
})
145+
}
146+
}

0 commit comments

Comments
 (0)