Simplify h_poly expression evaluation in Proof::create

This commit is contained in:
Jack Grigg 2020-11-24 23:38:26 +00:00
parent 61cddec3b8
commit 875c223748
2 changed files with 75 additions and 69 deletions

View file

@ -302,45 +302,36 @@ impl<C: CurveAffine> Proof<C> {
// Obtain challenge for keeping all separate gates linearly independent // Obtain challenge for keeping all separate gates linearly independent
let x_2: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); let x_2: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128()));
// Evaluate the circuit using the custom gates provided // Evaluate the h(X) polynomial's constraint system expressions for the constraints provided
let mut h_poly = domain.empty_extended(); let h_poly =
for poly in meta.gates.iter() { iter::empty()
h_poly = h_poly * x_2; // Custom constraints
.chain(meta.gates.iter().map(|poly| {
let evaluation = poly.evaluate( poly.evaluate(
&|index| pk.fixed_cosets[index].clone(), &|index| pk.fixed_cosets[index].clone(),
&|index| advice_cosets[index].clone(), &|index| advice_cosets[index].clone(),
&|index| aux_cosets[index].clone(), &|index| aux_cosets[index].clone(),
&|a, b| a + &b, &|a, b| a + &b,
&|a, b| a * &b, &|a, b| a * &b,
&|a, scalar| a * scalar, &|a, scalar| a * scalar,
); )
}))
h_poly = h_poly + &evaluation;
}
// l_0(X) * (1 - z(X)) = 0 // l_0(X) * (1 - z(X)) = 0
for coset in permutation_product_cosets.iter() { .chain(
parallelize(&mut h_poly, |h, start| { permutation_product_cosets
for ((h, c), l0) in h .iter()
.iter_mut() .cloned()
.zip(coset[start..].iter()) .map(|coset| Polynomial::one_minus(coset) * &pk.l0),
.zip(pk.l0[start..].iter()) )
{
*h *= &x_2;
*h += &(*l0 * &(C::Scalar::one() - c));
}
});
}
// z(X) \prod (p(X) + \beta s_i(X) + \gamma) - z(omega^{-1} X) \prod (p(X) + \delta^i \beta X + \gamma) // z(X) \prod (p(X) + \beta s_i(X) + \gamma) - z(omega^{-1} X) \prod (p(X) + \delta^i \beta X + \gamma)
for (permutation_index, columns) in pk.vk.cs.permutations.iter().enumerate() { .chain(pk.vk.cs.permutations.iter().enumerate().map(
h_poly = h_poly * x_2; |(permutation_index, columns)| {
let mut left = permutation_product_cosets[permutation_index].clone(); let mut left = permutation_product_cosets[permutation_index].clone();
for (advice, permutation) in columns for (advice, permutation) in columns
.iter() .iter()
.map(|&column| &advice_cosets[pk.vk.cs.get_advice_query_index(column, 0)]) .map(|&column| {
&advice_cosets[pk.vk.cs.get_advice_query_index(column, 0)]
})
.zip(pk.permutation_cosets[permutation_index].iter()) .zip(pk.permutation_cosets[permutation_index].iter())
{ {
parallelize(&mut left, |left, start| { parallelize(&mut left, |left, start| {
@ -357,13 +348,14 @@ impl<C: CurveAffine> Proof<C> {
let mut right = permutation_product_cosets_inv[permutation_index].clone(); let mut right = permutation_product_cosets_inv[permutation_index].clone();
let mut current_delta = x_0 * &C::Scalar::ZETA; let mut current_delta = x_0 * &C::Scalar::ZETA;
let step = domain.get_extended_omega(); let step = domain.get_extended_omega();
for advice in columns for advice in columns.iter().map(|&column| {
.iter() &advice_cosets[pk.vk.cs.get_advice_query_index(column, 0)]
.map(|&column| &advice_cosets[pk.vk.cs.get_advice_query_index(column, 0)]) }) {
{
parallelize(&mut right, move |right, start| { parallelize(&mut right, move |right, start| {
let mut beta_term = current_delta * &step.pow_vartime(&[start as u64, 0, 0, 0]); let mut beta_term =
for (right, advice) in right.iter_mut().zip(advice[start..].iter()) { current_delta * &step.pow_vartime(&[start as u64, 0, 0, 0]);
for (right, advice) in right.iter_mut().zip(advice[start..].iter())
{
*right *= &(*advice + &beta_term + &x_1); *right *= &(*advice + &beta_term + &x_1);
beta_term *= &step; beta_term *= &step;
} }
@ -371,8 +363,10 @@ impl<C: CurveAffine> Proof<C> {
current_delta *= &C::Scalar::DELTA; current_delta *= &C::Scalar::DELTA;
} }
h_poly = h_poly + &left - &right; left - &right
} },
))
.fold(domain.empty_extended(), |h_poly, v| h_poly * x_2 + &v);
// Divide by t(X) = X^{params.n} - 1. // Divide by t(X) = X^{params.n} - 1.
let h_poly = domain.divide_by_vanishing_poly(h_poly); let h_poly = domain.divide_by_vanishing_poly(h_poly);

View file

@ -127,6 +127,18 @@ impl<F, B> Polynomial<F, B> {
} }
} }
impl<F: Field> Polynomial<F, ExtendedLagrangeCoeff> {
/// Maps every coefficient `c` in `p` to `1 - c`.
pub fn one_minus(mut p: Self) -> Self {
parallelize(&mut p.values, |p, _start| {
for term in p {
*term = F::one() - *term;
}
});
p
}
}
impl<'a, F: Field, B: Basis> Add<&'a Polynomial<F, B>> for Polynomial<F, B> { impl<'a, F: Field, B: Basis> Add<&'a Polynomial<F, B>> for Polynomial<F, B> {
type Output = Polynomial<F, B>; type Output = Polynomial<F, B>;