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
13pub 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
60impl<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}