use super::{
query::{ProverQuery, VerifierQuery},
strategy::Guard,
Coeff, LagrangeCoeff, Polynomial,
};
use crate::poly::Error;
use crate::transcript::{EncodedChallenge, TranscriptRead, TranscriptWrite};
use halo2_middleware::ff::Field;
use halo2_middleware::zal::{impls::PlonkEngineConfig, traits::MsmAccel};
use halo2curves::CurveAffine;
use rand_core::RngCore;
use std::{
fmt::Debug,
io::{self},
ops::{Add, AddAssign, Mul, MulAssign},
};
pub trait CommitmentScheme {
type Scalar: Field;
type Curve: CurveAffine<ScalarExt = Self::Scalar>;
type ParamsProver: ParamsProver<Self::Curve>;
type ParamsVerifier: for<'params> ParamsVerifier<'params, Self::Curve>;
fn new_params(k: u32) -> Self::ParamsProver;
fn read_params<R: io::Read>(reader: &mut R) -> io::Result<Self::ParamsProver>;
}
pub trait Params<C: CurveAffine>: Sized + Clone + Debug {
fn k(&self) -> u32;
fn n(&self) -> u64;
fn downsize(&mut self, k: u32);
fn commit_lagrange(
&self,
engine: &impl MsmAccel<C>,
poly: &Polynomial<C::ScalarExt, LagrangeCoeff>,
r: Blind<C::ScalarExt>,
) -> C::CurveExt;
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()>;
fn read<R: io::Read>(reader: &mut R) -> io::Result<Self>;
}
pub trait ParamsProver<C: CurveAffine>: Params<C> {
fn new(k: u32) -> Self;
fn commit(
&self,
engine: &impl MsmAccel<C>,
poly: &Polynomial<C::ScalarExt, Coeff>,
r: Blind<C::ScalarExt>,
) -> C::CurveExt;
}
pub trait ParamsVerifier<'params, C: CurveAffine>: Params<C> {
type MSM: MSM<C> + 'params;
const COMMIT_INSTANCE: bool;
fn empty_msm(&'params self) -> Self::MSM;
}
pub trait MSM<C: CurveAffine>: Clone + Debug + Send + Sync {
fn append_term(&mut self, scalar: C::Scalar, point: C::CurveExt);
fn add_msm(&mut self, other: &Self)
where
Self: Sized;
fn scale(&mut self, factor: C::Scalar);
fn check(&self, engine: &impl MsmAccel<C>) -> bool;
fn eval(&self, engine: &impl MsmAccel<C>) -> C::CurveExt;
fn bases(&self) -> Vec<C::CurveExt>;
fn scalars(&self) -> Vec<C::Scalar>;
}
pub trait Prover<'params, Scheme: CommitmentScheme> {
fn new(params: &'params Scheme::ParamsProver) -> Self;
fn create_proof_with_engine<
'com,
E: EncodedChallenge<Scheme::Curve>,
T: TranscriptWrite<Scheme::Curve, E>,
R,
I,
>(
&self,
engine: &impl MsmAccel<Scheme::Curve>,
rng: R,
transcript: &mut T,
queries: I,
) -> io::Result<()>
where
I: IntoIterator<Item = ProverQuery<'com, Scheme::Curve>> + Clone,
R: RngCore;
fn create_proof<
'com,
E: EncodedChallenge<Scheme::Curve>,
T: TranscriptWrite<Scheme::Curve, E>,
R,
I,
>(
&self,
rng: R,
transcript: &mut T,
queries: I,
) -> io::Result<()>
where
I: IntoIterator<Item = ProverQuery<'com, Scheme::Curve>> + Clone,
R: RngCore,
{
let engine = PlonkEngineConfig::build_default::<Scheme::Curve>();
self.create_proof_with_engine(&engine.msm_backend, rng, transcript, queries)
}
}
pub trait Verifier<'params, Scheme: CommitmentScheme> {
type Guard: Guard<Scheme, MSMAccumulator = Self::MSMAccumulator>;
type MSMAccumulator;
fn new() -> Self;
fn verify_proof<
'com,
E: EncodedChallenge<Scheme::Curve>,
T: TranscriptRead<Scheme::Curve, E>,
I,
>(
&self,
transcript: &mut T,
queries: I,
msm: Self::MSMAccumulator,
) -> Result<Self::Guard, Error>
where
'params: 'com,
I: IntoIterator<
Item = VerifierQuery<
'com,
Scheme::Curve,
<Scheme::ParamsVerifier as ParamsVerifier<'params, Scheme::Curve>>::MSM,
>,
> + Clone;
}
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct Blind<F>(pub F);
impl<F: Field> Default for Blind<F> {
fn default() -> Self {
Blind(F::ONE)
}
}
impl<F: Field> Blind<F> {
pub fn new<R: RngCore>(rng: &mut R) -> Self {
Blind(F::random(rng))
}
}
impl<F: Field> Add for Blind<F> {
type Output = Self;
fn add(self, rhs: Blind<F>) -> Self {
Blind(self.0 + rhs.0)
}
}
impl<F: Field> Mul for Blind<F> {
type Output = Self;
fn mul(self, rhs: Blind<F>) -> Self {
Blind(self.0 * rhs.0)
}
}
impl<F: Field> AddAssign for Blind<F> {
fn add_assign(&mut self, rhs: Blind<F>) {
self.0 += rhs.0;
}
}
impl<F: Field> MulAssign for Blind<F> {
fn mul_assign(&mut self, rhs: Blind<F>) {
self.0 *= rhs.0;
}
}
impl<F: Field> AddAssign<F> for Blind<F> {
fn add_assign(&mut self, rhs: F) {
self.0 += rhs;
}
}
impl<F: Field> MulAssign<F> for Blind<F> {
fn mul_assign(&mut self, rhs: F) {
self.0 *= rhs;
}
}