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
1 changed files with 94 additions and 92 deletions

View File

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