1#![no_std]
5#![cfg_attr(docsrs, feature(doc_auto_cfg))]
6#![doc = include_str!("../README.md")]
7#![warn(missing_docs)]
8
9use core::marker::PhantomData;
34
35use ascon_core::{pad, State};
36pub use digest::{self, Digest, ExtendableOutput, Reset, Update, XofReader};
37use digest::{
38 block_buffer::Eager,
39 consts::{U32, U8},
40 core_api::{
41 AlgorithmName, Block, Buffer, BufferKindUser, CoreWrapper, ExtendableOutputCore,
42 FixedOutputCore, UpdateCore, XofReaderCore, XofReaderCoreWrapper,
43 },
44 crypto_common::BlockSizeUser,
45 HashMarker, Output, OutputSizeUser,
46};
47
48trait HashParameters {
50 const ROUNDS: usize;
52 const IV0: u64;
54 const IV1: u64;
56 const IV2: u64;
58 const IV3: u64;
60 const IV4: u64;
62}
63
64#[derive(Clone, Debug)]
66struct Parameters;
67
68impl HashParameters for Parameters {
69 const ROUNDS: usize = 12;
70 const IV0: u64 = 0xee9398aadb67f03d;
71 const IV1: u64 = 0x8bb21831c60f1002;
72 const IV2: u64 = 0xb48a92db98d5da62;
73 const IV3: u64 = 0x43189921b8f8e3e8;
74 const IV4: u64 = 0x348fa5c9d525e140;
75}
76
77#[derive(Clone, Debug)]
79struct ParametersA;
80
81impl HashParameters for ParametersA {
82 const ROUNDS: usize = 8;
83 const IV0: u64 = 0x01470194fc6528a6;
84 const IV1: u64 = 0x738ec38ac0adffa7;
85 const IV2: u64 = 0x2ec8e3296c76384c;
86 const IV3: u64 = 0xd6f6a54d7f52377d;
87 const IV4: u64 = 0xa13c42a223be8d87;
88}
89
90#[derive(Clone, Debug)]
91struct ParametersXof;
92
93impl HashParameters for ParametersXof {
94 const ROUNDS: usize = 12;
95 const IV0: u64 = 0xb57e273b814cd416;
96 const IV1: u64 = 0x2b51042562ae2420;
97 const IV2: u64 = 0x66a3a7768ddf2218;
98 const IV3: u64 = 0x5aad0a7a8153650c;
99 const IV4: u64 = 0x4f3e0e32539493b6;
100}
101
102#[derive(Clone, Debug)]
103struct ParametersAXof;
104
105impl HashParameters for ParametersAXof {
106 const ROUNDS: usize = 8;
107 const IV0: u64 = 0x44906568b77b9832;
108 const IV1: u64 = 0xcd8d6cae53455532;
109 const IV2: u64 = 0xf7b5212756422129;
110 const IV3: u64 = 0x246885e1de0d225b;
111 const IV4: u64 = 0xa8cb5ce33449973f;
112}
113
114#[derive(Clone, Debug)]
115struct HashCore<P: HashParameters> {
116 state: State,
117 phantom: PhantomData<P>,
118}
119
120impl<P: HashParameters> HashCore<P> {
121 fn absorb_block(&mut self, block: &[u8; 8]) {
122 self.state[0] ^= u64::from_be_bytes(*block);
123 self.permute_state();
124 }
125
126 fn absorb_last_block(&mut self, block: &[u8]) {
127 debug_assert!(block.len() < 8);
128
129 let len = block.len();
130 if len > 0 {
131 let mut tmp = [0u8; 8];
132 tmp[0..len].copy_from_slice(block);
133 self.state[0] ^= u64::from_be_bytes(tmp);
134 }
135 self.state[0] ^= pad(len);
136 self.state.permute_12();
137 }
138
139 fn squeeze(&mut self, mut block: &mut [u8]) {
141 debug_assert_eq!(block.len() % 8, 0);
142
143 while block.len() > 8 {
144 block[..8].copy_from_slice(&u64::to_be_bytes(self.state[0]));
145 self.permute_state();
146 block = &mut block[8..];
147 }
148 block[..8].copy_from_slice(&u64::to_be_bytes(self.state[0]));
149 }
150
151 fn squeeze_block(&mut self) -> [u8; 8] {
153 let ret = u64::to_be_bytes(self.state[0]);
154 self.permute_state();
155 ret
156 }
157
158 #[inline(always)]
159 fn permute_state(&mut self) {
160 if P::ROUNDS == 12 {
161 self.state.permute_12();
162 } else if P::ROUNDS == 8 {
163 self.state.permute_8();
164 } else if P::ROUNDS == 6 {
165 self.state.permute_6();
166 }
167 }
168}
169
170impl<P: HashParameters> Default for HashCore<P> {
171 fn default() -> Self {
172 Self {
173 state: State::new(P::IV0, P::IV1, P::IV2, P::IV3, P::IV4),
174 phantom: PhantomData,
175 }
176 }
177}
178
179#[derive(Clone, Debug, Default)]
181pub struct AsconCore {
182 state: HashCore<Parameters>,
183}
184
185impl HashMarker for AsconCore {}
186
187impl BlockSizeUser for AsconCore {
188 type BlockSize = U8;
189}
190
191impl BufferKindUser for AsconCore {
192 type BufferKind = Eager;
193}
194
195impl OutputSizeUser for AsconCore {
196 type OutputSize = U32;
197}
198
199impl UpdateCore for AsconCore {
200 fn update_blocks(&mut self, blocks: &[Block<Self>]) {
201 for block in blocks {
202 self.state.absorb_block(block.as_ref());
203 }
204 }
205}
206
207impl FixedOutputCore for AsconCore {
208 fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
209 debug_assert!(buffer.get_pos() < 8);
210 self.state
211 .absorb_last_block(&buffer.get_data()[..buffer.get_pos()]);
212 self.state.squeeze(out);
213 }
214}
215
216impl Reset for AsconCore {
217 fn reset(&mut self) {
218 *self = Default::default();
219 }
220}
221
222impl AlgorithmName for AsconCore {
223 fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
224 f.write_str("AsconHash")
225 }
226}
227
228#[derive(Clone, Debug, Default)]
230pub struct AsconACore {
231 state: HashCore<ParametersA>,
232}
233
234impl HashMarker for AsconACore {}
235
236impl BlockSizeUser for AsconACore {
237 type BlockSize = U8;
238}
239
240impl BufferKindUser for AsconACore {
241 type BufferKind = Eager;
242}
243
244impl OutputSizeUser for AsconACore {
245 type OutputSize = U32;
246}
247
248impl UpdateCore for AsconACore {
249 fn update_blocks(&mut self, blocks: &[Block<Self>]) {
250 for block in blocks {
251 self.state.absorb_block(block.as_ref());
252 }
253 }
254}
255
256impl FixedOutputCore for AsconACore {
257 fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
258 debug_assert!(buffer.get_pos() < 8);
259 self.state
260 .absorb_last_block(&buffer.get_data()[..buffer.get_pos()]);
261 self.state.squeeze(out);
262 }
263}
264
265impl Reset for AsconACore {
266 fn reset(&mut self) {
267 *self = Default::default();
268 }
269}
270
271impl AlgorithmName for AsconACore {
272 fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
273 f.write_str("AsconAHash")
274 }
275}
276
277#[derive(Clone, Debug, Default)]
279pub struct AsconXofCore {
280 state: HashCore<ParametersXof>,
281}
282
283impl HashMarker for AsconXofCore {}
284
285impl BlockSizeUser for AsconXofCore {
286 type BlockSize = U8;
287}
288
289impl BufferKindUser for AsconXofCore {
290 type BufferKind = Eager;
291}
292
293impl UpdateCore for AsconXofCore {
294 fn update_blocks(&mut self, blocks: &[Block<Self>]) {
295 for block in blocks {
296 self.state.absorb_block(block.as_ref());
297 }
298 }
299}
300
301#[derive(Clone, Debug)]
303pub struct AsconXofReaderCore {
304 hasher: HashCore<ParametersXof>,
305}
306
307impl BlockSizeUser for AsconXofReaderCore {
308 type BlockSize = U8;
309}
310
311impl XofReaderCore for AsconXofReaderCore {
312 fn read_block(&mut self) -> Block<Self> {
313 self.hasher.squeeze_block().into()
314 }
315}
316
317impl ExtendableOutputCore for AsconXofCore {
318 type ReaderCore = AsconXofReaderCore;
319
320 fn finalize_xof_core(&mut self, buffer: &mut Buffer<Self>) -> Self::ReaderCore {
321 debug_assert!(buffer.get_pos() < 8);
322 self.state
323 .absorb_last_block(&buffer.get_data()[..buffer.get_pos()]);
324 Self::ReaderCore {
325 hasher: self.state.clone(),
326 }
327 }
328}
329
330impl Reset for AsconXofCore {
331 fn reset(&mut self) {
332 *self = Default::default();
333 }
334}
335
336impl AlgorithmName for AsconXofCore {
337 fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
338 f.write_str("AsconXOF")
339 }
340}
341
342#[derive(Clone, Debug, Default)]
344pub struct AsconAXofCore {
345 state: HashCore<ParametersAXof>,
346}
347
348impl HashMarker for AsconAXofCore {}
349
350impl BlockSizeUser for AsconAXofCore {
351 type BlockSize = U8;
352}
353
354impl BufferKindUser for AsconAXofCore {
355 type BufferKind = Eager;
356}
357
358impl UpdateCore for AsconAXofCore {
359 fn update_blocks(&mut self, blocks: &[Block<Self>]) {
360 for block in blocks {
361 self.state.absorb_block(block.as_ref());
362 }
363 }
364}
365
366#[derive(Clone, Debug)]
368pub struct AsconAXofReaderCore {
369 hasher: HashCore<ParametersAXof>,
370}
371
372impl BlockSizeUser for AsconAXofReaderCore {
373 type BlockSize = U8;
374}
375
376impl XofReaderCore for AsconAXofReaderCore {
377 fn read_block(&mut self) -> Block<Self> {
378 self.hasher.squeeze_block().into()
379 }
380}
381
382impl ExtendableOutputCore for AsconAXofCore {
383 type ReaderCore = AsconAXofReaderCore;
384
385 fn finalize_xof_core(&mut self, buffer: &mut Buffer<Self>) -> Self::ReaderCore {
386 debug_assert!(buffer.get_pos() < 8);
387 self.state
388 .absorb_last_block(&buffer.get_data()[..buffer.get_pos()]);
389 Self::ReaderCore {
390 hasher: self.state.clone(),
391 }
392 }
393}
394
395impl Reset for AsconAXofCore {
396 fn reset(&mut self) {
397 *self = Default::default();
398 }
399}
400
401impl AlgorithmName for AsconAXofCore {
402 fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
403 f.write_str("AsconAXOF")
404 }
405}
406
407pub type AsconHash = CoreWrapper<AsconCore>;
418pub type AsconAHash = CoreWrapper<AsconACore>;
429pub type AsconXof = CoreWrapper<AsconXofCore>;
442pub type AsconXofReader = XofReaderCoreWrapper<AsconXofReaderCore>;
444pub type AsconAXof = CoreWrapper<AsconAXofCore>;
457pub type AsconAXofReader = XofReaderCoreWrapper<AsconAXofReaderCore>;