use ark_ff::PrimeField;
use ark_poly::Evaluations;
use ark_serialize::*;
use ark_std::fmt::Debug;
use ark_std::iter::Sum;
use ark_std::ops::{Add, Mul, Sub};
use ark_std::rand::Rng;
use ark_std::vec::Vec;
pub use id::IdentityCommitment;
use crate::Poly;
mod id;
pub mod kzg;
pub trait Commitment<F: PrimeField>:
Eq
+ Sized
+ Clone
+ Debug
+ Add<Self, Output = Self>
+ Mul<F, Output = Self>
+ Sub<Self, Output = Self>
+ Sum<Self>
+ CanonicalSerialize
+ CanonicalDeserialize
{
fn mul(&self, by: F) -> Self;
fn combine(coeffs: &[F], commitments: &[Self]) -> Self;
}
pub trait CommitterKey: Clone + Debug + CanonicalSerialize + CanonicalDeserialize {
fn max_degree(&self) -> usize;
fn max_evals(&self) -> usize {
self.max_degree() + 1
}
}
pub trait VerifierKey: Clone + Debug {
fn max_points(&self) -> usize {
1
}
}
pub trait RawVerifierKey:
Clone + Debug + Eq + PartialEq + CanonicalSerialize + CanonicalDeserialize
{
type VK: VerifierKey;
fn prepare(&self) -> Self::VK;
}
pub trait PcsParams {
type CK: CommitterKey;
type VK: VerifierKey;
type RVK: RawVerifierKey<VK = Self::VK>;
fn ck(&self) -> Self::CK;
fn vk(&self) -> Self::VK;
fn raw_vk(&self) -> Self::RVK;
fn ck_with_lagrangian(&self, _domain_size: usize) -> Self::CK {
unimplemented!();
}
}
pub trait PCS<F: PrimeField> {
type C: Commitment<F>;
type Proof: Clone + CanonicalSerialize + CanonicalDeserialize;
type CK: CommitterKey;
type VK: VerifierKey + Into<Self::CK>;
type Params: PcsParams<CK = Self::CK, VK = Self::VK>;
fn setup<R: Rng>(max_degree: usize, rng: &mut R) -> Self::Params;
fn commit(ck: &Self::CK, p: &Poly<F>) -> Result<Self::C, ()>;
fn commit_evals(ck: &Self::CK, evals: &Evaluations<F>) -> Result<Self::C, ()> {
let poly = evals.interpolate_by_ref();
Self::commit(ck, &poly)
}
fn open(ck: &Self::CK, p: &Poly<F>, x: F) -> Result<Self::Proof, ()>;
fn verify(vk: &Self::VK, c: Self::C, x: F, z: F, proof: Self::Proof) -> Result<(), ()>;
fn batch_verify<R: Rng>(
vk: &Self::VK,
c: Vec<Self::C>,
x: Vec<F>,
y: Vec<F>,
proof: Vec<Self::Proof>,
_rng: &mut R,
) -> Result<(), ()> {
assert_eq!(c.len(), x.len());
assert_eq!(c.len(), y.len());
c.into_iter()
.zip(x.into_iter())
.zip(y.into_iter())
.zip(proof.into_iter())
.all(|(((c, x), y), proof)| Self::verify(vk, c, x, y, proof).is_ok())
.then(|| ())
.ok_or(())
}
}