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    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: (F, 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.0.into())
96                    .collect();
97
98                Ok(CamlOracles {
99                    o: oracles.into(),
100                    p_eval: (p_eval[0][0].into(), p_eval[1][0].into()),
101                    opening_prechallenges,
102                    digest_before_evaluations: digest.into(),
103                })
104            }
105
106            #[ocaml_gen::func]
107            #[ocaml::func]
108            pub fn [<$F:snake _oracles_create_no_public>](
109                lgr_comm: Vec<CamlPolyComm<$CamlG>>,
110                index: $index,
111                proof: CamlProverProof<$CamlG, $CamlF>,
112            ) -> Result<CamlOracles<$CamlF>, ocaml::Error> {
113                let proof = CamlProofWithPublic {
114                    proof,
115                    public_evals: None,
116                };
117
118                let index: VerifierIndex<FULL_ROUNDS, $G, <OpeningProof<$G,FULL_ROUNDS> as poly_commitment::OpenProof<$G, FULL_ROUNDS>>::SRS> = index.into();
119
120                let lgr_comm: Vec<PolyComm<$G>> = lgr_comm
121                    .into_iter()
122                    .take(proof.proof.public.len())
123                    .map(Into::into)
124                    .collect();
125                let lgr_comm_refs: Vec<_> = lgr_comm.iter().collect();
126
127                let p_comm = PolyComm::<$G>::multi_scalar_mul(
128                    &lgr_comm_refs,
129                    &proof
130                        .proof
131                        .public
132                        .iter()
133                        .map(Into::<$F>::into)
134                        .map(|s| -s)
135                        .collect::<Vec<_>>(),
136                );
137
138                let p_comm = {
139                    index
140                        .srs()
141                        .mask_custom(
142                            p_comm.clone(),
143                            &p_comm.map(|_| $F::one()),
144                        )
145                        .unwrap()
146                        .commitment
147                };
148
149                let (proof, public_input): (ProverProof<$G, OpeningProof<$G, FULL_ROUNDS>, FULL_ROUNDS>, Vec<$F>) = proof.into();
150
151                let oracles_result =
152                    proof.oracles::<
153                        DefaultFqSponge<$curve_params, PlonkSpongeConstantsKimchi, FULL_ROUNDS>,
154                        DefaultFrSponge<$F, PlonkSpongeConstantsKimchi, FULL_ROUNDS>,
155                        _,
156                    >(&index, &p_comm, Some(&public_input))?;
157
158                let (mut sponge, combined_inner_product, p_eval, digest, oracles) = (
159                    oracles_result.fq_sponge,
160                    oracles_result.combined_inner_product,
161                    oracles_result.public_evals,
162                    oracles_result.digest,
163                    oracles_result.oracles,
164                );
165
166                sponge.absorb_fr(&[shift_scalar::<$G>(combined_inner_product)]);
167
168                let opening_prechallenges = proof
169                    .proof
170                    .prechallenges(&mut sponge)
171                    .into_iter()
172                    .map(|x| x.0.into())
173                    .collect();
174
175                Ok(CamlOracles {
176                    o: oracles.into(),
177                    p_eval: (p_eval[0][0].into(), p_eval[1][0].into()),
178                    opening_prechallenges,
179                    digest_before_evaluations: digest.into(),
180                })
181            }
182
183            #[ocaml_gen::func]
184            #[ocaml::func]
185            pub fn [<$F:snake _oracles_dummy>]() -> CamlRandomOracles<$CamlF> {
186                RandomOracles::<$F>::default().into()
187            }
188
189            #[ocaml_gen::func]
190            #[ocaml::func]
191            pub fn [<$F:snake _oracles_deep_copy>](
192                x: CamlRandomOracles<$CamlF>,
193            ) -> CamlRandomOracles<$CamlF> {
194                x
195            }
196        }
197    }
198}
199
200pub mod fp {
201    use super::*;
202    use crate::arkworks::{CamlFp, CamlGVesta};
203    use mina_curves::pasta::{Fp, Vesta, VestaParameters};
204
205    impl_oracles!(
206        CamlFp,
207        Fp,
208        CamlGVesta,
209        Vesta,
210        CamlPastaFpPlonkVerifierIndex,
211        VestaParameters
212    );
213}
214
215pub mod fq {
216    use super::*;
217    use crate::{
218        arkworks::{CamlFq, CamlGPallas},
219        oracles::CamlOracles,
220        pasta_fq_plonk_verifier_index::CamlPastaFqPlonkVerifierIndex,
221    };
222    use mina_curves::pasta::{Fq, Pallas, PallasParameters};
223
224    impl_oracles!(
225        CamlFq,
226        Fq,
227        CamlGPallas,
228        Pallas,
229        CamlPastaFqPlonkVerifierIndex,
230        PallasParameters
231    );
232}