digest/
xof_fixed.rs

1use core::fmt;
2use core::marker::PhantomData;
3
4use crypto_common::array::ArraySize;
5use crypto_common::hazmat::SerializableState;
6use crypto_common::{BlockSizeUser, KeyInit, KeySizeUser, OutputSizeUser, Reset};
7
8use crate::{
9    CollisionResistance, CustomizedInit, ExtendableOutput, ExtendableOutputReset, FixedOutput,
10    FixedOutputReset, HashMarker, Update,
11};
12
13/// Wrapper around [`ExtendableOutput`] types adding [`OutputSizeUser`] with the given size of `S`.
14pub struct XofFixedWrapper<T: ExtendableOutput, S: ArraySize> {
15    hash: T,
16    size: PhantomData<S>,
17}
18
19impl<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
28impl<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
37impl<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
46impl<T: ExtendableOutput + HashMarker, S: ArraySize> HashMarker for XofFixedWrapper<T, S> {}
47
48#[cfg(feature = "mac")]
49impl<T: ExtendableOutput + crate::MacMarker, S: ArraySize> crate::MacMarker
50    for XofFixedWrapper<T, S>
51{
52}
53
54impl<T: ExtendableOutput + CollisionResistance, S: ArraySize> CollisionResistance
55    for XofFixedWrapper<T, S>
56{
57    type CollisionResistance = T::CollisionResistance;
58}
59
60// this blanket impl is needed for HMAC
61impl<T: ExtendableOutput + BlockSizeUser, S: ArraySize> BlockSizeUser for XofFixedWrapper<T, S> {
62    type BlockSize = T::BlockSize;
63}
64
65impl<T: ExtendableOutput + KeySizeUser, S: ArraySize> KeySizeUser for XofFixedWrapper<T, S> {
66    type KeySize = T::KeySize;
67}
68
69impl<T: ExtendableOutput + KeyInit, S: ArraySize> KeyInit for XofFixedWrapper<T, S> {
70    fn new(key: &crypto_common::Key<Self>) -> Self {
71        Self {
72            hash: T::new(key),
73            size: PhantomData,
74        }
75    }
76}
77
78impl<T: ExtendableOutput + Reset, S: ArraySize> Reset for XofFixedWrapper<T, S> {
79    fn reset(&mut self) {
80        self.hash.reset();
81    }
82}
83
84impl<T: ExtendableOutput + Update, S: ArraySize> Update for XofFixedWrapper<T, S> {
85    fn update(&mut self, data: &[u8]) {
86        self.hash.update(data)
87    }
88}
89
90impl<T: ExtendableOutput, S: ArraySize> OutputSizeUser for XofFixedWrapper<T, S> {
91    type OutputSize = S;
92}
93
94impl<T: ExtendableOutput + Update, S: ArraySize> FixedOutput for XofFixedWrapper<T, S> {
95    fn finalize_into(self, out: &mut crypto_common::Output<Self>) {
96        self.hash.finalize_xof_into(out);
97    }
98}
99
100impl<T: ExtendableOutputReset, S: ArraySize> FixedOutputReset for XofFixedWrapper<T, S> {
101    fn finalize_into_reset(&mut self, out: &mut crypto_common::Output<Self>) {
102        self.hash.finalize_xof_reset_into(out);
103    }
104}
105
106impl<T: ExtendableOutput, S: ArraySize> ExtendableOutput for XofFixedWrapper<T, S> {
107    type Reader = T::Reader;
108
109    fn finalize_xof(self) -> Self::Reader {
110        self.hash.finalize_xof()
111    }
112}
113
114impl<T: ExtendableOutputReset, S: ArraySize> ExtendableOutputReset for XofFixedWrapper<T, S> {
115    fn finalize_xof_reset(&mut self) -> Self::Reader {
116        self.hash.finalize_xof_reset()
117    }
118}
119
120#[cfg(feature = "zeroize")]
121impl<T: ExtendableOutput + zeroize::ZeroizeOnDrop, S: ArraySize> zeroize::ZeroizeOnDrop
122    for XofFixedWrapper<T, S>
123{
124}
125
126impl<T: ExtendableOutput + CustomizedInit, S: ArraySize> CustomizedInit for XofFixedWrapper<T, S> {
127    fn new_customized(customization: &[u8]) -> Self {
128        Self {
129            hash: T::new_customized(customization),
130            size: PhantomData,
131        }
132    }
133}
134
135impl<T: ExtendableOutput + SerializableState, S: ArraySize> SerializableState
136    for XofFixedWrapper<T, S>
137{
138    type SerializedStateSize = T::SerializedStateSize;
139
140    fn serialize(&self) -> crypto_common::hazmat::SerializedState<Self> {
141        self.hash.serialize()
142    }
143
144    fn deserialize(
145        serialized_state: &crypto_common::hazmat::SerializedState<Self>,
146    ) -> Result<Self, crypto_common::hazmat::DeserializeStateError> {
147        T::deserialize(serialized_state).map(|hash| Self {
148            hash,
149            size: PhantomData,
150        })
151    }
152}