1use core::fmt;
8
9use block_buffer::LazyBuffer;
10use digest::block_api::{
11 AlgorithmName,
12 Block,
13 BlockSizeUser,
14 Buffer,
15 BufferKindUser,
16 Eager,
17 ExtendableOutputCore,
18 UpdateCore,
19};
20use digest::common::hazmat::{
21 DeserializeStateError,
22 SerializableState,
23 SerializedState,
24};
25use digest::consts::{
26 U16,
27 U32,
28 U136,
29 U168,
30 U400,
31};
32use digest::typenum::Unsigned;
33use digest::{
34 CollisionResistance,
35 CustomizedInit,
36 HashMarker,
37 Reset,
38};
39
40use crate::block_api::xor_block;
41use crate::{
42 CSHAKE_PAD,
43 DEFAULT_ROUND_COUNT as ROUNDS,
44 PLEN,
45 SHAKE_PAD,
46 SpongeReaderCore,
47};
48
49#[inline]
50fn plen_little_endian_from_serialized_bytes(
51 src: &[u8],
52) -> Result<[u64; PLEN], DeserializeStateError> {
53 let (lanes, remainder) = src.as_chunks::<8>();
54 if !remainder.is_empty() || lanes.len() != PLEN {
55 return Err(DeserializeStateError);
56 }
57 Ok(core::array::from_fn(|i| u64::from_le_bytes(lanes[i])))
58}
59
60macro_rules! impl_cshake {
61 (
62 $name:ident, $full_name:ident, $reader_name:ident, $rate:ident, $alg_name:expr
63 ) => {
64 #[doc = $alg_name]
65 #[doc = " core hasher."]
66 #[derive(Clone, Default)]
67 pub struct $name {
68 state: [u64; PLEN],
69 initial_state: [u64; PLEN],
70 }
71
72 impl $name {
73 pub fn new_with_function_name(function_name: &[u8], customization: &[u8]) -> Self {
78 let mut state = Self::default();
79
80 if function_name.is_empty() && customization.is_empty() {
81 return state;
82 }
83
84 #[inline(always)]
85 pub(crate) fn left_encode(val: u64, b: &mut [u8; 9]) -> &[u8] {
86 b[1..].copy_from_slice(&val.to_be_bytes());
87 let i = b[1..8].iter().take_while(|&&a| a == 0).count();
88 b[i] = (8 - i) as u8;
89 &b[i..]
90 }
91
92 let mut buffer: LazyBuffer<$rate> = Default::default();
95 let mut b = [0u8; 9];
96 buffer.digest_blocks(left_encode($rate::to_u64(), &mut b), |blocks| {
97 state.update_blocks(blocks)
98 });
99 let mut encode_str = |str: &[u8]| {
100 let str_bits_len = 8 * (str.len() as u64);
101 let encoded_len = left_encode(str_bits_len, &mut b);
102 buffer.digest_blocks(encoded_len, |blocks| state.update_blocks(blocks));
103 buffer.digest_blocks(str, |blocks| state.update_blocks(blocks));
104 };
105 encode_str(function_name);
106 encode_str(customization);
107 state.update_blocks(&[buffer.pad_with_zeros()]);
108 state.initial_state = state.state;
109 state
110 }
111 }
112
113 impl CustomizedInit for $name {
114 #[inline]
115 fn new_customized(customization: &[u8]) -> Self {
116 Self::new_with_function_name(&[], customization)
117 }
118 }
119
120 impl BufferKindUser for $name {
121 type BufferKind = Eager;
122 }
123
124 impl HashMarker for $name {}
125
126 impl BlockSizeUser for $name {
127 type BlockSize = $rate;
128 }
129
130 impl UpdateCore for $name {
131 #[inline]
132 fn update_blocks(&mut self, blocks: &[Block<Self>]) {
133 for block in blocks {
134 xor_block(&mut self.state, block);
135 lib_q_keccak::p1600(&mut self.state, ROUNDS);
136 }
137 }
138 }
139
140 impl ExtendableOutputCore for $name {
141 type ReaderCore = SpongeReaderCore<$rate>;
142
143 #[inline]
144 fn finalize_xof_core(&mut self, buffer: &mut Buffer<Self>) -> Self::ReaderCore {
145 let pos = buffer.get_pos();
146 let mut block = buffer.pad_with_zeros();
147 let pad = if self.initial_state == [0; PLEN] {
148 SHAKE_PAD
149 } else {
150 CSHAKE_PAD
151 };
152 block[pos] = pad;
153 let n = block.len();
154 block[n - 1] |= 0x80;
155
156 xor_block(&mut self.state, &block);
157 lib_q_keccak::p1600(&mut self.state, ROUNDS);
158
159 SpongeReaderCore::new(&self.state)
160 }
161 }
162
163 impl Reset for $name {
164 #[inline]
165 fn reset(&mut self) {
166 self.state = self.initial_state;
167 }
168 }
169
170 impl AlgorithmName for $name {
171 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 f.write_str($alg_name)
173 }
174 }
175
176 impl fmt::Debug for $name {
177 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178 f.write_str(concat!(stringify!($name), " { ... }"))
179 }
180 }
181
182 impl Drop for $name {
183 fn drop(&mut self) {
184 #[cfg(feature = "zeroize")]
185 {
186 use digest::zeroize::Zeroize;
187 self.state.zeroize();
188 self.initial_state.zeroize();
189 }
190 }
191 }
192
193 #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
194 #[cfg(feature = "zeroize")]
195 impl digest::zeroize::ZeroizeOnDrop for $name {}
196
197 impl SerializableState for $name {
198 type SerializedStateSize = U400;
199
200 fn serialize(&self) -> SerializedState<Self> {
201 let mut serialized_state = SerializedState::<Self>::default();
202 let mut chunks = serialized_state.chunks_exact_mut(8);
203
204 for (val, chunk) in self.state.iter().zip(&mut chunks) {
205 chunk.copy_from_slice(&val.to_le_bytes());
206 }
207 for (val, chunk) in self.initial_state.iter().zip(&mut chunks) {
208 chunk.copy_from_slice(&val.to_le_bytes());
209 }
210
211 serialized_state
212 }
213
214 fn deserialize(
215 serialized_state: &SerializedState<Self>,
216 ) -> Result<Self, DeserializeStateError> {
217 let bytes: &[u8] = serialized_state.as_ref();
218 let (state_src, initial_state_src) = bytes
219 .split_at_checked(200)
220 .ok_or(DeserializeStateError)?;
221 Ok(Self {
222 state: plen_little_endian_from_serialized_bytes(state_src)?,
223 initial_state: plen_little_endian_from_serialized_bytes(
224 initial_state_src,
225 )?,
226 })
227 }
228 }
229
230 digest::buffer_xof!(
231 #[doc = $alg_name]
232 #[doc = " hasher."]
233 pub struct $full_name($name);
234 impl: Debug AlgorithmName Clone Default BlockSizeUser CoreProxy HashMarker Update Reset ExtendableOutputReset CustomizedInit;
240 #[doc = $alg_name]
241 #[doc = " XOF reader."]
242 pub struct $reader_name(SpongeReaderCore<$rate>);
243 impl: XofReaderTraits;
244 );
245
246 impl $full_name {
247 pub fn new_with_function_name(function_name: &[u8], customization: &[u8]) -> Self {
252 Self {
253 core: $name::new_with_function_name(function_name, customization),
254 buffer: Default::default(),
255 }
256 }
257 }
258 };
259}
260
261impl_cshake!(CShake128Core, CShake128, CShake128Reader, U168, "cSHAKE128");
262impl_cshake!(CShake256Core, CShake256, CShake256Reader, U136, "cSHAKE256");
263
264impl SerializableState for CShake128 {
269 type SerializedStateSize = U400;
270
271 fn serialize(&self) -> SerializedState<Self> {
272 self.core.serialize()
273 }
274
275 fn deserialize(
276 serialized_state: &SerializedState<Self>,
277 ) -> Result<Self, DeserializeStateError> {
278 let core = CShake128Core::deserialize(serialized_state)?;
279 Ok(Self {
280 core,
281 buffer: Default::default(),
282 })
283 }
284}
285
286impl SerializableState for CShake256 {
287 type SerializedStateSize = U400;
288
289 fn serialize(&self) -> SerializedState<Self> {
290 self.core.serialize()
291 }
292
293 fn deserialize(
294 serialized_state: &SerializedState<Self>,
295 ) -> Result<Self, DeserializeStateError> {
296 let core = CShake256Core::deserialize(serialized_state)?;
297 Ok(Self {
298 core,
299 buffer: Default::default(),
300 })
301 }
302}
303
304impl CollisionResistance for CShake128 {
305 type CollisionResistance = U16;
307}
308
309impl CollisionResistance for CShake256 {
310 type CollisionResistance = U32;
312}