@@ -3,27 +3,27 @@ use core::fmt;
33use digest:: {
44 CollisionResistance , ExtendableOutput , ExtendableOutputReset , HashMarker , OutputSizeUser ,
55 Reset , Update ,
6- block_api:: AlgorithmName ,
7- block_buffer:: EagerBuffer ,
6+ common:: AlgorithmName ,
87 common:: hazmat:: { DeserializeStateError , SerializableState , SerializedState } ,
9- consts:: { U8 , U16 , U32 , U48 } ,
8+ consts:: { U8 , U16 , U32 , U41 } ,
109} ;
10+ use sponge_cursor:: SpongeCursor ;
1111
1212use crate :: { AsconXof128Reader , consts:: XOF_INIT_STATE } ;
1313
1414/// Ascon-XOF128 hasher.
1515#[ derive( Clone ) ]
1616pub struct AsconXof128 {
1717 state : State ,
18- buffer : EagerBuffer < U8 > ,
18+ cursor : SpongeCursor < U8 > ,
1919}
2020
2121impl Default for AsconXof128 {
2222 #[ inline]
2323 fn default ( ) -> Self {
2424 Self {
2525 state : XOF_INIT_STATE ,
26- buffer : Default :: default ( ) ,
26+ cursor : Default :: default ( ) ,
2727 }
2828 }
2929}
@@ -42,38 +42,31 @@ impl CollisionResistance for AsconXof128 {
4242impl Update for AsconXof128 {
4343 #[ inline]
4444 fn update ( & mut self , data : & [ u8 ] ) {
45- self . buffer . digest_blocks ( data, |blocks| {
46- for block in blocks {
47- self . state [ 0 ] ^= u64:: from_le_bytes ( block. 0 ) ;
48- ascon:: permute12 ( & mut self . state ) ;
49- }
50- } ) ;
45+ self . cursor
46+ . absorb_u64_le ( & mut self . state , ascon:: permute12, data) ;
5147 }
5248}
5349
5450impl AsconXof128 {
55- fn finalize_xof_dirty ( & mut self ) -> AsconXof128Reader {
56- let Self { state, buffer } = self ;
57- let len = buffer. get_pos ( ) ;
58- let last_block = buffer. pad_with_zeros ( ) ;
59- let pad = 1u64 << ( 8 * len) ;
60- state[ 0 ] ^= u64:: from_le_bytes ( last_block. 0 ) ^ pad;
61-
62- AsconXof128Reader :: new ( state)
51+ fn pad ( & mut self ) {
52+ let pos = self . cursor . pos ( ) ;
53+ self . state [ 0 ] ^= 1u64 << ( 8 * pos) ;
6354 }
6455}
6556
6657impl ExtendableOutput for AsconXof128 {
6758 type Reader = AsconXof128Reader ;
6859
6960 fn finalize_xof ( mut self ) -> Self :: Reader {
70- self . finalize_xof_dirty ( )
61+ self . pad ( ) ;
62+ AsconXof128Reader :: new ( & self . state )
7163 }
7264}
7365
7466impl ExtendableOutputReset for AsconXof128 {
7567 fn finalize_xof_reset ( & mut self ) -> Self :: Reader {
76- let res = self . finalize_xof_dirty ( ) ;
68+ self . pad ( ) ;
69+ let res = AsconXof128Reader :: new ( & self . state ) ;
7770 self . reset ( ) ;
7871 res
7972 }
@@ -83,7 +76,7 @@ impl Reset for AsconXof128 {
8376 #[ inline]
8477 fn reset ( & mut self ) {
8578 self . state = XOF_INIT_STATE ;
86- self . buffer . reset ( ) ;
79+ self . cursor = Default :: default ( ) ;
8780 }
8881}
8982
@@ -102,37 +95,36 @@ impl fmt::Debug for AsconXof128 {
10295}
10396
10497impl SerializableState for AsconXof128 {
105- type SerializedStateSize = U48 ;
98+ type SerializedStateSize = U41 ;
10699
107100 #[ inline]
108101 fn serialize ( & self ) -> SerializedState < Self > {
109102 let mut res = SerializedState :: < Self > :: default ( ) ;
110- let ( state_dst, buffer_dst ) = res. split_at_mut ( size_of :: < State > ( ) ) ;
103+ let ( state_dst, cursor_dst ) = res. split_at_mut ( size_of :: < State > ( ) ) ;
111104 let mut chunks = state_dst. chunks_exact_mut ( size_of :: < u64 > ( ) ) ;
112105 for ( src, dst) in self . state . iter ( ) . zip ( & mut chunks) {
113106 dst. copy_from_slice ( & src. to_le_bytes ( ) ) ;
114107 }
115108 assert ! ( chunks. into_remainder( ) . is_empty( ) ) ;
116- buffer_dst. copy_from_slice ( & self . buffer . serialize ( ) ) ;
109+ assert_eq ! ( cursor_dst. len( ) , 1 ) ;
110+ cursor_dst[ 0 ] = self . cursor . raw_pos ( ) ;
117111 res
118112 }
119113
120114 #[ inline]
121115 fn deserialize (
122116 serialized_state : & SerializedState < Self > ,
123117 ) -> Result < Self , DeserializeStateError > {
124- let ( state_src, buffer_src ) = serialized_state. split_at ( size_of :: < State > ( ) ) ;
118+ let ( state_src, cursor_src ) = serialized_state. split_at ( size_of :: < State > ( ) ) ;
125119 let state = core:: array:: from_fn ( |i| {
126120 let n = size_of :: < u64 > ( ) ;
127121 let chunk = & state_src[ n * i..] [ ..n] ;
128122 u64:: from_le_bytes ( chunk. try_into ( ) . expect ( "chunk has correct length" ) )
129123 } ) ;
130- let buffer_src = buffer_src
131- . try_into ( )
132- . expect ( "buffer_src has correct length" ) ;
133- EagerBuffer :: deserialize ( buffer_src)
134- . map_err ( |_| DeserializeStateError )
135- . map ( |buffer| Self { state, buffer } )
124+ assert_eq ! ( cursor_src. len( ) , 1 ) ;
125+ SpongeCursor :: new ( cursor_src[ 0 ] )
126+ . ok_or ( DeserializeStateError )
127+ . map ( |cursor| Self { state, cursor } )
136128 }
137129}
138130
@@ -141,10 +133,9 @@ impl Drop for AsconXof128 {
141133 fn drop ( & mut self ) {
142134 #[ cfg( feature = "zeroize" ) ]
143135 {
144- use digest:: zeroize:: { Zeroize , ZeroizeOnDrop } ;
145- fn assert_zeroize_on_drop < T : ZeroizeOnDrop > ( _: & mut T ) { }
136+ use digest:: zeroize:: Zeroize ;
146137 self . state . zeroize ( ) ;
147- assert_zeroize_on_drop ( & mut self . buffer ) ;
138+ self . cursor . zeroize ( ) ;
148139 }
149140 }
150141}
0 commit comments