33
44use core:: fmt:: Debug ;
55
6- use crate :: hashes:: HashSuite ;
6+ use crate :: hashes:: { HashDigest , HashSuite } ;
77use crate :: {
88 ParameterSet , address:: Address , fors:: ForsParams , hypertree:: HypertreeParams , wots:: WotsParams ,
99 xmss:: XmssParams ,
1010} ;
1111use crate :: { PkSeed , SkPrf , SkSeed } ;
1212use const_oid:: db:: fips205;
13- use digest:: { Digest , KeyInit , Mac } ;
14- use hmac:: Hmac ;
13+ use digest:: { Digest , KeyInit , Mac , Output , OutputSizeUser , Update } ;
14+ use hmac:: { EagerHash , Hmac } ;
1515use hybrid_array:: { Array , ArraySize } ;
1616use sha2:: { Sha256 , Sha512 } ;
17+ use signature:: Result ;
1718use typenum:: { Diff , Sum , U , U16 , U24 , U30 , U32 , U34 , U39 , U42 , U47 , U49 , U64 , U128 } ;
1819
1920/// Implementation of the MGF1 XOF
@@ -44,6 +45,36 @@ pub struct Sha2L1<N, M> {
4445 _m : core:: marker:: PhantomData < M > ,
4546}
4647
48+ /// `Digest` implementation [`Sha2L1`] and [`Sha2L35`].
49+ pub struct Sha2Digest < H : EagerHash > ( Inner < H > ) ;
50+
51+ enum Inner < H : EagerHash > {
52+ Hmac ( Hmac < H > ) ,
53+ Hash ( H ) ,
54+ }
55+
56+ impl < H : EagerHash > Update for Sha2Digest < H > {
57+ fn update ( & mut self , data : & [ u8 ] ) {
58+ match & mut self . 0 {
59+ Inner :: Hmac ( hmac) => Mac :: update ( hmac, data) ,
60+ Inner :: Hash ( hash) => Digest :: update ( hash, data) ,
61+ }
62+ }
63+ }
64+
65+ impl < H : EagerHash < Core : OutputSizeUser < OutputSize = H :: OutputSize > > > Sha2Digest < H > {
66+ fn finalize ( self ) -> Output < H > {
67+ match self . 0 {
68+ Inner :: Hmac ( hmac) => hmac. finalize ( ) . into_bytes ( ) ,
69+ Inner :: Hash ( hash) => hash. finalize ( ) ,
70+ }
71+ }
72+ }
73+
74+ impl < N : ArraySize , M : ArraySize > HashDigest for Sha2L1 < N , M > {
75+ type Digest = Sha2Digest < Sha256 > ;
76+ }
77+
4778impl < N : ArraySize , M : ArraySize > HashSuite for Sha2L1 < N , M >
4879where
4980 N : core:: ops:: Add < N > ,
@@ -61,35 +92,31 @@ where
6192 fn prf_msg (
6293 sk_prf : & SkPrf < Self :: N > ,
6394 opt_rand : & Array < u8 , Self :: N > ,
64- msg : & [ & [ impl AsRef < [ u8 ] > ] ] ,
65- ) -> Array < u8 , Self :: N > {
66- let mut mac = Hmac :: < Sha256 > :: new_from_slice ( sk_prf. as_ref ( ) ) . unwrap ( ) ;
95+ msg : & impl Fn ( & mut Self :: Digest ) -> Result < ( ) > ,
96+ ) -> Result < Array < u8 , Self :: N > > {
97+ let mut mac = Sha2Digest ( Inner :: Hmac (
98+ Hmac :: < Sha256 > :: new_from_slice ( sk_prf. as_ref ( ) ) . unwrap ( ) ,
99+ ) ) ;
67100 mac. update ( opt_rand. as_slice ( ) ) ;
68- msg. iter ( )
69- . copied ( )
70- . flatten ( )
71- . for_each ( |msg_part| mac. update ( msg_part. as_ref ( ) ) ) ;
72- let result = mac. finalize ( ) . into_bytes ( ) ;
73- Array :: clone_from_slice ( & result[ ..Self :: N :: USIZE ] )
101+ msg ( & mut mac) ?;
102+ let result = mac. finalize ( ) ;
103+ Ok ( Array :: clone_from_slice ( & result[ ..Self :: N :: USIZE ] ) )
74104 }
75105
76106 fn h_msg (
77107 rand : & Array < u8 , Self :: N > ,
78108 pk_seed : & PkSeed < Self :: N > ,
79109 pk_root : & Array < u8 , Self :: N > ,
80- msg : & [ & [ impl AsRef < [ u8 ] > ] ] ,
81- ) -> Array < u8 , Self :: M > {
82- let mut h = Sha256 :: new ( ) ;
110+ msg : & impl Fn ( & mut Self :: Digest ) -> Result < ( ) > ,
111+ ) -> Result < Array < u8 , Self :: M > > {
112+ let mut h = Sha2Digest ( Inner :: Hash ( Sha256 :: new ( ) ) ) ;
83113 h. update ( rand) ;
84- h. update ( pk_seed) ;
114+ h. update ( pk_seed. as_ref ( ) ) ;
85115 h. update ( pk_root) ;
86- msg. iter ( )
87- . copied ( )
88- . flatten ( )
89- . for_each ( |msg_part| h. update ( msg_part. as_ref ( ) ) ) ;
116+ msg ( & mut h) ?;
90117 let result = Array ( h. finalize ( ) . into ( ) ) ;
91118 let seed = rand. clone ( ) . concat ( pk_seed. 0 . clone ( ) ) . concat ( result) ;
92- mgf1 :: < Sha256 , Self :: M > ( & seed)
119+ Ok ( mgf1 :: < Sha256 , Self :: M > ( & seed) )
93120 }
94121
95122 fn prf_sk (
@@ -117,7 +144,8 @@ where
117144 . chain_update ( pk_seed)
118145 . chain_update ( & zeroes)
119146 . chain_update ( adrs. compressed ( ) ) ;
120- m. iter ( ) . for_each ( |x| sha. update ( x. as_slice ( ) ) ) ;
147+ m. iter ( )
148+ . for_each ( |x| Update :: update ( & mut sha, x. as_slice ( ) ) ) ;
121149 let hash = sha. finalize ( ) ;
122150 Array :: clone_from_slice ( & hash[ ..Self :: N :: USIZE ] )
123151 }
@@ -210,6 +238,10 @@ pub struct Sha2L35<N, M> {
210238 _m : core:: marker:: PhantomData < M > ,
211239}
212240
241+ impl < N : ArraySize , M : ArraySize > HashDigest for Sha2L35 < N , M > {
242+ type Digest = Sha2Digest < Sha512 > ;
243+ }
244+
213245impl < N : ArraySize , M : ArraySize > HashSuite for Sha2L35 < N , M >
214246where
215247 N : core:: ops:: Add < N > ,
@@ -229,35 +261,31 @@ where
229261 fn prf_msg (
230262 sk_prf : & SkPrf < Self :: N > ,
231263 opt_rand : & Array < u8 , Self :: N > ,
232- msg : & [ & [ impl AsRef < [ u8 ] > ] ] ,
233- ) -> Array < u8 , Self :: N > {
234- let mut mac = Hmac :: < Sha512 > :: new_from_slice ( sk_prf. as_ref ( ) ) . unwrap ( ) ;
264+ msg : & impl Fn ( & mut Self :: Digest ) -> Result < ( ) > ,
265+ ) -> Result < Array < u8 , Self :: N > > {
266+ let mut mac = Sha2Digest ( Inner :: Hmac (
267+ Hmac :: < Sha512 > :: new_from_slice ( sk_prf. as_ref ( ) ) . unwrap ( ) ,
268+ ) ) ;
235269 mac. update ( opt_rand. as_slice ( ) ) ;
236- msg. iter ( )
237- . copied ( )
238- . flatten ( )
239- . for_each ( |msg_part| mac. update ( msg_part. as_ref ( ) ) ) ;
240- let result = mac. finalize ( ) . into_bytes ( ) ;
241- Array :: clone_from_slice ( & result[ ..Self :: N :: USIZE ] )
270+ msg ( & mut mac) ?;
271+ let result = mac. finalize ( ) ;
272+ Ok ( Array :: clone_from_slice ( & result[ ..Self :: N :: USIZE ] ) )
242273 }
243274
244275 fn h_msg (
245276 rand : & Array < u8 , Self :: N > ,
246277 pk_seed : & PkSeed < Self :: N > ,
247278 pk_root : & Array < u8 , Self :: N > ,
248- msg : & [ & [ impl AsRef < [ u8 ] > ] ] ,
249- ) -> Array < u8 , Self :: M > {
250- let mut h = Sha512 :: new ( ) ;
279+ msg : & impl Fn ( & mut Self :: Digest ) -> Result < ( ) > ,
280+ ) -> Result < Array < u8 , Self :: M > > {
281+ let mut h = Sha2Digest ( Inner :: Hash ( Sha512 :: new ( ) ) ) ;
251282 h. update ( rand) ;
252- h. update ( pk_seed) ;
283+ h. update ( pk_seed. as_ref ( ) ) ;
253284 h. update ( pk_root) ;
254- msg. iter ( )
255- . copied ( )
256- . flatten ( )
257- . for_each ( |msg_part| h. update ( msg_part. as_ref ( ) ) ) ;
285+ msg ( & mut h) ?;
258286 let result = Array ( h. finalize ( ) . into ( ) ) ;
259287 let seed = rand. clone ( ) . concat ( pk_seed. 0 . clone ( ) ) . concat ( result) ;
260- mgf1 :: < Sha512 , Self :: M > ( & seed)
288+ Ok ( mgf1 :: < Sha512 , Self :: M > ( & seed) )
261289 }
262290
263291 fn prf_sk (
@@ -285,7 +313,8 @@ where
285313 . chain_update ( pk_seed)
286314 . chain_update ( & zeroes)
287315 . chain_update ( adrs. compressed ( ) ) ;
288- m. iter ( ) . for_each ( |x| sha. update ( x. as_slice ( ) ) ) ;
316+ m. iter ( )
317+ . for_each ( |x| Update :: update ( & mut sha, x. as_slice ( ) ) ) ;
289318 let hash = sha. finalize ( ) ;
290319 Array :: clone_from_slice ( & hash[ ..Self :: N :: USIZE ] )
291320 }
0 commit comments