Browse Source

Tests for the two functions we implemented so far

Ian Goldberg 5 years ago
parent
commit
a617445040
2 changed files with 81 additions and 15 deletions
  1. 0 8
      src/lib.rs
  2. 81 7
      src/vss.rs

+ 0 - 8
src/lib.rs

@@ -2,11 +2,3 @@ extern crate curve25519_dalek;
 extern crate rand;
 
 pub mod vss;
-
-#[cfg(test)]
-mod tests {
-    #[test]
-    fn it_works() {
-        assert_eq!(2 + 2, 4);
-    }
-}

+ 81 - 7
src/vss.rs

@@ -5,6 +5,7 @@ use rand::rngs::ThreadRng;
 
 pub type Secret = Scalar;
 
+#[derive(Copy, Clone)]
 pub struct Share {
     index: u32,
     value: Scalar,
@@ -30,17 +31,17 @@ pub fn generate_shares(secret: Secret, numshares: u32, threshold: u32) -> Result
 
     let mut comm: Commitment = Commitment { coms: Vec::with_capacity(threshold as usize) };
 
-    for _ in 1..numcoeffs {
+    for _ in 0..numcoeffs {
         coeffs.push(Scalar::random(&mut rng));
     }
 
-    for share_index in 1..numshares {
+    for share_index in 1..numshares+1 {
         // 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() {
+        for i in (0..numcoeffs).rev() {
             value += coeffs[i];
             value *= scalar_index;
         }
@@ -69,13 +70,13 @@ pub fn reconstruct_secret(shares: &Vec<Share>) -> Result<Secret, &'static str> {
 
     let mut lagrange_coeffs: Vec<Scalar> = Vec::with_capacity(numshares);
 
-    for i in 0..numshares-1 {
+    for i in 0..numshares {
         let mut num = Scalar::one();
         let mut den = Scalar::one();
-        for j in 0..numshares-1 {
+        for j in 0..numshares {
             if j==i { continue; }
             num *= Scalar::from(shares[j].index);
-            den *= Scalar::from(shares[j].index - shares[i].index);
+            den *= (Scalar::from(shares[j].index) - Scalar::from(shares[i].index));
         }
         if den == Scalar::zero() {
             return Err("Duplicate shares provided");
@@ -85,7 +86,7 @@ pub fn reconstruct_secret(shares: &Vec<Share>) -> Result<Secret, &'static str> {
 
     let mut secret = Scalar::zero();
 
-    for i in 0..numshares-1 {
+    for i in 0..numshares {
         secret += lagrange_coeffs[i] * shares[i].value;
     }
 
@@ -106,3 +107,76 @@ pub fn apply_commitment_update(oldcommitment: &Commitment, update: &Commitment)
 pub fn apply_share_update(oldshare: &Share, update: &Share) -> Result<Share, &'static str> {
     unimplemented!("Not yet implemented")
 }
+
+#[cfg(test)]
+mod tests {
+    use crate::vss::*;
+
+    #[test]
+    fn share_simple() {
+        let s = Secret::from(42u32);
+
+        let res = generate_shares(s, 5, 2);
+        assert!(res.is_ok());
+        let (com, shares) = res.unwrap();
+
+        let mut recshares: Vec<Share> = Vec::new();
+        recshares.push(shares[1]);
+        recshares.push(shares[3]);
+        let recres = reconstruct_secret(&recshares);
+        assert!(recres.is_ok());
+        assert_eq!(recres.unwrap(), s);
+    }
+
+    #[test]
+    fn share_not_enough() {
+        let s = Secret::from(42u32);
+
+        let res = generate_shares(s, 5, 2);
+        assert!(res.is_ok());
+        let (com, shares) = res.unwrap();
+
+        let mut recshares: Vec<Share> = Vec::new();
+        recshares.push(shares[1]);
+        let recres = reconstruct_secret(&recshares);
+        assert!(recres.is_ok());
+        assert_ne!(recres.unwrap(), s);
+    }
+
+    #[test]
+    fn share_dup() {
+        let s = Secret::from(42u32);
+
+        let res = generate_shares(s, 5, 2);
+        assert!(res.is_ok());
+        let (com, shares) = res.unwrap();
+
+        let mut recshares: Vec<Share> = Vec::new();
+        recshares.push(shares[1]);
+        recshares.push(shares[1]);
+        let recres = reconstruct_secret(&recshares);
+        assert!(recres.is_err());
+        assert_eq!(recres.err(), Some("Duplicate shares provided"));
+    }
+
+    #[test]
+    fn share_badparams() {
+        let s = Secret::from(42u32);
+
+        {
+            let res = generate_shares(s, 5, 0);
+            assert!(res.is_err());
+            assert_eq!(res.err(), Some("Threshold cannot be 0"));
+        }
+        {
+            let res = generate_shares(s, 0, 3);
+            assert!(res.is_err());
+            assert_eq!(res.err(), Some("Number of shares cannot be 0"));
+        }
+        {
+            let res = generate_shares(s, 1, 3);
+            assert!(res.is_err());
+            assert_eq!(res.err(), Some("Threshold cannot exceed numshares"));
+        }
+    }
+}