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}