plonky2/src/polynomial/commitment.rs

679 lines
22 KiB
Rust
Raw Normal View History

use anyhow::Result;
use rayon::prelude::*;
2021-05-18 15:22:06 +02:00
use crate::field::extension_field::FieldExtension;
use crate::field::extension_field::{Extendable, OEF};
2021-04-30 15:07:54 +02:00
use crate::field::field::Field;
2021-05-04 19:56:34 +02:00
use crate::field::lagrange::interpolant;
2021-05-05 18:23:59 +02:00
use crate::fri::{prover::fri_proof, verifier::verify_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_polys_with_powers, reduce_with_powers};
2021-05-04 19:56:34 +02:00
use crate::polynomial::polynomial::PolynomialCoeffs;
use crate::proof::{FriInitialTreeProof, FriProof, Hash, OpeningSet};
use crate::timed;
2021-05-04 17:48:26 +02:00
use crate::util::{log2_strict, reverse_index_bits_in_place, transpose};
2021-04-30 15:07:54 +02:00
2021-05-06 17:09:55 +02:00
pub const SALT_SIZE: usize = 2;
2021-05-06 23:14:37 +02:00
pub struct ListPolynomialCommitment<F: Field> {
2021-05-03 15:17:05 +02:00
pub polynomials: Vec<PolynomialCoeffs<F>>,
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 rate_bits: usize,
pub blinding: bool,
2021-04-30 15:07:54 +02:00
}
impl<F: Field> ListPolynomialCommitment<F> {
pub fn new(polynomials: Vec<PolynomialCoeffs<F>>, rate_bits: usize, blinding: bool) -> Self {
2021-05-03 15:17:05 +02:00
let degree = polynomials[0].len();
let lde_values = timed!(
Self::lde_values(&polynomials, rate_bits, blinding),
"to compute LDE"
);
let mut leaves = timed!(transpose(&lde_values), "to transpose LDEs");
reverse_index_bits_in_place(&mut leaves);
let merkle_tree = timed!(MerkleTree::new(leaves, false), "to build Merkle tree");
Self {
polynomials,
merkle_tree,
degree,
rate_bits,
blinding,
}
}
fn lde_values(
polynomials: &[PolynomialCoeffs<F>],
rate_bits: usize,
blinding: bool,
) -> Vec<Vec<F>> {
let degree = polynomials[0].len();
polynomials
2021-05-07 16:49:27 +02:00
.par_iter()
2021-05-03 15:17:05 +02:00
.map(|p| {
assert_eq!(p.len(), degree, "Polynomial degree invalid.");
p.clone()
.lde(rate_bits)
2021-05-03 15:17:05 +02:00
.coset_fft(F::MULTIPLICATIVE_GROUP_GENERATOR)
.values
})
.chain(if blinding {
2021-05-06 00:00:08 +02:00
// If blinding, salt with two random elements to each leaf vector.
2021-05-06 17:09:55 +02:00
(0..SALT_SIZE)
.map(|_| F::rand_vec(degree << rate_bits))
2021-05-03 15:17:05 +02:00
.collect()
2021-05-06 00:00:08 +02:00
} else {
Vec::new()
})
.collect()
2021-04-30 15:07:54 +02:00
}
2021-05-03 15:17:05 +02:00
2021-05-07 16:22:13 +02:00
pub fn leaf(&self, index: usize) -> &[F] {
let leaf = &self.merkle_tree.leaves[index];
&leaf[0..leaf.len() - if self.blinding { SALT_SIZE } else { 0 }]
2021-05-07 16:22:13 +02:00
}
2021-05-18 15:44:50 +02:00
pub fn open<const D: usize>(
2021-05-05 22:58:15 +02:00
&self,
2021-05-18 15:22:06 +02:00
points: &[F::Extension],
2021-05-05 22:58:15 +02:00
challenger: &mut Challenger<F>,
config: &FriConfig,
2021-05-18 15:44:50 +02:00
) -> (OpeningProof<F, D>, Vec<Vec<F::Extension>>)
2021-05-18 15:22:06 +02:00
where
2021-05-18 15:44:50 +02:00
F: Extendable<D>,
2021-05-18 15:22:06 +02:00
{
assert_eq!(self.rate_bits, config.rate_bits);
assert_eq!(config.check_basefield.len(), 1);
assert_eq!(config.blinding.len(), 1);
assert_eq!(self.blinding, config.blinding[0]);
2021-05-03 15:17:05 +02:00
for p in points {
assert_ne!(
p.exp(self.degree as u64),
2021-05-18 15:22:06 +02:00
F::Extension::ONE,
2021-05-03 15:17:05 +02:00
"Opening point is in the subgroup."
);
}
let evaluations = points
2021-05-07 16:49:27 +02:00
.par_iter()
2021-05-03 15:17:05 +02:00
.map(|&x| {
self.polynomials
.iter()
2021-05-18 15:22:06 +02:00
.map(|p| p.to_extension().eval(x))
2021-05-03 15:17:05 +02:00
.collect::<Vec<_>>()
})
.collect::<Vec<_>>();
for evals in &evaluations {
2021-05-18 15:22:06 +02:00
for e in evals {
challenger.observe_extension_element(e);
}
2021-05-03 15:17:05 +02:00
}
2021-05-18 15:22:06 +02:00
let alpha = challenger.get_extension_challenge();
2021-05-03 15:17:05 +02:00
2021-05-05 18:32:24 +02:00
// Scale polynomials by `alpha`.
let composition_poly = reduce_polys_with_powers(&self.polynomials, alpha);
2021-05-05 18:32:24 +02:00
// Scale evaluations by `alpha`.
2021-05-05 22:58:15 +02:00
let composition_evals = evaluations
2021-05-07 16:49:27 +02:00
.par_iter()
2021-05-03 15:17:05 +02:00
.map(|e| reduce_with_powers(e, alpha))
.collect::<Vec<_>>();
2021-05-05 22:58:15 +02:00
let quotient = Self::compute_quotient(points, &composition_evals, &composition_poly);
2021-05-04 17:48:26 +02:00
let quotient = if config.check_basefield[0] {
let composition_poly_conj = PolynomialCoeffs::<F>::frobenius(&composition_poly);
// This equality holds iff the polynomials in `self.polynomials` are defined over `F` and not `F::Extension`.
debug_assert_eq!(
composition_poly_conj.eval(points[0].frobenius()),
composition_evals[0].frobenius()
);
let quotient_conj = Self::compute_quotient(
&[points[0].frobenius()],
&[composition_evals[0].frobenius()],
&composition_poly_conj,
);
&(&quotient_conj * alpha.exp(self.polynomials.len() as u64)) + &quotient
} else {
quotient
};
let lde_quotient = PolynomialCoeffs::from(quotient.clone()).lde(self.rate_bits);
2021-05-04 19:56:34 +02:00
let lde_quotient_values = lde_quotient
.clone()
2021-05-18 15:22:06 +02:00
.coset_fft(F::MULTIPLICATIVE_GROUP_GENERATOR.into());
2021-05-04 17:48:26 +02:00
2021-05-03 15:17:05 +02:00
let fri_proof = fri_proof(
2021-05-06 17:09:55 +02:00
&[&self.merkle_tree],
2021-05-04 17:48:26 +02:00
&lde_quotient,
&lde_quotient_values,
2021-05-03 15:17:05 +02:00
challenger,
&config,
2021-05-03 15:17:05 +02:00
);
2021-05-04 17:48:26 +02:00
2021-05-05 22:58:15 +02:00
(
OpeningProof {
fri_proof,
quotient_degree: quotient.len(),
},
2021-05-04 17:48:26 +02:00
evaluations,
2021-05-05 22:58:15 +02:00
)
2021-05-03 15:17:05 +02:00
}
2021-05-05 18:32:24 +02:00
// pub fn batch_open<const D: usize>(
// commitments: &[&Self],
// opening_config: &OpeningConfig<F, D>,
// fri_config: &FriConfig,
// challenger: &mut Challenger<F>,
// ) -> (OpeningProof<F, D>, Vec<Vec<Vec<Vec<F::Extension>>>>)
// where
// F: Extendable<D>,
// {
// let degree = commitments[0].degree;
// assert_eq!(fri_config.blinding.len(), commitments.len());
// for (i, commitment) in commitments.iter().enumerate() {
// assert_eq!(commitment.rate_bits, fri_config.rate_bits, "Invalid rate.");
// assert_eq!(
// commitment.blinding, fri_config.blinding[i],
// "Invalid blinding paramater."
// );
// assert_eq!(
// commitment.degree, degree,
// "Trying to open polynomial commitments of different degrees."
// );
// }
// for &p in opening_config.points.iter().flat_map(|(v, _)| v) {
// assert_ne!(
// p.exp(degree as u64),
// F::Extension::ONE,
// "Opening point is in the subgroup."
// );
// }
//
// let evaluations = opening_config
// .points
// .iter()
// .map(|(xs, is)| {
// xs.iter()
// .map(|&x| {
// is.iter()
// .map(|&i| {
// commitments[i]
// .polynomials
// .iter()
// .map(|p| p.to_extension().eval(x))
// .collect::<Vec<_>>()
// })
// .collect::<Vec<_>>()
// })
// .collect::<Vec<_>>()
// })
// .collect::<Vec<_>>();
// for evals_per_point_vec in &evaluations {
// for evals_per_point in evals_per_point_vec {
// for evals in evals_per_point {
// challenger.observe_extension_elements(evals);
// }
// }
// }
//
// let alpha = challenger.get_extension_challenge();
// let mut cur_alpha = F::Extension::ONE;
//
// // Final low-degree polynomial that goes into FRI.
// let mut final_poly = PolynomialCoeffs::empty();
//
// for ((ps, is), evals) in opening_config.points.iter().zip(&evaluations) {
// let mut poly_count = 0;
// // Scale polynomials by `alpha`.
// let composition_poly = is
// .iter()
// .flat_map(|&i| &commitments[i].polynomials)
// .rev()
// .fold(PolynomialCoeffs::zero(degree), |acc, p| {
// poly_count += 1;
// &(&acc * alpha) + &p.to_extension()
// });
// // Scale evaluations by `alpha`.
// let composition_evals = &evals
// .iter()
// .map(|v| {
// v.iter()
// .flatten()
// .rev()
// .fold(F::Extension::ZERO, |acc, &e| acc * alpha + e)
// })
// .collect::<Vec<_>>();
//
// let quotient = Self::compute_quotient(ps, &composition_evals, &composition_poly);
// final_poly = &final_poly + &(&quotient * cur_alpha);
// cur_alpha *= alpha.exp(poly_count);
// }
//
// for &i in &opening_config.check_base_field {
// let commitment = commitments[i];
// let x = opening_config
// .points
// .iter()
// .find(|(xs, is)| is.contains(&i))
// .expect("Polynomial is never opened.")
// .0[0];
// let x_conj = x.frobenius();
// let mut poly_count = 0;
// let poly = commitment.polynomials.iter().rev().fold(
// PolynomialCoeffs::zero(degree),
// |acc, p| {
// poly_count += 1;
// &(&acc * alpha) + &p.to_extension()
// },
// );
// let e = poly.eval(x_conj);
// let quotient = Self::compute_quotient(&[x_conj], &[e], &poly);
// final_poly = &final_poly + &(&quotient * cur_alpha);
// cur_alpha *= alpha.exp(poly_count);
// }
//
// let lde_final_poly = final_poly.lde(fri_config.rate_bits);
// let lde_final_values = lde_final_poly
// .clone()
// .coset_fft(F::Extension::from_basefield(
// F::MULTIPLICATIVE_GROUP_GENERATOR,
// ));
//
// let fri_proof = fri_proof(
// &commitments
// .par_iter()
// .map(|c| &c.merkle_tree)
// .collect::<Vec<_>>(),
// &lde_final_poly,
// &lde_final_values,
// challenger,
// &fri_config,
// );
//
// (
// OpeningProof {
// fri_proof,
// quotient_degree: final_poly.len(),
// },
// evaluations,
// )
// }
pub fn open_plonk<const D: usize>(
commitments: &[&Self; 5],
zeta: F::Extension,
degree_log: usize,
2021-05-06 17:09:55 +02:00
challenger: &mut Challenger<F>,
config: &FriConfig,
) -> (OpeningProof<F, D>, OpeningSet<F, D>)
2021-05-18 15:22:06 +02:00
where
2021-05-18 15:44:50 +02:00
F: Extendable<D>,
2021-05-18 15:22:06 +02:00
{
let g = F::Extension::primitive_root_of_unity(degree_log);
dbg!(degree_log);
for &p in &[zeta, g * zeta] {
2021-05-06 17:09:55 +02:00
assert_ne!(
p.exp(1 << degree_log as u64),
2021-05-18 15:22:06 +02:00
F::Extension::ONE,
2021-05-06 17:09:55 +02:00
"Opening point is in the subgroup."
);
}
let os = OpeningSet::new(
zeta,
g,
commitments[0],
commitments[1],
commitments[2],
commitments[3],
commitments[4],
);
challenger.observe_opening_set(&os);
2021-05-06 17:09:55 +02:00
2021-05-18 15:22:06 +02:00
let alpha = challenger.get_extension_challenge();
dbg!(alpha);
let mut cur_alpha = F::Extension::ONE;
2021-05-06 17:09:55 +02:00
// Final low-degree polynomial that goes into FRI.
let mut final_poly = PolynomialCoeffs::empty();
// Count the total number of polynomials accumulated into `final_poly`.
let mut poly_count = 0;
let composition_poly = [0, 1, 4]
2021-05-06 17:09:55 +02:00
.iter()
.flat_map(|&i| &commitments[i].polynomials)
2021-05-06 17:09:55 +02:00
.rev()
.fold(PolynomialCoeffs::empty(), |acc, p| {
poly_count += 1;
2021-05-18 15:22:06 +02:00
&(&acc * alpha) + &p.to_extension()
2021-05-12 11:26:21 -07:00
});
let composition_eval = [&os.constants, &os.plonk_sigmas, &os.quotient_polys]
.iter()
.flat_map(|v| v.iter())
.rev()
.fold(F::Extension::ZERO, |acc, &e| acc * alpha + e);
let quotient = Self::compute_quotient(&[zeta], &[composition_eval], &composition_poly);
final_poly = &final_poly + &(&quotient * cur_alpha);
{
let lde_final_poly = final_poly.lde(config.rate_bits);
let lde_final_values = lde_final_poly
.clone()
.coset_fft(F::Extension::from_basefield(
F::MULTIPLICATIVE_GROUP_GENERATOR,
));
dbg!(lde_final_values);
}
cur_alpha = alpha.exp(poly_count);
let zs_composition_poly =
commitments[3]
.polynomials
.iter()
.rev()
.fold(PolynomialCoeffs::empty(), |acc, p| {
poly_count += 1;
&(&acc * alpha) + &p.to_extension()
});
let zs_composition_evals = [
reduce_with_powers(&os.plonk_zs, alpha),
reduce_with_powers(&os.plonk_zs_right, alpha),
];
let zs_quotient = Self::compute_quotient(
&[zeta, g * zeta],
&zs_composition_evals,
&zs_composition_poly,
);
final_poly = &final_poly + &(&zs_quotient * cur_alpha);
{
let lde_final_poly = final_poly.lde(config.rate_bits);
let lde_final_values = lde_final_poly
.clone()
.coset_fft(F::Extension::from_basefield(
F::MULTIPLICATIVE_GROUP_GENERATOR,
));
dbg!(lde_final_values);
dbg!(cur_alpha);
}
cur_alpha = alpha.exp(poly_count);
let wires_composition_poly =
commitments[2]
.polynomials
.iter()
.rev()
.fold(PolynomialCoeffs::empty(), |acc, p| {
poly_count += 1;
&(&acc * alpha) + &p.to_extension()
});
let wire_evals_frob = os.wires.iter().map(|e| e.frobenius()).collect::<Vec<_>>();
let wires_composition_evals = [
reduce_with_powers(&os.wires, alpha),
reduce_with_powers(&wire_evals_frob, alpha),
];
let wires_quotient = Self::compute_quotient(
&[zeta, zeta.frobenius()],
&wires_composition_evals,
&wires_composition_poly,
);
final_poly = &final_poly + &(&wires_quotient * cur_alpha);
2021-05-06 17:09:55 +02:00
dbg!(final_poly.coeffs.len());
let lde_final_poly = final_poly.lde(config.rate_bits);
let lde_final_values = lde_final_poly
.clone()
.coset_fft(F::Extension::from_basefield(
F::MULTIPLICATIVE_GROUP_GENERATOR,
));
2021-05-06 17:09:55 +02:00
let fri_proof = fri_proof(
&commitments
2021-05-07 16:49:27 +02:00
.par_iter()
2021-05-06 17:09:55 +02:00
.map(|c| &c.merkle_tree)
.collect::<Vec<_>>(),
&lde_final_poly,
&lde_final_values,
2021-05-06 17:09:55 +02:00
challenger,
&config,
2021-05-06 17:09:55 +02:00
);
(
OpeningProof {
fri_proof,
quotient_degree: final_poly.len(),
2021-05-06 17:09:55 +02:00
},
os,
2021-05-06 17:09:55 +02:00
)
}
2021-05-05 18:32:24 +02:00
/// Given `points=(x_i)`, `evals=(y_i)` and `poly=P` with `P(x_i)=y_i`, computes the polynomial
/// `Q=(P-I)/Z` where `I` interpolates `(x_i, y_i)` and `Z` is the vanishing polynomial on `(x_i)`.
2021-05-18 15:44:50 +02:00
fn compute_quotient<const D: usize>(
2021-05-18 15:22:06 +02:00
points: &[F::Extension],
evals: &[F::Extension],
poly: &PolynomialCoeffs<F::Extension>,
) -> PolynomialCoeffs<F::Extension>
where
2021-05-18 15:44:50 +02:00
F: Extendable<D>,
2021-05-18 15:22:06 +02:00
{
2021-05-05 18:32:24 +02:00
let pairs = points
.iter()
.zip(evals)
.map(|(&x, &e)| (x, e))
.collect::<Vec<_>>();
debug_assert!(pairs.iter().all(|&(x, e)| poly.eval(x) == e));
dbg!(&pairs);
let interpolant = interpolant(&pairs);
let denominator = points.iter().fold(PolynomialCoeffs::one(), |acc, &x| {
2021-05-18 15:22:06 +02:00
&acc * &PolynomialCoeffs::new(vec![-x, F::Extension::ONE])
});
let numerator = poly - &interpolant;
let (mut quotient, rem) = numerator.div_rem(&denominator);
2021-05-05 18:32:24 +02:00
debug_assert!(rem.is_zero());
quotient.padded(quotient.degree_plus_one().next_power_of_two())
2021-05-05 18:32:24 +02:00
}
2021-05-03 15:17:05 +02:00
}
2021-05-18 15:44:50 +02:00
pub struct OpeningProof<F: Field + Extendable<D>, const D: usize> {
fri_proof: FriProof<F, D>,
2021-05-06 15:14:43 +02:00
// TODO: Get the degree from `CommonCircuitData` instead.
2021-05-04 17:48:26 +02:00
quotient_degree: usize,
}
2021-05-18 15:44:50 +02:00
impl<F: Field + Extendable<D>, const D: usize> OpeningProof<F, D> {
2021-05-04 17:48:26 +02:00
pub fn verify(
&self,
zeta: F::Extension,
os: &OpeningSet<F, D>,
2021-05-06 17:09:55 +02:00
merkle_roots: &[Hash<F>],
2021-05-04 17:48:26 +02:00
challenger: &mut Challenger<F>,
fri_config: &FriConfig,
) -> Result<()> {
challenger.observe_opening_set(os);
2021-05-04 17:48:26 +02:00
2021-05-18 15:22:06 +02:00
let alpha = challenger.get_extension_challenge();
dbg!(alpha);
2021-05-04 17:48:26 +02:00
verify_fri_proof(
log2_strict(self.quotient_degree),
&os,
zeta,
2021-05-04 17:48:26 +02:00
alpha,
2021-05-06 17:09:55 +02:00
merkle_roots,
2021-05-04 17:48:26 +02:00
&self.fri_proof,
challenger,
fri_config,
)
}
}
#[cfg(test)]
mod tests {
use anyhow::Result;
use crate::field::crandall_field::CrandallField;
use super::*;
use std::convert::TryInto;
2021-05-18 15:44:50 +02:00
fn gen_random_test_case<F: Field + Extendable<D>, const D: usize>(
2021-05-05 17:00:47 +02:00
k: usize,
degree_log: usize,
) -> Vec<PolynomialCoeffs<F>> {
2021-05-05 17:00:47 +02:00
let degree = 1 << degree_log;
(0..k)
2021-05-06 15:14:43 +02:00
.map(|_| PolynomialCoeffs::new(F::rand_vec(degree)))
.collect()
2021-05-05 17:00:47 +02:00
}
fn gen_random_point<F: Field + Extendable<D>, const D: usize>(
degree_log: usize,
) -> F::Extension {
let degree = 1 << degree_log;
2021-05-04 17:48:26 +02:00
let mut point = F::Extension::rand();
while point.exp(degree as u64).is_one() {
point = F::Extension::rand();
}
2021-05-04 17:48:26 +02:00
point
2021-05-06 17:09:55 +02:00
}
2021-05-18 16:06:47 +02:00
fn check_batch_polynomial_commitment<F: Field + Extendable<D>, const D: usize>() -> Result<()> {
let ks = [1, 2, 3, 5, 8];
let degree_log = 2;
2021-05-06 17:09:55 +02:00
let fri_config = FriConfig {
proof_of_work_bits: 2,
rate_bits: 1,
// reduction_arity_bits: vec![2, 3, 1, 2],
reduction_arity_bits: vec![1],
2021-05-06 17:09:55 +02:00
num_query_rounds: 3,
blinding: vec![false, false, false, false, false],
check_basefield: vec![false, false, false],
2021-05-06 17:09:55 +02:00
};
let lpcs = ks
.iter()
.map(|&k| {
ListPolynomialCommitment::<F>::new(
gen_random_test_case(k, degree_log),
fri_config.rate_bits,
false,
)
})
.collect::<Vec<_>>();
2021-05-06 17:09:55 +02:00
let zeta = gen_random_point::<F, D>(degree_log);
let (proof, os) = ListPolynomialCommitment::open_plonk::<D>(
&[&lpcs[0], &lpcs[1], &lpcs[2], &lpcs[3], &lpcs[4]],
zeta,
degree_log,
2021-05-06 17:09:55 +02:00
&mut Challenger::new(),
&fri_config,
2021-05-06 17:09:55 +02:00
);
let os = OpeningSet::new(
zeta,
F::Extension::primitive_root_of_unity(degree_log),
&lpcs[0],
&lpcs[1],
&lpcs[2],
&lpcs[3],
&lpcs[4],
2021-05-06 17:09:55 +02:00
);
proof.verify(
zeta,
&os,
2021-05-06 17:09:55 +02:00
&[
lpcs[0].merkle_tree.root,
lpcs[1].merkle_tree.root,
lpcs[2].merkle_tree.root,
lpcs[3].merkle_tree.root,
lpcs[4].merkle_tree.root,
2021-05-06 17:09:55 +02:00
],
2021-05-06 15:19:06 +02:00
&mut Challenger::new(),
&fri_config,
)
2021-05-04 17:48:26 +02:00
}
2021-05-18 16:06:47 +02:00
// fn check_batch_polynomial_commitment_blinding<F: Field + Extendable<D>, const D: usize>(
// ) -> Result<()> {
// let k0 = 10;
// let k1 = 3;
// let k2 = 7;
// let degree_log = 11;
// let num_points = 5;
// let fri_config = FriConfig {
// proof_of_work_bits: 2,
// rate_bits: 2,
// reduction_arity_bits: vec![2, 3, 1, 2],
// num_query_rounds: 3,
// blinding: vec![true, false, true],
// check_basefield: vec![true, false, true],
// };
// let (polys0, _) = gen_random_test_case::<F, D>(k0, degree_log, num_points);
// let (polys1, _) = gen_random_test_case::<F, D>(k1, degree_log, num_points);
// let (polys2, points) = gen_random_test_case::<F, D>(k2, degree_log, num_points);
//
// let lpc0 = ListPolynomialCommitment::new(polys0, fri_config.rate_bits, true);
// let lpc1 = ListPolynomialCommitment::new(polys1, fri_config.rate_bits, false);
// let lpc2 = ListPolynomialCommitment::new(polys2, fri_config.rate_bits, true);
//
// let (proof, evaluations) = ListPolynomialCommitment::batch_open::<D>(
// &[&lpc0, &lpc1, &lpc2],
// &points,
// &fri_config,
// &mut Challenger::new(),
// );
// proof.verify(
// &points,
// &evaluations,
// &[
// lpc0.merkle_tree.root,
// lpc1.merkle_tree.root,
// lpc2.merkle_tree.root,
// ],
// &mut Challenger::new(),
// &fri_config,
// )
// }
2021-05-18 16:23:44 +02:00
macro_rules! tests_commitments {
($F:ty, $D:expr) => {
use super::*;
2021-05-18 16:06:47 +02:00
2021-05-18 16:23:44 +02:00
#[test]
fn test_batch_polynomial_commitment() -> Result<()> {
check_batch_polynomial_commitment::<$F, $D>()
}
2021-05-18 16:06:47 +02:00
// #[test]
// fn test_batch_polynomial_commitment_blinding() -> Result<()> {
// check_batch_polynomial_commitment_blinding::<$F, $D>()
// }
2021-05-18 16:23:44 +02:00
};
2021-05-18 16:06:47 +02:00
}
2021-05-18 16:23:44 +02:00
mod base {
tests_commitments!(crate::field::crandall_field::CrandallField, 1);
}
2021-05-18 16:06:47 +02:00
2021-05-18 16:23:44 +02:00
mod quadratic {
tests_commitments!(crate::field::crandall_field::CrandallField, 2);
2021-05-18 16:06:47 +02:00
}
mod quartic {
use super::*;
2021-05-18 16:23:44 +02:00
tests_commitments!(crate::field::crandall_field::CrandallField, 4);
2021-05-18 16:06:47 +02:00
}
2021-04-30 15:07:54 +02:00
}