diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6936990 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +**/*.rs.bk +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..fddeab0 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "secretsharing" +version = "0.1.0" +authors = ["pawanjay176 "] +edition = "2018" + +[dependencies] +rand = "0.6" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..7e87d79 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,9 @@ +mod utils; + + +fn main() { + println!("Hello, world!"); + println!("{:?}", utils::modinv(-18, 13)); + println!("{:?}", utils::random_polynomial(10, 50, 41)); + println!("{:?}", utils::mod_lagrange_interpolation(vec![(1,2), (3,4), (5,6)], 100)); +} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..575fc54 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,96 @@ +extern crate rand; + +use rand::Rng; + +pub fn egcd(a: i64,b: i64) -> (i64, i64, i64) { + if a == 0 { + (b, 0, 1) + } + else { + let (gcd, x, y) = egcd(b % a, a); + (gcd, y - (b/a) * x, x) + } +} + +pub fn modinv(a: i64, prime: i64) -> Option { + let (gcd, x, _) = egcd(a, prime); + + if gcd != 1 { + None + } + else { + Some(((x % prime) + prime) % prime) + } +} + +pub fn random_polynomial(degree: i64, intercept: i64, upper_bound: i64) -> Vec { + let mut coeff = vec![intercept]; + let mut rng = rand::thread_rng(); + for _ in 0..degree { + let c = rng.gen_range(0, upper_bound); + coeff.push(c); + } + coeff +} + + +pub fn get_polynomial_points(coeff: Vec, num_points: i64, prime: i64) -> Vec<(i64, i64)> { + let mut points: Vec<(i64, i64)> = Vec::new(); + for i in 1..=num_points { + let mut y = coeff[0]; + for j in 1..coeff.len() { + let exp: i64 = (i.pow(j as u32)) % prime; + let term = (coeff[j] * exp) % prime; + y = (y + term) % prime; + } + points.push((i,y)); + } + points +} + +pub fn mod_lagrange_interpolation(points: Vec<(i64, i64)>, prime: i64) -> i64 { + let mut res: i64 = 0; + let x_values: Vec = points.iter().map(|(x, _)| *x).collect(); + let y_values: Vec = points.iter().map(|(_, y)| *y).collect(); + for i in 0..points.len(){ + let mut num: i64 = 1; + let mut den: i64 = 1; + for j in 0..points.len(){ + if i == j { + continue + } + else { + num = (num * -x_values[j]) % prime; + den = (den * (x_values[i] - x_values[j])) % prime; + } + } + let lagrange_polynomial = num * modinv(den, prime).unwrap(); + res = (res + prime + (y_values[i] * lagrange_polynomial)) % prime; + } + res +} + +pub fn int_to_charset(val: u64, charset: String) -> String { + if val == 0 { + charset.chars().nth(0).unwrap().to_string() + } + else { + let mut res = String::new(); + let mut value = val.clone(); + while value > 0 { + value = value / charset.len() as u64; + let digit = value % charset.len() as u64; + res.push(charset.chars().nth(digit as usize).unwrap()); + } + res + } +} + +pub fn charset_to_int(val: String, charset: String) -> u64 { + let mut res: u64 = 0; + for c in val.chars() { + res = res * charset.len() as u64 + charset.find(c).unwrap() as u64; + } + res +} +