Remove query allocations from Proof::create

multiopen::Proof::create takes `instances: IntoIterator`, so we can just
pass it an iterator directly.
This commit is contained in:
Jack Grigg 2020-10-21 22:17:23 +01:00
parent 6360da1f4e
commit 61c9392475

View file

@ -1,3 +1,5 @@
use std::iter;
use super::{ use super::{
circuit::{Advice, Assignment, Circuit, Column, ConstraintSystem, Fixed}, circuit::{Advice, Assignment, Circuit, Column, ConstraintSystem, Fixed},
Error, Proof, ProvingKey, Error, Proof, ProvingKey,
@ -408,6 +410,7 @@ impl<C: CurveAffine> Proof<C> {
} }
let x_3: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); let x_3: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128()));
let x_3_inv = domain.rotate_omega(x_3, Rotation(-1));
// Evaluate polynomials at omega^i x_3 // Evaluate polynomials at omega^i x_3
let advice_evals: Vec<_> = meta let advice_evals: Vec<_> = meta
@ -476,101 +479,100 @@ impl<C: CurveAffine> Proof<C> {
transcript.absorb_scalar(*eval); transcript.absorb_scalar(*eval);
} }
let mut instances: Vec<ProverQuery<C>> = Vec::new(); let instances =
iter::empty()
for (query_index, &(column, at)) in pk.vk.cs.advice_queries.iter().enumerate() { .chain(pk.vk.cs.advice_queries.iter().enumerate().map(
let point = domain.rotate_omega(x_3, at); |(query_index, &(column, at))| ProverQuery {
point: domain.rotate_omega(x_3, at),
instances.push(ProverQuery { poly: &advice_polys[column.index()],
point, blind: advice_blinds[column.index()],
poly: &advice_polys[column.index()], eval: advice_evals[query_index],
blind: advice_blinds[column.index()], },
eval: advice_evals[query_index], ))
}); .chain(pk.vk.cs.aux_queries.iter().enumerate().map(
} |(query_index, &(column, at))| ProverQuery {
point: domain.rotate_omega(x_3, at),
for (query_index, &(column, at)) in pk.vk.cs.aux_queries.iter().enumerate() { poly: &aux_polys[column.index()],
let point = domain.rotate_omega(x_3, at); blind: Blind::default(),
eval: aux_evals[query_index],
instances.push(ProverQuery { },
point, ))
poly: &aux_polys[column.index()], .chain(pk.vk.cs.fixed_queries.iter().enumerate().map(
blind: Blind::default(), |(query_index, &(column, at))| ProverQuery {
eval: aux_evals[query_index], point: domain.rotate_omega(x_3, at),
}); poly: &pk.fixed_polys[column.index()],
} blind: Blind::default(),
eval: fixed_evals[query_index],
for (query_index, &(column, at)) in pk.vk.cs.fixed_queries.iter().enumerate() { },
let point = domain.rotate_omega(x_3, at); ))
// We query the h(X) polynomial at x_3
instances.push(ProverQuery { .chain(
point, h_pieces
poly: &pk.fixed_polys[column.index()], .iter()
blind: Blind::default(), .zip(h_blinds.iter())
eval: fixed_evals[query_index], .zip(h_evals.iter())
}); .map(|((h_poly, h_blind), h_eval)| ProverQuery {
} point: x_3,
poly: h_poly,
// We query the h(X) polynomial at x_3 blind: *h_blind,
for ((h_poly, h_blind), h_eval) in h_pieces.iter().zip(h_blinds.iter()).zip(h_evals.iter()) eval: *h_eval,
{ }),
instances.push(ProverQuery { );
point: x_3,
poly: h_poly,
blind: *h_blind,
eval: *h_eval,
});
}
// Handle permutation arguments, if any exist // Handle permutation arguments, if any exist
if !pk.vk.cs.permutations.is_empty() { let permutation_instances = if !pk.vk.cs.permutations.is_empty() {
// Open permutation product commitments at x_3 Some(
for ((poly, blind), eval) in permutation_product_polys iter::empty()
.iter() // Open permutation product commitments at x_3
.zip(permutation_product_blinds.iter()) .chain(
.zip(permutation_product_evals.iter()) permutation_product_polys
{ .iter()
instances.push(ProverQuery { .zip(permutation_product_blinds.iter())
point: x_3, .zip(permutation_product_evals.iter())
poly, .map(|((poly, blind), eval)| ProverQuery {
blind: *blind, point: x_3,
eval: *eval, poly,
}); blind: *blind,
} eval: *eval,
}),
)
// Open permutation polynomial commitments at x_3
.chain(
pk.permutation_polys
.iter()
.zip(permutation_evals.iter())
.flat_map(|(polys, evals)| polys.iter().zip(evals.iter()))
.map(|(poly, eval)| ProverQuery {
point: x_3,
poly,
blind: Blind::default(),
eval: *eval,
}),
)
// Open permutation product commitments at \omega^{-1} x_3
.chain(
permutation_product_polys
.iter()
.zip(permutation_product_blinds.iter())
.zip(permutation_product_inv_evals.iter())
.map(|((poly, blind), eval)| ProverQuery {
point: x_3_inv,
poly,
blind: *blind,
eval: *eval,
}),
),
)
} else {
None
};
// Open permutation polynomial commitments at x_3 let multiopening = multiopen::Proof::create(
for (poly, eval) in pk params,
.permutation_polys &mut transcript,
.iter() instances.chain(permutation_instances.into_iter().flatten()),
.zip(permutation_evals.iter()) )
.flat_map(|(polys, evals)| polys.iter().zip(evals.iter())) .map_err(|_| Error::OpeningError)?;
{
instances.push(ProverQuery {
point: x_3,
poly,
blind: Blind::default(),
eval: *eval,
});
}
let x_3_inv = domain.rotate_omega(x_3, Rotation(-1));
// Open permutation product commitments at \omega^{-1} x_3
for ((poly, blind), eval) in permutation_product_polys
.iter()
.zip(permutation_product_blinds.iter())
.zip(permutation_product_inv_evals.iter())
{
instances.push(ProverQuery {
point: x_3_inv,
poly,
blind: *blind,
eval: *eval,
});
}
}
let multiopening = multiopen::Proof::create(params, &mut transcript, instances)
.map_err(|_| Error::OpeningError)?;
Ok(Proof { Ok(Proof {
advice_commitments, advice_commitments,