Merge pull request #46 from poanetwork/afck-interpolate

Optimize polynomial interpolation in the curve.
master
Vladimir Komendantskiy 7 years ago committed by GitHub
commit f1742a6170
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 37
      src/lib.rs

@ -596,27 +596,40 @@ where
{ {
let samples: Vec<_> = items let samples: Vec<_> = items
.into_iter() .into_iter()
.take(t)
.map(|(i, sample)| (into_fr_plus_1(i), sample)) .map(|(i, sample)| (into_fr_plus_1(i), sample))
.collect(); .collect();
if samples.len() < t { if samples.len() < t {
return Err(Error::NotEnoughShares); return Err(Error::NotEnoughShares);
} }
let mut result = C::zero();
let mut indexes = Vec::new(); // Compute the products `x_prod[i]` of all but the `i`-th entry.
for (x, sample) in samples.iter().take(t) { let mut x_prod: Vec<C::Scalar> = Vec::with_capacity(t);
if indexes.contains(x) { let mut tmp = C::Scalar::one();
return Err(Error::DuplicateEntry); x_prod.push(tmp);
for (x, _) in samples.iter().take(t - 1) {
tmp.mul_assign(x);
x_prod.push(tmp);
}
tmp = C::Scalar::one();
let mut i = t - 2;
for (x, _) in samples[1..].iter().rev() {
tmp.mul_assign(x);
x_prod[i].mul_assign(&tmp);
i -= 1;
} }
indexes.push(x.clone());
let mut result = C::zero();
for (mut l0, (x, sample)) in x_prod.into_iter().zip(&samples) {
// Compute the value at 0 of the Lagrange polynomial that is `0` at the other data // Compute the value at 0 of the Lagrange polynomial that is `0` at the other data
// points but `1` at `x`. // points but `1` at `x`.
let mut l0 = C::Scalar::one(); let mut denom = C::Scalar::one();
for (x0, _) in samples.iter().take(t).filter(|(x0, _)| x0 != x) { for (x0, _) in samples.iter().filter(|(x0, _)| x0 != x) {
let mut denom = *x0; let mut diff = *x0;
denom.sub_assign(x); diff.sub_assign(x);
l0.mul_assign(x0); denom.mul_assign(&diff);
l0.mul_assign(&denom.inverse().expect("indices are different"));
} }
l0.mul_assign(&denom.inverse().ok_or(Error::DuplicateEntry)?);
result.add_assign(&sample.into_affine().mul(l0)); result.add_assign(&sample.into_affine().mul(l0));
} }
Ok(result) Ok(result)

Loading…
Cancel
Save