Skip to content

Commit

Permalink
Completed reconstruct secret shares
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexiaChen committed Jan 9, 2021
1 parent 9861e7d commit c8a5dd0
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 9 deletions.
29 changes: 27 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@ Thus PVSS can be used to share a secret among a group of participants so that ei
## Build

```bash
cargo build
cargo build --release
```

## Test

```bash
cargo test
cargo test --release
```

## Example

```rust
cargo run --release --example mpvss
```

### Usage
Expand Down Expand Up @@ -115,7 +121,26 @@ assert_eq!(
Once a participant collected at least `threshold` shares the secret can be reconstructed.

```rust
let share_boxs = [s1, s2, s3];
let r1 = p1
.mpvss
.reconstruct(&share_boxs, &distribute_shares_box)
.unwrap();
let r2 = p2
.mpvss
.reconstruct(&share_boxs, &distribute_shares_box)
.unwrap();
let r3 = p3
.mpvss
.reconstruct(&share_boxs, &distribute_shares_box)
.unwrap();

let r1_str = String::from_utf8(r1.to_biguint().unwrap().to_bytes_be()).unwrap();
assert_eq!(secret_message.clone(), r1_str);
let r2_str = String::from_utf8(r2.to_biguint().unwrap().to_bytes_be()).unwrap();
assert_eq!(secret_message.clone(), r2_str);
let r3_str = String::from_utf8(r3.to_biguint().unwrap().to_bytes_be()).unwrap();
assert_eq!(secret_message.clone(), r3_str);
```

## Related References:
Expand Down
102 changes: 97 additions & 5 deletions examples/mpvss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,103 @@
//
// Code is licensed under AGPL License, Version 3.0.

use mpvss_rs::MPVSS;
use mpvss_rs::Participant;
use num_bigint::{BigUint, ToBigInt};

fn main() {
let mpvss = MPVSS::new();
let secret_message = String::from("Hello MPVSS.");
drop(mpvss);
drop(secret_message);
let secret_message = String::from("Hello MPVSS Example.");
let secret = BigUint::from_bytes_be(&secret_message.as_bytes());
let mut dealer = Participant::new();
dealer.initialize();
let mut p1 = Participant::new();
let mut p2 = Participant::new();
let mut p3 = Participant::new();
p1.initialize();
p2.initialize();
p3.initialize();

let distribute_shares_box = dealer.distribute_secret(
secret.to_bigint().unwrap(),
vec![
p1.publickey.clone(),
p2.publickey.clone(),
p3.publickey.clone(),
],
3,
);

assert_eq!(
p1.mpvss.verify_distribution_shares(&distribute_shares_box),
true
);

assert_eq!(
p2.mpvss.verify_distribution_shares(&distribute_shares_box),
true
);

assert_eq!(
p3.mpvss.verify_distribution_shares(&distribute_shares_box),
true
);

// p1 extracts the share. [p2 and p3 do this as well.]
let s1 = p1
.extract_secret_share(&distribute_shares_box, &p1.privatekey)
.unwrap();

// p1, p2 and p3 exchange their descrypted shares.
// ...
let s2 = p2
.extract_secret_share(&distribute_shares_box, &p2.privatekey)
.unwrap();
let s3 = p3
.extract_secret_share(&distribute_shares_box, &p3.privatekey)
.unwrap();

// p1 verifies the share received from p2. [Actually everybody verifies every received share.]

assert_eq!(
p1.mpvss
.verify(&s2, &distribute_shares_box.shares[&p2.publickey]),
true
);

assert_eq!(
p2.mpvss
.verify(&s3, &distribute_shares_box.shares[&p3.publickey]),
true
);

assert_eq!(
p3.mpvss
.verify(&s1, &distribute_shares_box.shares[&s1.publickey]),
true
);

let share_boxs = [s1, s2, s3];
let r1 = p1
.mpvss
.reconstruct(&share_boxs, &distribute_shares_box)
.unwrap();
let r2 = p2
.mpvss
.reconstruct(&share_boxs, &distribute_shares_box)
.unwrap();
let r3 = p3
.mpvss
.reconstruct(&share_boxs, &distribute_shares_box)
.unwrap();

let r1_str = String::from_utf8(r1.to_biguint().unwrap().to_bytes_be()).unwrap();
assert_eq!(secret_message.clone(), r1_str);
let r2_str = String::from_utf8(r2.to_biguint().unwrap().to_bytes_be()).unwrap();
assert_eq!(secret_message.clone(), r2_str);
let r3_str = String::from_utf8(r3.to_biguint().unwrap().to_bytes_be()).unwrap();
assert_eq!(secret_message.clone(), r3_str);

println!("secret message: {}", secret_message);
println!("r1 str: {}", r1_str);
println!("r2 str: {}", r2_str);
println!("r3 str: {}", r3_str);
}
3 changes: 2 additions & 1 deletion src/mpvss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ impl MPVSS {
}

// Reconstruct the secret = H(G^s) xor U
let secret_hash = sha2::Sha256::digest(&secret.to_biguint().unwrap().to_bytes_le());
let secret_hash =
sha2::Sha256::digest(&secret.to_biguint().unwrap().to_str_radix(10).as_bytes());
let hash_big_uint =
BigUint::from_bytes_be(&secret_hash[..]).mod_floor(&self.q.to_biguint().unwrap());
let decrypted_secret = hash_big_uint ^ distribute_share_box.U.clone().to_biguint().unwrap();
Expand Down
79 changes: 79 additions & 0 deletions src/participant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ mod tests {
use super::Polynomial;
use super::MPVSS;
use super::{DistributionSharesBox, ShareBox};
use num_traits::{One, Zero};

struct Setup {
pub mpvss: MPVSS,
Expand Down Expand Up @@ -519,4 +520,82 @@ mod tests {
true
);
}

#[test]
fn test_reconstruction_with_all_participants() {
let distribution_shares_box = get_distribute_shares_box();
let share_box1 = get_share_box();
let mut share_box2 = ShareBox::new();
share_box2.init(
BigInt::from(132222922),
BigInt::from(157312059),
BigInt::zero(),
BigInt::zero(),
);
let mut share_box3 = ShareBox::new();
share_box3.init(
BigInt::from(65136827),
BigInt::from(63399333),
BigInt::zero(),
BigInt::zero(),
);

let setup = Setup::new();
let share_boxs = [share_box1, share_box2, share_box3];
let reconstructed_secret = setup
.mpvss
.reconstruct(&share_boxs, &distribution_shares_box)
.unwrap();
assert_eq!(reconstructed_secret, setup.secret);
}

// (3,4) threshhold reconstruct, participant 3 is not available, 1,2,4 is available
#[test]
fn test_reconstruction_with_sub_group() {
let share_box1 = get_share_box();
let mut share_box2 = ShareBox::new();
share_box2.init(
BigInt::from(132222922),
BigInt::from(157312059),
BigInt::zero(),
BigInt::zero(),
);

let public_key4 = BigInt::from(42);
let mut share_box4 = ShareBox::new();
share_box4.init(
public_key4.clone(),
BigInt::from(59066181),
BigInt::zero(),
BigInt::zero(),
);

let mut positions = HashMap::new();
positions.insert(share_box1.clone().publickey, 1_i64);
positions.insert(share_box2.clone().publickey, 2_i64);
positions.insert(share_box4.clone().publickey, 4_i64);
// remove participant 3 public key
positions.remove(&BigInt::from(65136827));
*positions.get_mut(&public_key4).unwrap() = 4_i64;

let mut distribution_shares_box = DistributionSharesBox::new();
distribution_shares_box.init(
vec![BigInt::zero(), BigInt::one(), BigInt::from(2)],
positions,
HashMap::new(),
vec![],
BigInt::zero(),
HashMap::new(),
BigInt::from(1284073502),
);

let setup = Setup::new();
let share_boxs = [share_box1, share_box2, share_box4];
let reconstructed_secret = setup
.mpvss
.reconstruct(&share_boxs, &distribution_shares_box)
.unwrap();
assert_eq!(reconstructed_secret, setup.secret);

}
}
23 changes: 22 additions & 1 deletion tests/mpvss_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn test_secret_str_utf8() {
}

#[test]
fn test_mpvss_distribute_verify() {
fn test_mpvss_distribute_verify_reconstruct() {
let secret_message = String::from("Hello MPVSS.");
let secret = BigUint::from_bytes_be(&secret_message.as_bytes());
let mut dealer = Participant::new();
Expand Down Expand Up @@ -86,4 +86,25 @@ fn test_mpvss_distribute_verify() {
.verify(&s1, &distribute_shares_box.shares[&s1.publickey]),
true
);

let share_boxs = [s1, s2, s3];
let r1 = p1
.mpvss
.reconstruct(&share_boxs, &distribute_shares_box)
.unwrap();
let r2 = p2
.mpvss
.reconstruct(&share_boxs, &distribute_shares_box)
.unwrap();
let r3 = p3
.mpvss
.reconstruct(&share_boxs, &distribute_shares_box)
.unwrap();

let r1_str = String::from_utf8(r1.to_biguint().unwrap().to_bytes_be()).unwrap();
assert_eq!(secret_message.clone(), r1_str);
let r2_str = String::from_utf8(r2.to_biguint().unwrap().to_bytes_be()).unwrap();
assert_eq!(secret_message.clone(), r2_str);
let r3_str = String::from_utf8(r3.to_biguint().unwrap().to_bytes_be()).unwrap();
assert_eq!(secret_message.clone(), r3_str);
}

0 comments on commit c8a5dd0

Please sign in to comment.