|
@@ -1,15 +1,59 @@
|
|
|
use curve25519_dalek::edwards::EdwardsPoint;
|
|
|
use curve25519_dalek::scalar::Scalar;
|
|
|
+use curve25519_dalek::constants::ED25519_BASEPOINT_POINT;
|
|
|
+use rand::rngs::ThreadRng;
|
|
|
|
|
|
pub type Secret = Scalar;
|
|
|
|
|
|
-pub struct Share {}
|
|
|
+pub struct Share {
|
|
|
+ index: u32,
|
|
|
+ value: Scalar,
|
|
|
+}
|
|
|
|
|
|
-pub struct Commitment {}
|
|
|
+pub struct Commitment {
|
|
|
+ coms: Vec<EdwardsPoint>,
|
|
|
+}
|
|
|
|
|
|
/// Create secret shares for a given secret.
|
|
|
pub fn generate_shares(secret: Secret, numshares: u32, threshold: u32) -> Result<(Commitment, Vec<Share>), &'static str> {
|
|
|
- unimplemented!("Not yet implemented")
|
|
|
+ if threshold < 1 { return Err("Threshold cannot be 0") }
|
|
|
+ if numshares < 1 { return Err("Number of shares cannot be 0") }
|
|
|
+ if threshold > numshares { return Err("Threshold cannot exceed numshares") }
|
|
|
+
|
|
|
+ let numcoeffs = (threshold-1) as usize;
|
|
|
+
|
|
|
+ let mut coeffs: Vec<Scalar> = Vec::with_capacity(numcoeffs);
|
|
|
+
|
|
|
+ let mut rng: ThreadRng = rand::thread_rng();
|
|
|
+
|
|
|
+ let mut shares: Vec<Share> = Vec::with_capacity(numshares as usize);
|
|
|
+
|
|
|
+ let mut comm: Commitment = Commitment { coms: Vec::with_capacity(threshold as usize) };
|
|
|
+
|
|
|
+ for _ in 1..numcoeffs {
|
|
|
+ coeffs.push(Scalar::random(&mut rng));
|
|
|
+ }
|
|
|
+
|
|
|
+ for share_index in 1..numshares {
|
|
|
+ // Evaluate the polynomial with `secret` as the constant term
|
|
|
+ // and `coeffs` as the other coefficients at the point x=share_index
|
|
|
+ // using Horner's method
|
|
|
+ let scalar_index = Scalar::from(share_index);
|
|
|
+ let mut value = Scalar::zero();
|
|
|
+ for i in (0..numcoeffs-1).rev() {
|
|
|
+ value += coeffs[i];
|
|
|
+ value *= scalar_index;
|
|
|
+ }
|
|
|
+ value += secret;
|
|
|
+ shares.push(Share{ index: share_index, value: value });
|
|
|
+ }
|
|
|
+
|
|
|
+ comm.coms.push(ED25519_BASEPOINT_POINT * secret);
|
|
|
+ for c in coeffs {
|
|
|
+ comm.coms.push(ED25519_BASEPOINT_POINT * c);
|
|
|
+ }
|
|
|
+
|
|
|
+ Ok((comm, shares))
|
|
|
}
|
|
|
|
|
|
/// Verify that a share is consistent with a commitment.
|