arnaucube
arnaucube/starky-tmpPublic Self-hosted repository
starky-tmp/src/circuit.rs
src/circuit.rsRaw
  1/// Plonky2 circuit to verify the fibonacci-starky proofs
  2use anyhow::Result;
  3use plonky2::iop::{target::Target, witness::PartialWitness};
  4use plonky2::plonk::circuit_builder::CircuitBuilder;
  5use starky::proof::{StarkProofWithPublicInputs, StarkProofWithPublicInputsTarget};
  6use starky::recursive_verifier::{
  7    add_virtual_stark_proof_with_pis, set_stark_proof_with_pis_target, verify_stark_proof_circuit,
  8};
  9use starky::stark::Stark;
 10use std::marker::PhantomData;
 11
 12use crate::{C, D, F, STARK_CONFIG};
 13
 14/// Plonky2 circuit to verify a Starky proof of fibstarky
 15pub struct FibStarkVerifierTargets<S: Stark<F, D> + Copy> {
 16    _s: PhantomData<S>,
 17
 18    proof_target: StarkProofWithPublicInputsTarget<D>,
 19    zero_target: Target,
 20}
 21impl<S: Stark<F, D> + Copy> FibStarkVerifierTargets<S> {
 22    pub fn add_targets(
 23        builder: &mut CircuitBuilder<F, D>,
 24        stark: S,
 25        degree_bits: usize,
 26    ) -> Result<Self> {
 27        let proof_target =
 28            add_virtual_stark_proof_with_pis(builder, &stark, &STARK_CONFIG, degree_bits, 0, 0);
 29
 30        verify_stark_proof_circuit::<F, C, S, D>(
 31            builder,
 32            stark,
 33            proof_target.clone(),
 34            &STARK_CONFIG,
 35            None,
 36        );
 37        let zero_target = builder.zero();
 38
 39        Ok(Self {
 40            _s: PhantomData,
 41            proof_target,
 42            zero_target,
 43        })
 44    }
 45    pub fn set_targets(
 46        &self,
 47        pw: &mut PartialWitness<F>,
 48        proof: &StarkProofWithPublicInputs<F, C, D>,
 49        degree_bits: usize,
 50    ) -> Result<()> {
 51        set_stark_proof_with_pis_target(
 52            pw,
 53            &self.proof_target,
 54            &proof,
 55            degree_bits,
 56            self.zero_target,
 57        )?;
 58        Ok(())
 59    }
 60}
 61
 62#[cfg(test)]
 63mod tests {
 64    use plonky2::field::types::Field;
 65    use plonky2::plonk::circuit_data::CircuitConfig;
 66    use plonky2::util::timing::TimingTree;
 67    use starky::prover::prove;
 68    use starky::verifier::verify_stark_proof;
 69
 70    use super::*;
 71    use crate::fibstark::FibonacciStark;
 72
 73    fn set_log() {
 74        let _ = env_logger::builder()
 75            .filter_level(log::LevelFilter::Debug)
 76            .is_test(true)
 77            .try_init();
 78    }
 79
 80    #[test]
 81    fn test_stark_verif_in_plonky2() -> Result<()> {
 82        set_log();
 83
 84        // 1) first generate the fibstark starky proof
 85        let num_rows = 1 << 10;
 86        let x0 = F::from_canonical_u32(2);
 87        let x1 = F::from_canonical_u32(7);
 88
 89        let stark = FibonacciStark::<F, D>::new(num_rows);
 90        let public_inputs = [x0, x1, stark.compute_native(x0, x1)];
 91        let trace = stark.generate_trace(public_inputs[0], public_inputs[1]);
 92
 93        let stark_proof = prove::<F, C, FibonacciStark<F, D>, D>(
 94            stark,
 95            &STARK_CONFIG,
 96            trace,
 97            &public_inputs,
 98            None,
 99            &mut TimingTree::default(),
100        )
101        .expect("We should have a valid proof!");
102
103        verify_stark_proof(stark, stark_proof.clone(), &STARK_CONFIG, None)
104            .expect("We should be able to verify this proof!");
105
106        // 2) now build a plonky2 circuit that verifies the starky proof
107        let degree_bits = stark_proof.proof.recover_degree_bits(&STARK_CONFIG);
108
109        // construct the circuit
110        let circuit_config = CircuitConfig::standard_recursion_config();
111        let mut builder = CircuitBuilder::<F, D>::new(circuit_config);
112        let plonky_targets =
113            FibStarkVerifierTargets::add_targets(&mut builder, stark, degree_bits)?;
114
115        builder.print_gate_counts(0);
116
117        // set concrete values to targets
118        let mut pw = PartialWitness::new();
119        plonky_targets.set_targets(&mut pw, &stark_proof, degree_bits)?;
120
121        // generate the plonky2 proof
122        let data = builder.build::<C>();
123        let proof = data.prove(pw)?;
124
125        // 3) verify the plonky2 proof
126        data.verify(proof)?;
127
128        Ok(())
129    }
130}