plonky2/src/plonk/circuit_data.rs

265 lines
9.3 KiB
Rust
Raw Normal View History

use std::collections::BTreeMap;
2021-06-30 18:54:28 +02:00
use std::ops::{Range, RangeFrom};
2021-06-25 11:24:26 +02:00
use anyhow::Result;
2021-05-18 15:22:06 +02:00
use crate::field::extension_field::Extendable;
2021-09-22 10:56:09 -07:00
use crate::field::fft::FftRootTable;
use crate::field::field_types::{Field, RichField};
use crate::fri::commitment::PolynomialBatchCommitment;
use crate::fri::reduction_strategies::FriReductionStrategy;
use crate::fri::{FriConfig, FriParams};
use crate::gates::gate::PrefixedGate;
2021-08-10 16:18:42 +02:00
use crate::hash::hash_types::{HashOut, MerkleCapTarget};
2021-08-10 13:33:44 +02:00
use crate::hash::merkle_tree::MerkleCap;
use crate::iop::generator::WitnessGenerator;
use crate::iop::target::Target;
use crate::iop::witness::PartialWitness;
use crate::plonk::proof::ProofWithPublicInputs;
use crate::plonk::prover::prove;
use crate::plonk::verifier::verify;
2021-07-13 09:15:16 +02:00
use crate::util::marking::MarkedTargets;
use crate::util::timing::TimingTree;
2021-02-09 21:25:21 -08:00
#[derive(Clone, Debug)]
2021-02-09 21:25:21 -08:00
pub struct CircuitConfig {
pub num_wires: usize,
pub num_routed_wires: usize,
pub constant_gate_size: usize,
2021-02-09 21:25:21 -08:00
pub security_bits: usize,
2021-03-25 15:20:14 -07:00
pub rate_bits: usize,
2021-05-14 08:07:00 -07:00
/// The number of challenge points to generate, for IOPs that have soundness errors of (roughly)
/// `degree / |F|`.
pub num_challenges: usize,
pub zero_knowledge: bool,
2021-08-10 13:33:44 +02:00
pub cap_height: usize,
2021-05-07 11:30:03 +02:00
// TODO: Find a better place for this.
pub fri_config: FriConfig,
}
impl Default for CircuitConfig {
fn default() -> Self {
CircuitConfig::standard_recursion_config()
}
2021-02-09 21:25:21 -08:00
}
impl CircuitConfig {
2021-03-21 11:57:33 -07:00
pub fn num_advice_wires(&self) -> usize {
2021-02-09 21:25:21 -08:00
self.num_wires - self.num_routed_wires
}
/// A typical recursion config, without zero-knowledge, targeting ~100 bit security.
pub(crate) fn standard_recursion_config() -> Self {
Self {
num_wires: 143,
num_routed_wires: 25,
constant_gate_size: 6,
security_bits: 100,
rate_bits: 3,
num_challenges: 2,
zero_knowledge: false,
cap_height: 3,
fri_config: FriConfig {
proof_of_work_bits: 16,
reduction_strategy: FriReductionStrategy::ConstantArityBits(3, 5),
num_query_rounds: 28,
},
}
}
pub(crate) fn standard_recursion_zk_config() -> Self {
CircuitConfig {
zero_knowledge: true,
..Self::standard_recursion_config()
}
}
2021-02-09 21:25:21 -08:00
}
/// Circuit data required by the prover or the verifier.
pub struct CircuitData<F: RichField + Extendable<D>, const D: usize> {
pub(crate) prover_only: ProverOnlyCircuitData<F, D>,
pub(crate) verifier_only: VerifierOnlyCircuitData<F>,
pub(crate) common: CommonCircuitData<F, D>,
2021-02-09 21:25:21 -08:00
}
impl<F: RichField + Extendable<D>, const D: usize> CircuitData<F, D> {
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, D>> {
prove(
&self.prover_only,
&self.common,
inputs,
&mut TimingTree::default(),
)
2021-02-09 21:25:21 -08:00
}
pub fn verify(&self, proof_with_pis: ProofWithPublicInputs<F, D>) -> Result<()> {
verify(proof_with_pis, &self.verifier_only, &self.common)
2021-02-09 21:25:21 -08:00
}
}
2021-04-02 20:58:19 -07:00
/// Circuit data required by the prover. This may be thought of as a proving key, although it
/// includes code for witness generation.
///
/// The goal here is to make proof generation as fast as we can, rather than making this prover
/// structure as succinct as we can. Thus we include various precomputed data which isn't strictly
/// required, like LDEs of preprocessed polynomials. If more succinctness was desired, we could
/// construct a more minimal prover structure and convert back and forth.
pub struct ProverCircuitData<F: RichField + Extendable<D>, const D: usize> {
pub(crate) prover_only: ProverOnlyCircuitData<F, D>,
pub(crate) common: CommonCircuitData<F, D>,
2021-02-09 21:25:21 -08:00
}
impl<F: RichField + Extendable<D>, const D: usize> ProverCircuitData<F, D> {
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, D>> {
prove(
&self.prover_only,
&self.common,
inputs,
&mut TimingTree::default(),
)
2021-02-09 21:25:21 -08:00
}
}
/// Circuit data required by the prover.
#[derive(Debug)]
pub struct VerifierCircuitData<F: RichField + Extendable<D>, const D: usize> {
pub(crate) verifier_only: VerifierOnlyCircuitData<F>,
pub(crate) common: CommonCircuitData<F, D>,
2021-02-09 21:25:21 -08:00
}
impl<F: RichField + Extendable<D>, const D: usize> VerifierCircuitData<F, D> {
pub fn verify(&self, proof_with_pis: ProofWithPublicInputs<F, D>) -> Result<()> {
verify(proof_with_pis, &self.verifier_only, &self.common)
2021-02-09 21:25:21 -08:00
}
}
/// Circuit data required by the prover, but not the verifier.
pub(crate) struct ProverOnlyCircuitData<F: RichField + Extendable<D>, const D: usize> {
2021-03-21 11:17:00 -07:00
pub generators: Vec<Box<dyn WitnessGenerator<F>>>,
/// Generator indices (within the `Vec` above), indexed by the representative of each target
/// they watch.
pub generator_indices_by_watches: BTreeMap<usize, Vec<usize>>,
2021-06-25 11:24:26 +02:00
/// Commitments to the constants polynomials and sigma polynomials.
pub constants_sigmas_commitment: PolynomialBatchCommitment<F>,
2021-06-28 08:56:36 -07:00
/// The transpose of the list of sigma polynomials.
pub sigmas: Vec<Vec<F>>,
2021-06-16 17:43:41 +02:00
/// Subgroup of order `degree`.
pub subgroup: Vec<F>,
/// Targets to be made public.
pub public_inputs: Vec<Target>,
2021-07-15 10:24:11 +02:00
/// A vector of marked targets. The values assigned to these targets will be displayed by the prover.
2021-07-15 09:52:42 +02:00
pub marked_targets: Vec<MarkedTargets<D>>,
/// A map from each `Target`'s index to the index of its representative in the disjoint-set
/// forest.
pub representative_map: Vec<usize>,
2021-09-22 10:56:09 -07:00
/// Pre-computed roots for faster FFT.
pub fft_root_table: Option<FftRootTable<F>>,
2021-02-09 21:25:21 -08:00
}
/// Circuit data required by the verifier, but not the prover.
#[derive(Debug)]
pub(crate) struct VerifierOnlyCircuitData<F: Field> {
2021-06-25 11:24:26 +02:00
/// A commitment to each constant polynomial and each permutation polynomial.
2021-08-10 15:53:27 +02:00
pub(crate) constants_sigmas_cap: MerkleCap<F>,
}
2021-02-09 21:25:21 -08:00
/// Circuit data required by both the prover and the verifier.
#[derive(Debug)]
pub struct CommonCircuitData<F: RichField + Extendable<D>, const D: usize> {
2021-03-25 15:20:14 -07:00
pub(crate) config: CircuitConfig,
2021-02-09 21:25:21 -08:00
pub(crate) fri_params: FriParams,
pub(crate) degree_bits: usize,
2021-02-09 21:25:21 -08:00
/// The types of gates used in this circuit, along with their prefixes.
pub(crate) gates: Vec<PrefixedGate<F, D>>,
2021-03-21 11:57:33 -07:00
2021-07-08 15:13:29 +02:00
/// The degree of the PLONK quotient polynomial.
pub(crate) quotient_degree_factor: usize,
2021-04-02 19:15:39 -07:00
/// The largest number of constraints imposed by any gate.
pub(crate) num_gate_constraints: usize,
2021-06-25 11:24:26 +02:00
/// The number of constant wires.
pub(crate) num_constants: usize,
pub(crate) num_virtual_targets: usize,
/// The `{k_i}` valued used in `S_ID_i` in Plonk's permutation argument.
2021-03-30 23:12:47 -07:00
pub(crate) k_is: Vec<F>,
2021-07-02 10:20:44 +02:00
/// The number of partial products needed to compute the `Z` polynomials and the number
2021-07-01 17:28:30 +02:00
/// of partial products needed to compute the final product.
2021-07-01 15:41:01 +02:00
pub(crate) num_partial_products: (usize, usize),
/// A digest of the "circuit" (i.e. the instance, minus public inputs), which can be used to
/// seed Fiat-Shamir.
pub(crate) circuit_digest: HashOut<F>,
2021-02-09 21:25:21 -08:00
}
2021-03-21 11:57:33 -07:00
impl<F: RichField + Extendable<D>, const D: usize> CommonCircuitData<F, D> {
pub fn degree(&self) -> usize {
1 << self.degree_bits
}
pub fn lde_size(&self) -> usize {
1 << (self.degree_bits + self.config.rate_bits)
}
pub fn lde_generator(&self) -> F {
F::primitive_root_of_unity(self.degree_bits + self.config.rate_bits)
}
pub fn constraint_degree(&self) -> usize {
2021-04-21 22:31:45 +02:00
self.gates
.iter()
.map(|g| g.gate.0.degree())
2021-03-21 11:57:33 -07:00
.max()
.expect("No gates?")
}
pub fn quotient_degree(&self) -> usize {
2021-07-08 15:13:29 +02:00
self.quotient_degree_factor * self.degree()
}
pub fn total_constraints(&self) -> usize {
// 2 constraints for each Z check.
2021-05-14 08:07:00 -07:00
self.config.num_challenges * 2 + self.num_gate_constraints
}
2021-06-25 11:24:26 +02:00
2021-06-25 11:49:29 +02:00
/// Range of the constants polynomials in the `constants_sigmas_commitment`.
2021-06-25 11:24:26 +02:00
pub fn constants_range(&self) -> Range<usize> {
0..self.num_constants
}
/// Range of the sigma polynomials in the `constants_sigmas_commitment`.
pub fn sigmas_range(&self) -> Range<usize> {
2021-06-28 09:47:47 +02:00
self.num_constants..self.num_constants + self.config.num_routed_wires
2021-06-25 11:24:26 +02:00
}
2021-06-30 18:54:28 +02:00
2021-07-02 10:58:59 +02:00
/// Range of the `z`s polynomials in the `zs_partial_products_commitment`.
2021-06-30 18:54:28 +02:00
pub fn zs_range(&self) -> Range<usize> {
0..self.config.num_challenges
}
2021-07-02 10:58:59 +02:00
/// Range of the partial products polynomials in the `zs_partial_products_commitment`.
2021-06-30 18:54:28 +02:00
pub fn partial_products_range(&self) -> RangeFrom<usize> {
self.config.num_challenges..
}
2021-10-02 10:46:02 +02:00
pub fn final_poly_len(&self) -> usize {
1 << (self.degree_bits - self.fri_params.total_arities())
2021-10-02 10:46:02 +02:00
}
2021-03-21 11:57:33 -07:00
}
2021-04-02 20:58:19 -07:00
/// The `Target` version of `VerifierCircuitData`, for use inside recursive circuits. Note that this
/// is intentionally missing certain fields, such as `CircuitConfig`, because we support only a
/// limited form of dynamic inner circuits. We can't practically make things like the wire count
/// dynamic, at least not without setting a maximum wire count and paying for the worst case.
2021-04-03 15:30:33 -07:00
pub struct VerifierCircuitTarget {
2021-07-09 10:01:58 +02:00
/// A commitment to each constant polynomial and each permutation polynomial.
2021-08-10 15:53:27 +02:00
pub(crate) constants_sigmas_cap: MerkleCapTarget,
2021-04-02 20:58:19 -07:00
}