11use ascon:: State ;
2+ use core:: fmt;
23use digest:: {
3- CollisionResistance , CustomizedInit , ExtendableOutput , HashMarker , OutputSizeUser , Update ,
4- common:: AlgorithmName ,
5- common:: hazmat:: { DeserializeStateError , SerializableState , SerializedState } ,
4+ CollisionResistance , ExtendableOutput , HashMarker , OutputSizeUser , TryCustomizedInit , Update ,
5+ common:: {
6+ AlgorithmName ,
7+ hazmat:: { DeserializeStateError , SerializableState , SerializedState } ,
8+ } ,
69 consts:: { U16 , U32 , U41 } ,
710} ;
811use sponge_cursor:: SpongeCursor ;
912
1013use crate :: { AsconXof128Reader , consts:: CXOF_INIT_STATE } ;
1114
15+ const MAX_CUSTOMIZATION_LEN : usize = 256 ;
16+
1217/// Ascon-CXOF128 hasher.
1318///
1419/// Note that NIST SP 800-232 specifies the following:
1520///
1621/// >The length of the customization string **shall** be at most 2048 bits (i.e., 256 bytes).
1722///
18- /// We do not check this condition as part of [`CustomizedInit::new_customized `] and
19- /// consider it the user's responsibility to use appropriately sized customization strings.
23+ /// Implementation of the [`TryCustomizedInit `] trait for this type returns
24+ /// [`InvalidCustomizationError`] for longer customization strings.
2025#[ derive( Clone , Debug ) ]
2126pub struct AsconCxof128 {
2227 state : State ,
2328 cursor : SpongeCursor < 8 > ,
2429}
2530
26- impl CustomizedInit for AsconCxof128 {
31+ impl TryCustomizedInit for AsconCxof128 {
32+ type Error = InvalidCustomizationError ;
2733 #[ inline]
28- fn new_customized ( customization : & [ u8 ] ) -> Self {
29- // We assume that in practice customization strings are always smaller than 2^61 bytes.
34+ fn try_new_customized ( customization : & [ u8 ] ) -> Result < Self , InvalidCustomizationError > {
35+ if customization. len ( ) > MAX_CUSTOMIZATION_LEN {
36+ return Err ( InvalidCustomizationError ) ;
37+ }
38+
3039 let bit_len = 8 * customization. len ( ) ;
3140 let mut state = CXOF_INIT_STATE ;
3241
33- state[ 0 ] ^= u64:: try_from ( bit_len) . expect ( "`usize` always fits into `u64` in practice " ) ;
42+ state[ 0 ] ^= u64:: try_from ( bit_len) . expect ( "`bit_len` can not be greater than 2048 " ) ;
3443
3544 ascon:: permute12 ( & mut state) ;
3645
@@ -53,7 +62,7 @@ impl CustomizedInit for AsconCxof128 {
5362 ascon:: permute12 ( & mut state) ;
5463
5564 let cursor = Default :: default ( ) ;
56- Self { state, cursor }
65+ Ok ( Self { state, cursor } )
5766 }
5867}
5968
@@ -141,3 +150,18 @@ impl Drop for AsconCxof128 {
141150
142151#[ cfg( feature = "zeroize" ) ]
143152impl digest:: zeroize:: ZeroizeOnDrop for AsconCxof128 { }
153+
154+ /// Invalid Ascon-CXOF128 customization string error.
155+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
156+ pub struct InvalidCustomizationError ;
157+
158+ impl fmt:: Display for InvalidCustomizationError {
159+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
160+ f. write_str (
161+ "Invalid Ascon-CXOF128 customization string. \
162+ The length of the customization string shall be at most 256 bytes.",
163+ )
164+ }
165+ }
166+
167+ impl core:: error:: Error for InvalidCustomizationError { }
0 commit comments