Files
RustySecrets/src/interpolation.rs
2016-12-02 14:56:12 +01:00

41 lines
1.3 KiB
Rust

use gf256::Gf256;
use std::io;
use std::io::prelude::*;
/// evaluates a polynomial at x=1, 2, 3, ... n (inclusive)
pub fn encode<W: Write>(src: &[u8], n: u8, w: &mut W) -> io::Result<()> {
for raw_x in 1..((n as u16) + 1) {
let x = Gf256::from_byte(raw_x as u8);
let mut fac = Gf256::one();
let mut acc = Gf256::zero();
for &coeff in src.iter() {
acc = acc + fac * Gf256::from_byte(coeff);
fac = fac * x;
}
try!(w.write(&[acc.to_byte()]));
}
Ok(())
}
/// evaluates an interpolated polynomial at `Gf256::zero()` where
/// the polynomial is determined using Lagrangian interpolation
/// based on the given x/y coordinates `src`.
pub fn lagrange_interpolate(src: &[(u8, u8)]) -> u8 {
let mut sum = Gf256::zero();
for (i, &(raw_xi, raw_yi)) in src.iter().enumerate() {
let xi = Gf256::from_byte(raw_xi);
let yi = Gf256::from_byte(raw_yi);
let mut prod = Gf256::one();
for (j, &(raw_xj, _)) in src.iter().enumerate() {
if i != j {
let xj = Gf256::from_byte(raw_xj);
let delta = xi - xj;
assert!(delta.poly != 0, "Duplicate shares");
prod = prod * xj / delta;
}
}
sum = sum + prod * yi;
}
sum.to_byte()
}