2021-05-30 13:25:53 -07:00
|
|
|
use crate::field::extension_field::Extendable;
|
2021-09-07 18:28:28 -07:00
|
|
|
use crate::field::field_types::RichField;
|
2021-07-29 22:00:29 -07:00
|
|
|
use crate::hash::hash_types::HashOutTarget;
|
|
|
|
|
use crate::iop::challenger::RecursiveChallenger;
|
|
|
|
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
|
|
|
|
use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData, VerifierCircuitTarget};
|
|
|
|
|
use crate::plonk::proof::ProofWithPublicInputsTarget;
|
|
|
|
|
use crate::plonk::vanishing_poly::eval_vanishing_poly_recursively;
|
|
|
|
|
use crate::plonk::vars::EvaluationTargets;
|
2021-07-23 17:31:00 +02:00
|
|
|
use crate::util::reducing::ReducingFactorTarget;
|
Reduce noise in FRI logging (#129)
* Reduce noise in FRI logging
Previously, all logs related to gate counts were at the `Debug` log level. This PR gives us more flexibility to adjust the log levels of particular scopes.
In particular, our circuit checks 40 FRI queries, and we log a bunch of steps for each query, creating a lot of noise. With this change, we log just a single FRI query at the `Debug` level, and demote others to the `Trace` level.
With `RUST_LOG=debug`, our logs now look like
```
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] 17631 gates to root
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 8 gates to observe proof and generates challenges
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 4150 gates to evaluate the vanishing polynomial at our challenge point, zeta.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 3184 gates to evaluate gate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 227 gates to evaluate InterpolationGate { num_points: 4, _phantom: PhantomData }<D=4> constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 867 gates to evaluate <R=101> GMiMCGate { ... } constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 576 gates to evaluate BaseSumGate { num_limbs: 63 } + Base: 2 constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 78 gates to evaluate ArithmeticExtensionGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 288 gates to evaluate BaseSumGate { num_limbs: 31 } + Base: 2 constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 115 gates to evaluate InsertionGate { vec_size: 3, _phantom: PhantomData }<D=4> constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 26 gates to evaluate BaseSumGate { num_limbs: 2 } + Base: 2 constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 633 gates to evaluate ReducingGate { num_coeffs: 21 } constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 4 gates to evaluate ConstantGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 11 gates to evaluate PublicInputGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 2 gates to evaluate NoopGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 16 gates to check vanishing and quotient polynomials.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 13336 gates to verify FRI proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 6 gates to recover the random betas used in the FRI reductions.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 4 gates to check PoW
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 104 gates to precompute reduced evaluations
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 330 gates to verify one (of 40) query rounds
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 95 gates to check FRI initial proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 22 gates to verify 0'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 33 gates to verify 1'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 20 gates to verify 2'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 20 gates to verify 3'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 34 gates to compute x from its index
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 32 gates to combine initial oracles
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 17 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 15 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 13 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 11 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 9 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 7 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer final evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 8 gates to evaluate final polynomial
```
This bit corresponds to the single FRI query being shown:
```
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 330 gates to verify one (of 40) query rounds
```
* Minor cleanup
* Address feedback
2021-07-26 16:21:14 -07:00
|
|
|
use crate::with_context;
|
2021-02-26 13:18:41 -08:00
|
|
|
|
2021-09-07 18:28:28 -07:00
|
|
|
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
2021-07-08 17:16:26 +02:00
|
|
|
/// Recursively verifies an inner proof.
|
|
|
|
|
pub fn add_recursive_verifier(
|
|
|
|
|
&mut self,
|
2021-07-21 08:26:19 -07:00
|
|
|
proof_with_pis: ProofWithPublicInputsTarget<D>,
|
2021-07-09 10:01:58 +02:00
|
|
|
inner_config: &CircuitConfig,
|
2021-07-12 14:25:28 +02:00
|
|
|
inner_verifier_data: &VerifierCircuitTarget,
|
|
|
|
|
inner_common_data: &CommonCircuitData<F, D>,
|
2021-07-08 17:16:26 +02:00
|
|
|
) {
|
2021-07-21 08:26:19 -07:00
|
|
|
let ProofWithPublicInputsTarget {
|
|
|
|
|
proof,
|
|
|
|
|
public_inputs,
|
|
|
|
|
} = proof_with_pis;
|
2021-07-12 14:25:28 +02:00
|
|
|
let one = self.one_extension();
|
|
|
|
|
|
|
|
|
|
let num_challenges = inner_config.num_challenges;
|
|
|
|
|
|
2021-07-22 10:27:10 -07:00
|
|
|
let public_inputs_hash = &self.hash_n_to_hash(public_inputs, true);
|
|
|
|
|
|
2021-07-12 14:25:28 +02:00
|
|
|
let mut challenger = RecursiveChallenger::new(self);
|
|
|
|
|
|
2021-07-19 12:22:18 -07:00
|
|
|
let (betas, gammas, alphas, zeta) =
|
Reduce noise in FRI logging (#129)
* Reduce noise in FRI logging
Previously, all logs related to gate counts were at the `Debug` log level. This PR gives us more flexibility to adjust the log levels of particular scopes.
In particular, our circuit checks 40 FRI queries, and we log a bunch of steps for each query, creating a lot of noise. With this change, we log just a single FRI query at the `Debug` level, and demote others to the `Trace` level.
With `RUST_LOG=debug`, our logs now look like
```
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] 17631 gates to root
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 8 gates to observe proof and generates challenges
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 4150 gates to evaluate the vanishing polynomial at our challenge point, zeta.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 3184 gates to evaluate gate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 227 gates to evaluate InterpolationGate { num_points: 4, _phantom: PhantomData }<D=4> constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 867 gates to evaluate <R=101> GMiMCGate { ... } constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 576 gates to evaluate BaseSumGate { num_limbs: 63 } + Base: 2 constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 78 gates to evaluate ArithmeticExtensionGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 288 gates to evaluate BaseSumGate { num_limbs: 31 } + Base: 2 constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 115 gates to evaluate InsertionGate { vec_size: 3, _phantom: PhantomData }<D=4> constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 26 gates to evaluate BaseSumGate { num_limbs: 2 } + Base: 2 constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 633 gates to evaluate ReducingGate { num_coeffs: 21 } constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 4 gates to evaluate ConstantGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 11 gates to evaluate PublicInputGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 2 gates to evaluate NoopGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 16 gates to check vanishing and quotient polynomials.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 13336 gates to verify FRI proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 6 gates to recover the random betas used in the FRI reductions.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 4 gates to check PoW
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 104 gates to precompute reduced evaluations
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 330 gates to verify one (of 40) query rounds
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 95 gates to check FRI initial proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 22 gates to verify 0'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 33 gates to verify 1'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 20 gates to verify 2'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 20 gates to verify 3'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 34 gates to compute x from its index
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 32 gates to combine initial oracles
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 17 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 15 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 13 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 11 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 9 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 7 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer final evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 8 gates to evaluate final polynomial
```
This bit corresponds to the single FRI query being shown:
```
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 330 gates to verify one (of 40) query rounds
```
* Minor cleanup
* Address feedback
2021-07-26 16:21:14 -07:00
|
|
|
with_context!(self, "observe proof and generates challenges", {
|
2021-07-22 10:27:10 -07:00
|
|
|
// Observe the instance.
|
2021-07-29 22:00:29 -07:00
|
|
|
let digest = HashOutTarget::from_vec(
|
2021-07-19 12:22:18 -07:00
|
|
|
self.constants(&inner_common_data.circuit_digest.elements),
|
|
|
|
|
);
|
|
|
|
|
challenger.observe_hash(&digest);
|
2021-08-16 10:41:12 +02:00
|
|
|
challenger.observe_hash(public_inputs_hash);
|
2021-07-12 14:25:28 +02:00
|
|
|
|
2021-08-10 15:53:27 +02:00
|
|
|
challenger.observe_cap(&proof.wires_cap);
|
2021-07-19 12:22:18 -07:00
|
|
|
let betas = challenger.get_n_challenges(self, num_challenges);
|
|
|
|
|
let gammas = challenger.get_n_challenges(self, num_challenges);
|
2021-07-12 14:25:28 +02:00
|
|
|
|
2021-08-10 15:53:27 +02:00
|
|
|
challenger.observe_cap(&proof.plonk_zs_partial_products_cap);
|
2021-07-19 12:22:18 -07:00
|
|
|
let alphas = challenger.get_n_challenges(self, num_challenges);
|
2021-07-08 17:16:26 +02:00
|
|
|
|
2021-08-10 15:53:27 +02:00
|
|
|
challenger.observe_cap(&proof.quotient_polys_cap);
|
2021-07-19 12:22:18 -07:00
|
|
|
let zeta = challenger.get_extension_challenge(self);
|
|
|
|
|
|
|
|
|
|
(betas, gammas, alphas, zeta)
|
|
|
|
|
});
|
2021-07-12 14:25:28 +02:00
|
|
|
|
|
|
|
|
let local_constants = &proof.openings.constants;
|
|
|
|
|
let local_wires = &proof.openings.wires;
|
|
|
|
|
let vars = EvaluationTargets {
|
|
|
|
|
local_constants,
|
|
|
|
|
local_wires,
|
2021-07-21 08:26:19 -07:00
|
|
|
public_inputs_hash,
|
2021-07-12 14:25:28 +02:00
|
|
|
};
|
|
|
|
|
let local_zs = &proof.openings.plonk_zs;
|
|
|
|
|
let next_zs = &proof.openings.plonk_zs_right;
|
|
|
|
|
let s_sigmas = &proof.openings.plonk_sigmas;
|
|
|
|
|
let partial_products = &proof.openings.partial_products;
|
|
|
|
|
|
2021-07-20 12:49:02 -07:00
|
|
|
let zeta_pow_deg = self.exp_power_of_2_extension(zeta, inner_common_data.degree_bits);
|
Reduce noise in FRI logging (#129)
* Reduce noise in FRI logging
Previously, all logs related to gate counts were at the `Debug` log level. This PR gives us more flexibility to adjust the log levels of particular scopes.
In particular, our circuit checks 40 FRI queries, and we log a bunch of steps for each query, creating a lot of noise. With this change, we log just a single FRI query at the `Debug` level, and demote others to the `Trace` level.
With `RUST_LOG=debug`, our logs now look like
```
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] 17631 gates to root
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 8 gates to observe proof and generates challenges
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 4150 gates to evaluate the vanishing polynomial at our challenge point, zeta.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 3184 gates to evaluate gate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 227 gates to evaluate InterpolationGate { num_points: 4, _phantom: PhantomData }<D=4> constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 867 gates to evaluate <R=101> GMiMCGate { ... } constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 576 gates to evaluate BaseSumGate { num_limbs: 63 } + Base: 2 constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 78 gates to evaluate ArithmeticExtensionGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 288 gates to evaluate BaseSumGate { num_limbs: 31 } + Base: 2 constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 115 gates to evaluate InsertionGate { vec_size: 3, _phantom: PhantomData }<D=4> constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 26 gates to evaluate BaseSumGate { num_limbs: 2 } + Base: 2 constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 633 gates to evaluate ReducingGate { num_coeffs: 21 } constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 4 gates to evaluate ConstantGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 11 gates to evaluate PublicInputGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 2 gates to evaluate NoopGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 16 gates to check vanishing and quotient polynomials.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 13336 gates to verify FRI proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 6 gates to recover the random betas used in the FRI reductions.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 4 gates to check PoW
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 104 gates to precompute reduced evaluations
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 330 gates to verify one (of 40) query rounds
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 95 gates to check FRI initial proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 22 gates to verify 0'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 33 gates to verify 1'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 20 gates to verify 2'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 20 gates to verify 3'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 34 gates to compute x from its index
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 32 gates to combine initial oracles
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 17 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 15 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 13 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 11 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 9 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 7 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer final evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 8 gates to evaluate final polynomial
```
This bit corresponds to the single FRI query being shown:
```
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 330 gates to verify one (of 40) query rounds
```
* Minor cleanup
* Address feedback
2021-07-26 16:21:14 -07:00
|
|
|
let vanishing_polys_zeta = with_context!(
|
2021-07-12 14:25:28 +02:00
|
|
|
self,
|
2021-07-19 12:22:18 -07:00
|
|
|
"evaluate the vanishing polynomial at our challenge point, zeta.",
|
|
|
|
|
eval_vanishing_poly_recursively(
|
|
|
|
|
self,
|
|
|
|
|
inner_common_data,
|
|
|
|
|
zeta,
|
|
|
|
|
zeta_pow_deg,
|
|
|
|
|
vars,
|
|
|
|
|
local_zs,
|
|
|
|
|
next_zs,
|
|
|
|
|
partial_products,
|
|
|
|
|
s_sigmas,
|
|
|
|
|
&betas,
|
|
|
|
|
&gammas,
|
|
|
|
|
&alphas,
|
|
|
|
|
)
|
2021-07-12 14:25:28 +02:00
|
|
|
);
|
|
|
|
|
|
Reduce noise in FRI logging (#129)
* Reduce noise in FRI logging
Previously, all logs related to gate counts were at the `Debug` log level. This PR gives us more flexibility to adjust the log levels of particular scopes.
In particular, our circuit checks 40 FRI queries, and we log a bunch of steps for each query, creating a lot of noise. With this change, we log just a single FRI query at the `Debug` level, and demote others to the `Trace` level.
With `RUST_LOG=debug`, our logs now look like
```
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] 17631 gates to root
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 8 gates to observe proof and generates challenges
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 4150 gates to evaluate the vanishing polynomial at our challenge point, zeta.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 3184 gates to evaluate gate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 227 gates to evaluate InterpolationGate { num_points: 4, _phantom: PhantomData }<D=4> constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 867 gates to evaluate <R=101> GMiMCGate { ... } constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 576 gates to evaluate BaseSumGate { num_limbs: 63 } + Base: 2 constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 78 gates to evaluate ArithmeticExtensionGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 288 gates to evaluate BaseSumGate { num_limbs: 31 } + Base: 2 constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 115 gates to evaluate InsertionGate { vec_size: 3, _phantom: PhantomData }<D=4> constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 26 gates to evaluate BaseSumGate { num_limbs: 2 } + Base: 2 constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 633 gates to evaluate ReducingGate { num_coeffs: 21 } constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 4 gates to evaluate ConstantGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 11 gates to evaluate PublicInputGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 2 gates to evaluate NoopGate constraints
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 16 gates to check vanishing and quotient polynomials.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | 13336 gates to verify FRI proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 6 gates to recover the random betas used in the FRI reductions.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 4 gates to check PoW
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 104 gates to precompute reduced evaluations
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 330 gates to verify one (of 40) query rounds
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 95 gates to check FRI initial proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 22 gates to verify 0'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 33 gates to verify 1'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 20 gates to verify 2'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | | 20 gates to verify 3'th initial Merkle proof
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 34 gates to compute x from its index
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 32 gates to combine initial oracles
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 17 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 15 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 13 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 11 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 9 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 7 gates to verify FRI round Merkle proof.
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 10 gates to infer final evaluation using interpolation
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | | 8 gates to evaluate final polynomial
```
This bit corresponds to the single FRI query being shown:
```
[2021-07-26T21:07:45Z DEBUG plonky2::context_tree] | | 330 gates to verify one (of 40) query rounds
```
* Minor cleanup
* Address feedback
2021-07-26 16:21:14 -07:00
|
|
|
with_context!(self, "check vanishing and quotient polynomials.", {
|
2021-07-19 12:22:18 -07:00
|
|
|
let quotient_polys_zeta = &proof.openings.quotient_polys;
|
|
|
|
|
let mut scale = ReducingFactorTarget::new(zeta_pow_deg);
|
|
|
|
|
let z_h_zeta = self.sub_extension(zeta_pow_deg, one);
|
|
|
|
|
for (i, chunk) in quotient_polys_zeta
|
|
|
|
|
.chunks(inner_common_data.quotient_degree_factor)
|
|
|
|
|
.enumerate()
|
|
|
|
|
{
|
|
|
|
|
let recombined_quotient = scale.reduce(chunk, self);
|
|
|
|
|
let computed_vanishing_poly = self.mul_extension(z_h_zeta, recombined_quotient);
|
2021-08-24 18:20:47 +02:00
|
|
|
self.connect_extension(vanishing_polys_zeta[i], computed_vanishing_poly);
|
2021-07-19 12:22:18 -07:00
|
|
|
}
|
|
|
|
|
});
|
2021-07-13 09:44:35 +02:00
|
|
|
|
2021-08-10 15:53:27 +02:00
|
|
|
let merkle_caps = &[
|
|
|
|
|
inner_verifier_data.constants_sigmas_cap.clone(),
|
|
|
|
|
proof.wires_cap,
|
|
|
|
|
proof.plonk_zs_partial_products_cap,
|
|
|
|
|
proof.quotient_polys_cap,
|
2021-07-13 09:44:35 +02:00
|
|
|
];
|
|
|
|
|
|
2021-08-08 09:14:07 -07:00
|
|
|
with_context!(
|
2021-07-13 09:44:35 +02:00
|
|
|
self,
|
2021-08-08 09:14:07 -07:00
|
|
|
"verify FRI proof",
|
|
|
|
|
self.verify_fri_proof(
|
|
|
|
|
&proof.openings,
|
|
|
|
|
zeta,
|
2021-08-10 15:53:27 +02:00
|
|
|
merkle_caps,
|
2021-08-08 09:14:07 -07:00
|
|
|
&proof.opening_proof,
|
|
|
|
|
&mut challenger,
|
|
|
|
|
inner_common_data,
|
|
|
|
|
)
|
2021-07-13 09:44:35 +02:00
|
|
|
);
|
2021-07-08 17:16:26 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-10 14:19:12 +02:00
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use anyhow::Result;
|
2021-08-10 15:28:41 +02:00
|
|
|
use log::info;
|
2021-08-10 14:19:12 +02:00
|
|
|
|
|
|
|
|
use super::*;
|
2021-09-28 10:03:19 -07:00
|
|
|
use crate::field::goldilocks_field::GoldilocksField;
|
2021-08-10 14:19:12 +02:00
|
|
|
use crate::fri::proof::{
|
|
|
|
|
FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget,
|
|
|
|
|
};
|
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;
|
2021-08-10 14:19:12 +02:00
|
|
|
use crate::fri::FriConfig;
|
|
|
|
|
use crate::gadgets::polynomial::PolynomialCoeffsExtTarget;
|
|
|
|
|
use crate::hash::merkle_proofs::MerkleProofTarget;
|
2021-08-20 09:50:07 +02:00
|
|
|
use crate::iop::witness::{PartialWitness, Witness};
|
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
|
|
|
use crate::plonk::circuit_data::VerifierOnlyCircuitData;
|
2021-10-01 16:54:14 +02:00
|
|
|
use crate::plonk::proof::{
|
|
|
|
|
CompressedProofWithPublicInputs, OpeningSetTarget, Proof, ProofTarget,
|
|
|
|
|
ProofWithPublicInputs,
|
|
|
|
|
};
|
2021-08-10 14:19:12 +02:00
|
|
|
use crate::util::log2_strict;
|
|
|
|
|
|
|
|
|
|
// Construct a `FriQueryRoundTarget` with the same dimensions as the ones in `proof`.
|
2021-09-07 18:28:28 -07:00
|
|
|
fn get_fri_query_round<F: RichField + Extendable<D>, const D: usize>(
|
2021-08-10 14:19:12 +02:00
|
|
|
proof: &Proof<F, D>,
|
|
|
|
|
builder: &mut CircuitBuilder<F, D>,
|
|
|
|
|
) -> FriQueryRoundTarget<D> {
|
|
|
|
|
let mut query_round = FriQueryRoundTarget {
|
|
|
|
|
initial_trees_proof: FriInitialTreeProofTarget {
|
|
|
|
|
evals_proofs: vec![],
|
|
|
|
|
},
|
|
|
|
|
steps: vec![],
|
|
|
|
|
};
|
|
|
|
|
for (v, merkle_proof) in &proof.opening_proof.query_round_proofs[0]
|
|
|
|
|
.initial_trees_proof
|
|
|
|
|
.evals_proofs
|
|
|
|
|
{
|
|
|
|
|
query_round.initial_trees_proof.evals_proofs.push((
|
|
|
|
|
builder.add_virtual_targets(v.len()),
|
|
|
|
|
MerkleProofTarget {
|
|
|
|
|
siblings: builder.add_virtual_hashes(merkle_proof.siblings.len()),
|
|
|
|
|
},
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
for step in &proof.opening_proof.query_round_proofs[0].steps {
|
|
|
|
|
query_round.steps.push(FriQueryStepTarget {
|
|
|
|
|
evals: builder.add_virtual_extension_targets(step.evals.len()),
|
|
|
|
|
merkle_proof: MerkleProofTarget {
|
|
|
|
|
siblings: builder.add_virtual_hashes(step.merkle_proof.siblings.len()),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
query_round
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Construct a `ProofTarget` with the same dimensions as `proof`.
|
2021-09-07 18:28:28 -07:00
|
|
|
fn proof_to_proof_target<F: RichField + Extendable<D>, const D: usize>(
|
2021-08-10 14:19:12 +02:00
|
|
|
proof_with_pis: &ProofWithPublicInputs<F, D>,
|
|
|
|
|
builder: &mut CircuitBuilder<F, D>,
|
|
|
|
|
) -> ProofWithPublicInputsTarget<D> {
|
|
|
|
|
let ProofWithPublicInputs {
|
|
|
|
|
proof,
|
|
|
|
|
public_inputs,
|
|
|
|
|
} = proof_with_pis;
|
|
|
|
|
|
2021-08-10 15:53:27 +02:00
|
|
|
let wires_cap = builder.add_virtual_cap(log2_strict(proof.wires_cap.0.len()));
|
|
|
|
|
let plonk_zs_cap =
|
|
|
|
|
builder.add_virtual_cap(log2_strict(proof.plonk_zs_partial_products_cap.0.len()));
|
|
|
|
|
let quotient_polys_cap =
|
|
|
|
|
builder.add_virtual_cap(log2_strict(proof.quotient_polys_cap.0.len()));
|
2021-08-10 14:19:12 +02:00
|
|
|
|
|
|
|
|
let openings = OpeningSetTarget {
|
|
|
|
|
constants: builder.add_virtual_extension_targets(proof.openings.constants.len()),
|
|
|
|
|
plonk_sigmas: builder.add_virtual_extension_targets(proof.openings.plonk_sigmas.len()),
|
|
|
|
|
wires: builder.add_virtual_extension_targets(proof.openings.wires.len()),
|
|
|
|
|
plonk_zs: builder.add_virtual_extension_targets(proof.openings.plonk_zs.len()),
|
|
|
|
|
plonk_zs_right: builder
|
|
|
|
|
.add_virtual_extension_targets(proof.openings.plonk_zs_right.len()),
|
|
|
|
|
partial_products: builder
|
|
|
|
|
.add_virtual_extension_targets(proof.openings.partial_products.len()),
|
|
|
|
|
quotient_polys: builder
|
|
|
|
|
.add_virtual_extension_targets(proof.openings.quotient_polys.len()),
|
|
|
|
|
};
|
|
|
|
|
let query_round_proofs = (0..proof.opening_proof.query_round_proofs.len())
|
|
|
|
|
.map(|_| get_fri_query_round(proof, builder))
|
|
|
|
|
.collect();
|
2021-08-10 15:53:27 +02:00
|
|
|
let commit_phase_merkle_caps = proof
|
2021-08-10 14:19:12 +02:00
|
|
|
.opening_proof
|
2021-08-10 15:53:27 +02:00
|
|
|
.commit_phase_merkle_caps
|
2021-08-10 14:19:12 +02:00
|
|
|
.iter()
|
|
|
|
|
.map(|r| builder.add_virtual_cap(log2_strict(r.0.len())))
|
|
|
|
|
.collect();
|
|
|
|
|
let opening_proof = FriProofTarget {
|
2021-08-10 15:53:27 +02:00
|
|
|
commit_phase_merkle_caps,
|
2021-08-10 14:19:12 +02:00
|
|
|
query_round_proofs,
|
|
|
|
|
final_poly: PolynomialCoeffsExtTarget(
|
|
|
|
|
builder.add_virtual_extension_targets(proof.opening_proof.final_poly.len()),
|
|
|
|
|
),
|
|
|
|
|
pow_witness: builder.add_virtual_target(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let proof = ProofTarget {
|
2021-08-10 15:53:27 +02:00
|
|
|
wires_cap,
|
|
|
|
|
plonk_zs_partial_products_cap: plonk_zs_cap,
|
|
|
|
|
quotient_polys_cap,
|
2021-08-10 14:19:12 +02:00
|
|
|
openings,
|
|
|
|
|
opening_proof,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let public_inputs = builder.add_virtual_targets(public_inputs.len());
|
|
|
|
|
ProofWithPublicInputsTarget {
|
|
|
|
|
proof,
|
|
|
|
|
public_inputs,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set the targets in a `ProofTarget` to their corresponding values in a `Proof`.
|
2021-09-25 19:41:48 -07:00
|
|
|
fn set_proof_target<F: RichField + Extendable<D>, const D: usize>(
|
2021-08-10 14:19:12 +02:00
|
|
|
proof: &ProofWithPublicInputs<F, D>,
|
|
|
|
|
pt: &ProofWithPublicInputsTarget<D>,
|
|
|
|
|
pw: &mut PartialWitness<F>,
|
|
|
|
|
) {
|
|
|
|
|
let ProofWithPublicInputs {
|
|
|
|
|
proof,
|
|
|
|
|
public_inputs,
|
|
|
|
|
} = proof;
|
|
|
|
|
let ProofWithPublicInputsTarget {
|
|
|
|
|
proof: pt,
|
|
|
|
|
public_inputs: pi_targets,
|
|
|
|
|
} = pt;
|
|
|
|
|
|
|
|
|
|
// Set public inputs.
|
|
|
|
|
for (&pi_t, &pi) in pi_targets.iter().zip(public_inputs) {
|
|
|
|
|
pw.set_target(pi_t, pi);
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-10 15:53:27 +02:00
|
|
|
pw.set_cap_target(&pt.wires_cap, &proof.wires_cap);
|
2021-08-10 14:19:12 +02:00
|
|
|
pw.set_cap_target(
|
2021-08-10 15:53:27 +02:00
|
|
|
&pt.plonk_zs_partial_products_cap,
|
|
|
|
|
&proof.plonk_zs_partial_products_cap,
|
2021-08-10 14:19:12 +02:00
|
|
|
);
|
2021-08-10 15:53:27 +02:00
|
|
|
pw.set_cap_target(&pt.quotient_polys_cap, &proof.quotient_polys_cap);
|
2021-08-10 14:19:12 +02:00
|
|
|
|
|
|
|
|
for (&t, &x) in pt.openings.wires.iter().zip(&proof.openings.wires) {
|
|
|
|
|
pw.set_extension_target(t, x);
|
|
|
|
|
}
|
|
|
|
|
for (&t, &x) in pt.openings.constants.iter().zip(&proof.openings.constants) {
|
|
|
|
|
pw.set_extension_target(t, x);
|
|
|
|
|
}
|
|
|
|
|
for (&t, &x) in pt
|
|
|
|
|
.openings
|
|
|
|
|
.plonk_sigmas
|
|
|
|
|
.iter()
|
|
|
|
|
.zip(&proof.openings.plonk_sigmas)
|
|
|
|
|
{
|
|
|
|
|
pw.set_extension_target(t, x);
|
|
|
|
|
}
|
|
|
|
|
for (&t, &x) in pt.openings.plonk_zs.iter().zip(&proof.openings.plonk_zs) {
|
|
|
|
|
pw.set_extension_target(t, x);
|
|
|
|
|
}
|
|
|
|
|
for (&t, &x) in pt
|
|
|
|
|
.openings
|
|
|
|
|
.plonk_zs_right
|
|
|
|
|
.iter()
|
|
|
|
|
.zip(&proof.openings.plonk_zs_right)
|
|
|
|
|
{
|
|
|
|
|
pw.set_extension_target(t, x);
|
|
|
|
|
}
|
|
|
|
|
for (&t, &x) in pt
|
|
|
|
|
.openings
|
|
|
|
|
.partial_products
|
|
|
|
|
.iter()
|
|
|
|
|
.zip(&proof.openings.partial_products)
|
|
|
|
|
{
|
|
|
|
|
pw.set_extension_target(t, x);
|
|
|
|
|
}
|
|
|
|
|
for (&t, &x) in pt
|
|
|
|
|
.openings
|
|
|
|
|
.quotient_polys
|
|
|
|
|
.iter()
|
|
|
|
|
.zip(&proof.openings.quotient_polys)
|
|
|
|
|
{
|
|
|
|
|
pw.set_extension_target(t, x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let fri_proof = &proof.opening_proof;
|
|
|
|
|
let fpt = &pt.opening_proof;
|
|
|
|
|
|
|
|
|
|
pw.set_target(fpt.pow_witness, fri_proof.pow_witness);
|
|
|
|
|
|
|
|
|
|
for (&t, &x) in fpt.final_poly.0.iter().zip(&fri_proof.final_poly.coeffs) {
|
|
|
|
|
pw.set_extension_target(t, x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (t, x) in fpt
|
2021-08-10 15:53:27 +02:00
|
|
|
.commit_phase_merkle_caps
|
2021-08-10 14:19:12 +02:00
|
|
|
.iter()
|
2021-08-10 15:53:27 +02:00
|
|
|
.zip(&fri_proof.commit_phase_merkle_caps)
|
2021-08-10 14:19:12 +02:00
|
|
|
{
|
|
|
|
|
pw.set_cap_target(t, x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (qt, q) in fpt
|
|
|
|
|
.query_round_proofs
|
|
|
|
|
.iter()
|
|
|
|
|
.zip(&fri_proof.query_round_proofs)
|
|
|
|
|
{
|
|
|
|
|
for (at, a) in qt
|
|
|
|
|
.initial_trees_proof
|
|
|
|
|
.evals_proofs
|
|
|
|
|
.iter()
|
|
|
|
|
.zip(&q.initial_trees_proof.evals_proofs)
|
|
|
|
|
{
|
|
|
|
|
for (&t, &x) in at.0.iter().zip(&a.0) {
|
|
|
|
|
pw.set_target(t, x);
|
|
|
|
|
}
|
|
|
|
|
for (&t, &x) in at.1.siblings.iter().zip(&a.1.siblings) {
|
|
|
|
|
pw.set_hash_target(t, x);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (st, s) in qt.steps.iter().zip(&q.steps) {
|
|
|
|
|
for (&t, &x) in st.evals.iter().zip(&s.evals) {
|
|
|
|
|
pw.set_extension_target(t, x);
|
|
|
|
|
}
|
|
|
|
|
for (&t, &x) in st
|
|
|
|
|
.merkle_proof
|
|
|
|
|
.siblings
|
|
|
|
|
.iter()
|
|
|
|
|
.zip(&s.merkle_proof.siblings)
|
|
|
|
|
{
|
|
|
|
|
pw.set_hash_target(t, x);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[ignore]
|
|
|
|
|
fn test_recursive_verifier() -> Result<()> {
|
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
|
|
|
init_logger();
|
2021-09-28 10:03:19 -07:00
|
|
|
type F = GoldilocksField;
|
2021-08-10 14:19:12 +02:00
|
|
|
const D: usize = 4;
|
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
|
|
|
let config = CircuitConfig::standard_recursion_config();
|
2021-08-10 14:19:12 +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
|
|
|
let (proof, vd, cd) = dummy_proof::<F, D>(&config, 8_000)?;
|
|
|
|
|
let (proof, _vd, cd) = recursive_proof(proof, vd, cd, &config, &config, true)?;
|
|
|
|
|
test_serialization(&proof, &cd)?;
|
2021-08-10 14:19:12 +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
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[ignore]
|
|
|
|
|
fn test_recursive_recursive_verifier() -> Result<()> {
|
|
|
|
|
init_logger();
|
|
|
|
|
type F = GoldilocksField;
|
|
|
|
|
const D: usize = 4;
|
2021-08-10 14:19:12 +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
|
|
|
let config = CircuitConfig::standard_recursion_config();
|
2021-08-10 14:19:12 +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
|
|
|
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)?;
|
2021-08-10 14:19:12 +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
|
|
|
test_serialization(&proof, &cd)?;
|
|
|
|
|
|
|
|
|
|
Ok(())
|
2021-08-10 14:19:12 +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
|
|
|
/// Creates a chain of recursive proofs where the last proof is made as small as reasonably
|
|
|
|
|
/// possible, using a high rate, high PoW bits, etc.
|
2021-08-10 14:19:12 +02:00
|
|
|
#[test]
|
|
|
|
|
#[ignore]
|
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
|
|
|
fn test_size_optimized_recursion() -> Result<()> {
|
|
|
|
|
init_logger();
|
2021-09-28 10:03:19 -07:00
|
|
|
type F = GoldilocksField;
|
2021-08-10 14:19:12 +02:00
|
|
|
const D: usize = 4;
|
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
|
|
|
|
|
|
|
|
let normal_config = CircuitConfig::standard_recursion_config();
|
|
|
|
|
let final_config = CircuitConfig {
|
|
|
|
|
rate_bits: 7,
|
2021-10-12 21:36:20 +02:00
|
|
|
cap_height: 0,
|
2021-08-10 14:19:12 +02:00
|
|
|
fri_config: FriConfig {
|
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
|
|
|
proof_of_work_bits: 23,
|
2021-10-05 16:33:08 -07:00
|
|
|
reduction_strategy: FriReductionStrategy::MinSize(None),
|
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
|
|
|
num_query_rounds: 11,
|
2021-08-10 14:19:12 +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
|
|
|
..normal_config
|
2021-08-10 14:19:12 +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
|
|
|
let (proof, vd, cd) = dummy_proof::<F, D>(&normal_config, 8_000)?;
|
|
|
|
|
let (proof, vd, cd) =
|
|
|
|
|
recursive_proof(proof, vd, cd, &normal_config, &normal_config, false)?;
|
|
|
|
|
let (proof, _vd, cd) = recursive_proof(proof, vd, cd, &normal_config, &final_config, true)?;
|
|
|
|
|
|
|
|
|
|
test_serialization(&proof, &cd)?;
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn dummy_proof<F: RichField + Extendable<D>, const D: usize>(
|
|
|
|
|
config: &CircuitConfig,
|
|
|
|
|
num_dummy_gates: u64,
|
|
|
|
|
) -> Result<(
|
|
|
|
|
ProofWithPublicInputs<F, D>,
|
|
|
|
|
VerifierOnlyCircuitData<F>,
|
|
|
|
|
CommonCircuitData<F, D>,
|
|
|
|
|
)> {
|
|
|
|
|
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
|
|
|
|
for i in 0..num_dummy_gates {
|
|
|
|
|
builder.constant(F::from_canonical_u64(i));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let data = builder.build();
|
|
|
|
|
let proof = data.prove(PartialWitness::new())?;
|
|
|
|
|
data.verify(proof.clone())?;
|
|
|
|
|
|
|
|
|
|
Ok((proof, data.verifier_only, data.common))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn recursive_proof<F: RichField + Extendable<D>, const D: usize>(
|
|
|
|
|
inner_proof: ProofWithPublicInputs<F, D>,
|
|
|
|
|
inner_vd: VerifierOnlyCircuitData<F>,
|
|
|
|
|
inner_cd: CommonCircuitData<F, D>,
|
|
|
|
|
inner_config: &CircuitConfig,
|
|
|
|
|
config: &CircuitConfig,
|
|
|
|
|
print_gate_counts: bool,
|
|
|
|
|
) -> Result<(
|
|
|
|
|
ProofWithPublicInputs<F, D>,
|
|
|
|
|
VerifierOnlyCircuitData<F>,
|
|
|
|
|
CommonCircuitData<F, D>,
|
|
|
|
|
)> {
|
2021-08-10 14:19:12 +02:00
|
|
|
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
2021-08-20 11:56:57 +02:00
|
|
|
let mut pw = PartialWitness::new();
|
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
|
|
|
let pt = proof_to_proof_target(&inner_proof, &mut builder);
|
|
|
|
|
set_proof_target(&inner_proof, &pt, &mut pw);
|
2021-08-10 14:19:12 +02:00
|
|
|
|
|
|
|
|
let inner_data = VerifierCircuitTarget {
|
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
|
|
|
constants_sigmas_cap: builder.add_virtual_cap(inner_config.cap_height),
|
2021-08-10 14:19:12 +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
|
|
|
pw.set_cap_target(
|
|
|
|
|
&inner_data.constants_sigmas_cap,
|
|
|
|
|
&inner_vd.constants_sigmas_cap,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
builder.add_recursive_verifier(pt, &inner_config, &inner_data, &inner_cd);
|
2021-08-10 14:19:12 +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
|
|
|
if print_gate_counts {
|
|
|
|
|
builder.print_gate_counts(0);
|
|
|
|
|
}
|
2021-08-10 14:19:12 +02:00
|
|
|
|
|
|
|
|
let data = builder.build();
|
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
|
|
|
let proof = data.prove(pw)?;
|
|
|
|
|
data.verify(proof.clone())?;
|
|
|
|
|
|
|
|
|
|
Ok((proof, data.verifier_only, data.common))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Test serialization and print some size info.
|
|
|
|
|
fn test_serialization<F: RichField + Extendable<D>, const D: usize>(
|
|
|
|
|
proof: &ProofWithPublicInputs<F, D>,
|
|
|
|
|
cd: &CommonCircuitData<F, D>,
|
|
|
|
|
) -> Result<()> {
|
|
|
|
|
let proof_bytes = proof.to_bytes()?;
|
2021-10-01 16:54:14 +02:00
|
|
|
info!("Proof length: {} bytes", proof_bytes.len());
|
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
|
|
|
let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, &cd)?;
|
|
|
|
|
assert_eq!(proof, &proof_from_bytes);
|
|
|
|
|
|
2021-09-20 17:34:52 +02:00
|
|
|
let now = std::time::Instant::now();
|
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
|
|
|
let compressed_proof = proof.clone().compress(&cd)?;
|
|
|
|
|
let decompressed_compressed_proof = compressed_proof.clone().decompress(&cd)?;
|
|
|
|
|
info!("{:.4}s to compress proof", now.elapsed().as_secs_f64());
|
|
|
|
|
assert_eq!(proof, &decompressed_compressed_proof);
|
|
|
|
|
|
|
|
|
|
let compressed_proof_bytes = compressed_proof.to_bytes()?;
|
2021-09-20 17:34:52 +02:00
|
|
|
info!(
|
|
|
|
|
"Compressed proof length: {} bytes",
|
|
|
|
|
compressed_proof_bytes.len()
|
|
|
|
|
);
|
2021-10-02 10:46:02 +02:00
|
|
|
let compressed_proof_from_bytes =
|
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
|
|
|
CompressedProofWithPublicInputs::from_bytes(compressed_proof_bytes, &cd)?;
|
|
|
|
|
assert_eq!(compressed_proof, compressed_proof_from_bytes);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn init_logger() {
|
2021-10-08 17:07:03 -07:00
|
|
|
let _ = env_logger::builder().format_timestamp(None).try_init();
|
2021-08-10 14:19:12 +02:00
|
|
|
}
|
|
|
|
|
}
|