-
Notifications
You must be signed in to change notification settings - Fork 151
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Create lib.rs * Create shamir_secret_sharing.rs * Delete examples/src directory * Update Cargo.toml * Create lib.rs * Create shamir_secret_sharing.rs * Create Cargo.toml * Create README.md * Update shamir_secret_sharing.rs
- Loading branch information
Showing
5 changed files
with
147 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[package] | ||
name = "shamir_secret_sharing" | ||
version.workspace = true | ||
edition.workspace = true | ||
license.workspace = true | ||
repository.workspace = true | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
|
||
lambdaworks-math = { git = "https://github.com/lambdaclass/lambdaworks.git" } | ||
rand = { version = "0.8", features = [ "std", "std_rng" ] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Shamir's Secret Sharing | ||
|
||
## Usage example | ||
|
||
```rust | ||
// Definition of the secret | ||
// Creation of 6 shares | ||
// 3 shares will be used to recover the secret | ||
let sss = ShamirSecretSharing { | ||
secret: FE::new(1234), | ||
n: 6, | ||
k: 3, | ||
}; | ||
|
||
// Polynomial calculation | ||
let polynomial = sss.calculate_polynomial(); | ||
|
||
// Produce shares | ||
let shares = sss.generating_shares(polynomial.clone()); | ||
|
||
// Specify the x and y coordinates of the shares to use | ||
let shares_to_use_x = vec![shares.x[1], shares.x[3], shares.x[4]]; | ||
let shares_to_use_y = vec![shares.y[1], shares.y[3], shares.y[4]]; | ||
|
||
// Interpolation | ||
let poly_2 = sss.reconstructing(shares_to_use_x, shares_to_use_y); | ||
|
||
// Recover the free coefficient of the polynomial | ||
let secret_recovered = sss.recover(&poly_2); | ||
|
||
// Verifications | ||
assert_eq!(polynomial, poly_2); | ||
assert_eq!(sss.secret, secret_recovered); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod shamir_secret_sharing; |
98 changes: 98 additions & 0 deletions
98
examples/shamir_secret_sharing/src/shamir_secret_sharing.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
use lambdaworks_math::{ | ||
field::{element::FieldElement, traits::IsField}, | ||
polynomial::Polynomial, | ||
}; | ||
|
||
use rand::distributions::Standard; | ||
use rand::prelude::Distribution; | ||
use rand::random; | ||
|
||
pub struct ShamirSecretSharing<F: IsField> { | ||
secret: FieldElement<F>, | ||
n: usize, | ||
k: usize, | ||
} | ||
|
||
pub struct Shares<F: IsField> { | ||
pub x: Vec<FieldElement<F>>, | ||
pub y: Vec<FieldElement<F>>, | ||
} | ||
|
||
impl<F: IsField> ShamirSecretSharing<F> { | ||
pub fn calculate_polynomial(&self) -> Polynomial<FieldElement<F>> | ||
where | ||
Standard: Distribution<<F as IsField>::BaseType>, | ||
{ | ||
let mut coefficients = Vec::new(); | ||
coefficients.push(self.secret.clone()); | ||
for _ in 0..self.k - 1 { | ||
coefficients.push(FieldElement::<F>::new(random())); | ||
} | ||
|
||
let polynomial = Polynomial::new(coefficients.as_slice()); | ||
polynomial | ||
} | ||
|
||
pub fn generating_shares(&self, polynomial: Polynomial<FieldElement<F>>) -> Shares<F> | ||
where | ||
Standard: Distribution<<F as IsField>::BaseType>, | ||
{ | ||
let mut shares_x: Vec<FieldElement<F>> = Vec::new(); | ||
let mut shares_y: Vec<FieldElement<F>> = Vec::new(); | ||
|
||
for _ in 0..self.n { | ||
let x = FieldElement::<F>::new(random()); | ||
let y = polynomial.evaluate(&x); | ||
shares_x.push(x); | ||
shares_y.push(y); | ||
} | ||
|
||
Shares { | ||
x: shares_x, | ||
y: shares_y, | ||
} | ||
} | ||
|
||
pub fn reconstructing( | ||
&self, | ||
x: Vec<FieldElement<F>>, | ||
y: Vec<FieldElement<F>>, | ||
) -> Polynomial<FieldElement<F>> { | ||
Polynomial::interpolate(&x, &y).unwrap() | ||
} | ||
|
||
pub fn recover(&self, polynomial: &Polynomial<FieldElement<F>>) -> FieldElement<F> { | ||
polynomial.coefficients()[0].clone() | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
#[allow(non_snake_case)] | ||
mod tests { | ||
|
||
use crate::shamir_secret_sharing::ShamirSecretSharing; | ||
use lambdaworks_math::field::element::FieldElement; | ||
use lambdaworks_math::field::fields::u64_prime_field::U64PrimeField; | ||
|
||
#[test] | ||
fn shamir_secret_sharing_works() { | ||
const ORDER: u64 = 1613; | ||
type F = U64PrimeField<ORDER>; | ||
type FE = FieldElement<F>; | ||
|
||
let sss = ShamirSecretSharing { | ||
secret: FE::new(1234), | ||
n: 6, | ||
k: 3, | ||
}; | ||
|
||
let polynomial = sss.calculate_polynomial(); | ||
let shares = sss.generating_shares(polynomial.clone()); | ||
let shares_to_use_x = vec![shares.x[1], shares.x[3], shares.x[4]]; | ||
let shares_to_use_y = vec![shares.y[1], shares.y[3], shares.y[4]]; | ||
let poly_2 = sss.reconstructing(shares_to_use_x, shares_to_use_y); | ||
let secret_recovered = sss.recover(&poly_2); | ||
assert_eq!(polynomial, poly_2); | ||
assert_eq!(sss.secret, secret_recovered); | ||
} | ||
} |