@@ -97,18 +97,66 @@ impl<E: Curve> TrustedDealerBuilder<E> {
9797 ///
9898 /// Returns error if provided inputs are invalid, or if internal
9999 /// error has occurred.
100+ ///
101+ /// For Shamir secret sharing, it's shared at points `1` to `n`
102+ ///
103+ /// Returns error if provided inputs are invalid, or if internal
104+ /// error has occurred.
100105 pub fn generate_shares (
101106 self ,
102107 rng : & mut ( impl rand_core:: RngCore + rand_core:: CryptoRng ) ,
103108 ) -> Result < Vec < CoreKeyShare < E > > , TrustedDealerError > {
104- let shared_secret_key = self
105- . shared_secret_key
106- . unwrap_or_else ( || NonZero :: < SecretScalar < _ > > :: random ( rng) ) ;
107- let shared_public_key = Point :: generator ( ) * & shared_secret_key;
108109 let key_shares_indexes = ( 1 ..=self . n )
109110 . map ( |i| generic_ec:: NonZero :: from_scalar ( Scalar :: from ( i) ) )
110111 . collect :: < Option < Vec < _ > > > ( )
111112 . ok_or ( Reason :: DeriveKeyShareIndex ) ?;
113+ self . generate_shares_at ( key_shares_indexes, rng)
114+ }
115+
116+ /// Generates [`CoreKeyShare`]s shared at random points
117+ ///
118+ /// Returns error if provided inputs are invalid, or if internal
119+ /// error has occurred.
120+ ///
121+ /// For Shamir secret sharing, the points at which the value is shared at
122+ /// are chosen at random between `1` and `u16::MAX`. For additive shares,
123+ /// this is the same as [`TrustedDealerBuilder::generate_shares`]
124+ ///
125+ /// Returns error if provided inputs are invalid, or if internal
126+ /// error has occurred.
127+ pub fn generate_shares_at_random (
128+ self ,
129+ rng : & mut ( impl rand_core:: RngCore + rand_core:: CryptoRng ) ,
130+ ) -> Result < Vec < CoreKeyShare < E > > , TrustedDealerError > {
131+ // The chance of scalars repeating is negligible for usual fields in EC.
132+ // But in any case the dupliactes are checked during the validation of
133+ // CoreKeyShare
134+ let points = ( 0 ..self . n )
135+ . map ( |_| generic_ec:: NonZero :: < Scalar < E > > :: random ( rng) )
136+ . collect ( ) ;
137+ self . generate_shares_at ( points, rng)
138+ }
139+
140+ /// Generates [`CoreKeyShare`]s shared at preimages provided. Each share is
141+ /// going to have the given `preimages` as its `I` component.
142+ ///
143+ /// Preimages are ignored for additive key shares.
144+ ///
145+ /// Returns error if provided inputs are invalid, or if internal
146+ /// error has occurred.
147+ pub fn generate_shares_at (
148+ self ,
149+ preimages : Vec < NonZero < Scalar < E > > > ,
150+ rng : & mut ( impl rand_core:: RngCore + rand_core:: CryptoRng ) ,
151+ ) -> Result < Vec < CoreKeyShare < E > > , TrustedDealerError > {
152+ if preimages. len ( ) != usize:: from ( self . n ) {
153+ return Err ( Reason :: InvalidPreimages . into ( ) ) ;
154+ }
155+
156+ let shared_secret_key = self
157+ . shared_secret_key
158+ . unwrap_or_else ( || NonZero :: < SecretScalar < _ > > :: random ( rng) ) ;
159+ let shared_public_key = Point :: generator ( ) * & shared_secret_key;
112160 let secret_shares = if let Some ( t) = self . t {
113161 let f = generic_ec_zkp:: polynomial:: Polynomial :: sample_with_const_term (
114162 rng,
@@ -120,7 +168,7 @@ impl<E: Curve> TrustedDealerBuilder<E> {
120168 Point :: generator( ) * f. value:: <_, Scalar <_>>( & Scalar :: zero( ) )
121169 ) ;
122170
123- key_shares_indexes
171+ preimages
124172 . iter ( )
125173 . map ( |I_i | f. value ( I_i ) )
126174 . map ( |mut x_i| SecretScalar :: new ( & mut x_i) )
@@ -150,7 +198,7 @@ impl<E: Curve> TrustedDealerBuilder<E> {
150198
151199 let vss_setup = self . t . map ( |t| VssSetup {
152200 min_signers : t,
153- I : key_shares_indexes ,
201+ I : preimages ,
154202 } ) ;
155203
156204 #[ cfg( feature = "hd-wallet" ) ]
@@ -198,6 +246,8 @@ enum Reason {
198246 DeriveKeyShareIndex ,
199247 #[ displaydoc( "randomly generated share is zero - probability of that is negligible" ) ]
200248 ZeroShare ,
249+ #[ displaydoc( "invalid share preimages given" ) ]
250+ InvalidPreimages ,
201251}
202252
203253impl From < Reason > for TrustedDealerError {
0 commit comments