3
3
#![ no_std]
4
4
#![ forbid( unused_crate_dependencies, missing_docs) ]
5
5
6
- #[ cfg( feature = "std" ) ]
6
+ #[ cfg( any ( feature = "std" , test ) ) ]
7
7
extern crate std;
8
8
9
9
extern crate alloc;
@@ -173,14 +173,16 @@ pub struct Blame {
173
173
174
174
#[ cfg( test) ]
175
175
mod tests {
176
- use alloc:: vec;
176
+ use alloc:: { vec, vec :: Vec } ;
177
177
178
+ use rand:: Rng ;
178
179
use round_based:: simulation:: Simulation ;
180
+ use sha2:: { Digest , Sha256 } ;
179
181
180
182
use super :: { protocol_of_random_generation, Msg } ;
181
183
182
184
#[ tokio:: test]
183
- async fn main ( ) {
185
+ async fn simulation_async ( ) {
184
186
let mut rng = rand_dev:: DevRng :: new ( ) ;
185
187
186
188
let n: u16 = 5 ;
@@ -203,4 +205,149 @@ mod tests {
203
205
204
206
std:: println!( "Output randomness: {}" , hex:: encode( output[ 0 ] ) ) ;
205
207
}
208
+
209
+ #[ test]
210
+ fn simulation_sync ( ) {
211
+ let mut rng = rand_dev:: DevRng :: new ( ) ;
212
+
213
+ let simulation = round_based:: simulation:: SimulationSync :: from_async_fn ( 5 , |i, party| {
214
+ protocol_of_random_generation ( party, i, 5 , rng. fork ( ) )
215
+ } ) ;
216
+
217
+ let outputs = simulation
218
+ . run ( )
219
+ . unwrap ( )
220
+ . into_iter ( )
221
+ . collect :: < Result < Vec < _ > , _ > > ( )
222
+ . unwrap ( ) ;
223
+ for output_i in & outputs {
224
+ assert_eq ! ( * output_i, outputs[ 0 ] ) ;
225
+ }
226
+ }
227
+
228
+ // Emulate the protocol using the state machine interface
229
+ #[ test]
230
+ fn state_machine ( ) {
231
+ use super :: { CommitMsg , DecommitMsg , Msg } ;
232
+ use round_based:: {
233
+ state_machine:: { ProceedResult , StateMachine } ,
234
+ Incoming , Outgoing ,
235
+ } ;
236
+
237
+ let mut rng = rand_dev:: DevRng :: new ( ) ;
238
+
239
+ let party1_rng: [ u8 ; 32 ] = rng. gen ( ) ;
240
+ let party1_com = Sha256 :: digest ( party1_rng) ;
241
+
242
+ let party2_rng: [ u8 ; 32 ] = rng. gen ( ) ;
243
+ let party2_com = Sha256 :: digest ( party2_rng) ;
244
+
245
+ // Start the protocol
246
+ let mut party0 = round_based:: state_machine:: wrap_protocol ( |party| async {
247
+ protocol_of_random_generation ( party, 0 , 3 , rng) . await
248
+ } ) ;
249
+
250
+ // Round 1
251
+
252
+ // Party sends its commitment
253
+ let ProceedResult :: SendMsg ( Outgoing {
254
+ msg : Msg :: CommitMsg ( party0_com) ,
255
+ ..
256
+ } ) = party0. proceed ( )
257
+ else {
258
+ panic ! ( "unexpected response" )
259
+ } ;
260
+
261
+ // Round 2
262
+
263
+ // Party needs messages sent by other parties in round 1
264
+ let ProceedResult :: NeedsOneMoreMessage = party0. proceed ( ) else {
265
+ panic ! ( "unexpected response" )
266
+ } ;
267
+ // Provide message from party 1
268
+ party0
269
+ . received_msg ( Incoming {
270
+ id : 0 ,
271
+ sender : 1 ,
272
+ msg_type : round_based:: MessageType :: Broadcast ,
273
+ msg : Msg :: CommitMsg ( CommitMsg {
274
+ commitment : party1_com,
275
+ } ) ,
276
+ } )
277
+ . unwrap ( ) ;
278
+ let ProceedResult :: NeedsOneMoreMessage = party0. proceed ( ) else {
279
+ panic ! ( "unexpected response" )
280
+ } ;
281
+ // Provide message from party 2
282
+ party0
283
+ . received_msg ( Incoming {
284
+ id : 1 ,
285
+ sender : 2 ,
286
+ msg_type : round_based:: MessageType :: Broadcast ,
287
+ msg : Msg :: CommitMsg ( CommitMsg {
288
+ commitment : party2_com,
289
+ } ) ,
290
+ } )
291
+ . unwrap ( ) ;
292
+
293
+ // Party sends message in round 2
294
+ let ProceedResult :: SendMsg ( Outgoing {
295
+ msg : Msg :: DecommitMsg ( party0_rng) ,
296
+ ..
297
+ } ) = party0. proceed ( )
298
+ else {
299
+ panic ! ( "unexpected response" )
300
+ } ;
301
+
302
+ {
303
+ // Check that commitment matches the revealed randomness
304
+ let expected = Sha256 :: digest ( party0_rng. randomness ) ;
305
+ assert_eq ! ( party0_com. commitment, expected) ;
306
+ }
307
+
308
+ // Final round
309
+
310
+ // Party needs messages sent by other parties in round 2
311
+ let ProceedResult :: NeedsOneMoreMessage = party0. proceed ( ) else {
312
+ panic ! ( "unexpected response" )
313
+ } ;
314
+ // Provide message from party 1
315
+ party0
316
+ . received_msg ( Incoming {
317
+ id : 3 ,
318
+ sender : 1 ,
319
+ msg_type : round_based:: MessageType :: Broadcast ,
320
+ msg : Msg :: DecommitMsg ( DecommitMsg {
321
+ randomness : party1_rng,
322
+ } ) ,
323
+ } )
324
+ . unwrap ( ) ;
325
+ let ProceedResult :: NeedsOneMoreMessage = party0. proceed ( ) else {
326
+ panic ! ( "unexpected response" )
327
+ } ;
328
+ // Provide message from party 2
329
+ party0
330
+ . received_msg ( Incoming {
331
+ id : 3 ,
332
+ sender : 2 ,
333
+ msg_type : round_based:: MessageType :: Broadcast ,
334
+ msg : Msg :: DecommitMsg ( DecommitMsg {
335
+ randomness : party2_rng,
336
+ } ) ,
337
+ } )
338
+ . unwrap ( ) ;
339
+ // Obtain the protocol result
340
+ let ProceedResult :: Output ( Ok ( output_rng) ) = party0. proceed ( ) else {
341
+ panic ! ( "unexpected response" )
342
+ } ;
343
+
344
+ let output_expected = party0_rng
345
+ . randomness
346
+ . iter ( )
347
+ . zip ( & party1_rng)
348
+ . zip ( & party2_rng)
349
+ . map ( |( ( a, b) , c) | a ^ b ^ c)
350
+ . collect :: < alloc:: vec:: Vec < _ > > ( ) ;
351
+ assert_eq ! ( output_rng, output_expected. as_slice( ) ) ;
352
+ }
206
353
}
0 commit comments