openvm_native_recursion/fri/
hints.rs1use openvm_native_compiler::{
2 asm::AsmConfig,
3 ir::{Builder, Config, Usize, DIGEST_SIZE},
4};
5use openvm_stark_backend::p3_field::PrimeCharacteristicRing;
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 commit_pow_witnesses = Vec::<InnerVal>::read(builder);
93 let query_proofs = Vec::<InnerQueryProof>::read(builder);
94 let final_poly = builder.hint_exts();
95 let query_pow_witness = builder.hint_felt();
96 Self::HintVariable {
97 commit_phase_commits,
98 commit_pow_witnesses,
99 query_proofs,
100 final_poly,
101 query_pow_witness,
102 }
103 }
104
105 fn write(&self) -> Vec<Vec<<C as Config>::F>> {
106 let mut stream = Vec::new();
107
108 stream.extend(Vec::<InnerDigest>::write(
109 &self
110 .commit_phase_commits
111 .iter()
112 .map(|x| (*x).into())
113 .collect(),
114 ));
115 stream.extend(Vec::<InnerVal>::write(&self.commit_pow_witnesses));
116 stream.extend(Vec::<InnerQueryProof>::write(&self.query_proofs));
117 stream.extend(self.final_poly.write());
118 stream.push(vec![self.query_pow_witness]);
119
120 stream
121 }
122}
123
124impl Hintable<C> for InnerBatchOpening {
125 type HintVariable = BatchOpeningVariable<C>;
126
127 fn read(builder: &mut Builder<C>) -> Self::HintVariable {
128 builder.cycle_tracker_start("HintOpenedValues");
129 let opened_values = read_hint_slice(builder);
130 builder.cycle_tracker_end("HintOpenedValues");
131 builder.cycle_tracker_start("HintOpeningProof");
132 let opening_proof = read_hint_slice(builder);
133 builder.cycle_tracker_end("HintOpeningProof");
134 Self::HintVariable {
135 opened_values,
136 opening_proof,
137 }
138 }
139
140 fn write(&self) -> Vec<Vec<<C as Config>::F>> {
141 let mut stream = Vec::new();
142 let flat_opened_values: Vec<_> = self.opened_values.iter().flatten().copied().collect();
143 stream.extend(vec![
144 vec![InnerVal::from_usize(flat_opened_values.len())],
145 flat_opened_values,
146 ]);
147 stream.extend(write_opening_proof(&self.opening_proof));
148 stream
149 }
150}
151
152impl VecAutoHintable for InnerBatchOpening {}
153impl VecAutoHintable for Vec<InnerBatchOpening> {}
154
155fn read_hint_slice(builder: &mut Builder<C>) -> HintSlice<C> {
156 let length = Usize::from(builder.hint_var());
157 let id = Usize::from(builder.hint_load());
158 HintSlice { length, id }
159}
160
161fn write_opening_proof(opening_proof: &[InnerDigest]) -> Vec<Vec<InnerVal>> {
162 vec![
163 vec![InnerVal::from_usize(opening_proof.len())],
164 opening_proof.iter().flatten().copied().collect(),
165 ]
166}