@@ -12,6 +12,7 @@ use num_bigint::{BigInt, BigUint, RandBigInt, ToBigInt};
1212use num_integer:: Integer ;
1313use num_primes:: Generator ;
1414use num_traits:: identities:: { One , Zero } ;
15+ use rayon:: prelude:: * ;
1516use sha2:: { Digest , Sha256 } ;
1617use std:: clone:: Clone ;
1718use std:: collections:: BTreeMap ;
@@ -189,6 +190,61 @@ impl MPVSS {
189190 dleq. check ( & challenge_hasher)
190191 }
191192
193+ fn compute_factor (
194+ & self ,
195+ position : i64 ,
196+ share : & BigInt ,
197+ values : & [ i64 ] ,
198+ ) -> BigInt {
199+ let mut exponent = BigInt :: one ( ) ;
200+ let lagrangeCoefficient = Util :: lagrange_coefficient ( & position, values) ;
201+ if lagrangeCoefficient. 0 . clone ( ) % lagrangeCoefficient. 1 . clone ( )
202+ == BigInt :: zero ( )
203+ {
204+ // Lagrange coefficient is an integer
205+ exponent = lagrangeCoefficient. 0 . clone ( )
206+ / Util :: abs ( & lagrangeCoefficient. 1 ) ;
207+ } else {
208+ // Lagrange coefficient is a proper fraction
209+ // Cancel fraction if possible
210+ let mut numerator = lagrangeCoefficient. 0 . to_biguint ( ) . unwrap ( ) ;
211+ let mut denominator =
212+ Util :: abs ( & lagrangeCoefficient. 1 ) . to_biguint ( ) . unwrap ( ) ;
213+ let gcd = numerator. gcd ( & denominator) ;
214+ numerator = numerator / gcd. clone ( ) ;
215+ denominator = denominator / gcd. clone ( ) ;
216+
217+ let q1 = self . q . clone ( ) - BigInt :: one ( ) ;
218+ let inverseDenominator = Util :: mod_inverse (
219+ & denominator. to_bigint ( ) . unwrap ( ) ,
220+ & q1. to_bigint ( ) . unwrap ( ) ,
221+ ) ;
222+ if inverseDenominator. is_some ( ) {
223+ exponent = ( numerator. to_bigint ( ) . unwrap ( )
224+ * inverseDenominator. unwrap ( ) )
225+ % q1. clone ( ) . to_bigint ( ) . unwrap ( ) ;
226+ } else {
227+ eprintln ! ( "ERROR: Denominator of Lagrange coefficient fraction does not have an inverse. Share cannot be processed." ) ;
228+ }
229+ }
230+ let mut factor = share
231+ . to_bigint ( )
232+ . unwrap ( )
233+ . modpow ( & exponent, & self . q . to_bigint ( ) . unwrap ( ) ) ;
234+ if lagrangeCoefficient. 0 * lagrangeCoefficient. 1 < BigInt :: zero ( ) {
235+ // Lagrange coefficient was negative. S^(-lambda) = 1/(S^lambda)
236+ let inverseFactor =
237+ Util :: mod_inverse ( & factor, & self . q . to_bigint ( ) . unwrap ( ) ) ;
238+ if inverseFactor. is_some ( ) {
239+ factor = inverseFactor. unwrap ( ) ;
240+ } else {
241+ eprintln ! ( "ERROR: Lagrange coefficient was negative and does not have an inverse. Share cannot be processed." )
242+ }
243+ }
244+
245+ factor
246+ }
247+
192248 /// Reconstruct secret from share boxs
193249 pub fn reconstruct (
194250 & self ,
@@ -214,52 +270,59 @@ impl MPVSS {
214270 let mut secret: BigInt = BigInt :: one ( ) ;
215271 let values: Vec < i64 > = shares. keys ( ) . map ( |key| * key) . collect ( ) ;
216272 for ( position, share) in shares {
217- let mut exponent = BigInt :: one ( ) ;
218- let lagrangeCoefficient =
219- Util :: lagrange_coefficient ( & position, values. as_slice ( ) ) ;
220- if lagrangeCoefficient. 0 . clone ( ) % lagrangeCoefficient. 1 . clone ( )
221- == BigInt :: zero ( )
222- {
223- // Lagrange coefficient is an integer
224- exponent = lagrangeCoefficient. 0 . clone ( )
225- / Util :: abs ( & lagrangeCoefficient. 1 ) ;
226- } else {
227- // Lagrange coefficient is a proper fraction
228- // Cancel fraction if possible
229- let mut numerator = lagrangeCoefficient. 0 . to_biguint ( ) . unwrap ( ) ;
230- let mut denominator =
231- Util :: abs ( & lagrangeCoefficient. 1 ) . to_biguint ( ) . unwrap ( ) ;
232- let gcd = numerator. gcd ( & denominator) ;
233- numerator = numerator / gcd. clone ( ) ;
234- denominator = denominator / gcd. clone ( ) ;
273+ let factor =
274+ self . compute_factor ( position, & share, values. as_slice ( ) ) ;
275+ secret = ( secret * factor) % self . q . clone ( ) ;
276+ }
235277
236- let q1 = self . q . clone ( ) - BigInt :: one ( ) ;
237- let inverseDenominator = Util :: mod_inverse (
238- & denominator . to_bigint ( ) . unwrap ( ) ,
239- & q1 . to_bigint ( ) . unwrap ( ) ,
240- ) ;
241- if inverseDenominator . is_some ( ) {
242- exponent = ( numerator . to_bigint ( ) . unwrap ( )
243- * inverseDenominator . unwrap ( ) )
244- % q1 . clone ( ) . to_bigint ( ) . unwrap ( ) ;
245- } else {
246- println ! ( "ERROR: Denominator of Lagrange coefficient fraction does not have an inverse. Share cannot be processed." ) ;
247- }
248- }
249- let mut factor = share
250- . to_bigint ( )
251- . unwrap ( )
252- . modpow ( & exponent , & self . q . to_bigint ( ) . unwrap ( ) ) ;
253- if lagrangeCoefficient . 0 * lagrangeCoefficient . 1 < BigInt :: zero ( ) {
254- // Lagrange coefficient was negative. S^(-lambda) = 1/(S^lambda)
255- let inverseFactor =
256- Util :: mod_inverse ( & factor , & self . q . to_bigint ( ) . unwrap ( ) ) ;
257- if inverseFactor . is_some ( ) {
258- factor = inverseFactor . unwrap ( ) ;
259- } else {
260- println ! ( "ERROR: Lagrange coefficient was negative and does not have an inverse. Share cannot be processed." )
261- }
278+ // Reconstruct the secret = H(G^s) xor U
279+ let secret_hash = sha2 :: Sha256 :: digest (
280+ & secret . to_biguint ( ) . unwrap ( ) . to_str_radix ( 10 ) . as_bytes ( ) ,
281+ ) ;
282+ let hash_big_uint = BigUint :: from_bytes_be ( & secret_hash [ .. ] )
283+ . mod_floor ( & self . q . to_biguint ( ) . unwrap ( ) ) ;
284+ let decrypted_secret = hash_big_uint
285+ ^ distribute_share_box . U . clone ( ) . to_biguint ( ) . unwrap ( ) ;
286+ Some ( decrypted_secret . to_bigint ( ) . unwrap ( ) )
287+ }
288+
289+ /// Reconstruct secret from share boxs using multi threaded
290+ pub fn reconstruct_parallelized (
291+ & self ,
292+ share_boxs : & [ ShareBox ] ,
293+ distribute_share_box : & DistributionSharesBox ,
294+ ) -> Option < BigInt > {
295+ if share_boxs . len ( ) < distribute_share_box . commitments . len ( ) {
296+ return None ;
297+ }
298+ let mut shares : BTreeMap < i64 , BigInt > = BTreeMap :: new ( ) ;
299+ for share_box in share_boxs . iter ( ) {
300+ let position =
301+ distribute_share_box . positions . get ( & share_box . publickey ) ;
302+ if position . is_none ( ) {
303+ return None ;
262304 }
305+ shares. insert ( * position. unwrap ( ) , share_box. share . clone ( ) ) ;
306+ }
307+ // Pooling the shares. Suppose
308+ // w.l.o.g. that participantsPiproduce correctvalues for S_i, for i= 1,...,t.
309+ // The secret G^s is obtained by Lagrange interpolation:
310+ // ∏(i=1->t)(S^λ_i) = ∏(i=1->t)(G^p(i))^λ_i = G^(∑(i=1->t)p(i)*λ_i = G^p(0) = G^s,
311+ let mut secret: BigInt = BigInt :: one ( ) ;
312+ let values: Vec < i64 > = shares. keys ( ) . map ( |key| * key) . collect ( ) ;
313+ let shares_vec: Vec < ( i64 , BigInt ) > = shares
314+ . into_iter ( )
315+ . map ( |( postion, share) | ( postion, share) )
316+ . collect ( ) ;
317+ let shares_slice = shares_vec. as_slice ( ) ;
318+ let factors: Vec < BigInt > = shares_slice
319+ . par_iter ( )
320+ . map ( |( position, share) | {
321+ self . compute_factor ( * position, share, values. as_slice ( ) )
322+ } )
323+ . collect ( ) ;
324+
325+ for factor in factors {
263326 secret = ( secret * factor) % self . q . clone ( ) ;
264327 }
265328
0 commit comments