dev: Add `CircuitCost::marginal_proof_size` API

This commit is contained in:
Jack Grigg 2021-07-27 02:21:03 +01:00
parent 334036b942
commit dac3bf31e4
1 changed files with 77 additions and 18 deletions

View File

@ -4,6 +4,7 @@ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
iter, iter,
marker::PhantomData, marker::PhantomData,
ops::{Add, Mul},
}; };
use ff::{Field, PrimeField}; use ff::{Field, PrimeField};
@ -202,39 +203,53 @@ impl<G: PrimeGroup, ConcreteCircuit: Circuit<G::Scalar>> CircuitCost<G, Concrete
(self.permutation_cols + chunk_size - 1) / chunk_size (self.permutation_cols + chunk_size - 1) / chunk_size
} }
/// Returns the proof size for the given number of instances of this circuit. /// Returns the marginal proof size per instance of this circuit.
pub fn proof_size(&self, instances: usize) -> ProofSize<G> { pub fn marginal_proof_size(&self) -> MarginalProofSize<G> {
let chunks = self.permutation_chunks(); let chunks = self.permutation_chunks();
ProofSize { MarginalProofSize {
// Cells: // Cells:
// - 1 commitment per advice column per instance // - 1 commitment per advice column per instance
// - 1 eval per instance column query per instance // - 1 eval per instance column query per instance
// - 1 eval per advice column query per instance // - 1 eval per advice column query per instance
// - 1 eval per fixed column query instance: ProofContribution::new(0, self.instance_queries),
instance: ProofContribution::new(0, self.instance_queries * instances), advice: ProofContribution::new(self.advice_columns, self.advice_queries),
advice: ProofContribution::new(
self.advice_columns * instances,
self.advice_queries * instances,
),
fixed: ProofContribution::new(0, self.fixed_queries),
// Lookup arguments: // Lookup arguments:
// - 3 commitments per lookup argument per instance // - 3 commitments per lookup argument per instance
// - 5 evals per lookup argument per instance // - 5 evals per lookup argument per instance
lookups: ProofContribution::new( lookups: ProofContribution::new(3 * self.lookups, 5 * self.lookups),
3 * self.lookups * instances,
5 * self.lookups * instances,
),
// Global permutation argument: // Global permutation argument:
// - chunks commitments per instance // - chunks commitments per instance
// - 2*chunks + (chunks - 1) evals per instance // - 2*chunks + (chunks - 1) evals per instance
equality: ProofContribution::new(chunks, 3 * chunks - 1),
_marker: PhantomData::default(),
}
}
/// Returns the proof size for the given number of instances of this circuit.
pub fn proof_size(&self, instances: usize) -> ProofSize<G> {
let marginal = self.marginal_proof_size();
ProofSize {
// Cells:
// - marginal cost per instance
// - 1 eval per fixed column query
instance: marginal.instance * instances,
advice: marginal.advice * instances,
fixed: ProofContribution::new(0, self.fixed_queries),
// Lookup arguments:
// - marginal cost per instance
lookups: marginal.lookups * instances,
// Global permutation argument:
// - marginal cost per instance
// - 1 eval per column // - 1 eval per column
equality: ProofContribution::new( equality: marginal.equality * instances
chunks * instances, + ProofContribution::new(0, self.permutation_cols),
(3 * chunks - 1) * instances + self.permutation_cols,
),
// Vanishing argument: // Vanishing argument:
// - 1 + (max_deg - 1) commitments // - 1 + (max_deg - 1) commitments
@ -278,6 +293,50 @@ impl ProofContribution {
} }
} }
impl Add for ProofContribution {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self {
commitments: self.commitments + rhs.commitments,
evaluations: self.evaluations + rhs.evaluations,
}
}
}
impl Mul<usize> for ProofContribution {
type Output = Self;
fn mul(self, instances: usize) -> Self::Output {
Self {
commitments: self.commitments * instances,
evaluations: self.evaluations * instances,
}
}
}
/// The marginal size of a Halo 2 proof, broken down into its contributing factors.
#[derive(Debug)]
pub struct MarginalProofSize<G: PrimeGroup> {
instance: ProofContribution,
advice: ProofContribution,
lookups: ProofContribution,
equality: ProofContribution,
_marker: PhantomData<G>,
}
impl<G: PrimeGroup> From<MarginalProofSize<G>> for usize {
fn from(proof: MarginalProofSize<G>) -> Self {
let point = G::Repr::default().as_ref().len();
let scalar = <G::Scalar as PrimeField>::Repr::default().as_ref().len();
proof.instance.len(point, scalar)
+ proof.advice.len(point, scalar)
+ proof.lookups.len(point, scalar)
+ proof.equality.len(point, scalar)
}
}
/// The size of a Halo 2 proof, broken down into its contributing factors. /// The size of a Halo 2 proof, broken down into its contributing factors.
#[derive(Debug)] #[derive(Debug)]
pub struct ProofSize<G: PrimeGroup> { pub struct ProofSize<G: PrimeGroup> {