1use crate::pasta_fp_plonk_verifier_index::CamlPastaFpPlonkVerifierIndex;
2use ark_ff::One;
3use kimchi::{
4 circuits::scalars::{caml::CamlRandomOracles, RandomOracles},
5 proof::ProverProof,
6 prover::caml::{CamlProofWithPublic, CamlProverProof},
7 verifier_index::VerifierIndex,
8};
9use mina_poseidon::{
10 self,
11 constants::PlonkSpongeConstantsKimchi,
12 pasta::FULL_ROUNDS,
13 sponge::{DefaultFqSponge, DefaultFrSponge},
14 FqSponge,
15};
16use paste::paste;
17use poly_commitment::{
18 commitment::{caml::CamlPolyComm, shift_scalar, PolyComm},
19 ipa::OpeningProof,
20 SRS,
21};
22
23#[derive(ocaml::IntoValue, ocaml::FromValue, ocaml_gen::Struct)]
24pub struct CamlOracles<F> {
25 pub o: CamlRandomOracles<F>,
26 pub p_eval: (Vec<F>, Vec<F>),
27 pub opening_prechallenges: Vec<F>,
28 pub digest_before_evaluations: F,
29}
30
31macro_rules! impl_oracles {
32 ($CamlF: ty, $F: ty, $CamlG: ty, $G: ty, $index: ty, $curve_params: ty) => {
33 paste! {
34 #[ocaml_gen::func]
35 #[ocaml::func]
36 pub fn [<$F:snake _oracles_create>](
37 lgr_comm: Vec<CamlPolyComm<$CamlG>>,
38 index: $index,
39 proof: CamlProofWithPublic<$CamlG, $CamlF>,
40 ) -> Result<CamlOracles<$CamlF>, ocaml::Error> {
41 let index: VerifierIndex<FULL_ROUNDS, $G, <OpeningProof<$G, FULL_ROUNDS> as poly_commitment::OpenProof<$G, FULL_ROUNDS>>::SRS> = index.into();
42
43 let lgr_comm: Vec<PolyComm<$G>> = lgr_comm
44 .into_iter()
45 .take(proof.proof.public.len())
46 .map(Into::into)
47 .collect();
48 let lgr_comm_refs: Vec<_> = lgr_comm.iter().collect();
49
50 let p_comm = PolyComm::<$G>::multi_scalar_mul(
51 &lgr_comm_refs,
52 &proof
53 .proof
54 .public
55 .iter()
56 .map(Into::<$F>::into)
57 .map(|s| -s)
58 .collect::<Vec<_>>(),
59 );
60
61 let p_comm = {
62 index
63 .srs()
64 .mask_custom(
65 p_comm.clone(),
66 &p_comm.map(|_| $F::one()),
67 )
68 .unwrap()
69 .commitment
70 };
71
72 let (proof, public_input): (ProverProof<$G, OpeningProof<$G, FULL_ROUNDS>, FULL_ROUNDS>, Vec<$F>) = proof.into();
73
74 let oracles_result =
75 proof.oracles::<
76 DefaultFqSponge<$curve_params, PlonkSpongeConstantsKimchi, FULL_ROUNDS>,
77 DefaultFrSponge<$F, PlonkSpongeConstantsKimchi, FULL_ROUNDS>,
78 <OpeningProof<$G, FULL_ROUNDS> as poly_commitment::OpenProof<$G, FULL_ROUNDS>>::SRS,
79 >(&index, &p_comm, Some(&public_input))?;
80
81 let (mut sponge, combined_inner_product, p_eval, digest, oracles) = (
82 oracles_result.fq_sponge,
83 oracles_result.combined_inner_product,
84 oracles_result.public_evals,
85 oracles_result.digest,
86 oracles_result.oracles,
87 );
88
89 sponge.absorb_fr(&[shift_scalar::<$G>(combined_inner_product)]);
90
91 let opening_prechallenges = proof
92 .proof
93 .prechallenges(&mut sponge)
94 .into_iter()
95 .map(|x| x.inner().into())
96 .collect();
97
98 let [pe0, pe1] = p_eval;
99 Ok(CamlOracles {
100 o: oracles.into(),
101 p_eval: (
102 pe0.into_iter().map(Into::into).collect(),
103 pe1.into_iter().map(Into::into).collect(),
104 ),
105 opening_prechallenges,
106 digest_before_evaluations: digest.into(),
107 })
108 }
109
110 #[ocaml_gen::func]
111 #[ocaml::func]
112 pub fn [<$F:snake _oracles_create_no_public>](
113 lgr_comm: Vec<CamlPolyComm<$CamlG>>,
114 index: $index,
115 proof: CamlProverProof<$CamlG, $CamlF>,
116 ) -> Result<CamlOracles<$CamlF>, ocaml::Error> {
117 let proof = CamlProofWithPublic {
118 proof,
119 public_evals: None,
120 };
121
122 let index: VerifierIndex<FULL_ROUNDS, $G, <OpeningProof<$G,FULL_ROUNDS> as poly_commitment::OpenProof<$G, FULL_ROUNDS>>::SRS> = index.into();
123
124 let lgr_comm: Vec<PolyComm<$G>> = lgr_comm
125 .into_iter()
126 .take(proof.proof.public.len())
127 .map(Into::into)
128 .collect();
129 let lgr_comm_refs: Vec<_> = lgr_comm.iter().collect();
130
131 let p_comm = PolyComm::<$G>::multi_scalar_mul(
132 &lgr_comm_refs,
133 &proof
134 .proof
135 .public
136 .iter()
137 .map(Into::<$F>::into)
138 .map(|s| -s)
139 .collect::<Vec<_>>(),
140 );
141
142 let p_comm = {
143 index
144 .srs()
145 .mask_custom(
146 p_comm.clone(),
147 &p_comm.map(|_| $F::one()),
148 )
149 .unwrap()
150 .commitment
151 };
152
153 let (proof, public_input): (ProverProof<$G, OpeningProof<$G, FULL_ROUNDS>, FULL_ROUNDS>, Vec<$F>) = proof.into();
154
155 let oracles_result =
156 proof.oracles::<
157 DefaultFqSponge<$curve_params, PlonkSpongeConstantsKimchi, FULL_ROUNDS>,
158 DefaultFrSponge<$F, PlonkSpongeConstantsKimchi, FULL_ROUNDS>,
159 _,
160 >(&index, &p_comm, Some(&public_input))?;
161
162 let (mut sponge, combined_inner_product, p_eval, digest, oracles) = (
163 oracles_result.fq_sponge,
164 oracles_result.combined_inner_product,
165 oracles_result.public_evals,
166 oracles_result.digest,
167 oracles_result.oracles,
168 );
169
170 sponge.absorb_fr(&[shift_scalar::<$G>(combined_inner_product)]);
171
172 let opening_prechallenges = proof
173 .proof
174 .prechallenges(&mut sponge)
175 .into_iter()
176 .map(|x| x.inner().into())
177 .collect();
178
179 let [pe0, pe1] = p_eval;
180 Ok(CamlOracles {
181 o: oracles.into(),
182 p_eval: (
183 pe0.into_iter().map(Into::into).collect(),
184 pe1.into_iter().map(Into::into).collect(),
185 ),
186 opening_prechallenges,
187 digest_before_evaluations: digest.into(),
188 })
189 }
190
191 #[ocaml_gen::func]
192 #[ocaml::func]
193 pub fn [<$F:snake _oracles_dummy>]() -> CamlRandomOracles<$CamlF> {
194 RandomOracles::<$F>::default().into()
195 }
196
197 #[ocaml_gen::func]
198 #[ocaml::func]
199 pub fn [<$F:snake _oracles_deep_copy>](
200 x: CamlRandomOracles<$CamlF>,
201 ) -> CamlRandomOracles<$CamlF> {
202 x
203 }
204 }
205 }
206}
207
208pub mod fp {
209 use super::*;
210 use crate::arkworks::{CamlFp, CamlGVesta};
211 use mina_curves::pasta::{Fp, Vesta, VestaParameters};
212
213 impl_oracles!(
214 CamlFp,
215 Fp,
216 CamlGVesta,
217 Vesta,
218 CamlPastaFpPlonkVerifierIndex,
219 VestaParameters
220 );
221}
222
223pub mod fq {
224 use super::*;
225 use crate::{
226 arkworks::{CamlFq, CamlGPallas},
227 oracles::CamlOracles,
228 pasta_fq_plonk_verifier_index::CamlPastaFqPlonkVerifierIndex,
229 };
230 use mina_curves::pasta::{Fq, Pallas, PallasParameters};
231
232 impl_oracles!(
233 CamlFq,
234 Fq,
235 CamlGPallas,
236 Pallas,
237 CamlPastaFqPlonkVerifierIndex,
238 PallasParameters
239 );
240}