use crate::{
errors::SpartanError,
traits::{Engine, TranscriptReprTrait},
};
use core::fmt::Debug;
use ff::Field;
use serde::{Deserialize, Serialize};
pub trait CommitmentTrait<E: Engine>:
Clone
+ Debug
+ PartialEq
+ Eq
+ Send
+ Sync
+ TranscriptReprTrait<E::GE>
+ Serialize
+ for<'de> Deserialize<'de>
{
}
pub trait PCSEngineTrait<E: Engine>: Clone + Send + Sync {
type CommitmentKey: Clone + Debug + Send + Sync + Serialize + for<'de> Deserialize<'de>;
type VerifierKey: Clone + Send + Sync + Serialize + for<'de> Deserialize<'de>;
type Commitment: CommitmentTrait<E>;
type Blind: Clone + Debug + Send + Sync + PartialEq + Eq + Serialize + for<'de> Deserialize<'de>;
type EvaluationArgument: Clone + Debug + Send + Sync + Serialize + for<'de> Deserialize<'de>;
fn setup(
label: &'static [u8],
n: usize,
width: usize,
) -> (Self::CommitmentKey, Self::VerifierKey);
fn precompute_ck(_ck: &Self::CommitmentKey) {}
fn blind(ck: &Self::CommitmentKey, n: usize) -> Self::Blind;
fn commit(
ck: &Self::CommitmentKey,
v: &[E::Scalar],
r: &Self::Blind,
is_small: bool,
) -> Result<Self::Commitment, SpartanError>;
fn commit_zeros(
ck: &Self::CommitmentKey,
n: usize,
r: &Self::Blind,
) -> Result<Self::Commitment, SpartanError> {
let zeros = vec![E::Scalar::ZERO; n];
Self::commit(ck, &zeros, r, true)
}
fn check_commitment(comm: &Self::Commitment, n: usize, width: usize) -> Result<(), SpartanError>;
fn rerandomize_commitment(
ck: &Self::CommitmentKey,
comm: &Self::Commitment,
r_old: &Self::Blind,
r_new: &Self::Blind,
) -> Result<Self::Commitment, SpartanError>;
fn combine_commitments(comms: &[Self::Commitment]) -> Result<Self::Commitment, SpartanError>;
fn combine_blinds(blinds: &[Self::Blind]) -> Result<Self::Blind, SpartanError>;
fn prove(
ck: &Self::CommitmentKey,
ck_eval: &Self::CommitmentKey,
transcript: &mut E::TE,
comm: &Self::Commitment,
poly: &[E::Scalar],
blind: &Self::Blind,
point: &[E::Scalar],
comm_eval: &Self::Commitment,
blind_eval: &Self::Blind,
) -> Result<Self::EvaluationArgument, SpartanError>;
fn verify(
vk: &Self::VerifierKey,
ck_eval: &Self::CommitmentKey,
transcript: &mut E::TE,
comm: &Self::Commitment,
point: &[E::Scalar],
comm_eval: &Self::Commitment,
arg: &Self::EvaluationArgument,
) -> Result<(), SpartanError>;
fn commit_without_blind(
_ck: &Self::CommitmentKey,
_v: &[E::Scalar],
_is_small: bool,
) -> Result<Vec<E::GE>, SpartanError> {
Err(SpartanError::InternalError {
reason: "commit_without_blind not supported for this PCS".to_string(),
})
}
fn commit_incremental(
_ck: &Self::CommitmentKey,
_raw: &[E::GE],
_delta: &[E::Scalar],
_blind: &Self::Blind,
) -> Result<Self::Commitment, SpartanError> {
Err(SpartanError::InternalError {
reason: "commit_incremental not supported for this PCS".to_string(),
})
}
fn prove_direct(
_ck: &Self::CommitmentKey,
_poly: &[E::Scalar],
_blind: &Self::Blind,
_point: &[E::Scalar],
) -> Result<(Vec<E::Scalar>, E::Scalar), SpartanError> {
Err(SpartanError::InternalError {
reason: "prove_direct not supported for this PCS".to_string(),
})
}
fn verify_direct(
_vk: &Self::VerifierKey,
_comm: &Self::Commitment,
_v: &[E::Scalar],
_combined_blind: &E::Scalar,
_point: &[E::Scalar],
) -> Result<E::Scalar, SpartanError> {
Err(SpartanError::InternalError {
reason: "verify_direct not supported for this PCS".to_string(),
})
}
}
pub trait FoldingEngineTrait<E: Engine>: PCSEngineTrait<E> {
fn fold_commitments(
comms: &[Self::Commitment],
weights: &[E::Scalar],
) -> Result<Self::Commitment, SpartanError>;
fn fold_blinds(
blinds: &[Self::Blind],
weights: &[E::Scalar],
) -> Result<Self::Blind, SpartanError>;
fn fold_commitments_partial(
comms: &[Self::Commitment],
weights: &[E::Scalar],
_num_data_rows: usize,
_folded_blind: &Self::Blind,
_ck: &Self::CommitmentKey,
) -> Result<Self::Commitment, SpartanError> {
Self::fold_commitments(comms, weights)
}
}