1use alloc::vec::Vec;
5
6use crate::{alphas::Alphas, circuits::scalars::RandomOracles, proof::PointEvaluations};
7use mina_poseidon::FqSponge;
8use poly_commitment::commitment::{CommitmentCurve, PolyComm};
9
10pub 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 pub fq_sponge: EFqSponge,
18 pub digest: G::ScalarField,
20 pub oracles: RandomOracles<G::ScalarField>,
22 pub all_alphas: Alphas<G::ScalarField>,
24 pub public_evals: [Vec<G::ScalarField>; 2],
26 pub powers_of_eval_points_for_chunks: PointEvaluations<G::ScalarField>,
28 #[allow(clippy::type_complexity)]
30 pub polys: Vec<(PolyComm<G>, Vec<Vec<G::ScalarField>>)>,
31 pub zeta1: G::ScalarField,
33 pub ft_eval0: G::ScalarField,
35 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}