Skip to content

Commit

Permalink
Improve prover-key size on write (increase exec time on read)
Browse files Browse the repository at this point in the history
  • Loading branch information
miguel-ambrona committed Apr 23, 2024
1 parent c161056 commit b6d8ab7
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 19 deletions.
57 changes: 45 additions & 12 deletions halo2_proofs/src/plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use blake2b_simd::Params as Blake2bParams;
use group::ff::{Field, FromUniformBytes, PrimeField};

use crate::arithmetic::CurveAffine;
use crate::arithmetic::{parallelize, CurveAffine};
use crate::helpers::{
polynomial_slice_byte_length, read_polynomial_vec, write_polynomial_slice, SerdeCurveAffine,
SerdePrimeField,
Expand Down Expand Up @@ -387,12 +387,7 @@ where
/// Does so by first writing the verifying key and then serializing the rest of the data (in the form of field polynomials)
pub fn write<W: io::Write>(&self, writer: &mut W, format: SerdeFormat) -> io::Result<()> {
self.vk.write(writer, format)?;
self.l0.write(writer, format)?;
self.l_last.write(writer, format)?;
self.l_active_row.write(writer, format)?;
write_polynomial_slice(&self.fixed_values, writer, format)?;
write_polynomial_slice(&self.fixed_polys, writer, format)?;
write_polynomial_slice(&self.fixed_cosets, writer, format)?;
self.permutation.write(writer, format)?;
Ok(())
}
Expand All @@ -419,13 +414,51 @@ where
#[cfg(feature = "circuit-params")]
params,
)?;
let l0 = Polynomial::read(reader, format)?;
let l_last = Polynomial::read(reader, format)?;
let l_active_row = Polynomial::read(reader, format)?;

// Compute l_0(X)
let mut l0 = vk.domain.empty_lagrange();
l0[0] = C::Scalar::ONE;
let l0 = vk.domain.lagrange_to_coeff(l0);
let l0 = vk.domain.coeff_to_extended(l0);

// Compute l_blind(X) which evaluates to 1 for each blinding factor row
// and 0 otherwise over the domain.
let mut l_blind = vk.domain.empty_lagrange();
for evaluation in l_blind[..].iter_mut().rev().take(vk.cs.blinding_factors()) {
*evaluation = C::Scalar::ONE;
}
let l_blind = vk.domain.lagrange_to_coeff(l_blind);
let l_blind = vk.domain.coeff_to_extended(l_blind);

// Compute l_last(X) which evaluates to 1 on the first inactive row (just
// before the blinding factors) and 0 otherwise over the domain
let mut l_last = vk.domain.empty_lagrange();
let n = l_last.len();
l_last[n - vk.cs.blinding_factors() - 1] = C::Scalar::ONE;
let l_last = vk.domain.lagrange_to_coeff(l_last);
let l_last = vk.domain.coeff_to_extended(l_last);

// Compute l_active_row(X)
let one = C::Scalar::ONE;
let mut l_active_row = vk.domain.empty_extended();
parallelize(&mut l_active_row, |values, start| {
for (i, value) in values.iter_mut().enumerate() {
let idx = i + start;
*value = one - (l_last[idx] + l_blind[idx]);
}
});

let fixed_values = read_polynomial_vec(reader, format)?;
let fixed_polys = read_polynomial_vec(reader, format)?;
let fixed_cosets = read_polynomial_vec(reader, format)?;
let permutation = permutation::ProvingKey::read(reader, format)?;
let fixed_polys: Vec<_> = fixed_values
.iter()
.map(|poly| vk.domain.lagrange_to_coeff(poly.clone()))
.collect();
let fixed_cosets = fixed_polys
.iter()
.map(|poly| vk.domain.coeff_to_extended(poly.clone()))
.collect();
let permutation =
permutation::ProvingKey::read(reader, format, &vk.domain, &vk.cs.permutation)?;
let ev = Evaluator::new(vk.cs());
Ok(Self {
vk,
Expand Down
35 changes: 28 additions & 7 deletions halo2_proofs/src/plonk/permutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
use super::circuit::{Any, Column};
use crate::{
arithmetic::CurveAffine,
arithmetic::{parallelize, CurveAffine},
helpers::{
polynomial_slice_byte_length, read_polynomial_vec, write_polynomial_slice,
SerdeCurveAffine, SerdePrimeField,
},
poly::{Coeff, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial},
poly::{Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial},
SerdeFormat,
};

Expand Down Expand Up @@ -138,10 +138,33 @@ where
C::Scalar: SerdePrimeField,
{
/// Reads proving key for a single permutation argument from buffer using `Polynomial::read`.
pub(super) fn read<R: io::Read>(reader: &mut R, format: SerdeFormat) -> io::Result<Self> {
pub(super) fn read<R: io::Read>(
reader: &mut R,
format: SerdeFormat,
domain: &EvaluationDomain<C::Scalar>,
p: &Argument,
) -> io::Result<Self> {
let permutations = read_polynomial_vec(reader, format)?;
let polys = read_polynomial_vec(reader, format)?;
let cosets = read_polynomial_vec(reader, format)?;
let mut polys = vec![domain.empty_coeff(); p.columns.len()];
{
parallelize(&mut polys, |o, start| {
for (x, poly) in o.iter_mut().enumerate() {
let i = start + x;
let permutation_poly = permutations[i].clone();
*poly = domain.lagrange_to_coeff(permutation_poly);
}
});
}
let mut cosets = vec![domain.empty_extended(); p.columns.len()];
{
parallelize(&mut cosets, |o, start| {
for (x, coset) in o.iter_mut().enumerate() {
let i = start + x;
let poly = polys[i].clone();
*coset = domain.coeff_to_extended(poly);
}
});
}
Ok(ProvingKey {
permutations,
polys,
Expand All @@ -156,8 +179,6 @@ where
format: SerdeFormat,
) -> io::Result<()> {
write_polynomial_slice(&self.permutations, writer, format)?;
write_polynomial_slice(&self.polys, writer, format)?;
write_polynomial_slice(&self.cosets, writer, format)?;
Ok(())
}
}
Expand Down

0 comments on commit b6d8ab7

Please sign in to comment.