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<G, EFqSponge>
11where
12    G: CommitmentCurve,
13    EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField>,
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 poly_commitment::{commitment::shift_scalar, ipa::OpeningProof};
42
43    use crate::{
44        circuits::scalars::caml::CamlRandomOracles, curve::KimchiCurve, error::VerifyError,
45        plonk_sponge::FrSponge, proof::ProverProof, verifier_index::VerifierIndex,
46    };
47
48    use super::*;
49
50    #[derive(ocaml::IntoValue, ocaml::FromValue, ocaml_gen::Struct)]
51    pub struct CamlOracles<CamlF> {
52        pub o: CamlRandomOracles<CamlF>,
53        pub public_evals: (CamlF, CamlF),
54        pub opening_prechallenges: Vec<CamlF>,
55        pub digest_before_evaluations: CamlF,
56    }
57
58    pub fn create_caml_oracles<G, CamlF, EFqSponge, EFrSponge, CurveParams>(
59        lgr_comm: Vec<PolyComm<G>>,
60        index: VerifierIndex<G, OpeningProof<G>>,
61        proof: ProverProof<G, OpeningProof<G>>,
62        public_input: &[G::ScalarField],
63    ) -> Result<CamlOracles<CamlF>, VerifyError>
64    where
65        G: KimchiCurve,
66        G::BaseField: PrimeField,
67        EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField>,
68        EFrSponge: FrSponge<G::ScalarField>,
69        CamlF: From<G::ScalarField>,
70    {
71        let lgr_comm: Vec<PolyComm<G>> = lgr_comm.into_iter().take(public_input.len()).collect();
72        let lgr_comm_refs: Vec<_> = lgr_comm.iter().collect();
73
74        let negated_public: Vec<_> = public_input.iter().map(|s| -*s).collect();
75
76        let p_comm = PolyComm::<G>::multi_scalar_mul(&lgr_comm_refs, &negated_public);
77
78        let oracles_result =
79            proof.oracles::<EFqSponge, EFrSponge>(&index, &p_comm, Some(public_input))?;
80
81        let (mut sponge, combined_inner_product, public_evals, 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            public_evals: (public_evals[0][0].into(), public_evals[1][0].into()),
101            opening_prechallenges,
102            digest_before_evaluations: digest.into(),
103        })
104    }
105}