openvm_continuations/circuit/deferral/inner/verifier/
trace.rs1use std::borrow::{Borrow, BorrowMut};
2
3use openvm_cpu_backend::CpuBackend;
4use openvm_stark_backend::{proof::Proof, prover::AirProvingContext};
5use openvm_stark_sdk::config::baby_bear_poseidon2::{BabyBearPoseidon2Config, F};
6use openvm_verify_stark_host::pvs::{VerifierBasePvs, VkCommit, VERIFIER_PVS_AIR_ID};
7use p3_field::{Field, PrimeCharacteristicRing, PrimeField32};
8use p3_matrix::dense::RowMajorMatrix;
9
10use crate::circuit::deferral::inner::verifier::air::{DeferralChildLevel, DeferralVerifierPvsCols};
11
12pub struct DeferralVerifierPvsTraceCtx {
13 pub proving_ctx: AirProvingContext<CpuBackend<BabyBearPoseidon2Config>>,
14 pub range_check_inputs: Vec<usize>,
15}
16
17pub fn generate_proving_ctx(
18 proofs: &[Proof<BabyBearPoseidon2Config>],
19 child_is_agg: bool,
20 child_vk_commit: VkCommit<F>,
21) -> DeferralVerifierPvsTraceCtx {
22 let num_proofs = proofs.len();
23 let height = num_proofs.next_power_of_two();
24 let width = DeferralVerifierPvsCols::<u8>::width();
25
26 debug_assert!(num_proofs > 0);
27
28 let mut trace = vec![F::ZERO; height * width];
29 let mut range_check_inputs = vec![];
30 let mut child_level = DeferralChildLevel::App;
31
32 for (proof_idx, (proof, chunk)) in proofs.iter().zip(trace.chunks_exact_mut(width)).enumerate()
33 {
34 let cols: &mut DeferralVerifierPvsCols<F> = chunk.borrow_mut();
35 cols.proof_idx = F::from_usize(proof_idx);
36 cols.is_valid = F::ONE;
37
38 if child_is_agg {
39 cols.has_verifier_pvs = F::ONE;
40
41 let child_pvs: &VerifierBasePvs<F> =
42 proof.public_values[VERIFIER_PVS_AIR_ID].as_slice().borrow();
43 cols.child_pvs = *child_pvs;
44
45 child_level = match child_pvs.internal_flag {
46 F::ZERO => DeferralChildLevel::Leaf,
47 F::ONE => DeferralChildLevel::InternalForLeaf,
48 F::TWO => DeferralChildLevel::InternalRecursive,
49 _ => unreachable!(),
50 };
51 }
52
53 let depth = cols.child_pvs.recursion_depth.as_canonical_u32();
54 cols.recursion_flag = F::from_u32(depth.min(2));
55 cols.depth_inv = if depth >= 2 {
56 (cols.child_pvs.recursion_depth * (cols.child_pvs.recursion_depth - F::ONE)).inverse()
57 } else {
58 F::ZERO
59 };
60 range_check_inputs.push(depth as usize);
61 }
62
63 let last_row: &DeferralVerifierPvsCols<F> =
64 trace[(num_proofs - 1) * width..num_proofs * width].borrow();
65 let mut pvs = last_row.child_pvs;
66
67 match child_level {
69 DeferralChildLevel::App => {
70 pvs.app_vk_commit = child_vk_commit;
71 }
72 DeferralChildLevel::Leaf => {
73 pvs.leaf_vk_commit = child_vk_commit;
74 pvs.internal_flag = F::ONE;
75 }
76 DeferralChildLevel::InternalForLeaf => {
77 pvs.internal_for_leaf_vk_commit = child_vk_commit;
78 pvs.internal_flag = F::TWO;
79 pvs.recursion_depth = F::ONE;
80 }
81 DeferralChildLevel::InternalRecursive => {
82 pvs.internal_recursive_vk_commit = child_vk_commit;
83 pvs.internal_flag = F::TWO;
84 pvs.recursion_depth = last_row.child_pvs.recursion_depth + F::ONE;
85 }
86 }
87
88 DeferralVerifierPvsTraceCtx {
89 proving_ctx: AirProvingContext {
90 cached_mains: vec![],
91 common_main: RowMajorMatrix::new(trace, width),
92 public_values: pvs.to_vec(),
93 },
94 range_check_inputs,
95 }
96}