use alloc::vec::Vec;
use core::fmt::Debug;
use lib_q_stark_field::ExtensionField;
use lib_q_stark_matrix::Matrix;
use lib_q_stark_matrix::dense::RowMajorMatrix;
use serde::Serialize;
use serde::de::DeserializeOwned;
use crate::PolynomialSpace;
pub type Val<D> = <D as PolynomialSpace>::Val;
pub trait Pcs<Challenge, Challenger>
where
Challenge: ExtensionField<Val<Self::Domain>>,
{
type Domain: PolynomialSpace;
type Commitment: Clone + Serialize + DeserializeOwned;
type ProverData;
type EvaluationsOnDomain<'a>: Matrix<Val<Self::Domain>> + 'a;
type Proof: Clone + Serialize + DeserializeOwned;
type Error: Debug;
const ZK: bool;
const TRACE_IDX: usize = Self::ZK as usize;
const QUOTIENT_IDX: usize = Self::TRACE_IDX + 1;
const PREPROCESSED_TRACE_IDX: usize = Self::QUOTIENT_IDX + 1;
fn natural_domain_for_degree(&self, degree: usize) -> Self::Domain;
#[allow(clippy::type_complexity)]
fn commit(
&self,
evaluations: impl IntoIterator<Item = (Self::Domain, RowMajorMatrix<Val<Self::Domain>>)>,
) -> (Self::Commitment, Self::ProverData);
#[allow(clippy::type_complexity)]
fn commit_quotient(
&self,
quotient_domain: Self::Domain,
quotient_evaluations: RowMajorMatrix<Val<Self::Domain>>,
num_chunks: usize,
) -> (Self::Commitment, Self::ProverData) {
let quotient_sub_evaluations =
quotient_domain.split_evals(num_chunks, quotient_evaluations);
let quotient_sub_domains = quotient_domain.split_domains(num_chunks);
let ldes = self.get_quotient_ldes(
quotient_sub_domains
.into_iter()
.zip(quotient_sub_evaluations),
num_chunks,
);
self.commit_ldes(ldes)
}
fn get_quotient_ldes(
&self,
evaluations: impl IntoIterator<Item = (Self::Domain, RowMajorMatrix<Val<Self::Domain>>)>,
num_chunks: usize,
) -> Vec<RowMajorMatrix<Val<Self::Domain>>>;
fn commit_ldes(
&self,
ldes: Vec<RowMajorMatrix<Val<Self::Domain>>>,
) -> (Self::Commitment, Self::ProverData);
fn commit_preprocessing(
&self,
evaluations: impl IntoIterator<Item = (Self::Domain, RowMajorMatrix<Val<Self::Domain>>)>,
) -> (Self::Commitment, Self::ProverData) {
self.commit(evaluations)
}
fn get_evaluations_on_domain<'a>(
&self,
prover_data: &'a Self::ProverData,
idx: usize,
domain: Self::Domain,
) -> Self::EvaluationsOnDomain<'a>;
fn get_evaluations_on_domain_no_random<'a>(
&self,
prover_data: &'a Self::ProverData,
idx: usize,
domain: Self::Domain,
) -> Self::EvaluationsOnDomain<'a> {
self.get_evaluations_on_domain(prover_data, idx, domain)
}
fn open(
&self,
commitment_data_with_opening_points: Vec<(
// The matrices and auxiliary prover data
&Self::ProverData,
// for each matrix,
Vec<
Vec<Challenge>,
>,
)>,
fiat_shamir_challenger: &mut Challenger,
) -> (OpenedValues<Challenge>, Self::Proof);
#[allow(clippy::type_complexity)]
fn open_with_preprocessing(
&self,
rounds: Vec<(&Self::ProverData, Vec<Vec<Challenge>>)>,
challenger: &mut Challenger,
_is_preprocessing: bool,
) -> (OpenedValues<Challenge>, Self::Proof) {
self.open(rounds, challenger)
}
#[allow(clippy::type_complexity)]
fn verify(
&self,
commitments_with_opening_points: Vec<(
// The commitment
Self::Commitment,
// for each matrix in the commitment:
Vec<(
// its domain,
Self::Domain,
// A vector of (point, claimed_evaluation) pairs
Vec<(
// the point the matrix was opened at,
Challenge,
// the claimed evaluations at that point
Vec<Challenge>,
)>,
)>,
)>,
proof: &Self::Proof,
fiat_shamir_challenger: &mut Challenger,
) -> Result<(), Self::Error>;
fn get_opt_randomization_poly_commitment(
&self,
_domains: impl IntoIterator<Item = Self::Domain>,
) -> Option<(Self::Commitment, Self::ProverData)> {
None
}
}
pub type OpenedValues<F> = Vec<OpenedValuesForRound<F>>;
pub type OpenedValuesForRound<F> = Vec<OpenedValuesForMatrix<F>>;
pub type OpenedValuesForMatrix<F> = Vec<OpenedValuesForPoint<F>>;
pub type OpenedValuesForPoint<F> = Vec<F>;