plonky2/src/polynomial/commitment.rs

118 lines
3.6 KiB
Rust
Raw Normal View History

2021-05-03 15:17:05 +02:00
use crate::field::fft::fft;
2021-04-30 15:07:54 +02:00
use crate::field::field::Field;
2021-05-03 15:17:05 +02:00
use crate::field::lagrange::{interpolant, interpolate};
use crate::fri::{fri_proof, FriConfig};
2021-04-30 15:07:54 +02:00
use crate::merkle_tree::MerkleTree;
2021-05-03 15:17:05 +02:00
use crate::plonk_challenger::Challenger;
use crate::plonk_common::reduce_with_powers;
use crate::polynomial::old_polynomial::Polynomial;
use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues};
2021-04-30 15:07:54 +02:00
use crate::util::transpose;
struct ListPolynomialCommitment<F: Field> {
2021-05-03 15:17:05 +02:00
pub polynomials: Vec<PolynomialCoeffs<F>>,
pub fri_config: FriConfig,
2021-04-30 15:07:54 +02:00
pub merkle_tree: MerkleTree<F>,
2021-05-03 15:17:05 +02:00
pub degree: usize,
pub blinding: bool,
2021-04-30 15:07:54 +02:00
}
impl<F: Field> ListPolynomialCommitment<F> {
2021-05-03 15:17:05 +02:00
pub fn new(
polynomials: Vec<PolynomialCoeffs<F>>,
fri_config: &FriConfig,
blinding: bool,
) -> Self {
let degree = polynomials[0].len();
let mut lde_values = polynomials
.iter()
.map(|p| {
assert_eq!(p.len(), degree, "Polynomial degree invalid.");
p.clone()
.lde(fri_config.rate_bits)
.coset_fft(F::MULTIPLICATIVE_GROUP_GENERATOR)
.values
})
.chain(blinding.then(|| {
(0..(degree << fri_config.rate_bits))
.map(|_| F::rand())
.collect()
}))
2021-04-30 15:07:54 +02:00
.collect::<Vec<_>>();
2021-05-03 15:17:05 +02:00
2021-04-30 15:07:54 +02:00
let merkle_tree = MerkleTree::new(transpose(&lde_values), false);
Self {
2021-05-03 15:17:05 +02:00
polynomials,
fri_config: fri_config.clone(),
2021-04-30 15:07:54 +02:00
merkle_tree,
2021-05-03 15:17:05 +02:00
degree,
blinding,
2021-04-30 15:07:54 +02:00
}
}
2021-05-03 15:17:05 +02:00
pub fn open(&self, points: &[F], challenger: &mut Challenger<F>) -> OpeningProof<F> {
for p in points {
assert_ne!(
p.exp_usize(self.degree),
F::ONE,
"Opening point is in the subgroup."
);
}
let evaluations = points
.iter()
.map(|&x| {
self.polynomials
.iter()
.map(|p| p.eval(x))
.collect::<Vec<_>>()
})
.collect::<Vec<_>>();
for evals in &evaluations {
challenger.observe_elements(evals);
}
let alpha = challenger.get_challenge();
let scaled_poly = self
.polynomials
.iter()
.rev()
.map(|p| p.clone().into())
.fold(Polynomial::empty(), |acc, p| acc.scalar_mul(alpha).add(&p));
let scaled_evals = evaluations
.iter()
.map(|e| reduce_with_powers(e, alpha))
.collect::<Vec<_>>();
let pairs = points
.iter()
.zip(&scaled_evals)
.map(|(&x, &e)| (x, e))
.collect::<Vec<_>>();
debug_assert!(pairs.iter().all(|&(x, e)| scaled_poly.eval(x) == e));
let interpolant: Polynomial<F> = interpolant(&pairs).into();
let denominator = points.iter().fold(Polynomial::empty(), |acc, &x| {
acc.mul(&vec![-x, F::ONE].into())
});
let numerator = scaled_poly.add(&interpolant.neg());
let (mut quotient, rem) = numerator.polynomial_division(&denominator);
debug_assert!(rem.is_zero());
quotient.pad(quotient.degree().next_power_of_two());
let quotient_values = fft(quotient.clone().into());
let fri_proof = fri_proof(
&quotient.into(),
&quotient_values,
challenger,
&self.fri_config,
);
todo!()
}
}
pub struct OpeningProof<F: Field> {
evaluations: Vec<Vec<F>>,
2021-04-30 15:07:54 +02:00
}