openvm_native_recursion/fri/
witness.rs

1use openvm_native_compiler::{
2    ir::{Builder, Witness, WitnessRef},
3    prelude::*,
4};
5
6use super::types::BatchOpeningVariable;
7use crate::{
8    config::outer::{
9        OuterBatchOpening, OuterCommitPhaseStep, OuterConfig, OuterDigest, OuterFriProof,
10        OuterQueryProof,
11    },
12    fri::types::{FriCommitPhaseProofStepVariable, FriProofVariable, FriQueryProofVariable},
13    vars::HintSlice,
14    witness::{VectorWitnessable, Witnessable},
15};
16
17type C = OuterConfig;
18
19impl Witnessable<C> for OuterCommitPhaseStep {
20    type WitnessVariable = FriCommitPhaseProofStepVariable<C>;
21
22    fn read(&self, builder: &mut Builder<C>) -> Self::WitnessVariable {
23        let sibling_value = self.sibling_value.read(builder);
24        let opening_proof = read_opening_proof(builder, &self.opening_proof);
25        Self::WitnessVariable {
26            sibling_value,
27            opening_proof,
28        }
29    }
30
31    fn write(&self, witness: &mut Witness<OuterConfig>) {
32        self.sibling_value.write(witness);
33        write_opening_proof(witness, &self.opening_proof);
34    }
35}
36
37impl VectorWitnessable<C> for OuterCommitPhaseStep {}
38
39impl Witnessable<C> for OuterQueryProof {
40    type WitnessVariable = FriQueryProofVariable<C>;
41
42    fn read(&self, builder: &mut Builder<C>) -> Self::WitnessVariable {
43        let input_proof = self.input_proof.read(builder);
44        let commit_phase_openings = self.commit_phase_openings.read(builder);
45        Self::WitnessVariable {
46            input_proof,
47            commit_phase_openings,
48        }
49    }
50
51    fn write(&self, witness: &mut Witness<OuterConfig>) {
52        self.input_proof.write(witness);
53        self.commit_phase_openings.write(witness);
54    }
55}
56
57impl VectorWitnessable<C> for OuterQueryProof {}
58
59impl Witnessable<C> for OuterFriProof {
60    type WitnessVariable = FriProofVariable<C>;
61
62    fn read(&self, builder: &mut Builder<C>) -> Self::WitnessVariable {
63        let commit_phase_commits = self.commit_phase_commits.read(builder);
64        let query_proofs = self.query_proofs.read(builder);
65        let final_poly = self.final_poly.read(builder);
66        let pow_witness = self.pow_witness.read(builder);
67        Self::WitnessVariable {
68            commit_phase_commits,
69            query_proofs,
70            final_poly,
71            pow_witness,
72        }
73    }
74
75    fn write(&self, witness: &mut Witness<OuterConfig>) {
76        self.commit_phase_commits.write(witness);
77        <Vec<_> as Witnessable<C>>::write(&self.query_proofs, witness);
78        self.final_poly.write(witness);
79        self.pow_witness.write(witness);
80    }
81}
82
83impl Witnessable<C> for OuterBatchOpening {
84    type WitnessVariable = BatchOpeningVariable<C>;
85
86    fn read(&self, builder: &mut Builder<C>) -> Self::WitnessVariable {
87        let opened_values_refs: Vec<WitnessRef> = self
88            .opened_values
89            .iter()
90            .flatten()
91            .map(|x| x.read(builder).into())
92            .collect();
93        let length = Usize::from(opened_values_refs.len());
94        let id = builder.witness_load(opened_values_refs);
95        let opened_values = HintSlice { length, id };
96
97        let opening_proof = read_opening_proof(builder, &self.opening_proof);
98        Self::WitnessVariable {
99            opened_values,
100            opening_proof,
101        }
102    }
103
104    fn write(&self, witness: &mut Witness<OuterConfig>) {
105        let opened_values: Vec<_> = self
106            .opened_values
107            .iter()
108            .flat_map(|op| op.to_vec())
109            .collect();
110        opened_values.write(witness);
111        write_opening_proof(witness, &self.opening_proof);
112    }
113}
114
115impl VectorWitnessable<C> for OuterBatchOpening {}
116impl VectorWitnessable<C> for Vec<OuterBatchOpening> {}
117
118fn read_opening_proof(builder: &mut Builder<C>, opening_proof: &[OuterDigest]) -> HintSlice<C> {
119    let opening_proof: Vec<WitnessRef> = opening_proof
120        .iter()
121        .flatten()
122        .map(|x| x.read(builder).into())
123        .collect();
124    let length = Usize::from(opening_proof.len());
125    let id = builder.witness_load(opening_proof);
126    HintSlice { length, id }
127}
128fn write_opening_proof(witness: &mut Witness<OuterConfig>, opening_proof: &[OuterDigest]) {
129    let opening_proof: Vec<_> = opening_proof.iter().flat_map(|op| op.to_vec()).collect();
130    opening_proof.write(witness);
131}