3
3
4
4
use core:: fmt:: Debug ;
5
5
6
- use crate :: hashes:: HashSuite ;
6
+ use crate :: hashes:: { HashDigest , HashSuite } ;
7
7
use crate :: {
8
8
ParameterSet , address:: Address , fors:: ForsParams , hypertree:: HypertreeParams , wots:: WotsParams ,
9
9
xmss:: XmssParams ,
10
10
} ;
11
11
use crate :: { PkSeed , SkPrf , SkSeed } ;
12
12
use 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 } ;
15
15
use hybrid_array:: { Array , ArraySize } ;
16
16
use sha2:: { Sha256 , Sha512 } ;
17
+ use signature:: Result ;
17
18
use typenum:: { Diff , Sum , U , U16 , U24 , U30 , U32 , U34 , U39 , U42 , U47 , U49 , U64 , U128 } ;
18
19
19
20
/// Implementation of the MGF1 XOF
@@ -44,6 +45,36 @@ pub struct Sha2L1<N, M> {
44
45
_m : core:: marker:: PhantomData < M > ,
45
46
}
46
47
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
+
47
78
impl < N : ArraySize , M : ArraySize > HashSuite for Sha2L1 < N , M >
48
79
where
49
80
N : core:: ops:: Add < N > ,
@@ -61,35 +92,31 @@ where
61
92
fn prf_msg (
62
93
sk_prf : & SkPrf < Self :: N > ,
63
94
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
+ ) ) ;
67
100
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 ] ) )
74
104
}
75
105
76
106
fn h_msg (
77
107
rand : & Array < u8 , Self :: N > ,
78
108
pk_seed : & PkSeed < Self :: N > ,
79
109
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 ( ) ) ) ;
83
113
h. update ( rand) ;
84
- h. update ( pk_seed) ;
114
+ h. update ( pk_seed. as_ref ( ) ) ;
85
115
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) ?;
90
117
let result = Array ( h. finalize ( ) . into ( ) ) ;
91
118
let seed = rand. clone ( ) . concat ( pk_seed. 0 . clone ( ) ) . concat ( result) ;
92
- mgf1 :: < Sha256 , Self :: M > ( & seed)
119
+ Ok ( mgf1 :: < Sha256 , Self :: M > ( & seed) )
93
120
}
94
121
95
122
fn prf_sk (
@@ -117,7 +144,8 @@ where
117
144
. chain_update ( pk_seed)
118
145
. chain_update ( & zeroes)
119
146
. 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 ( ) ) ) ;
121
149
let hash = sha. finalize ( ) ;
122
150
Array :: clone_from_slice ( & hash[ ..Self :: N :: USIZE ] )
123
151
}
@@ -210,6 +238,10 @@ pub struct Sha2L35<N, M> {
210
238
_m : core:: marker:: PhantomData < M > ,
211
239
}
212
240
241
+ impl < N : ArraySize , M : ArraySize > HashDigest for Sha2L35 < N , M > {
242
+ type Digest = Sha2Digest < Sha512 > ;
243
+ }
244
+
213
245
impl < N : ArraySize , M : ArraySize > HashSuite for Sha2L35 < N , M >
214
246
where
215
247
N : core:: ops:: Add < N > ,
@@ -229,35 +261,31 @@ where
229
261
fn prf_msg (
230
262
sk_prf : & SkPrf < Self :: N > ,
231
263
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
+ ) ) ;
235
269
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 ] ) )
242
273
}
243
274
244
275
fn h_msg (
245
276
rand : & Array < u8 , Self :: N > ,
246
277
pk_seed : & PkSeed < Self :: N > ,
247
278
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 ( ) ) ) ;
251
282
h. update ( rand) ;
252
- h. update ( pk_seed) ;
283
+ h. update ( pk_seed. as_ref ( ) ) ;
253
284
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) ?;
258
286
let result = Array ( h. finalize ( ) . into ( ) ) ;
259
287
let seed = rand. clone ( ) . concat ( pk_seed. 0 . clone ( ) ) . concat ( result) ;
260
- mgf1 :: < Sha512 , Self :: M > ( & seed)
288
+ Ok ( mgf1 :: < Sha512 , Self :: M > ( & seed) )
261
289
}
262
290
263
291
fn prf_sk (
@@ -285,7 +313,8 @@ where
285
313
. chain_update ( pk_seed)
286
314
. chain_update ( & zeroes)
287
315
. 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 ( ) ) ) ;
289
318
let hash = sha. finalize ( ) ;
290
319
Array :: clone_from_slice ( & hash[ ..Self :: N :: USIZE ] )
291
320
}
0 commit comments