openvm_native_recursion/fri/
hints.rs
1use openvm_native_compiler::{
2 asm::AsmConfig,
3 ir::{Builder, Config, Usize, DIGEST_SIZE},
4};
5use openvm_stark_backend::p3_field::FieldAlgebra;
6
7use super::types::BatchOpeningVariable;
8use crate::{
9 digest::DigestVariable,
10 fri::types::{FriCommitPhaseProofStepVariable, FriProofVariable, FriQueryProofVariable},
11 hints::{
12 Hintable, InnerBatchOpening, InnerChallenge, InnerCommitPhaseStep, InnerDigest,
13 InnerFriProof, InnerQueryProof, InnerVal, VecAutoHintable,
14 },
15 types::InnerConfig,
16 vars::HintSlice,
17};
18
19type C = InnerConfig;
20
21impl Hintable<C> for InnerDigest {
22 type HintVariable = DigestVariable<C>;
23
24 fn read(builder: &mut Builder<AsmConfig<InnerVal, InnerChallenge>>) -> Self::HintVariable {
25 let digest = builder.hint_felts_fixed(DIGEST_SIZE);
26 DigestVariable::Felt(digest)
27 }
28
29 fn write(&self) -> Vec<Vec<InnerVal>> {
30 let h: [InnerVal; DIGEST_SIZE] = *self;
31 h.map(|x| vec![x]).to_vec()
32 }
33}
34
35impl VecAutoHintable for InnerDigest {}
36
37impl Hintable<C> for InnerCommitPhaseStep {
38 type HintVariable = FriCommitPhaseProofStepVariable<C>;
39
40 fn read(builder: &mut Builder<C>) -> Self::HintVariable {
41 let sibling_value = builder.hint_ext();
42 let opening_proof = read_hint_slice(builder);
43 Self::HintVariable {
44 sibling_value,
45 opening_proof,
46 }
47 }
48
49 fn write(&self) -> Vec<Vec<<C as Config>::F>> {
50 let mut stream = Vec::new();
51
52 stream.extend(Hintable::<C>::write(&self.sibling_value));
53 stream.extend(write_opening_proof(&self.opening_proof));
54
55 stream
56 }
57}
58
59impl VecAutoHintable for InnerCommitPhaseStep {}
60
61impl Hintable<C> for InnerQueryProof {
62 type HintVariable = FriQueryProofVariable<C>;
63
64 fn read(builder: &mut Builder<C>) -> Self::HintVariable {
65 let input_proof = Vec::<InnerBatchOpening>::read(builder);
66 let commit_phase_openings = Vec::<InnerCommitPhaseStep>::read(builder);
67 Self::HintVariable {
68 input_proof,
69 commit_phase_openings,
70 }
71 }
72
73 fn write(&self) -> Vec<Vec<<C as Config>::F>> {
74 let mut stream = Vec::new();
75
76 stream.extend(self.input_proof.write());
77 stream.extend(Vec::<InnerCommitPhaseStep>::write(
78 &self.commit_phase_openings,
79 ));
80
81 stream
82 }
83}
84
85impl VecAutoHintable for InnerQueryProof {}
86
87impl Hintable<C> for InnerFriProof {
88 type HintVariable = FriProofVariable<C>;
89
90 fn read(builder: &mut Builder<C>) -> Self::HintVariable {
91 let commit_phase_commits = Vec::<InnerDigest>::read(builder);
92 let query_proofs = Vec::<InnerQueryProof>::read(builder);
93 let final_poly = builder.hint_exts();
94 let pow_witness = builder.hint_felt();
95 Self::HintVariable {
96 commit_phase_commits,
97 query_proofs,
98 final_poly,
99 pow_witness,
100 }
101 }
102
103 fn write(&self) -> Vec<Vec<<C as Config>::F>> {
104 let mut stream = Vec::new();
105
106 stream.extend(Vec::<InnerDigest>::write(
107 &self
108 .commit_phase_commits
109 .iter()
110 .map(|x| (*x).into())
111 .collect(),
112 ));
113 stream.extend(Vec::<InnerQueryProof>::write(&self.query_proofs));
114 stream.extend(self.final_poly.write());
115 stream.push(vec![self.pow_witness]);
116
117 stream
118 }
119}
120
121impl Hintable<C> for InnerBatchOpening {
122 type HintVariable = BatchOpeningVariable<C>;
123
124 fn read(builder: &mut Builder<C>) -> Self::HintVariable {
125 builder.cycle_tracker_start("HintOpenedValues");
126 let opened_values = read_hint_slice(builder);
127 builder.cycle_tracker_end("HintOpenedValues");
128 builder.cycle_tracker_start("HintOpeningProof");
129 let opening_proof = read_hint_slice(builder);
130 builder.cycle_tracker_end("HintOpeningProof");
131 Self::HintVariable {
132 opened_values,
133 opening_proof,
134 }
135 }
136
137 fn write(&self) -> Vec<Vec<<C as Config>::F>> {
138 let mut stream = Vec::new();
139 let flat_opened_values: Vec<_> = self.opened_values.iter().flatten().copied().collect();
140 stream.extend(vec![
141 vec![InnerVal::from_canonical_usize(flat_opened_values.len())],
142 flat_opened_values,
143 ]);
144 stream.extend(write_opening_proof(&self.opening_proof));
145 stream
146 }
147}
148
149impl VecAutoHintable for InnerBatchOpening {}
150impl VecAutoHintable for Vec<InnerBatchOpening> {}
151
152fn read_hint_slice(builder: &mut Builder<C>) -> HintSlice<C> {
153 let length = Usize::from(builder.hint_var());
154 let id = Usize::from(builder.hint_load());
155 HintSlice { length, id }
156}
157
158fn write_opening_proof(opening_proof: &[InnerDigest]) -> Vec<Vec<InnerVal>> {
159 vec![
160 vec![InnerVal::from_canonical_usize(opening_proof.len())],
161 opening_proof.iter().flatten().copied().collect(),
162 ]
163}