Skip to main content

ModpGroup

Struct ModpGroup 

Source
pub struct ModpGroup { /* private fields */ }
Expand description

2048-bit MODP Group from RFC 3526 (Group ID 14)

§Group Parameters

  • q: Safe prime (2048-bit)
  • g: Sophie Germain prime = (q-1)/2 (subgroup order)
  • G: Generator = 2

The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }

Implementations§

Source§

impl ModpGroup

Source

pub fn new() -> Arc<Self>

Create a new MODP group using RFC 3526 2048-bit prime

Examples found in repository?
examples/mpvss_all.rs (line 11)
10fn main() {
11    let group = ModpGroup::new();
12    let secret_message = String::from("Hello 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    p1.initialize();
19    p2.initialize();
20    p3.initialize();
21
22    let publickeys = vec![
23        p1.publickey.clone(),
24        p2.publickey.clone(),
25        p3.publickey.clone(),
26    ];
27
28    let distribute_shares_box = dealer.distribute_secret(
29        &string_to_secret(&secret_message),
30        &publickeys,
31        3,
32    );
33
34    assert_eq!(p1.verify_distribution_shares(&distribute_shares_box), true);
35    assert_eq!(p2.verify_distribution_shares(&distribute_shares_box), true);
36    assert_eq!(p3.verify_distribution_shares(&distribute_shares_box), true);
37
38    // p1 extracts the share. [p2 and p3 do this as well.]
39    let mut rng = rand::thread_rng();
40    let w: num_bigint::BigInt = rng
41        .gen_biguint_below(&group.modulus().to_biguint().unwrap())
42        .to_bigint()
43        .unwrap();
44
45    let s1 = p1
46        .extract_secret_share(&distribute_shares_box, &p1.privatekey, &w)
47        .unwrap();
48
49    // p1, p2 and p3 exchange their descrypted shares.
50    let s2 = p2
51        .extract_secret_share(&distribute_shares_box, &p2.privatekey, &w)
52        .unwrap();
53    let s3 = p3
54        .extract_secret_share(&distribute_shares_box, &p3.privatekey, &w)
55        .unwrap();
56
57    // p1 verifies the share received from p2. [Actually everybody verifies every received share.]
58    assert_eq!(
59        p1.verify_share(&s2, &distribute_shares_box, &p2.publickey),
60        true
61    );
62
63    assert_eq!(
64        p2.verify_share(&s3, &distribute_shares_box, &p3.publickey),
65        true
66    );
67
68    assert_eq!(
69        p3.verify_share(&s1, &distribute_shares_box, &s1.publickey),
70        true
71    );
72
73    let share_boxs = [s1, s2, s3];
74    let r1 = dealer
75        .reconstruct(&share_boxs, &distribute_shares_box)
76        .unwrap();
77    let r2 = dealer
78        .reconstruct(&share_boxs, &distribute_shares_box)
79        .unwrap();
80    let r3 = dealer
81        .reconstruct(&share_boxs, &distribute_shares_box)
82        .unwrap();
83
84    let r1_str = string_from_secret(&r1);
85    assert_eq!(secret_message.clone(), r1_str);
86    let r2_str = string_from_secret(&r2);
87    assert_eq!(secret_message.clone(), r2_str);
88    let r3_str = string_from_secret(&r3);
89    assert_eq!(secret_message.clone(), r3_str);
90
91    println!("secret message: {}", secret_message);
92    println!("r1 str: {}", r1_str);
93    println!("r2 str: {}", r2_str);
94    println!("r3 str: {}", r3_str);
95}
More examples
Hide additional examples
examples/mpvss_sub.rs (line 11)
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}
Source

pub fn init(length: u32) -> Arc<Self>

Initialize a MODP group by generating a safe prime of length bits

Source

pub fn modulus(&self) -> &BigInt

Get the safe prime modulus q

Examples found in repository?
examples/mpvss_all.rs (line 41)
10fn main() {
11    let group = ModpGroup::new();
12    let secret_message = String::from("Hello 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    p1.initialize();
19    p2.initialize();
20    p3.initialize();
21
22    let publickeys = vec![
23        p1.publickey.clone(),
24        p2.publickey.clone(),
25        p3.publickey.clone(),
26    ];
27
28    let distribute_shares_box = dealer.distribute_secret(
29        &string_to_secret(&secret_message),
30        &publickeys,
31        3,
32    );
33
34    assert_eq!(p1.verify_distribution_shares(&distribute_shares_box), true);
35    assert_eq!(p2.verify_distribution_shares(&distribute_shares_box), true);
36    assert_eq!(p3.verify_distribution_shares(&distribute_shares_box), true);
37
38    // p1 extracts the share. [p2 and p3 do this as well.]
39    let mut rng = rand::thread_rng();
40    let w: num_bigint::BigInt = rng
41        .gen_biguint_below(&group.modulus().to_biguint().unwrap())
42        .to_bigint()
43        .unwrap();
44
45    let s1 = p1
46        .extract_secret_share(&distribute_shares_box, &p1.privatekey, &w)
47        .unwrap();
48
49    // p1, p2 and p3 exchange their descrypted shares.
50    let s2 = p2
51        .extract_secret_share(&distribute_shares_box, &p2.privatekey, &w)
52        .unwrap();
53    let s3 = p3
54        .extract_secret_share(&distribute_shares_box, &p3.privatekey, &w)
55        .unwrap();
56
57    // p1 verifies the share received from p2. [Actually everybody verifies every received share.]
58    assert_eq!(
59        p1.verify_share(&s2, &distribute_shares_box, &p2.publickey),
60        true
61    );
62
63    assert_eq!(
64        p2.verify_share(&s3, &distribute_shares_box, &p3.publickey),
65        true
66    );
67
68    assert_eq!(
69        p3.verify_share(&s1, &distribute_shares_box, &s1.publickey),
70        true
71    );
72
73    let share_boxs = [s1, s2, s3];
74    let r1 = dealer
75        .reconstruct(&share_boxs, &distribute_shares_box)
76        .unwrap();
77    let r2 = dealer
78        .reconstruct(&share_boxs, &distribute_shares_box)
79        .unwrap();
80    let r3 = dealer
81        .reconstruct(&share_boxs, &distribute_shares_box)
82        .unwrap();
83
84    let r1_str = string_from_secret(&r1);
85    assert_eq!(secret_message.clone(), r1_str);
86    let r2_str = string_from_secret(&r2);
87    assert_eq!(secret_message.clone(), r2_str);
88    let r3_str = string_from_secret(&r3);
89    assert_eq!(secret_message.clone(), r3_str);
90
91    println!("secret message: {}", secret_message);
92    println!("r1 str: {}", r1_str);
93    println!("r2 str: {}", r2_str);
94    println!("r3 str: {}", r3_str);
95}
More examples
Hide additional examples
examples/mpvss_sub.rs (line 45)
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}
Source

pub fn subgroup_order_value(&self) -> &BigInt

Get the subgroup order g (Sophie Germain prime)

Trait Implementations§

Source§

impl Clone for ModpGroup

Source§

fn clone(&self) -> ModpGroup

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ModpGroup

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Group for ModpGroup

Source§

type Scalar = BigInt

Scalar type (exponent in MODP, private key in EC)
Source§

type Element = BigInt

Group element type (BigInt for MODP, Point for EC)
Source§

fn order(&self) -> &Self::Scalar

Group order (q-1 for MODP, curve order n for EC)
Source§

fn subgroup_order(&self) -> &Self::Scalar

Subgroup order (g=(q-1)/2 for MODP, n for EC with cofactor 1)
Source§

fn generator(&self) -> Self::Element

Main generator G (used for commitments and public key generation) Read more
Source§

fn subgroup_generator(&self) -> Self::Element

Subgroup generator g (used for computing commitments C_j = g^a_j) Read more
Source§

fn identity(&self) -> Self::Element

Identity element (1 for MODP, point at infinity for EC)
Source§

fn exp(&self, base: &Self::Element, scalar: &Self::Scalar) -> Self::Element

Group exponentiation/scalar multiplication: base^exp (MODP) or exp*base (EC) Read more
Source§

fn mul(&self, a: &Self::Element, b: &Self::Element) -> Self::Element

Group multiplication: A * B (MODP) or A + B (EC) Read more
Source§

fn scalar_inverse(&self, x: &Self::Scalar) -> Option<Self::Scalar>

Scalar modular inverse (for decryption and Lagrange interpolation) Read more
Source§

fn element_inverse(&self, x: &Self::Element) -> Option<Self::Element>

Element inverse (for handling negative Lagrange coefficients) Read more
Source§

fn hash_to_scalar(&self, data: &[u8]) -> Self::Scalar

Hash bytes to scalar (for DLEQ challenges) Read more
Source§

fn element_to_bytes(&self, elem: &Self::Element) -> Vec<u8>

Serialize element to bytes (for hashing and storage)
Source§

fn bytes_to_element(&self, bytes: &[u8]) -> Option<Self::Element>

Deserialize bytes to element Read more
Source§

fn scalar_to_bytes(&self, scalar: &Self::Scalar) -> Vec<u8>

Serialize scalar to bytes
Source§

fn generate_private_key(&self) -> Self::Scalar

Generate a random private key (scalar coprime to group order) Read more
Source§

fn generate_public_key(&self, private_key: &Self::Scalar) -> Self::Element

Derive public key from private key: P = G^k (MODP) or P = k*G (EC)
Source§

fn scalar_mul(&self, a: &Self::Scalar, b: &Self::Scalar) -> Self::Scalar

Scalar multiplication: (a * b) mod order Read more
Source§

fn scalar_sub(&self, a: &Self::Scalar, b: &Self::Scalar) -> Self::Scalar

Scalar subtraction: (a - b) mod order Read more
Source§

fn modulus(&self) -> Option<&BigInt>

Get the group modulus (for MODP groups) or None for groups without a modulus Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.