mirror of
https://github.com/arnaucube/shamirsecretsharing.git
synced 2026-02-07 03:26:45 +01:00
Add blog link, small pending updates
This commit is contained in:
@@ -1,35 +1,34 @@
|
||||
extern crate rand;
|
||||
extern crate num;
|
||||
extern crate num_bigint;
|
||||
extern crate num_traits;
|
||||
extern crate rand;
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use num_bigint::RandBigInt;
|
||||
use num::pow::pow;
|
||||
use num::Integer;
|
||||
|
||||
use num_bigint::RandBigInt;
|
||||
|
||||
use num_bigint::{BigInt, ToBigInt};
|
||||
use num_traits::{Zero, One};
|
||||
use num_traits::{One, Zero};
|
||||
|
||||
fn modulus(a: &BigInt, m: &BigInt) -> BigInt {
|
||||
((a%m) + m) % m
|
||||
((a % m) + m) % m
|
||||
}
|
||||
|
||||
pub fn create(t: u32, n: u32,p: &BigInt, k: &BigInt) -> Vec<[BigInt;2]> {
|
||||
pub fn create(t: u32, n: u32, p: &BigInt, k: &BigInt) -> Vec<[BigInt; 2]> {
|
||||
// t: number of secrets needed
|
||||
// n: number of shares
|
||||
// p: random point
|
||||
// p: size of finite field
|
||||
// k: secret to share
|
||||
if k>p {
|
||||
if k > p {
|
||||
println!("\nERROR: need k<p\n");
|
||||
}
|
||||
|
||||
// generate base_polynomial
|
||||
let mut base_polynomial: Vec<BigInt> = Vec::new();
|
||||
base_polynomial.push(k.clone());
|
||||
for _ in 0..t as usize-1 {
|
||||
for _ in 0..t as usize - 1 {
|
||||
let mut rng = rand::thread_rng();
|
||||
let a = rng.gen_bigint(1024);
|
||||
base_polynomial.push(a);
|
||||
@@ -37,11 +36,11 @@ pub fn create(t: u32, n: u32,p: &BigInt, k: &BigInt) -> Vec<[BigInt;2]> {
|
||||
|
||||
// calculate shares, based on the base_polynomial
|
||||
let mut shares: Vec<BigInt> = Vec::new();
|
||||
for i in 1..n+1 {
|
||||
for i in 1..n + 1 {
|
||||
let mut p_res: BigInt = Zero::zero();
|
||||
let mut x = 0;
|
||||
for pol_elem in &base_polynomial {
|
||||
if x==0 {
|
||||
if x == 0 {
|
||||
p_res = p_res + pol_elem;
|
||||
} else {
|
||||
let i_pow = pow(i, x);
|
||||
@@ -49,23 +48,23 @@ pub fn create(t: u32, n: u32,p: &BigInt, k: &BigInt) -> Vec<[BigInt;2]> {
|
||||
p_res = p_res + curr_elem;
|
||||
p_res = modulus(&p_res, p);
|
||||
}
|
||||
x = x+1;
|
||||
x = x + 1;
|
||||
}
|
||||
shares.push(p_res);
|
||||
}
|
||||
pack_shares(shares)
|
||||
}
|
||||
|
||||
fn pack_shares(shares: Vec<BigInt>) -> Vec<[BigInt;2]> {
|
||||
let mut r: Vec<[BigInt;2]> = Vec::new();
|
||||
fn pack_shares(shares: Vec<BigInt>) -> Vec<[BigInt; 2]> {
|
||||
let mut r: Vec<[BigInt; 2]> = Vec::new();
|
||||
for i in 0..shares.len() {
|
||||
let curr: [BigInt;2] = [shares[i].clone(), (i+1).to_bigint().unwrap()];
|
||||
let curr: [BigInt; 2] = [shares[i].clone(), (i + 1).to_bigint().unwrap()];
|
||||
r.push(curr);
|
||||
}
|
||||
r
|
||||
}
|
||||
|
||||
fn unpack_shares(s: Vec<[BigInt;2]>) -> (Vec<BigInt>, Vec<BigInt>) {
|
||||
fn unpack_shares(s: Vec<[BigInt; 2]>) -> (Vec<BigInt>, Vec<BigInt>) {
|
||||
let mut shares: Vec<BigInt> = Vec::new();
|
||||
let mut is: Vec<BigInt> = Vec::new();
|
||||
for i in 0..s.len() {
|
||||
@@ -100,9 +99,9 @@ pub fn kalinski_inv(a: &BigInt, modulo: &BigInt) -> BigInt {
|
||||
// This Phase I indeed is the Binary GCD algorithm , a version o Stein's algorithm
|
||||
// which tries to remove the expensive division operation away from the Classical
|
||||
// Euclidean GDC algorithm replacing it for Bit-shifting, subtraction and comparaison.
|
||||
//
|
||||
//
|
||||
// Output = `a^(-1) * 2^k (mod l)` where `k = log2(modulo) == Number of bits`.
|
||||
//
|
||||
//
|
||||
// Stein, J.: Computational problems associated with Racah algebra.J. Comput. Phys.1, 397–405 (1967).
|
||||
let phase1 = |a: &BigInt| -> (BigInt, u64) {
|
||||
assert!(a != &BigInt::zero());
|
||||
@@ -114,35 +113,31 @@ pub fn kalinski_inv(a: &BigInt, modulo: &BigInt) -> BigInt {
|
||||
let mut k = 0u64;
|
||||
|
||||
while v > BigInt::zero() {
|
||||
match(u.is_even(), v.is_even(), u > v, v >= u) {
|
||||
match (u.is_even(), v.is_even(), u > v, v >= u) {
|
||||
// u is even
|
||||
(true, _, _, _) => {
|
||||
|
||||
u = u >> 1;
|
||||
s = s << 1;
|
||||
},
|
||||
}
|
||||
// u isn't even but v is even
|
||||
(false, true, _, _) => {
|
||||
|
||||
v = v >> 1;
|
||||
r = &r << 1;
|
||||
},
|
||||
}
|
||||
// u and v aren't even and u > v
|
||||
(false, false, true, _) => {
|
||||
|
||||
u = &u - &v;
|
||||
u = u >> 1;
|
||||
r = &r + &s;
|
||||
s = &s << 1;
|
||||
},
|
||||
}
|
||||
// u and v aren't even and v > u
|
||||
(false, false, false, true) => {
|
||||
|
||||
v = &v - &u;
|
||||
v = v >> 1;
|
||||
s = &r + &s;
|
||||
r = &r << 1;
|
||||
},
|
||||
}
|
||||
(false, false, false, false) => panic!("Unexpected error has ocurred."),
|
||||
}
|
||||
k += 1;
|
||||
@@ -155,8 +150,8 @@ pub fn kalinski_inv(a: &BigInt, modulo: &BigInt) -> BigInt {
|
||||
|
||||
// Phase II performs some adjustments to obtain
|
||||
// the Montgomery inverse.
|
||||
//
|
||||
// We implement it as a clousure to be able to grap the
|
||||
//
|
||||
// We implement it as a clousure to be able to grap the
|
||||
// kalinski_inv scope to get `modulo` variable.
|
||||
let phase2 = |r: &BigInt, k: &u64| -> BigInt {
|
||||
let mut rr = r.clone();
|
||||
@@ -166,13 +161,13 @@ pub fn kalinski_inv(a: &BigInt, modulo: &BigInt) -> BigInt {
|
||||
match rr.is_even() {
|
||||
true => {
|
||||
rr = rr >> 1;
|
||||
},
|
||||
}
|
||||
false => {
|
||||
rr = (rr + modulo) >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
rr
|
||||
rr
|
||||
};
|
||||
|
||||
let (r, z) = phase1(&a.clone());
|
||||
@@ -180,7 +175,7 @@ pub fn kalinski_inv(a: &BigInt, modulo: &BigInt) -> BigInt {
|
||||
phase2(&r, &z)
|
||||
}
|
||||
|
||||
pub fn lagrange_interpolation(p: &BigInt, shares_packed: Vec<[BigInt;2]>) -> BigInt {
|
||||
pub fn lagrange_interpolation(p: &BigInt, shares_packed: Vec<[BigInt; 2]>) -> BigInt {
|
||||
let mut res_n: BigInt = Zero::zero();
|
||||
let mut res_d: BigInt = Zero::zero();
|
||||
let (shares, sh_i) = unpack_shares(shares_packed);
|
||||
@@ -198,7 +193,8 @@ pub fn lagrange_interpolation(p: &BigInt, shares_packed: Vec<[BigInt;2]>) -> Big
|
||||
}
|
||||
let numerator: BigInt = &shares[i] * &lagrange_numerator;
|
||||
|
||||
let quo: BigInt = (&numerator / &lagrange_denominator) + (&lagrange_denominator ) % &lagrange_denominator;
|
||||
let quo: BigInt =
|
||||
(&numerator / &lagrange_denominator) + (&lagrange_denominator) % &lagrange_denominator;
|
||||
if quo != Zero::zero() {
|
||||
res_n = res_n + quo;
|
||||
} else {
|
||||
@@ -218,7 +214,6 @@ pub fn lagrange_interpolation(p: &BigInt, shares_packed: Vec<[BigInt;2]>) -> Big
|
||||
r
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
@@ -227,15 +222,16 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_create_and_lagrange_interpolation() {
|
||||
let mut rng = rand::thread_rng();
|
||||
let p = rng.gen_biguint(1024).to_bigint().unwrap();
|
||||
println!("p: {:?}", p);
|
||||
let k = BigInt::parse_bytes(b"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", 10).unwrap();
|
||||
// 2 ** 127 - 1
|
||||
let p = BigInt::parse_bytes(b"170141183460469231731687303715884105727", 10).unwrap();
|
||||
println!("p: {:?}", p.to_string());
|
||||
|
||||
let k = BigInt::parse_bytes(b"12345678901234567890123456789012345678", 10).unwrap();
|
||||
|
||||
let s = create(3, 6, &p, &k);
|
||||
// println!("s: {:?}", s);
|
||||
|
||||
let mut shares_to_use: Vec<[BigInt;2]> = Vec::new();
|
||||
let mut shares_to_use: Vec<[BigInt; 2]> = Vec::new();
|
||||
shares_to_use.push(s[2].clone());
|
||||
shares_to_use.push(s[1].clone());
|
||||
shares_to_use.push(s[0].clone());
|
||||
@@ -263,10 +259,16 @@ mod tests {
|
||||
// Tested: 182687704666362864775460604089535377456991567872
|
||||
// Expected for: inverse_mod(a, l) computed on SageMath:
|
||||
// `7155219595916845557842258654134856828180378438239419449390401977965479867845`.
|
||||
let modul3 = BigInt::from_str("7237005577332262213973186563042994240857116359379907606001950938285454250989").unwrap();
|
||||
let modul3 = BigInt::from_str(
|
||||
"7237005577332262213973186563042994240857116359379907606001950938285454250989",
|
||||
)
|
||||
.unwrap();
|
||||
let d = BigInt::from_str("182687704666362864775460604089535377456991567872").unwrap();
|
||||
let res4 = kalinski_inv(&d, &modul3);
|
||||
let expected4 = BigInt::from_str("7155219595916845557842258654134856828180378438239419449390401977965479867845").unwrap();
|
||||
let res4 = kalinski_inv(&d, &modul3);
|
||||
let expected4 = BigInt::from_str(
|
||||
"7155219595916845557842258654134856828180378438239419449390401977965479867845",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(expected4, res4);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user