@@ -13,15 +13,17 @@ pub use digest;
1313
1414use core:: fmt;
1515use digest:: {
16- CollisionResistance , CustomizedInit , ExtendableOutput , ExtendableOutputReset , HashMarker ,
17- Reset , Update , XofReader ,
16+ CollisionResistance , CustomizedInit , ExtendableOutput , HashMarker , Update , XofReader ,
1817 array:: Array ,
1918 block_api:: { AlgorithmName , BlockSizeUser } ,
2019 block_buffer:: { BlockSizes , EagerBuffer , ReadBuffer } ,
2120 consts:: { U16 , U32 , U136 , U168 } ,
2221} ;
2322use keccak:: { Keccak , State1600 } ;
2423
24+ const SHAKE_PAD : u8 = 0x1F ;
25+ const CSHAKE_PAD : u8 = 0x04 ;
26+
2527/// cSHAKE128 hasher.
2628pub type CShake128 = CShake < U168 > ;
2729/// cSHAKE256 hasher.
@@ -33,23 +35,15 @@ pub type CShake256 = CShake<U136>;
3335#[ derive( Clone ) ]
3436pub struct CShake < Rate : BlockSizes > {
3537 state : State1600 ,
36- initial_state : State1600 ,
37- keccak : Keccak ,
3838 buffer : EagerBuffer < Rate > ,
39+ pad : u8 ,
40+ keccak : Keccak ,
3941}
4042
4143impl < Rate : BlockSizes > Default for CShake < Rate > {
4244 #[ inline]
4345 fn default ( ) -> Self {
44- const {
45- assert ! ( Rate :: USIZE == 168 || Rate :: USIZE == 136 , "unsupported rate" ) ;
46- }
47- Self {
48- state : Default :: default ( ) ,
49- initial_state : Default :: default ( ) ,
50- keccak : Keccak :: new ( ) ,
51- buffer : Default :: default ( ) ,
52- }
46+ Self :: new_with_function_name ( b"" , b"" )
5347 }
5448}
5549
@@ -59,10 +53,21 @@ impl<Rate: BlockSizes> CShake<Rate> {
5953 /// Note that the function name is intended for use by NIST and should only be set to
6054 /// values defined by NIST. You probably don't need to use this function.
6155 pub fn new_with_function_name ( function_name : & [ u8 ] , customization : & [ u8 ] ) -> Self {
62- let mut state = Self :: default ( ) ;
56+ const {
57+ assert ! ( Rate :: USIZE == 168 || Rate :: USIZE == 136 , "unsupported rate" ) ;
58+ }
59+
60+ let buffer = Default :: default ( ) ;
61+ let keccak = Keccak :: new ( ) ;
62+ let mut state = State1600 :: default ( ) ;
6363
6464 if function_name. is_empty ( ) && customization. is_empty ( ) {
65- return state;
65+ return Self {
66+ state,
67+ buffer,
68+ keccak,
69+ pad : SHAKE_PAD ,
70+ } ;
6671 }
6772
6873 #[ inline( always) ]
@@ -73,9 +78,9 @@ impl<Rate: BlockSizes> CShake<Rate> {
7378 & b[ i..]
7479 }
7580
76- state . keccak . with_f1600 ( |f1600| {
81+ keccak. with_f1600 ( |f1600| {
7782 let mut buffer: EagerBuffer < Rate > = Default :: default ( ) ;
78- let state = & mut state. state ;
83+ let state = & mut state;
7984 let mut b = [ 0u8 ; 9 ] ;
8085
8186 buffer. digest_blocks ( left_encode ( Rate :: U64 , & mut b) , |blocks| {
@@ -96,8 +101,12 @@ impl<Rate: BlockSizes> CShake<Rate> {
96101 update_blocks ( f1600, state, & [ buffer. pad_with_zeros ( ) ] )
97102 } ) ;
98103
99- state. initial_state = state. state ;
100- state
104+ Self {
105+ state,
106+ buffer,
107+ keccak,
108+ pad : CSHAKE_PAD ,
109+ }
101110 }
102111}
103112
@@ -129,34 +138,18 @@ impl<Rate: BlockSizes> Update for CShake<Rate> {
129138 }
130139}
131140
132- impl < Rate : BlockSizes > Reset for CShake < Rate > {
133- #[ inline]
134- fn reset ( & mut self ) {
135- self . state = self . initial_state ;
136- self . buffer . reset ( ) ;
137- }
138- }
139-
140141impl < Rate : BlockSizes > CShake < Rate > {
141142 fn finalize_dirty ( & mut self ) {
142143 let Self {
143144 state,
144- keccak,
145145 buffer,
146- initial_state,
146+ pad,
147+ keccak,
147148 } = self ;
148149
149- const SHAKE_PAD : u8 = 0x1f ;
150- const CSHAKE_PAD : u8 = 0x04 ;
151-
152150 let pos = buffer. get_pos ( ) ;
153151 let mut block = buffer. pad_with_zeros ( ) ;
154- let pad = if initial_state. iter ( ) . all ( |& b| b == 0 ) {
155- SHAKE_PAD
156- } else {
157- CSHAKE_PAD
158- } ;
159- block[ pos] = pad;
152+ block[ pos] = * pad;
160153 let n = block. len ( ) ;
161154 block[ n - 1 ] |= 0x80 ;
162155
@@ -181,20 +174,6 @@ impl<Rate: BlockSizes> ExtendableOutput for CShake<Rate> {
181174 }
182175}
183176
184- impl < Rate : BlockSizes > ExtendableOutputReset for CShake < Rate > {
185- #[ inline]
186- fn finalize_xof_reset ( & mut self ) -> Self :: Reader {
187- self . finalize_dirty ( ) ;
188- let reader = Self :: Reader {
189- state : self . state ,
190- keccak : self . keccak ,
191- buffer : Default :: default ( ) ,
192- } ;
193- self . reset ( ) ;
194- reader
195- }
196- }
197-
198177impl < Rate : BlockSizes > AlgorithmName for CShake < Rate > {
199178 fn write_alg_name ( f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
200179 let alg_name = match Rate :: USIZE {
@@ -223,7 +202,7 @@ impl<Rate: BlockSizes> Drop for CShake<Rate> {
223202 {
224203 use digest:: zeroize:: Zeroize ;
225204 self . state . zeroize ( ) ;
226- self . initial_state . zeroize ( ) ;
205+ self . pad . zeroize ( ) ;
227206 // self.buffer is zeroized by its `Drop`
228207 }
229208 }
0 commit comments