kimchi_stubs/
oracles.rs

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