@@ -174,7 +174,7 @@ impl<Z> PointPoly<Z> {
174174#[ derive( Clone , Debug ) ]
175175pub struct KeyGen {
176176 point_polys : Vec < PointPoly > ,
177- keygen_id : Point < EvenY > ,
177+ keygen_id : Scalar ,
178178 frost_key : FrostKey ,
179179}
180180
@@ -310,7 +310,7 @@ impl FrostKey {
310310 }
311311}
312312
313- impl < H : Digest < OutputSize = U32 > + Clone , NG : AddTag > Frost < H , NG > {
313+ impl < H : Digest < OutputSize = U32 > + Clone , NG : AddTag + NonceGen > Frost < H , NG > {
314314 /// Create secret shares and our proof-of-possession to be shared with other participants.
315315 ///
316316 /// Secret shares are created for every other participant by evaluating our secret polynomial
@@ -322,31 +322,23 @@ impl<H: Digest<OutputSize = U32> + Clone, NG: AddTag> Frost<H, NG> {
322322 ///
323323 /// ## Return value
324324 ///
325- /// Returns a vector of secret shares and a proof of possession, as a tupple.
325+ /// Returns a vector of secret shares and a proof of possession Signature
326326 /// The secret shares at index 0 is destined for participant 1.
327327 pub fn create_shares (
328328 & self ,
329329 KeyGen : & KeyGen ,
330330 scalar_poly : ScalarPoly ,
331- rng : & mut ( impl RngCore + CryptoRng ) ,
332- ) -> ( Vec < Scalar < Secret , Zero > > , ( Point , Scalar < Secret , Zero > ) ) {
333- // Create proof of possession
334- let pop_r = Scalar :: random ( rng) ;
335- let pop_R = g ! ( pop_r * G ) . normalize ( ) ;
336- let pop_c = Scalar :: from_hash (
337- self . keygen_id_hash
338- . clone ( )
339- . add ( g ! ( { scalar_poly. 0 [ 0 ] . clone( ) } * G ) . normalize ( ) )
340- . add ( KeyGen . keygen_id )
341- . add ( pop_R) ,
342- ) ;
343- let pop_z = s ! ( pop_c + pop_r) ;
331+ ) -> ( Vec < Scalar < Secret , Zero > > , Signature ) {
332+ let key_pair = self . schnorr . new_keypair ( scalar_poly. 0 [ 0 ] . clone ( ) ) ;
333+ let pop = self
334+ . schnorr
335+ . sign ( & key_pair, Message :: < Public > :: plain ( "frost-pop" , b"" ) ) ;
344336
345337 let shares = ( 1 ..=KeyGen . point_polys . len ( ) )
346338 . map ( |i| scalar_poly. eval ( i as u32 ) )
347339 . collect ( ) ;
348340
349- ( shares, ( pop_R , pop_z ) )
341+ ( shares, pop )
350342 }
351343}
352344
@@ -356,22 +348,14 @@ impl<H: Digest<OutputSize = U32> + Clone, NG: AddTag> Frost<H, NG> {
356348 /// ## Return value
357349 ///
358350 /// Returns `bool` true if the proof of possession matches this point poly,
359- fn verify_pop (
360- & self ,
361- keygen_id : Point < secp256kfun:: marker:: EvenY > ,
362- point_poly : & PointPoly ,
363- pop : ( Point , Scalar < Secret , Zero > ) ,
364- ) -> bool {
365- let first_point = point_poly. 0 [ 0 ] ;
366- let ( pop_R, pop_z) = pop;
367- let pop_c = Scalar :: from_hash (
368- self . keygen_id_hash
369- . clone ( )
370- . add ( first_point)
371- . add ( keygen_id)
372- . add ( pop_R) ,
373- ) ;
374- !g ! ( pop_R + pop_c * first_point - pop_z * G ) . is_zero ( )
351+ fn verify_pop ( & self , point_poly : & PointPoly , pop : Signature ) -> bool {
352+ let ( even_poly_point, _) = point_poly. 0 [ 0 ] . into_point_with_even_y ( ) ;
353+
354+ self . schnorr . verify (
355+ & even_poly_point,
356+ Message :: < Public > :: plain ( "frost-pop" , b"" ) ,
357+ & pop,
358+ )
375359 }
376360}
377361
@@ -411,7 +395,7 @@ impl<H: Digest<OutputSize = U32> + Clone, NG: AddTag> Frost<H, NG> {
411395 . into_point_with_even_y ( ) ;
412396
413397 // TODO set keygen id
414- let keygen_id = joint_public_key;
398+ let keygen_id = Scalar :: from_hash ( self . keygen_id_hash . clone ( ) . add ( joint_public_key) ) ;
415399
416400 let verification_shares = ( 1 ..=point_polys. len ( ) )
417401 . map ( |i| joint_poly. eval ( i as u32 ) . normalize ( ) . mark :: < NonZero > ( ) )
@@ -447,20 +431,21 @@ impl<H: Digest<OutputSize = U32> + Clone, NG: AddTag> Frost<H, NG> {
447431 KeyGen : KeyGen ,
448432 my_index : u32 ,
449433 secret_shares : Vec < Scalar < Secret , Zero > > ,
450- proofs_of_possession : Vec < ( Point , Scalar < Secret , Zero > ) > ,
434+ proofs_of_possession : Vec < Signature > ,
451435 ) -> Result < ( Scalar , FrostKey ) , FinishKeyGenError > {
452436 assert_eq ! (
453437 secret_shares. len( ) ,
454438 KeyGen . frost_key. verification_shares. len( )
455439 ) ;
440+ assert_eq ! ( secret_shares. len( ) , proofs_of_possession. len( ) ) ;
456441
457442 for ( i, ( poly, pop) ) in KeyGen
458443 . point_polys
459444 . iter ( )
460445 . zip ( proofs_of_possession)
461446 . enumerate ( )
462447 {
463- if !self . verify_pop ( KeyGen . keygen_id , poly, pop) {
448+ if !self . verify_pop ( poly, pop) {
464449 return Err ( FinishKeyGenError :: InvalidProofOfPossession ( i) ) ;
465450 }
466451 }
@@ -711,30 +696,11 @@ impl<H: Digest<OutputSize = U32> + Clone, NG: NonceGen + AddTag> Frost<H, NG> {
711696 }
712697}
713698
714- /// Allows getting the FrostKey
715- // TODO seal this trait
716- pub trait GetFrostKey {
717- /// Get Frost key
718- fn get_frost_key ( & self ) -> & FrostKey ;
719- }
720-
721- impl GetFrostKey for KeyGen {
722- fn get_frost_key ( & self ) -> & FrostKey {
723- & self . frost_key
724- }
725- }
726-
727- impl GetFrostKey for FrostKey {
728- fn get_frost_key ( & self ) -> & FrostKey {
729- & self
730- }
731- }
732-
733699#[ cfg( test) ]
734700mod test {
701+ use core:: num:: NonZeroU32 ;
702+
735703 use super :: * ;
736- use rand:: { prelude:: IteratorRandom , Rng } ;
737- // proptest::prelude::*};
738704 use secp256kfun:: {
739705 nonce:: Deterministic ,
740706 proptest:: { arbitrary:: any, proptest} ,
@@ -743,95 +709,124 @@ mod test {
743709
744710 proptest ! {
745711 #[ test]
746- fn frost_prop_test( n_parties in 3u32 ..8 , something in any:: <u32 >( ) ) {
747- let mut rng = rand:: thread_rng( ) ;
748- let threshold = rng. gen_range( 2 ..=n_parties) ;
712+ fn frost_prop_test( n_parties in 3u32 ..8 , threshold in 3u32 ..8 , signers_mask_seed in any:: <u32 >( ) , tweak1 in any:: <Scalar <Public , Zero >>( ) , tweak2 in any:: <Scalar <Public , Zero >>( ) , use_tweak2 in any:: <bool >( ) ) {
713+ // Two tweaks
749714 let frost = Frost :: new( Schnorr :: <Sha256 , Deterministic <Sha256 >>:: new(
750715 Deterministic :: <Sha256 >:: default ( ) ,
751716 ) ) ;
752717 dbg!( threshold, n_parties) ;
753-
754- let scalar_polys: Vec <ScalarPoly > = ( 0 ..n_parties) . map( |_| ScalarPoly :: random( threshold, & mut rng) ) . collect( ) ;
755- let point_polys: Vec <PointPoly > = scalar_polys. iter( ) . map( |sp| sp. to_point_poly( ) ) . collect( ) ;
756-
757- let KeyGen = frost. new_keygen( point_polys) . unwrap( ) ;
758-
759- let mut proofs_of_possession= vec![ ] ;
760- let mut shares_vec = vec![ ] ;
761- for sp in scalar_polys {
762- let ( shares, pop) = frost. create_shares( & KeyGen , sp, & mut rng) ;
763- proofs_of_possession. push( pop) ;
764- shares_vec. push( shares) ;
765- }
766-
767- // let recieved_shares = signer_indexes.iter().zip(signer_indexes).map(|(i, j)| (i,j)).collect();
768- let mut recieved_shares: Vec <Vec <_>> = vec![ ] ;
769- for party_index in 0 ..n_parties {
770- recieved_shares. push( vec![ ] ) ;
771- for share_index in 0 ..n_parties {
772- recieved_shares[ party_index as usize ] . push( shares_vec[ share_index as usize ] [ party_index as usize ] . clone( ) ) ;
718+ if n_parties < threshold {
719+ dbg!( "too few parties for this threshold" ) ;
720+ } else {
721+ // create some scalar poly for each party
722+ let mut scalar_polys = vec![ ] ;
723+ for i in 1 ..=n_parties {
724+ let scalar_poly = ( 1 ..=threshold) . map( |j| Scalar :: from_non_zero_u32( NonZeroU32 :: new( i* j) . expect( "starts from 1" ) ) ) . collect( ) ;
725+ scalar_polys. push( ScalarPoly :: new( scalar_poly) ) ;
773726 }
774- }
727+ let point_polys : Vec < PointPoly > = scalar_polys . iter ( ) . map ( |sp| sp . to_point_poly ( ) ) . collect ( ) ;
775728
776- let ( secret_shares, frost_keys) : ( Vec <Scalar >, Vec <FrostKey >) = ( 0 ..n_parties) . map( |i| {
777- let ( secret_share, frost) = frost. finish_keygen(
778- KeyGen . clone( ) ,
779- i,
780- recieved_shares[ i as usize ] . clone( ) ,
781- proofs_of_possession. clone( ) ,
782- )
783- . unwrap( ) ;
784- ( secret_share, frost)
785- } ) . unzip( ) ;
786-
787-
788- // Signing coalition of t to n parties
789- let n_signers = if threshold == n_parties {
790- threshold
791- } else {
792- rng. gen_range( threshold..=n_parties)
793- } ;
794- let signer_indexes = ( 0 ..n_parties) . choose_multiple( & mut rng, n_signers as usize ) ;
729+ let KeyGen = frost. new_keygen( point_polys) . unwrap( ) ;
795730
796- let sid = frost_keys[ 0 ] . joint_public_key. to_bytes( ) ;
731+ let mut proofs_of_possession= vec![ ] ;
732+ let mut shares_vec = vec![ ] ;
733+ for sp in scalar_polys {
734+ let ( shares, pop) = frost. create_shares( & KeyGen , sp) ;
735+ proofs_of_possession. push( pop) ;
736+ shares_vec. push( shares) ;
737+ }
797738
798- let nonces: Vec <NonceKeyPair > = signer_indexes. iter( ) . map( |i| frost. gen_nonce( & secret_shares[ * i as usize ] , & sid) ) . collect( ) ;
739+ // collect the recieved shares for each party
740+ let mut recieved_shares: Vec <Vec <_>> = vec![ ] ;
741+ for party_index in 0 ..n_parties {
742+ recieved_shares. push( vec![ ] ) ;
743+ for share_index in 0 ..n_parties {
744+ recieved_shares[ party_index as usize ] . push( shares_vec[ share_index as usize ] [ party_index as usize ] . clone( ) ) ;
745+ }
746+ }
799747
800- let mut recieved_nonces: Vec <_> = vec![ ] ;
801- for ( i, nonce) in signer_indexes. iter( ) . zip( nonces. clone( ) ) {
802- recieved_nonces. push( ( * i, nonce. public( ) ) ) ;
803- }
748+ // finish keygen for each party
749+ let ( secret_shares, frost_keys) : ( Vec <Scalar >, Vec <FrostKey >) = ( 0 ..n_parties) . map( |i| {
750+ let ( secret_share, mut frost_key) = frost. finish_keygen(
751+ KeyGen . clone( ) ,
752+ i,
753+ recieved_shares[ i as usize ] . clone( ) ,
754+ proofs_of_possession. clone( ) ,
755+ )
756+ . unwrap( ) ;
757+ frost_key = frost_key. tweak( tweak1. clone( ) ) . expect( "applying tweak1" ) ;
758+ frost_key = if use_tweak2 {
759+ frost_key. tweak( tweak2. clone( ) ) . expect( "applying tweak2" )
760+ } else {
761+ frost_key
762+ } ;
763+ ( secret_share, frost_key)
764+ } ) . unzip( ) ;
765+
766+ // create a mask of signers
767+ // use bytes from random u32 to determine whether a party is a signer or not
768+ let mut signers_mask = vec![ true ] ;
769+ while signers_mask. len( ) < n_parties as usize {
770+ for v in signers_mask_seed. to_be_bytes( ) {
771+ if v > 128 {
772+ signers_mask. push( true ) ;
773+ } else {
774+ signers_mask. push( false ) ;
775+ }
776+ if signers_mask. len( ) >= n_parties as usize {
777+ break
778+ }
779+ }
780+ }
781+ let mut signer_indexes = vec![ ] ;
782+ for ( index, included) in signers_mask. iter( ) . enumerate( ) {
783+ if * included {
784+ signer_indexes. push( index) ;
785+ }
786+ }
787+ dbg!( & signer_indexes) ;
788+
789+ if signer_indexes. len( ) < threshold as usize {
790+ dbg!( "less signers than threshold.. skipping" ) ;
791+ } else {
792+ let sid = frost_keys[ 0 ] . joint_public_key. to_bytes( ) ;
793+ let nonces: Vec <NonceKeyPair > = signer_indexes. iter( ) . map( |i| frost. gen_nonce( & secret_shares[ * i as usize ] , & sid) ) . collect( ) ;
794+ // dbg!(&nonces);
795+
796+ let mut recieved_nonces: Vec <_> = vec![ ] ;
797+ for ( i, nonce) in signer_indexes. iter( ) . zip( nonces. clone( ) ) {
798+ recieved_nonces. push( ( * i as u32 , nonce. public( ) ) ) ;
799+ }
800+
801+ // Create Frost signing session
802+ let mut signatures = vec![ ] ;
803+ for i in 0 ..signer_indexes. len( ) {
804+ let signer_index = signer_indexes[ i] as usize ;
805+ let session = frost. start_sign_session( & frost_keys[ signer_index] , recieved_nonces. clone( ) , Message :: plain( "test" , b"test" ) ) ;
806+ dbg!( nonces[ i] . clone( ) ) ;
807+ let sig = frost. sign( & frost_keys[ signer_index] , & session, signer_index as u32 , & secret_shares[ signer_index] , nonces[ i] . clone( ) ) ;
808+ assert!( frost. verify_signature_share( & frost_keys[ signer_index] , & session, signer_index as u32 , sig) ) ;
809+ signatures. push( sig) ;
810+ }
811+
812+ // TODO get this session from loop above
813+ // assert same and use one
814+ let session = frost. start_sign_session( & frost_keys[ signer_indexes[ 0 ] as usize ] , recieved_nonces. clone( ) , Message :: plain( "test" , b"test" ) ) ;
815+ let combined_sig = frost. combine_signature_shares( & frost_keys[ signer_indexes[ 0 ] as usize ] , & session, signatures) ;
816+
817+ assert!( frost. schnorr. verify(
818+ & frost_keys[ signer_indexes[ 0 ] as usize ] . joint_public_key,
819+ Message :: <Public >:: plain( "test" , b"test" ) ,
820+ & combined_sig
821+ ) ) ;
804822
805- dbg!( recieved_nonces. clone( ) ) ;
806-
807- // Create Frost signing session
808- let mut signatures = vec![ ] ;
809- for i in 0 ..signer_indexes. len( ) {
810- let signer_index = signer_indexes[ i] as usize ;
811- let session = frost. start_sign_session( & frost_keys[ signer_index] , recieved_nonces. clone( ) , Message :: plain( "test" , b"test" ) ) ;
812- dbg!( nonces[ i] . clone( ) ) ;
813- let sig = frost. sign( & frost_keys[ signer_index] , & session, signer_index as u32 , & secret_shares[ signer_index] , nonces[ i] . clone( ) ) ;
814- assert!( frost. verify_signature_share( & frost_keys[ signer_index] , & session, signer_index as u32 , sig) ) ;
815- signatures. push( sig) ;
823+ }
816824 }
817-
818- // TODO get this session from loop above
819- let session = frost. start_sign_session( & frost_keys[ signer_indexes[ 0 ] as usize ] , recieved_nonces. clone( ) , Message :: plain( "test" , b"test" ) ) ;
820- let combined_sig = frost. combine_signature_shares( & frost_keys[ signer_indexes[ 0 ] as usize ] , & session, signatures) ;
821-
822- assert!( frost. schnorr. verify(
823- & frost_keys[ signer_indexes[ 0 ] as usize ] . joint_public_key,
824- Message :: <Public >:: plain( "test" , b"test" ) ,
825- & combined_sig
826- ) ) ;
827-
828-
829825 }
830826 }
831827
832828 #[ test]
833829 fn frost_test_end_to_end ( ) {
834- let mut rng = rand:: thread_rng ( ) ;
835830 // Create a secret polynomial for each participant
836831 let sp1 = ScalarPoly :: new ( vec ! [ s!( 3 ) , s!( 7 ) ] ) ;
837832 let sp2 = ScalarPoly :: new ( vec ! [ s!( 11 ) , s!( 13 ) ] ) ;
@@ -847,9 +842,9 @@ mod test {
847842 ] ;
848843
849844 let KeyGen = frost. new_keygen ( point_polys) . unwrap ( ) ;
850- let ( shares1, pop1) = frost. create_shares ( & KeyGen , sp1, & mut rng ) ;
851- let ( shares2, pop2) = frost. create_shares ( & KeyGen , sp2, & mut rng ) ;
852- let ( shares3, pop3) = frost. create_shares ( & KeyGen , sp3, & mut rng ) ;
845+ let ( shares1, pop1) = frost. create_shares ( & KeyGen , sp1) ;
846+ let ( shares2, pop2) = frost. create_shares ( & KeyGen , sp2) ;
847+ let ( shares3, pop3) = frost. create_shares ( & KeyGen , sp3) ;
853848 let proofs_of_possession = vec ! [ pop1, pop2, pop3] ;
854849
855850 let ( secret_share1, mut frost_key) = frost
@@ -881,18 +876,20 @@ mod test {
881876 assert_eq ! ( frost_key, jk3) ;
882877
883878 let use_tweak = true ;
884- if use_tweak {
885- let tweak = Scalar :: from_bytes ( [
879+ let tweak = if use_tweak {
880+ Scalar :: from_bytes ( [
886881 0xE8 , 0xF7 , 0x91 , 0xFF , 0x92 , 0x25 , 0xA2 , 0xAF , 0x01 , 0x02 , 0xAF , 0xFF , 0x4A , 0x9A ,
887882 0x72 , 0x3D , 0x96 , 0x12 , 0xA6 , 0x82 , 0xA2 , 0x5E , 0xBE , 0x79 , 0x80 , 0x2B , 0x26 , 0x3C ,
888883 0xDF , 0xCD , 0x83 , 0xBB ,
889884 ] )
890- . unwrap ( ) ;
891- // let tweak = Scalar::zero();
892- frost_key = frost_key. tweak ( tweak. clone ( ) ) . expect ( "tweak worked" ) ;
893- jk2 = jk2. tweak ( tweak. clone ( ) ) . expect ( "tweak worked" ) ;
894- jk3 = jk3. tweak ( tweak) . expect ( "tweak worked" ) ;
895- }
885+ . unwrap ( )
886+ } else {
887+ Scalar :: zero ( )
888+ } ;
889+
890+ frost_key = frost_key. tweak ( tweak. clone ( ) ) . expect ( "tweak worked" ) ;
891+ jk2 = jk2. tweak ( tweak. clone ( ) ) . expect ( "tweak worked" ) ;
892+ jk3 = jk3. tweak ( tweak) . expect ( "tweak worked" ) ;
896893
897894 // TODO USE PROPER SID
898895 // public => [ b"r2-frost", my_index.to_be_bytes(), frost_key.joint_public_key, &frost_key.verification_shares[..], sid]
0 commit comments