2021-09-13 16:38:55 -07:00
|
|
|
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
|
|
|
|
2021-05-26 16:23:17 -07: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;
|
2021-09-07 18:28:28 -07:00
|
|
|
use crate::field::field_types::{Field, RichField};
|
2021-07-29 22:00:29 -07:00
|
|
|
use crate::fri::commitment::PolynomialBatchCommitment;
|
Automatically select FRI reduction arities (#282)
* Automatically select FRI reduction arities
This way when a proof's degree changes, we won't need to manually update the `FriConfig`s of any recursive proofs on top of it.
For now I've added two methods of selecting arities. The first, `ConstantArityBits`, just applies a fixed reduciton arity until the degree has shrunk below a certain threshold. The second, `MinSize`, searches for the sequence of arities that minimizes proof size.
Note that this optimization is approximate -- e.g. it doesn't account for the effect of compression, and doesn't count some minor contributions to proof size, like the Merkle roots from the commit phase. It also assumes we're not using Merkle caps in serialized proofs, and that we're inferring one of the evaluations, even though we haven't made those changes yet.
I think we should generally use `ConstantArityBits` for proofs that we will recurse on, since using a single arity tends to be more recursion-friendly. We could use `MinSize` for generating final bridge proofs, since we won't do further recursion on top of those.
* Fix tests
* Feedback
2021-10-04 13:52:05 -07:00
|
|
|
use crate::fri::reduction_strategies::FriReductionStrategy;
|
|
|
|
|
use crate::fri::{FriConfig, FriParams};
|
2021-09-07 18:28:28 -07:00
|
|
|
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;
|
2021-07-29 22:00:29 -07:00
|
|
|
use crate::iop::generator::WitnessGenerator;
|
|
|
|
|
use crate::iop::target::Target;
|
2021-09-28 22:31:20 -07:00
|
|
|
use crate::iop::witness::PartialWitness;
|
2021-07-29 22:00:29 -07:00
|
|
|
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;
|
2021-10-21 14:22:22 -07:00
|
|
|
use crate::util::timing::TimingTree;
|
2021-02-09 21:25:21 -08:00
|
|
|
|
2021-08-20 08:44:28 -07:00
|
|
|
#[derive(Clone, Debug)]
|
2021-02-09 21:25:21 -08:00
|
|
|
pub struct CircuitConfig {
|
|
|
|
|
pub num_wires: usize,
|
|
|
|
|
pub num_routed_wires: usize,
|
2021-11-02 14:41:12 -07:00
|
|
|
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,
|
2021-07-18 23:24:33 -07:00
|
|
|
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,
|
2021-03-28 15:36:51 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for CircuitConfig {
|
|
|
|
|
fn default() -> Self {
|
2021-10-19 12:38:20 -07:00
|
|
|
CircuitConfig::standard_recursion_config()
|
2021-03-28 15:36:51 -07:00
|
|
|
}
|
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
|
|
|
|
|
}
|
2021-06-11 09:44:19 +02:00
|
|
|
|
Refactor recursion tests (#285)
* Refactor recursion tests
E.g. the main part of `test_recursive_recursive_verifier` is now
```rust
let (proof, vd, cd) = dummy_proof::<F, D>(&config, 8_000)?;
let (proof, vd, cd) = recursive_proof(proof, vd, cd, &config, &config, false)?;
let (proof, _vd, cd) = recursive_proof(proof, vd, cd, &config, &config, true)?;
```
Also adds a new `test_size_optimized_recursion` to see how small we can make the final proof in a recursion chain. The final proof is ~74kb (depending on compression luck) and takes ~20s to prove on my M1 (depending on PoW luck).
* Refactor serialization
* Don't log timestamps
2021-10-05 08:36:24 -07:00
|
|
|
/// A typical recursion config, without zero-knowledge, targeting ~100 bit security.
|
|
|
|
|
pub(crate) fn standard_recursion_config() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
num_wires: 143,
|
2021-11-05 09:29:08 -07:00
|
|
|
num_routed_wires: 25,
|
2021-11-02 14:41:12 -07:00
|
|
|
constant_gate_size: 6,
|
2021-10-19 12:38:20 -07:00
|
|
|
security_bits: 100,
|
Refactor recursion tests (#285)
* Refactor recursion tests
E.g. the main part of `test_recursive_recursive_verifier` is now
```rust
let (proof, vd, cd) = dummy_proof::<F, D>(&config, 8_000)?;
let (proof, vd, cd) = recursive_proof(proof, vd, cd, &config, &config, false)?;
let (proof, _vd, cd) = recursive_proof(proof, vd, cd, &config, &config, true)?;
```
Also adds a new `test_size_optimized_recursion` to see how small we can make the final proof in a recursion chain. The final proof is ~74kb (depending on compression luck) and takes ~20s to prove on my M1 (depending on PoW luck).
* Refactor serialization
* Don't log timestamps
2021-10-05 08:36:24 -07:00
|
|
|
rate_bits: 3,
|
2021-10-19 12:38:20 -07:00
|
|
|
num_challenges: 2,
|
Refactor recursion tests (#285)
* Refactor recursion tests
E.g. the main part of `test_recursive_recursive_verifier` is now
```rust
let (proof, vd, cd) = dummy_proof::<F, D>(&config, 8_000)?;
let (proof, vd, cd) = recursive_proof(proof, vd, cd, &config, &config, false)?;
let (proof, _vd, cd) = recursive_proof(proof, vd, cd, &config, &config, true)?;
```
Also adds a new `test_size_optimized_recursion` to see how small we can make the final proof in a recursion chain. The final proof is ~74kb (depending on compression luck) and takes ~20s to prove on my M1 (depending on PoW luck).
* Refactor serialization
* Don't log timestamps
2021-10-05 08:36:24 -07:00
|
|
|
zero_knowledge: false,
|
|
|
|
|
cap_height: 3,
|
|
|
|
|
fri_config: FriConfig {
|
|
|
|
|
proof_of_work_bits: 16,
|
|
|
|
|
reduction_strategy: FriReductionStrategy::ConstantArityBits(3, 5),
|
|
|
|
|
num_query_rounds: 28,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-03 14:30:32 -07:00
|
|
|
pub(crate) fn standard_recursion_zk_config() -> Self {
|
2021-08-14 10:01:10 -07:00
|
|
|
CircuitConfig {
|
|
|
|
|
zero_knowledge: true,
|
2021-11-03 14:30:32 -07:00
|
|
|
..Self::standard_recursion_config()
|
2021-06-11 09:44:19 +02:00
|
|
|
}
|
|
|
|
|
}
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Circuit data required by the prover or the verifier.
|
2021-09-07 18:28:28 -07:00
|
|
|
pub struct CircuitData<F: RichField + Extendable<D>, const D: usize> {
|
2021-06-23 14:16:05 +02:00
|
|
|
pub(crate) prover_only: ProverOnlyCircuitData<F, D>,
|
2021-04-23 14:18:03 -07:00
|
|
|
pub(crate) verifier_only: VerifierOnlyCircuitData<F>,
|
2021-05-30 13:25:53 -07:00
|
|
|
pub(crate) common: CommonCircuitData<F, D>,
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
|
|
|
|
|
2021-09-07 18:28:28 -07:00
|
|
|
impl<F: RichField + Extendable<D>, const D: usize> CircuitData<F, D> {
|
2021-07-21 08:26:19 -07:00
|
|
|
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, D>> {
|
2021-10-21 14:22:22 -07:00
|
|
|
prove(
|
|
|
|
|
&self.prover_only,
|
|
|
|
|
&self.common,
|
|
|
|
|
inputs,
|
|
|
|
|
&mut TimingTree::default(),
|
|
|
|
|
)
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
|
|
|
|
|
2021-07-21 08:26:19 -07: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.
|
2021-09-07 18:28:28 -07:00
|
|
|
pub struct ProverCircuitData<F: RichField + Extendable<D>, const D: usize> {
|
2021-06-23 14:16:05 +02:00
|
|
|
pub(crate) prover_only: ProverOnlyCircuitData<F, D>,
|
2021-05-30 13:25:53 -07:00
|
|
|
pub(crate) common: CommonCircuitData<F, D>,
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
|
|
|
|
|
2021-09-07 18:28:28 -07:00
|
|
|
impl<F: RichField + Extendable<D>, const D: usize> ProverCircuitData<F, D> {
|
2021-07-21 08:26:19 -07:00
|
|
|
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, D>> {
|
2021-10-21 14:22:22 -07:00
|
|
|
prove(
|
|
|
|
|
&self.prover_only,
|
|
|
|
|
&self.common,
|
|
|
|
|
inputs,
|
|
|
|
|
&mut TimingTree::default(),
|
|
|
|
|
)
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Circuit data required by the prover.
|
2021-08-20 08:44:28 -07:00
|
|
|
#[derive(Debug)]
|
2021-09-07 18:28:28 -07:00
|
|
|
pub struct VerifierCircuitData<F: RichField + Extendable<D>, const D: usize> {
|
2021-04-23 14:18:03 -07:00
|
|
|
pub(crate) verifier_only: VerifierOnlyCircuitData<F>,
|
2021-05-30 13:25:53 -07:00
|
|
|
pub(crate) common: CommonCircuitData<F, D>,
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
|
|
|
|
|
2021-09-07 18:28:28 -07:00
|
|
|
impl<F: RichField + Extendable<D>, const D: usize> VerifierCircuitData<F, D> {
|
2021-07-21 08:26:19 -07: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
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Circuit data required by the prover, but not the verifier.
|
2021-09-07 18:28:28 -07:00
|
|
|
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>>>,
|
2021-09-13 16:38:55 -07:00
|
|
|
/// 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.
|
2021-07-29 22:00:29 -07:00
|
|
|
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>,
|
2021-07-21 08:26:19 -07:00
|
|
|
/// 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>>,
|
2021-09-28 22:31:20 -07:00
|
|
|
/// 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.
|
2021-08-20 08:44:28 -07:00
|
|
|
#[derive(Debug)]
|
2021-04-23 14:18:03 -07:00
|
|
|
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-04-23 14:18:03 -07:00
|
|
|
}
|
2021-02-09 21:25:21 -08:00
|
|
|
|
|
|
|
|
/// Circuit data required by both the prover and the verifier.
|
2021-08-20 08:44:28 -07:00
|
|
|
#[derive(Debug)]
|
2021-09-07 18:28:28 -07:00
|
|
|
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
|
|
|
|
Automatically select FRI reduction arities (#282)
* Automatically select FRI reduction arities
This way when a proof's degree changes, we won't need to manually update the `FriConfig`s of any recursive proofs on top of it.
For now I've added two methods of selecting arities. The first, `ConstantArityBits`, just applies a fixed reduciton arity until the degree has shrunk below a certain threshold. The second, `MinSize`, searches for the sequence of arities that minimizes proof size.
Note that this optimization is approximate -- e.g. it doesn't account for the effect of compression, and doesn't count some minor contributions to proof size, like the Merkle roots from the commit phase. It also assumes we're not using Merkle caps in serialized proofs, and that we're inferring one of the evaluations, even though we haven't made those changes yet.
I think we should generally use `ConstantArityBits` for proofs that we will recurse on, since using a single arity tends to be more recursion-friendly. We could use `MinSize` for generating final bridge proofs, since we won't do further recursion on top of those.
* Fix tests
* Feedback
2021-10-04 13:52:05 -07:00
|
|
|
pub(crate) fri_params: FriParams,
|
|
|
|
|
|
2021-03-28 15:36:51 -07:00
|
|
|
pub(crate) degree_bits: usize,
|
2021-02-09 21:25:21 -08:00
|
|
|
|
2021-06-24 18:06:48 +02: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-06-17 15:49:21 +02:00
|
|
|
|
2021-04-02 19:15:39 -07:00
|
|
|
/// The largest number of constraints imposed by any gate.
|
2021-03-28 15:36:51 -07:00
|
|
|
pub(crate) num_gate_constraints: usize,
|
|
|
|
|
|
2021-06-25 11:24:26 +02:00
|
|
|
/// The number of constant wires.
|
|
|
|
|
pub(crate) num_constants: usize,
|
|
|
|
|
|
2021-09-28 22:31:20 -07:00
|
|
|
pub(crate) num_virtual_targets: usize,
|
|
|
|
|
|
2021-04-04 11:35:58 -07:00
|
|
|
/// 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-04-22 16:32:57 -07:00
|
|
|
|
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),
|
|
|
|
|
|
2021-04-22 16:32:57 -07:00
|
|
|
/// A digest of the "circuit" (i.e. the instance, minus public inputs), which can be used to
|
|
|
|
|
/// seed Fiat-Shamir.
|
2021-07-29 22:00:29 -07:00
|
|
|
pub(crate) circuit_digest: HashOut<F>,
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
2021-03-21 11:57:33 -07:00
|
|
|
|
2021-09-07 18:28:28 -07:00
|
|
|
impl<F: RichField + Extendable<D>, const D: usize> CommonCircuitData<F, D> {
|
2021-03-28 15:36:51 -07:00
|
|
|
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()
|
2021-06-24 18:06:48 +02:00
|
|
|
.map(|g| g.gate.0.degree())
|
2021-03-21 11:57:33 -07:00
|
|
|
.max()
|
|
|
|
|
.expect("No gates?")
|
|
|
|
|
}
|
2021-03-28 15:36:51 -07:00
|
|
|
|
2021-04-01 13:22:54 -07:00
|
|
|
pub fn quotient_degree(&self) -> usize {
|
2021-07-08 15:13:29 +02:00
|
|
|
self.quotient_degree_factor * self.degree()
|
2021-04-01 13:22:54 -07:00
|
|
|
}
|
|
|
|
|
|
2021-03-28 15:36:51 -07:00
|
|
|
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-03-28 15:36:51 -07:00
|
|
|
}
|
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 {
|
Automatically select FRI reduction arities (#282)
* Automatically select FRI reduction arities
This way when a proof's degree changes, we won't need to manually update the `FriConfig`s of any recursive proofs on top of it.
For now I've added two methods of selecting arities. The first, `ConstantArityBits`, just applies a fixed reduciton arity until the degree has shrunk below a certain threshold. The second, `MinSize`, searches for the sequence of arities that minimizes proof size.
Note that this optimization is approximate -- e.g. it doesn't account for the effect of compression, and doesn't count some minor contributions to proof size, like the Merkle roots from the commit phase. It also assumes we're not using Merkle caps in serialized proofs, and that we're inferring one of the evaluations, even though we haven't made those changes yet.
I think we should generally use `ConstantArityBits` for proofs that we will recurse on, since using a single arity tends to be more recursion-friendly. We could use `MinSize` for generating final bridge proofs, since we won't do further recursion on top of those.
* Fix tests
* Feedback
2021-10-04 13:52:05 -07:00
|
|
|
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
|
|
|
}
|