1use crate::{alphas::Alphas, circuits::scalars::RandomOracles, proof::PointEvaluations};
6use mina_poseidon::FqSponge;
7use poly_commitment::commitment::{CommitmentCurve, PolyComm};
8
9pub 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 pub fq_sponge: EFqSponge,
17 pub digest: G::ScalarField,
19 pub oracles: RandomOracles<G::ScalarField>,
21 pub all_alphas: Alphas<G::ScalarField>,
23 pub public_evals: [Vec<G::ScalarField>; 2],
25 pub powers_of_eval_points_for_chunks: PointEvaluations<G::ScalarField>,
27 #[allow(clippy::type_complexity)]
29 pub polys: Vec<(PolyComm<G>, Vec<Vec<G::ScalarField>>)>,
30 pub zeta1: G::ScalarField,
32 pub ft_eval0: G::ScalarField,
34 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}