use crate::{alphas::Alphas, circuits::scalars::RandomOracles, proof::PointEvaluations};
use mina_poseidon::FqSponge;
use poly_commitment::commitment::{CommitmentCurve, PolyComm};
pub struct OraclesResult<G, EFqSponge>
where
G: CommitmentCurve,
EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField>,
{
pub fq_sponge: EFqSponge,
pub digest: G::ScalarField,
pub oracles: RandomOracles<G::ScalarField>,
pub all_alphas: Alphas<G::ScalarField>,
pub public_evals: [Vec<G::ScalarField>; 2],
pub powers_of_eval_points_for_chunks: PointEvaluations<G::ScalarField>,
#[allow(clippy::type_complexity)]
pub polys: Vec<(PolyComm<G>, Vec<Vec<G::ScalarField>>)>,
pub zeta1: G::ScalarField,
pub ft_eval0: G::ScalarField,
pub combined_inner_product: G::ScalarField,
}
#[cfg(feature = "ocaml_types")]
pub mod caml {
use ark_ff::PrimeField;
use poly_commitment::{commitment::shift_scalar, ipa::OpeningProof};
use crate::{
circuits::scalars::caml::CamlRandomOracles, curve::KimchiCurve, error::VerifyError,
plonk_sponge::FrSponge, proof::ProverProof, verifier_index::VerifierIndex,
};
use super::*;
#[derive(ocaml::IntoValue, ocaml::FromValue, ocaml_gen::Struct)]
pub struct CamlOracles<CamlF> {
pub o: CamlRandomOracles<CamlF>,
pub public_evals: (CamlF, CamlF),
pub opening_prechallenges: Vec<CamlF>,
pub digest_before_evaluations: CamlF,
}
pub fn create_caml_oracles<G, CamlF, EFqSponge, EFrSponge, CurveParams>(
lgr_comm: Vec<PolyComm<G>>,
index: VerifierIndex<G, OpeningProof<G>>,
proof: ProverProof<G, OpeningProof<G>>,
public_input: &[G::ScalarField],
) -> Result<CamlOracles<CamlF>, VerifyError>
where
G: KimchiCurve,
G::BaseField: PrimeField,
EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField>,
EFrSponge: FrSponge<G::ScalarField>,
CamlF: From<G::ScalarField>,
{
let lgr_comm: Vec<PolyComm<G>> = lgr_comm.into_iter().take(public_input.len()).collect();
let lgr_comm_refs: Vec<_> = lgr_comm.iter().collect();
let negated_public: Vec<_> = public_input.iter().map(|s| -*s).collect();
let p_comm = PolyComm::<G>::multi_scalar_mul(&lgr_comm_refs, &negated_public);
let oracles_result =
proof.oracles::<EFqSponge, EFrSponge>(&index, &p_comm, Some(public_input))?;
let (mut sponge, combined_inner_product, public_evals, digest, oracles) = (
oracles_result.fq_sponge,
oracles_result.combined_inner_product,
oracles_result.public_evals,
oracles_result.digest,
oracles_result.oracles,
);
sponge.absorb_fr(&[shift_scalar::<G>(combined_inner_product)]);
let opening_prechallenges = proof
.proof
.prechallenges(&mut sponge)
.into_iter()
.map(|x| x.0.into())
.collect();
Ok(CamlOracles {
o: oracles.into(),
public_evals: (public_evals[0][0].into(), public_evals[1][0].into()),
opening_prechallenges,
digest_before_evaluations: digest.into(),
})
}
}