diff --git a/plonky2/src/fri/mod.rs b/plonky2/src/fri/mod.rs index 87c4c2aa..d362420e 100644 --- a/plonky2/src/fri/mod.rs +++ b/plonky2/src/fri/mod.rs @@ -54,7 +54,7 @@ impl FriConfig { /// FRI parameters, including generated parameters which are specific to an instance size, in /// contrast to `FriConfig` which is user-specified and independent of instance size. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct FriParams { /// User-specified FRI configuration. pub config: FriConfig, diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index bfa012da..3a2cccb0 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -50,7 +50,7 @@ pub struct CircuitBuilder, const D: usize> { pub config: CircuitConfig, /// The types of gates used in this circuit. - gates: HashSet>, + pub(crate) gates: HashSet>, /// The concrete placement of each gate. pub(crate) gate_instances: Vec>, diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index 7e69ef31..879ed6d3 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -263,7 +263,7 @@ pub struct VerifierOnlyCircuitData, const D: usize> { } /// Circuit data required by both the prover and the verifier. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct CommonCircuitData< F: RichField + Extendable, C: GenericConfig, diff --git a/plonky2/src/plonk/recursive_verifier.rs b/plonky2/src/plonk/recursive_verifier.rs index ecce34e1..487373e3 100644 --- a/plonky2/src/plonk/recursive_verifier.rs +++ b/plonky2/src/plonk/recursive_verifier.rs @@ -445,4 +445,46 @@ mod tests { fn init_logger() { let _ = env_logger::builder().format_timestamp(None).try_init(); } + + #[test] + fn test_cyclic_recursion() -> Result<()> { + const D: usize = 2; + type C = PoseidonGoldilocksConfig; + type F = >::F; + // type FF = >::FE; + + let config = CircuitConfig::standard_recursion_config(); + let (proof, vd, cd) = dummy_proof::(&config, 1 << 13)?; + + let (proof, vd, cd) = + recursive_proof::(proof, vd, cd, &config, None, false, false)?; + let (_proof, _vd, cd) = + recursive_proof::(proof, vd, cd, &config, None, false, false)?; + + let config = CircuitConfig::standard_recursion_config(); + let mut pw = PartialWitness::new(); + let mut builder = CircuitBuilder::::new(config); + + let verifier_data = VerifierCircuitTarget { + constants_sigmas_cap: builder.add_virtual_cap(builder.config.fri_config.cap_height), + }; + for i in 0..1 << builder.config.fri_config.cap_height { + builder.register_public_inputs(&verifier_data.constants_sigmas_cap.0[i].elements); + } + let pt = builder.add_virtual_proof_with_pis(&cd); + builder.verify_proof(pt, &verifier_data, &cd); + + let inner_gates = cd.gates.iter().map(|g| g.0.id()).collect::>(); + for gate in &builder.gates { + assert!(inner_gates.contains(&gate.0.id()), "{}", gate.0.id()); + } + for _ in builder.num_gates()..(1 << 13) - 100 { + builder.add_gate(NoopGate, vec![]); + } + let data = builder.build::(); + dbg!(data.common.degree_bits); + let proof = data.prove(pw)?; + + data.verify(proof) + } }