use crate::modules::field::Field;
use std::ops::{Add, Sub, Mul};
use rand::Rng;
pub fn interpolate_at_zero(points: &[(u64, Field)]) -> Field {
let mut acc = Field::zero();
for i in 0..points.len() {
let (xi, yi) = (points[i].0 as u128, points[i].1);
let mut num = Field::one();
let mut den = Field::one();
for (j, (xj_u64, _yj)) in points.iter().enumerate() {
if i == j { continue; }
let xj = *xj_u64 as u128;
let xi_f = Field::new(xi);
let xj_f = Field::new(xj);
num = num.mul(xj_f.mul(Field::one())); den = den.mul(xj_f.sub(xi_f)); }
if let Some(inv) = den.inv() {
acc = acc.add(yi.mul(num).mul(inv));
} else {
panic!("Denominator not invertible in interpolation");
}
}
acc
}
pub struct ShamirVSS;
impl ShamirVSS {
pub fn share(secret: Field, n: usize, t: usize) -> Vec<(u64, Field)> {
assert!(t <= n && t >= 1);
let mut rng = rand::rng();
let mut coeffs: Vec<Field> = Vec::with_capacity(t);
coeffs.push(secret);
for _ in 1..t {
let r: u64 = rng.random_range(0..Field::MOD);
coeffs.push(Field::new(r as u128));
}
let mut shares = Vec::with_capacity(n);
for i in 1..=n {
let x = Field::new(i as u128);
let mut y = Field::zero();
let mut pow = Field::one();
for c in &coeffs {
y = y.add(c .mul(pow));
pow = pow.mul(x);
}
shares.push((i as u64, y));
}
shares
}
}