Skip to main content

mpvss_sub/
mpvss_sub.rs

1// Copyright 2020-2026 MathxH Chen.
2//
3// Code is licensed under MIT Apache Dual License
4
5use mpvss_rs::Participant;
6use mpvss_rs::groups::ModpGroup;
7use mpvss_rs::{string_from_secret, string_to_secret};
8use num_bigint::{RandBigInt, ToBigInt};
9
10fn main() {
11    let group = ModpGroup::new();
12    let secret_message = String::from("Hello Sub MPVSS Example.");
13    let mut dealer = Participant::with_arc(group.clone());
14    dealer.initialize();
15    let mut p1 = Participant::with_arc(ModpGroup::new());
16    let mut p2 = Participant::with_arc(ModpGroup::new());
17    let mut p3 = Participant::with_arc(ModpGroup::new());
18    let mut p4 = Participant::with_arc(ModpGroup::new());
19    p1.initialize();
20    p2.initialize();
21    p3.initialize();
22    p4.initialize();
23
24    let publickeys = vec![
25        p1.publickey.clone(),
26        p2.publickey.clone(),
27        p3.publickey.clone(),
28        p4.publickey.clone(),
29    ];
30
31    let distribute_shares_box = dealer.distribute_secret(
32        &string_to_secret(&secret_message),
33        &publickeys,
34        3,
35    );
36
37    assert_eq!(p1.verify_distribution_shares(&distribute_shares_box), true);
38    assert_eq!(p2.verify_distribution_shares(&distribute_shares_box), true);
39    assert_eq!(p3.verify_distribution_shares(&distribute_shares_box), true);
40    assert_eq!(p4.verify_distribution_shares(&distribute_shares_box), true);
41
42    // p1 extracts the share. [p2, p3 and p4 do this as well.]
43    let mut rng = rand::thread_rng();
44    let w: num_bigint::BigInt = rng
45        .gen_biguint_below(&group.modulus().to_biguint().unwrap())
46        .to_bigint()
47        .unwrap();
48
49    let s1 = p1
50        .extract_secret_share(&distribute_shares_box, &p1.privatekey, &w)
51        .unwrap();
52
53    // p1, p2, p3, p4 exchange their descrypted shares.
54    let s2 = p2
55        .extract_secret_share(&distribute_shares_box, &p2.privatekey, &w)
56        .unwrap();
57    let s3 = p3
58        .extract_secret_share(&distribute_shares_box, &p3.privatekey, &w)
59        .unwrap();
60    let s4 = p4
61        .extract_secret_share(&distribute_shares_box, &p4.privatekey, &w)
62        .unwrap();
63
64    // p1 verifies the share received from p2. [Actually everybody verifies every received share.]
65    assert_eq!(
66        p1.verify_share(&s2, &distribute_shares_box, &p2.publickey),
67        true
68    );
69
70    assert_eq!(
71        p2.verify_share(&s3, &distribute_shares_box, &p3.publickey),
72        true
73    );
74
75    assert_eq!(
76        p3.verify_share(&s1, &distribute_shares_box, &s1.publickey),
77        true
78    );
79
80    assert_eq!(
81        p4.verify_share(&s2, &distribute_shares_box, &s2.publickey),
82        true
83    );
84
85    // Threshold is 3, so p1, p2, p4 can reconstruct (or any 3 participants)
86    let share_boxs = [s1.clone(), s2.clone(), s4.clone()];
87    let r1 = dealer
88        .reconstruct(&share_boxs, &distribute_shares_box)
89        .unwrap();
90    let r2 = dealer
91        .reconstruct(&share_boxs, &distribute_shares_box)
92        .unwrap();
93    let r3 = dealer
94        .reconstruct(&share_boxs, &distribute_shares_box)
95        .unwrap();
96    let r4 = dealer
97        .reconstruct(&share_boxs, &distribute_shares_box)
98        .unwrap();
99
100    let r1_str = string_from_secret(&r1);
101    assert_eq!(secret_message.clone(), r1_str);
102    let r2_str = string_from_secret(&r2);
103    assert_eq!(secret_message.clone(), r2_str);
104    let r3_str = string_from_secret(&r3);
105    assert_eq!(secret_message.clone(), r3_str);
106    let r4_str = string_from_secret(&r4);
107    assert_eq!(secret_message.clone(), r4_str);
108
109    println!("secret message: {}", secret_message);
110    println!("r1 str: {}", r1_str);
111    println!("r2 str: {}", r2_str);
112    println!("r3 str: {}", r3_str);
113    println!("r4 str: {}", r4_str);
114}