kimchi/
oracles.rs

1//! This type and logic only exists for the OCaml side.
2//! As we move more code to the Rust side,
3//! we hope to be able to remove this code in the future.
4
5use crate::{alphas::Alphas, circuits::scalars::RandomOracles, proof::PointEvaluations};
6use mina_poseidon::FqSponge;
7use poly_commitment::commitment::{CommitmentCurve, PolyComm};
8
9/// The result of running the oracle protocol
10pub struct OraclesResult<const FULL_ROUNDS: usize, G, EFqSponge>
11where
12    G: CommitmentCurve,
13    EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField, FULL_ROUNDS>,
14{
15    /// A sponge that acts on the base field of a curve
16    pub fq_sponge: EFqSponge,
17    /// the last evaluation of the Fq-Sponge in this protocol
18    pub digest: G::ScalarField,
19    /// the challenges produced in the protocol
20    pub oracles: RandomOracles<G::ScalarField>,
21    /// the computed powers of alpha
22    pub all_alphas: Alphas<G::ScalarField>,
23    /// public polynomial evaluations
24    pub public_evals: [Vec<G::ScalarField>; 2],
25    /// zeta^n and (zeta * omega)^n
26    pub powers_of_eval_points_for_chunks: PointEvaluations<G::ScalarField>,
27    /// recursion data
28    #[allow(clippy::type_complexity)]
29    pub polys: Vec<(PolyComm<G>, Vec<Vec<G::ScalarField>>)>,
30    /// pre-computed zeta^n
31    pub zeta1: G::ScalarField,
32    /// The evaluation f(zeta) - t(zeta) * Z_H(zeta)
33    pub ft_eval0: G::ScalarField,
34    /// Used by the OCaml side
35    pub combined_inner_product: G::ScalarField,
36}
37
38#[cfg(feature = "ocaml_types")]
39pub mod caml {
40    use ark_ff::PrimeField;
41    use mina_poseidon::poseidon::ArithmeticSpongeParams;
42    use poly_commitment::{commitment::shift_scalar, ipa::OpeningProof};
43
44    use crate::{
45        circuits::scalars::caml::CamlRandomOracles, curve::KimchiCurve, error::VerifyError,
46        plonk_sponge::FrSponge, proof::ProverProof, verifier_index::VerifierIndex,
47    };
48
49    use super::*;
50
51    #[derive(ocaml::IntoValue, ocaml::FromValue, ocaml_gen::Struct)]
52    pub struct CamlOracles<CamlF> {
53        pub o: CamlRandomOracles<CamlF>,
54        pub public_evals: (CamlF, CamlF),
55        pub opening_prechallenges: Vec<CamlF>,
56        pub digest_before_evaluations: CamlF,
57    }
58
59    pub fn create_caml_oracles<
60        const FULL_ROUNDS: usize,
61        G,
62        CamlF,
63        EFqSponge,
64        EFrSponge,
65        CurveParams,
66    >(
67        lgr_comm: Vec<PolyComm<G>>,
68        index: VerifierIndex<FULL_ROUNDS, G, CurveParams>,
69        proof: ProverProof<G, OpeningProof<G, FULL_ROUNDS>, FULL_ROUNDS>,
70        public_input: &[G::ScalarField],
71    ) -> Result<CamlOracles<CamlF>, VerifyError>
72    where
73        G: KimchiCurve<FULL_ROUNDS>,
74        G::BaseField: PrimeField,
75        EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField, FULL_ROUNDS>,
76        EFrSponge: FrSponge<G::ScalarField>,
77        EFrSponge: From<&'static ArithmeticSpongeParams<G::ScalarField, FULL_ROUNDS>>,
78        CamlF: From<G::ScalarField>,
79        CurveParams: poly_commitment::OpenProof<G, FULL_ROUNDS>,
80    {
81        let lgr_comm: Vec<PolyComm<G>> = lgr_comm.into_iter().take(public_input.len()).collect();
82        let lgr_comm_refs: Vec<_> = lgr_comm.iter().collect();
83
84        let negated_public: Vec<_> = public_input.iter().map(|s| -*s).collect();
85
86        let p_comm = PolyComm::<G>::multi_scalar_mul(&lgr_comm_refs, &negated_public);
87
88        let oracles_result = proof.oracles::<EFqSponge, EFrSponge, CurveParams>(
89            &index,
90            &p_comm,
91            Some(public_input),
92        )?;
93
94        let (mut sponge, combined_inner_product, public_evals, digest, oracles) = (
95            oracles_result.fq_sponge,
96            oracles_result.combined_inner_product,
97            oracles_result.public_evals,
98            oracles_result.digest,
99            oracles_result.oracles,
100        );
101
102        sponge.absorb_fr(&[shift_scalar::<G>(combined_inner_product)]);
103
104        let opening_prechallenges = proof
105            .proof
106            .prechallenges(&mut sponge)
107            .into_iter()
108            .map(|x| x.0.into())
109            .collect();
110
111        Ok(CamlOracles {
112            o: oracles.into(),
113            public_evals: (public_evals[0][0].into(), public_evals[1][0].into()),
114            opening_prechallenges,
115            digest_before_evaluations: digest.into(),
116        })
117    }
118}