openvm_continuations/prover/deferral/hook/
mod.rs

1use std::sync::Arc;
2
3use eyre::Result;
4use openvm_recursion_circuit::system::{AggregationSubCircuit, VerifierConfig, VerifierTraceGen};
5use openvm_stark_backend::{
6    keygen::types::{MultiStarkProvingKey, MultiStarkVerifyingKey},
7    proof::Proof,
8    prover::{
9        CommittedTraceData, DeviceDataTransporter, DeviceMultiStarkProvingKey, ProverBackend,
10        ProverDevice,
11    },
12    EngineDeviceCtx, StarkEngine, SystemParams,
13};
14use openvm_stark_sdk::config::baby_bear_poseidon2::{Digest, EF, F};
15use p3_field::{Field, PrimeField32};
16use tracing::instrument;
17
18use crate::{
19    circuit::{
20        deferral::hook::{DeferralHookCircuit, DeferralHookTraceGen, DeferralIoCommit},
21        Circuit,
22    },
23    prover::trace_heights_tracing_info,
24    CommitBytes, VkCommitBytes, SC,
25};
26
27mod trace;
28
29pub struct DeferralHookProver<
30    PB: ProverBackend<Val = F, Challenge = EF, Commitment = Digest>,
31    S: AggregationSubCircuit,
32    T,
33> {
34    pk: Arc<MultiStarkProvingKey<SC>>,
35    d_pk: DeviceMultiStarkProvingKey<PB>,
36    vk: Arc<MultiStarkVerifyingKey<SC>>,
37
38    agg_node_tracegen: T,
39
40    child_vk: Arc<MultiStarkVerifyingKey<SC>>,
41    child_vk_pcs_data: CommittedTraceData<PB>,
42    circuit: Arc<DeferralHookCircuit<S>>,
43}
44
45impl<PB, S, T> DeferralHookProver<PB, S, T>
46where
47    PB: ProverBackend<Val = F, Challenge = EF, Commitment = Digest>,
48    S: AggregationSubCircuit,
49    PB::Matrix: Clone,
50{
51    #[instrument(name = "total_proof", skip_all)]
52    pub fn prove<E: StarkEngine<SC = SC, PB = PB>>(
53        &self,
54        proof: Proof<SC>,
55        leaf_children: Vec<DeferralIoCommit<F>>,
56    ) -> Result<Proof<SC>>
57    where
58        S: VerifierTraceGen<PB, SC, EngineDeviceCtx<E>>,
59        T: DeferralHookTraceGen<PB, EngineDeviceCtx<E>>,
60    {
61        let engine = E::new(self.pk.params.clone());
62        let proving_ctx =
63            self.generate_proving_ctx(proof, leaf_children, engine.device().device_ctx());
64        if tracing::enabled!(tracing::Level::DEBUG) {
65            trace_heights_tracing_info::<_, SC>(&proving_ctx.per_trace, &self.circuit.airs());
66        }
67        #[cfg(debug_assertions)]
68        if crate::prover::debug_checks_enabled() {
69            crate::prover::debug_constraints(&self.circuit, &proving_ctx, &engine);
70        }
71        let proof = engine.prove(&self.d_pk, proving_ctx)?;
72        #[cfg(debug_assertions)]
73        if crate::prover::debug_checks_enabled() {
74            engine.verify(&self.vk, &proof)?;
75        }
76        Ok(proof)
77    }
78    pub fn new<E: StarkEngine<SC = SC, PB = PB>>(
79        child_vk: Arc<MultiStarkVerifyingKey<SC>>,
80        internal_recursive_cached_commit: CommitBytes,
81        system_params: SystemParams,
82    ) -> Self
83    where
84        S: VerifierTraceGen<PB, SC, EngineDeviceCtx<E>>,
85        T: DeferralHookTraceGen<PB, EngineDeviceCtx<E>>,
86        PB::Val: Field + PrimeField32,
87        PB::Matrix: Clone,
88        PB::Commitment: Into<CommitBytes>,
89    {
90        let verifier_circuit = S::new(
91            child_vk.clone(),
92            VerifierConfig {
93                continuations_enabled: true,
94                ..Default::default()
95            },
96        );
97        let engine = E::new(system_params);
98        let child_vk_pcs_data = verifier_circuit.commit_child_vk(&engine, &child_vk);
99        let internal_recursive_vk_commit = VkCommitBytes {
100            cached_commit: internal_recursive_cached_commit,
101            vk_pre_hash: child_vk.pre_hash.into(),
102        };
103        let circuit = Arc::new(DeferralHookCircuit::new(
104            Arc::new(verifier_circuit),
105            internal_recursive_vk_commit,
106        ));
107        let (pk, vk) = engine.keygen(&circuit.airs());
108        let d_pk = engine.device().transport_pk_to_device(&pk);
109
110        Self {
111            pk: Arc::new(pk),
112            d_pk,
113            vk: Arc::new(vk),
114            agg_node_tracegen: T::new(),
115            child_vk,
116            child_vk_pcs_data,
117            circuit,
118        }
119    }
120
121    pub fn from_pk<E: StarkEngine<SC = SC, PB = PB>>(
122        child_vk: Arc<MultiStarkVerifyingKey<SC>>,
123        internal_recursive_cached_commit: CommitBytes,
124        pk: Arc<MultiStarkProvingKey<SC>>,
125    ) -> Self
126    where
127        S: VerifierTraceGen<PB, SC, EngineDeviceCtx<E>>,
128        T: DeferralHookTraceGen<PB, EngineDeviceCtx<E>>,
129        PB::Val: Field + PrimeField32,
130        PB::Matrix: Clone,
131        PB::Commitment: Into<CommitBytes>,
132    {
133        let verifier_circuit = S::new(
134            child_vk.clone(),
135            VerifierConfig {
136                continuations_enabled: true,
137                ..Default::default()
138            },
139        );
140        let engine = E::new(pk.params.clone());
141        let child_vk_pcs_data = verifier_circuit.commit_child_vk(&engine, &child_vk);
142        let internal_recursive_vk_commit = VkCommitBytes {
143            cached_commit: internal_recursive_cached_commit,
144            vk_pre_hash: child_vk.pre_hash.into(),
145        };
146        let circuit = Arc::new(DeferralHookCircuit::new(
147            Arc::new(verifier_circuit),
148            internal_recursive_vk_commit,
149        ));
150        let vk = Arc::new(pk.get_vk());
151        let d_pk = engine.device().transport_pk_to_device(pk.as_ref());
152        Self {
153            pk,
154            d_pk,
155            vk,
156            agg_node_tracegen: T::new(),
157            child_vk,
158            child_vk_pcs_data,
159            circuit,
160        }
161    }
162
163    pub fn get_circuit(&self) -> Arc<DeferralHookCircuit<S>> {
164        self.circuit.clone()
165    }
166
167    pub fn get_pk(&self) -> Arc<MultiStarkProvingKey<SC>> {
168        self.pk.clone()
169    }
170
171    pub fn get_vk(&self) -> Arc<MultiStarkVerifyingKey<SC>> {
172        self.vk.clone()
173    }
174
175    pub fn get_cached_commit(&self) -> <PB as ProverBackend>::Commitment {
176        self.child_vk_pcs_data.commitment
177    }
178}