openvm_continuations/circuit/deferral/inner/verifier/
trace.rs

1use 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    // Note app_vk_commit is def_vk_commit here
68    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}