use mpvss_rs::Participant;
use mpvss_rs::groups::ModpGroup;
use mpvss_rs::{string_from_secret, string_to_secret};
use num_bigint::{RandBigInt, ToBigInt};
fn main() {
let group = ModpGroup::new();
let secret_message = String::from("Hello Sub MPVSS Example.");
let mut dealer = Participant::with_arc(group.clone());
dealer.initialize();
let mut p1 = Participant::with_arc(ModpGroup::new());
let mut p2 = Participant::with_arc(ModpGroup::new());
let mut p3 = Participant::with_arc(ModpGroup::new());
let mut p4 = Participant::with_arc(ModpGroup::new());
p1.initialize();
p2.initialize();
p3.initialize();
p4.initialize();
let publickeys = vec![
p1.publickey.clone(),
p2.publickey.clone(),
p3.publickey.clone(),
p4.publickey.clone(),
];
let distribute_shares_box = dealer.distribute_secret(
&string_to_secret(&secret_message),
&publickeys,
3,
);
assert_eq!(p1.verify_distribution_shares(&distribute_shares_box), true);
assert_eq!(p2.verify_distribution_shares(&distribute_shares_box), true);
assert_eq!(p3.verify_distribution_shares(&distribute_shares_box), true);
assert_eq!(p4.verify_distribution_shares(&distribute_shares_box), true);
let mut rng = rand::thread_rng();
let w: num_bigint::BigInt = rng
.gen_biguint_below(&group.modulus().to_biguint().unwrap())
.to_bigint()
.unwrap();
let s1 = p1
.extract_secret_share(&distribute_shares_box, &p1.privatekey, &w)
.unwrap();
let s2 = p2
.extract_secret_share(&distribute_shares_box, &p2.privatekey, &w)
.unwrap();
let s3 = p3
.extract_secret_share(&distribute_shares_box, &p3.privatekey, &w)
.unwrap();
let s4 = p4
.extract_secret_share(&distribute_shares_box, &p4.privatekey, &w)
.unwrap();
assert_eq!(
p1.verify_share(&s2, &distribute_shares_box, &p2.publickey),
true
);
assert_eq!(
p2.verify_share(&s3, &distribute_shares_box, &p3.publickey),
true
);
assert_eq!(
p3.verify_share(&s1, &distribute_shares_box, &s1.publickey),
true
);
assert_eq!(
p4.verify_share(&s2, &distribute_shares_box, &s2.publickey),
true
);
let share_boxs = [s1.clone(), s2.clone(), s4.clone()];
let r1 = dealer
.reconstruct(&share_boxs, &distribute_shares_box)
.unwrap();
let r2 = dealer
.reconstruct(&share_boxs, &distribute_shares_box)
.unwrap();
let r3 = dealer
.reconstruct(&share_boxs, &distribute_shares_box)
.unwrap();
let r4 = dealer
.reconstruct(&share_boxs, &distribute_shares_box)
.unwrap();
let r1_str = string_from_secret(&r1);
assert_eq!(secret_message.clone(), r1_str);
let r2_str = string_from_secret(&r2);
assert_eq!(secret_message.clone(), r2_str);
let r3_str = string_from_secret(&r3);
assert_eq!(secret_message.clone(), r3_str);
let r4_str = string_from_secret(&r4);
assert_eq!(secret_message.clone(), r4_str);
println!("secret message: {}", secret_message);
println!("r1 str: {}", r1_str);
println!("r2 str: {}", r2_str);
println!("r3 str: {}", r3_str);
println!("r4 str: {}", r4_str);
}