@@ -3,8 +3,7 @@ mod generic {
3
3
use cggmp21_tests:: external_verifier:: ExternalVerifier ;
4
4
use generic_ec:: { coords:: HasAffineX , Curve , Point } ;
5
5
use rand:: seq:: SliceRandom ;
6
- use rand:: { Rng , RngCore , SeedableRng } ;
7
- use rand_chacha:: ChaCha20Rng ;
6
+ use rand:: { Rng , RngCore } ;
8
7
use rand_dev:: DevRng ;
9
8
use round_based:: simulation:: Simulation ;
10
9
use sha2:: Sha256 ;
@@ -68,7 +67,7 @@ mod generic {
68
67
let mut outputs = vec ! [ ] ;
69
68
for ( i, share) in ( 0 ..) . zip ( participants_shares) {
70
69
let party = simulation. add_party ( ) ;
71
- let mut party_rng = ChaCha20Rng :: from_seed ( rng. gen ( ) ) ;
70
+ let mut party_rng = rng. fork ( ) ;
72
71
73
72
#[ cfg( feature = "hd-wallets" ) ]
74
73
let derivation_path = derivation_path. clone ( ) ;
@@ -114,6 +113,105 @@ mod generic {
114
113
. expect ( "external verification failed" )
115
114
}
116
115
116
+ #[ test_case:: case( Some ( 3 ) , 5 , false ; "t3n5" ) ]
117
+ #[ cfg_attr( feature = "hd-wallets" , test_case:: case( Some ( 3 ) , 5 , true ; "t3n5-hd" ) ) ]
118
+ #[ tokio:: test]
119
+ async fn signing_with_presigs < E : Curve , V > ( t : Option < u16 > , n : u16 , hd_wallet : bool )
120
+ where
121
+ Point < E > : HasAffineX < E > ,
122
+ V : ExternalVerifier < E > ,
123
+ {
124
+ #[ cfg( not( feature = "hd-wallets" ) ) ]
125
+ assert ! ( !hd_wallet) ;
126
+
127
+ let mut rng = DevRng :: new ( ) ;
128
+
129
+ let shares = cggmp21_tests:: CACHED_SHARES
130
+ . get_shares :: < E , SecurityLevel128 > ( t, n, hd_wallet)
131
+ . expect ( "retrieve cached shares" ) ;
132
+
133
+ let mut simulation = Simulation :: < Msg < E , Sha256 > > :: new ( ) ;
134
+
135
+ let eid: [ u8 ; 32 ] = rng. gen ( ) ;
136
+ let eid = ExecutionId :: new ( & eid) ;
137
+
138
+ // Choose `t` signers to generate presignature
139
+ let t = shares[ 0 ] . min_signers ( ) ;
140
+ let mut participants = ( 0 ..n) . collect :: < Vec < _ > > ( ) ;
141
+ participants. shuffle ( & mut rng) ;
142
+ let participants = & participants[ ..usize:: from ( t) ] ;
143
+ println ! ( "Signers: {participants:?}" ) ;
144
+
145
+ let participants_shares = participants. iter ( ) . map ( |i| & shares[ usize:: from ( * i) ] ) ;
146
+
147
+ let mut outputs = vec ! [ ] ;
148
+ for ( i, share) in ( 0 ..) . zip ( participants_shares) {
149
+ let party = simulation. add_party ( ) ;
150
+ let mut party_rng = rng. fork ( ) ;
151
+
152
+ outputs. push ( async move {
153
+ cggmp21:: signing ( eid, i, participants, share)
154
+ . generate_presignature ( & mut party_rng, party)
155
+ . await
156
+ } ) ;
157
+ }
158
+
159
+ let presignatures = futures:: future:: try_join_all ( outputs)
160
+ . await
161
+ . expect ( "signing failed" ) ;
162
+
163
+ // Now, that we have presignatures generated, we learn (generate) a messages to sign
164
+ // and the derivation path (if hd is enabled)
165
+ let mut original_message_to_sign = [ 0u8 ; 100 ] ;
166
+ rng. fill_bytes ( & mut original_message_to_sign) ;
167
+ let message_to_sign = DataToSign :: digest :: < Sha256 > ( & original_message_to_sign) ;
168
+
169
+ #[ cfg( feature = "hd-wallets" ) ]
170
+ let derivation_path = if hd_wallet {
171
+ Some ( cggmp21_tests:: random_derivation_path ( & mut rng) )
172
+ } else {
173
+ None
174
+ } ;
175
+
176
+ let partial_signatures = presignatures
177
+ . into_iter ( )
178
+ . map ( |presig| {
179
+ #[ cfg( feature = "hd-wallets" ) ]
180
+ let presig = if let Some ( derivation_path) = & derivation_path {
181
+ let epub = shares[ 0 ] . extended_public_key ( ) . expect ( "not hd wallet" ) ;
182
+ presig
183
+ . set_derivation_path ( epub, derivation_path. iter ( ) . copied ( ) )
184
+ . unwrap ( )
185
+ } else {
186
+ presig
187
+ } ;
188
+ presig. issue_partial_signature ( message_to_sign)
189
+ } )
190
+ . collect :: < Vec < _ > > ( ) ;
191
+
192
+ let signature = cggmp21:: PartialSignature :: combine ( & partial_signatures)
193
+ . expect ( "invalid partial sigantures" ) ;
194
+
195
+ #[ cfg( feature = "hd-wallets" ) ]
196
+ let public_key = if let Some ( path) = & derivation_path {
197
+ shares[ 0 ]
198
+ . derive_child_public_key ( path. iter ( ) . cloned ( ) )
199
+ . unwrap ( )
200
+ . public_key
201
+ } else {
202
+ shares[ 0 ] . shared_public_key
203
+ } ;
204
+ #[ cfg( not( feature = "hd-wallets" ) ) ]
205
+ let public_key = shares[ 0 ] . shared_public_key ;
206
+
207
+ signature
208
+ . verify ( & public_key, & message_to_sign)
209
+ . expect ( "signature is not valid" ) ;
210
+
211
+ V :: verify ( & public_key, & signature, & original_message_to_sign)
212
+ . expect ( "external verification failed" )
213
+ }
214
+
117
215
#[ instantiate_tests( <cggmp21:: supported_curves:: Secp256k1 , cggmp21_tests:: external_verifier:: blockchains:: Bitcoin >) ]
118
216
mod secp256k1 { }
119
217
#[ instantiate_tests( <cggmp21:: supported_curves:: Secp256r1 , cggmp21_tests:: external_verifier:: Noop >) ]
0 commit comments