From f2c423ee61d81a3401c67590f50d9076ee13c4e9 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Tue, 10 Aug 2021 14:19:12 +0200 Subject: [PATCH] save 13 gates --- src/fri/prover.rs | 3 +- src/fri/recursive_verifier.rs | 3 +- src/fri/verifier.rs | 13 +- src/plonk/recursive_verifier.rs | 714 ++++++++++++++++---------------- 4 files changed, 368 insertions(+), 365 deletions(-) diff --git a/src/fri/prover.rs b/src/fri/prover.rs index 340f749b..3d6d6e83 100644 --- a/src/fri/prover.rs +++ b/src/fri/prover.rs @@ -156,8 +156,7 @@ fn fri_prover_query_round, const D: usize>( let arity_bits = config.reduction_arity_bits[i]; let arity = 1 << arity_bits; let mut evals = unflatten(tree.get(x_index >> arity_bits)); - dbg!(&evals); - evals.remove(x_index & (arity - 1)); + // evals.remove(x_index & (arity - 1)); let merkle_proof = tree.prove(x_index >> arity_bits); query_steps.push(FriQueryStep { diff --git a/src/fri/recursive_verifier.rs b/src/fri/recursive_verifier.rs index 844facb7..5e801e9c 100644 --- a/src/fri/recursive_verifier.rs +++ b/src/fri/recursive_verifier.rs @@ -341,7 +341,8 @@ impl, const D: usize> CircuitBuilder { let high_x_index_bits = x_index_bits.split_off(arity_bits); old_x_index_bits = x_index_bits; let low_x_index = self.le_sum(old_x_index_bits.iter()); - evals = self.insert(low_x_index, e_x, evals); + // evals = self.insert(low_x_index, e_x, evals); + self.random_access(low_x_index, e_x, evals.clone()); with_context!( self, "verify FRI round Merkle proof.", diff --git a/src/fri/verifier.rs b/src/fri/verifier.rs index b9e77acc..a6e70220 100644 --- a/src/fri/verifier.rs +++ b/src/fri/verifier.rs @@ -274,13 +274,6 @@ fn fri_verifier_query_round, const D: usize>( let arity = 1 << arity_bits; let next_domain_size = domain_size >> arity_bits; let e_x = if i == 0 { - dbg!( - &round_proof.initial_trees_proof, - alpha, - zeta, - subgroup_x, - precomputed_reduced_evals - ); fri_combine_initial( &round_proof.initial_trees_proof, alpha, @@ -300,10 +293,10 @@ fn fri_verifier_query_round, const D: usize>( betas[i - 1], ) }; - dbg!(e_x); let mut evals = round_proof.steps[i].evals.clone(); - // Insert P(y) into the evaluation vector, since it wasn't included by the prover. - evals.insert(x_index & (arity - 1), e_x); + // // Insert P(y) into the evaluation vector, since it wasn't included by the prover. + ensure!(evals[x_index & (arity - 1)] == e_x); + // evals.insert(x_index & (arity - 1), e_x); verify_merkle_proof( flatten(&evals), x_index >> arity_bits, diff --git a/src/plonk/recursive_verifier.rs b/src/plonk/recursive_verifier.rs index 7fc909e5..0c297c66 100644 --- a/src/plonk/recursive_verifier.rs +++ b/src/plonk/recursive_verifier.rs @@ -129,355 +129,365 @@ impl, const D: usize> CircuitBuilder { } } -// #[cfg(test)] -// mod tests { -// use anyhow::Result; -// -// use super::*; -// use crate::field::crandall_field::CrandallField; -// use crate::fri::proof::{ -// FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget, -// }; -// use crate::fri::FriConfig; -// use crate::gadgets::polynomial::PolynomialCoeffsExtTarget; -// use crate::hash::merkle_proofs::MerkleProofTarget; -// use crate::iop::witness::PartialWitness; -// use crate::plonk::proof::{OpeningSetTarget, Proof, ProofTarget, ProofWithPublicInputs}; -// use crate::plonk::verifier::verify; -// -// // Construct a `FriQueryRoundTarget` with the same dimensions as the ones in `proof`. -// fn get_fri_query_round, const D: usize>( -// proof: &Proof, -// builder: &mut CircuitBuilder, -// ) -> FriQueryRoundTarget { -// 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`. -// fn proof_to_proof_target, const D: usize>( -// proof_with_pis: &ProofWithPublicInputs, -// builder: &mut CircuitBuilder, -// ) -> ProofWithPublicInputsTarget { -// let ProofWithPublicInputs { -// proof, -// public_inputs, -// } = proof_with_pis; -// -// let wires_root = builder.add_virtual_hash(); -// let plonk_zs_root = builder.add_virtual_hash(); -// let quotient_polys_root = builder.add_virtual_hash(); -// -// 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(); -// let commit_phase_merkle_roots = (0..proof.opening_proof.commit_phase_merkle_roots.len()) -// .map(|_| builder.add_virtual_hash()) -// .collect(); -// let opening_proof = FriProofTarget { -// commit_phase_merkle_roots, -// 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 { -// wires_root, -// plonk_zs_partial_products_root: plonk_zs_root, -// quotient_polys_root, -// 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`. -// fn set_proof_target, const D: usize>( -// proof: &ProofWithPublicInputs, -// pt: &ProofWithPublicInputsTarget, -// pw: &mut PartialWitness, -// ) { -// 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); -// } -// -// pw.set_hash_target(pt.wires_root, proof.wires_root); -// pw.set_hash_target( -// pt.plonk_zs_partial_products_root, -// proof.plonk_zs_partial_products_root, -// ); -// pw.set_hash_target(pt.quotient_polys_root, proof.quotient_polys_root); -// -// 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 -// .commit_phase_merkle_roots -// .iter() -// .zip(&fri_proof.commit_phase_merkle_roots) -// { -// pw.set_hash_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<()> { -// env_logger::init(); -// type F = CrandallField; -// const D: usize = 4; -// let config = CircuitConfig { -// num_wires: 126, -// num_routed_wires: 33, -// security_bits: 128, -// rate_bits: 3, -// num_challenges: 3, -// zero_knowledge: false, -// fri_config: FriConfig { -// proof_of_work_bits: 1, -// reduction_arity_bits: vec![2, 2, 2, 2, 2, 2], -// num_query_rounds: 40, -// }, -// }; -// let (proof_with_pis, vd, cd) = { -// let mut builder = CircuitBuilder::::new(config.clone()); -// let _two = builder.two(); -// let _two = builder.hash_n_to_hash(vec![_two], true).elements[0]; -// for _ in 0..10000 { -// let _two = builder.mul(_two, _two); -// } -// let data = builder.build(); -// ( -// data.prove(PartialWitness::new(config.num_wires))?, -// data.verifier_only, -// data.common, -// ) -// }; -// verify(proof_with_pis.clone(), &vd, &cd)?; -// -// let mut builder = CircuitBuilder::::new(config.clone()); -// let mut pw = PartialWitness::new(config.num_wires); -// let pt = proof_to_proof_target(&proof_with_pis, &mut builder); -// set_proof_target(&proof_with_pis, &pt, &mut pw); -// -// let inner_data = VerifierCircuitTarget { -// constants_sigmas_root: builder.add_virtual_hash(), -// }; -// pw.set_hash_target(inner_data.constants_sigmas_root, vd.constants_sigmas_root); -// -// builder.add_recursive_verifier(pt, &config, &inner_data, &cd); -// -// builder.print_gate_counts(0); -// let data = builder.build(); -// let recursive_proof = data.prove(pw)?; -// -// verify(recursive_proof, &data.verifier_only, &data.common) -// } -// -// #[test] -// #[ignore] -// fn test_recursive_recursive_verifier() -> Result<()> { -// env_logger::init(); -// type F = CrandallField; -// const D: usize = 4; -// let config = CircuitConfig { -// num_wires: 126, -// num_routed_wires: 33, -// security_bits: 128, -// rate_bits: 3, -// num_challenges: 3, -// zero_knowledge: false, -// fri_config: FriConfig { -// proof_of_work_bits: 1, -// reduction_arity_bits: vec![2, 2, 2, 2, 2, 2], -// num_query_rounds: 40, -// }, -// }; -// let (proof_with_pis, vd, cd) = { -// let (proof_with_pis, vd, cd) = { -// let mut builder = CircuitBuilder::::new(config.clone()); -// let _two = builder.two(); -// let _two = builder.hash_n_to_hash(vec![_two], true).elements[0]; -// for _ in 0..10000 { -// let _two = builder.mul(_two, _two); -// } -// let data = builder.build(); -// ( -// data.prove(PartialWitness::new(config.num_wires))?, -// data.verifier_only, -// data.common, -// ) -// }; -// verify(proof_with_pis.clone(), &vd, &cd)?; -// -// let mut builder = CircuitBuilder::::new(config.clone()); -// let mut pw = PartialWitness::new(config.num_wires); -// let pt = proof_to_proof_target(&proof_with_pis, &mut builder); -// set_proof_target(&proof_with_pis, &pt, &mut pw); -// -// let inner_data = VerifierCircuitTarget { -// constants_sigmas_root: builder.add_virtual_hash(), -// }; -// pw.set_hash_target(inner_data.constants_sigmas_root, vd.constants_sigmas_root); -// -// builder.add_recursive_verifier(pt, &config, &inner_data, &cd); -// -// let data = builder.build(); -// let recursive_proof = data.prove(pw)?; -// (recursive_proof, data.verifier_only, data.common) -// }; -// -// verify(proof_with_pis.clone(), &vd, &cd)?; -// let mut builder = CircuitBuilder::::new(config.clone()); -// let mut pw = PartialWitness::new(config.num_wires); -// let pt = proof_to_proof_target(&proof_with_pis, &mut builder); -// set_proof_target(&proof_with_pis, &pt, &mut pw); -// -// let inner_data = VerifierCircuitTarget { -// constants_sigmas_root: builder.add_virtual_hash(), -// }; -// pw.set_hash_target(inner_data.constants_sigmas_root, vd.constants_sigmas_root); -// -// builder.add_recursive_verifier(pt, &config, &inner_data, &cd); -// -// builder.print_gate_counts(0); -// let data = builder.build(); -// let recursive_proof = data.prove(pw)?; -// verify(recursive_proof, &data.verifier_only, &data.common) -// } -// } +#[cfg(test)] +mod tests { + use anyhow::Result; + + use super::*; + use crate::field::crandall_field::CrandallField; + use crate::fri::proof::{ + FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget, + }; + use crate::fri::FriConfig; + use crate::gadgets::polynomial::PolynomialCoeffsExtTarget; + use crate::hash::merkle_proofs::MerkleProofTarget; + use crate::iop::witness::PartialWitness; + use crate::plonk::proof::{OpeningSetTarget, Proof, ProofTarget, ProofWithPublicInputs}; + use crate::plonk::verifier::verify; + use crate::util::log2_strict; + + // Construct a `FriQueryRoundTarget` with the same dimensions as the ones in `proof`. + fn get_fri_query_round, const D: usize>( + proof: &Proof, + builder: &mut CircuitBuilder, + ) -> FriQueryRoundTarget { + 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`. + fn proof_to_proof_target, const D: usize>( + proof_with_pis: &ProofWithPublicInputs, + builder: &mut CircuitBuilder, + ) -> ProofWithPublicInputsTarget { + let ProofWithPublicInputs { + proof, + public_inputs, + } = proof_with_pis; + + let wires_root = builder.add_virtual_cap(log2_strict(proof.wires_root.0.len())); + let plonk_zs_root = + builder.add_virtual_cap(log2_strict(proof.plonk_zs_partial_products_root.0.len())); + let quotient_polys_root = + builder.add_virtual_cap(log2_strict(proof.quotient_polys_root.0.len())); + + 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(); + let commit_phase_merkle_roots = proof + .opening_proof + .commit_phase_merkle_roots + .iter() + .map(|r| builder.add_virtual_cap(log2_strict(r.0.len()))) + .collect(); + let opening_proof = FriProofTarget { + commit_phase_merkle_roots, + 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 { + wires_root, + plonk_zs_partial_products_root: plonk_zs_root, + quotient_polys_root, + 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`. + fn set_proof_target, const D: usize>( + proof: &ProofWithPublicInputs, + pt: &ProofWithPublicInputsTarget, + pw: &mut PartialWitness, + ) { + 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); + } + + pw.set_cap_target(&pt.wires_root, &proof.wires_root); + pw.set_cap_target( + &pt.plonk_zs_partial_products_root, + &proof.plonk_zs_partial_products_root, + ); + pw.set_cap_target(&pt.quotient_polys_root, &proof.quotient_polys_root); + + 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 + .commit_phase_merkle_roots + .iter() + .zip(&fri_proof.commit_phase_merkle_roots) + { + 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<()> { + env_logger::init(); + type F = CrandallField; + const D: usize = 4; + let config = CircuitConfig { + num_wires: 126, + num_routed_wires: 33, + security_bits: 128, + rate_bits: 3, + num_challenges: 3, + zero_knowledge: false, + cap_height: 2, + fri_config: FriConfig { + proof_of_work_bits: 1, + reduction_arity_bits: vec![2, 2, 2, 2, 2, 2], + num_query_rounds: 40, + cap_height: 1, + }, + }; + let (proof_with_pis, vd, cd) = { + let mut builder = CircuitBuilder::::new(config.clone()); + let _two = builder.two(); + let _two = builder.hash_n_to_hash(vec![_two], true).elements[0]; + for _ in 0..10000 { + let _two = builder.mul(_two, _two); + } + let data = builder.build(); + ( + data.prove(PartialWitness::new(config.num_wires))?, + data.verifier_only, + data.common, + ) + }; + verify(proof_with_pis.clone(), &vd, &cd)?; + + let mut builder = CircuitBuilder::::new(config.clone()); + let mut pw = PartialWitness::new(config.num_wires); + let pt = proof_to_proof_target(&proof_with_pis, &mut builder); + set_proof_target(&proof_with_pis, &pt, &mut pw); + + let inner_data = VerifierCircuitTarget { + constants_sigmas_root: builder.add_virtual_cap(config.cap_height), + }; + pw.set_cap_target(&inner_data.constants_sigmas_root, &vd.constants_sigmas_root); + + builder.add_recursive_verifier(pt, &config, &inner_data, &cd); + + builder.print_gate_counts(0); + let data = builder.build(); + let recursive_proof = data.prove(pw)?; + + verify(recursive_proof, &data.verifier_only, &data.common) + } + + #[test] + #[ignore] + fn test_recursive_recursive_verifier() -> Result<()> { + env_logger::init(); + type F = CrandallField; + const D: usize = 4; + let config = CircuitConfig { + num_wires: 126, + num_routed_wires: 33, + security_bits: 128, + rate_bits: 3, + num_challenges: 3, + zero_knowledge: false, + cap_height: 2, + fri_config: FriConfig { + proof_of_work_bits: 1, + reduction_arity_bits: vec![2, 2, 2, 2, 2, 2], + num_query_rounds: 40, + cap_height: 2, + }, + }; + let (proof_with_pis, vd, cd) = { + let (proof_with_pis, vd, cd) = { + let mut builder = CircuitBuilder::::new(config.clone()); + let _two = builder.two(); + let _two = builder.hash_n_to_hash(vec![_two], true).elements[0]; + for _ in 0..10000 { + let _two = builder.mul(_two, _two); + } + let data = builder.build(); + ( + data.prove(PartialWitness::new(config.num_wires))?, + data.verifier_only, + data.common, + ) + }; + verify(proof_with_pis.clone(), &vd, &cd)?; + + let mut builder = CircuitBuilder::::new(config.clone()); + let mut pw = PartialWitness::new(config.num_wires); + let pt = proof_to_proof_target(&proof_with_pis, &mut builder); + set_proof_target(&proof_with_pis, &pt, &mut pw); + + let inner_data = VerifierCircuitTarget { + constants_sigmas_root: builder.add_virtual_cap(config.cap_height), + }; + pw.set_cap_target(&inner_data.constants_sigmas_root, &vd.constants_sigmas_root); + + builder.add_recursive_verifier(pt, &config, &inner_data, &cd); + + let data = builder.build(); + let recursive_proof = data.prove(pw)?; + (recursive_proof, data.verifier_only, data.common) + }; + + verify(proof_with_pis.clone(), &vd, &cd)?; + let mut builder = CircuitBuilder::::new(config.clone()); + let mut pw = PartialWitness::new(config.num_wires); + let pt = proof_to_proof_target(&proof_with_pis, &mut builder); + set_proof_target(&proof_with_pis, &pt, &mut pw); + + let inner_data = VerifierCircuitTarget { + constants_sigmas_root: builder.add_virtual_cap(config.cap_height), + }; + pw.set_cap_target(&inner_data.constants_sigmas_root, &vd.constants_sigmas_root); + + builder.add_recursive_verifier(pt, &config, &inner_data, &cd); + + builder.print_gate_counts(0); + let data = builder.build(); + let recursive_proof = data.prove(pw)?; + verify(recursive_proof, &data.verifier_only, &data.common) + } +}