Skip to main content

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