@@ -21,7 +21,7 @@ use secp256kfun::{KeyPair, hash::Hash32, nonce::NonceGen, prelude::*, rand_core}
2121/// certifying the aggregated keygen input in certpedpop.
2222pub trait CertificationScheme {
2323 /// The signature type produced by this scheme
24- type Signature : Clone + core:: fmt:: Debug ;
24+ type Signature : Clone + core:: fmt:: Debug + PartialEq ;
2525
2626 /// The output produced by successful verification
2727 type Output : Clone + core:: fmt:: Debug ;
@@ -146,14 +146,17 @@ impl<Sig> Default for Certificate<Sig> {
146146 }
147147}
148148
149- impl < Sig > Certificate < Sig > {
149+ impl < Sig : PartialEq + core :: fmt :: Debug > Certificate < Sig > {
150150 /// Create a new empty certificate
151151 pub fn new ( ) -> Self {
152152 Self :: default ( )
153153 }
154154
155155 /// Insert a signature/proof for a public key
156156 pub fn insert ( & mut self , key : Point , sig : Sig ) {
157+ if let Some ( existing) = self . 0 . get ( & key) {
158+ assert_eq ! ( existing, & sig, "certification should not change" ) ;
159+ }
157160 self . 0 . insert ( key, sig) ;
158161 }
159162
@@ -402,38 +405,47 @@ pub fn simulate_keygen<H: Hash32, NG: NonceGen, S: CertificationScheme>(
402405 cert_scheme : & S ,
403406 threshold : u32 ,
404407 n_receivers : u32 ,
405- n_generators : u32 ,
408+ n_extra_generators : u32 ,
406409 fingerprint : Fingerprint ,
407410 rng : & mut impl rand_core:: RngCore ,
408411) -> (
409412 CertifiedKeygen < S > ,
410413 Vec < ( PairedSecretShare < Normal > , KeyPair ) > ,
411414) {
412- let share_receivers = ( 1 ..=n_receivers)
413- . map ( |i| Scalar :: from ( i) . non_zero ( ) . unwrap ( ) )
414- . collect :: < BTreeSet < _ > > ( ) ;
415-
416- let mut receiver_enckeys = share_receivers
417- . iter ( )
418- . cloned ( )
419- . map ( |party_index| ( party_index, KeyPair :: new ( Scalar :: random ( rng) ) ) )
415+ let mut receiver_enckeys = ( 1 ..=n_receivers)
416+ . map ( |i| {
417+ let party_index = Scalar :: from ( i) . non_zero ( ) . unwrap ( ) ;
418+ ( party_index, KeyPair :: new ( Scalar :: random ( rng) ) )
419+ } )
420420 . collect :: < BTreeMap < _ , _ > > ( ) ;
421421
422422 let public_receiver_enckeys = receiver_enckeys
423423 . iter ( )
424424 . map ( |( party_index, enckeypair) | ( * party_index, enckeypair. public_key ( ) ) )
425425 . collect :: < BTreeMap < ShareIndex , Point > > ( ) ;
426426
427+ // Total number of generators is receivers + extra generators
428+ let n_generators = n_receivers + n_extra_generators;
429+
430+ // Generate keypairs for contributors - receivers will use their existing keypairs
431+ let contributor_keys: Vec < _ > = ( 1 ..=n_receivers)
432+ . map ( |i| {
433+ let party_index = Scalar :: from ( i) . non_zero ( ) . unwrap ( ) ;
434+ receiver_enckeys[ & party_index]
435+ } )
436+ . chain ( core:: iter:: repeat_n (
437+ KeyPair :: new ( Scalar :: random ( rng) ) ,
438+ n_extra_generators as _ ,
439+ ) )
440+ . collect ( ) ;
441+
427442 let ( contributors, to_coordinator_messages) : ( Vec < Contributor > , Vec < KeygenInput > ) = ( 0
428443 ..n_generators)
429444 . map ( |i| {
430445 Contributor :: gen_keygen_input ( schnorr, threshold, & public_receiver_enckeys, i, rng)
431446 } )
432447 . unzip ( ) ;
433448
434- let contributor_keys = ( 0 ..n_generators)
435- . map ( |_| KeyPair :: new ( Scalar :: random ( rng) ) )
436- . collect :: < Vec < _ > > ( ) ;
437449 let contributor_public_keys = contributor_keys
438450 . iter ( )
439451 . map ( |kp| kp. public_key ( ) )
@@ -550,7 +562,7 @@ mod test {
550562 #[ test]
551563 fn certified_run_simulate_keygen(
552564 ( n_receivers, threshold) in ( 1u32 ..=4 ) . prop_flat_map( |n| ( Just ( n) , 1u32 ..=n) ) ,
553- n_generators in 1u32 .. 5 ,
565+ n_extra_generators in 0u32 ..= 3 ,
554566 ) {
555567 let schnorr = crate :: new_with_deterministic_nonces:: <sha2:: Sha256 >( ) ;
556568 let mut rng = TestRng :: deterministic_rng( RngAlgorithm :: ChaCha ) ;
@@ -560,7 +572,7 @@ mod test {
560572 & schnorr,
561573 threshold,
562574 n_receivers,
563- n_generators ,
575+ n_extra_generators ,
564576 Fingerprint :: none( ) ,
565577 & mut rng
566578 ) ;
@@ -583,14 +595,14 @@ mod test {
583595
584596 let threshold = 2 ;
585597 let n_receivers = 3 ;
586- let n_generators = 2 ;
598+ let n_extra_generators = 0 ; // All receivers are also generators
587599
588600 let ( certified_keygen, _) = certpedpop:: simulate_keygen (
589601 & schnorr,
590602 & vrf_certifier,
591603 threshold,
592604 n_receivers,
593- n_generators ,
605+ n_extra_generators ,
594606 Fingerprint :: none ( ) ,
595607 & mut rng,
596608 ) ;
@@ -605,107 +617,7 @@ mod test {
605617 // Verify we have the expected number of VRF outputs
606618 assert_eq ! (
607619 certified_keygen. outputs( ) . len( ) ,
608- ( n_receivers + n_generators ) as usize
620+ ( n_receivers + n_extra_generators ) as usize
609621 ) ;
610622 }
611-
612- #[ test]
613- fn contributors_are_receivers ( ) {
614- use proptest:: test_runner:: { RngAlgorithm , TestRng } ;
615- let schnorr = crate :: new_with_deterministic_nonces :: < sha2:: Sha256 > ( ) ;
616- let mut rng = TestRng :: deterministic_rng ( RngAlgorithm :: ChaCha ) ;
617-
618- let threshold = 3 ;
619- let n_receivers = 5 ;
620- let n_contributors = 2 ; // First 2 receivers will also be contributors
621-
622- // Create receiver keypairs
623- let share_receivers = ( 1 ..=n_receivers)
624- . map ( |i| Scalar :: from ( i as u32 ) . non_zero ( ) . unwrap ( ) )
625- . collect :: < BTreeSet < _ > > ( ) ;
626-
627- let receiver_enckeys = share_receivers
628- . iter ( )
629- . cloned ( )
630- . map ( |party_index| ( party_index, KeyPair :: new ( Scalar :: random ( & mut rng) ) ) )
631- . collect :: < BTreeMap < _ , _ > > ( ) ;
632-
633- let public_receiver_enckeys = receiver_enckeys
634- . iter ( )
635- . map ( |( party_index, enckeypair) | ( * party_index, enckeypair. public_key ( ) ) )
636- . collect :: < BTreeMap < ShareIndex , Point > > ( ) ;
637-
638- // Generate contributors
639- let ( contributors, to_coordinator_messages) : ( Vec < Contributor > , Vec < KeygenInput > ) = ( 0
640- ..n_contributors)
641- . map ( |i| {
642- Contributor :: gen_keygen_input (
643- & schnorr,
644- threshold,
645- & public_receiver_enckeys,
646- i,
647- & mut rng,
648- )
649- } )
650- . unzip ( ) ;
651-
652- // Contributors use the first n_contributors receiver keypairs
653- let contributor_keys: Vec < KeyPair > = receiver_enckeys
654- . values ( )
655- . take ( n_contributors as usize )
656- . cloned ( )
657- . collect ( ) ;
658-
659- let contributor_public_keys = contributor_keys
660- . iter ( )
661- . map ( |kp| kp. public_key ( ) )
662- . collect :: < Vec < _ > > ( ) ;
663-
664- // Aggregate inputs
665- let mut aggregator = Coordinator :: new ( threshold, n_contributors, & public_receiver_enckeys) ;
666-
667- for ( i, to_coordinator_message) in to_coordinator_messages. into_iter ( ) . enumerate ( ) {
668- aggregator
669- . add_input ( & schnorr, i as u32 , to_coordinator_message)
670- . unwrap ( ) ;
671- }
672-
673- let agg_input = aggregator. finish ( ) . unwrap ( ) ;
674- let mut certificate = Certificate :: new ( ) ;
675-
676- // Contributors certify
677- for ( contributor, keypair) in contributors. into_iter ( ) . zip ( contributor_keys. iter ( ) ) {
678- let sig = contributor
679- . verify_agg_input ( & schnorr, & agg_input, keypair)
680- . unwrap ( ) ;
681- certificate. insert ( keypair. public_key ( ) , sig) ;
682- }
683-
684- // Receivers certify
685- let mut paired_secret_shares = vec ! [ ] ;
686- let mut share_receivers = vec ! [ ] ;
687- for ( party_index, enckey) in & receiver_enckeys {
688- let ( share_receiver, cert) = SecretShareReceiver :: receive_secret_share (
689- & schnorr,
690- & schnorr,
691- * party_index,
692- enckey,
693- & agg_input,
694- )
695- . unwrap ( ) ;
696- certificate. insert ( enckey. public_key ( ) , cert) ;
697- share_receivers. push ( share_receiver) ;
698- }
699-
700- // Finalize
701- for share_receiver in share_receivers {
702- let ( _certified_keygen, paired_secret_share) = share_receiver
703- . finalize ( & schnorr, certificate. clone ( ) , & contributor_public_keys)
704- . unwrap ( ) ;
705- paired_secret_shares. push ( paired_secret_share. non_zero ( ) . unwrap ( ) ) ;
706- }
707-
708- // Verify we have the expected number of unique shares
709- assert_eq ! ( paired_secret_shares. len( ) , n_receivers as usize ) ;
710- }
711623}
0 commit comments