use alloc::vec;
use alloc::vec::Vec;
use core::fmt::Debug;
use p3_matrix::dense::RowMajorMatrix;
use p3_matrix::{Dimensions, Matrix};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
pub trait Mmcs<T: Send + Sync + Clone>: Clone {
type ProverData<M>;
type Commitment: Clone + Serialize + DeserializeOwned;
type Proof: Clone + Serialize + DeserializeOwned;
type Error: Debug;
fn commit<M: Matrix<T>>(&self, inputs: Vec<M>) -> (Self::Commitment, Self::ProverData<M>);
fn commit_matrix<M: Matrix<T>>(&self, input: M) -> (Self::Commitment, Self::ProverData<M>) {
self.commit(vec![input])
}
fn commit_vec(&self, input: Vec<T>) -> (Self::Commitment, Self::ProverData<RowMajorMatrix<T>>)
where
T: Clone + Send + Sync,
{
self.commit_matrix(RowMajorMatrix::new_col(input))
}
fn open_batch<M: Matrix<T>>(
&self,
index: usize,
prover_data: &Self::ProverData<M>,
) -> BatchOpening<T, Self>;
fn get_matrices<'a, M: Matrix<T>>(&self, prover_data: &'a Self::ProverData<M>) -> Vec<&'a M>;
fn get_matrix_heights<M: Matrix<T>>(&self, prover_data: &Self::ProverData<M>) -> Vec<usize> {
self.get_matrices(prover_data)
.iter()
.map(|matrix| matrix.height())
.collect()
}
fn get_max_height<M: Matrix<T>>(&self, prover_data: &Self::ProverData<M>) -> usize {
self.get_matrix_heights(prover_data)
.into_iter()
.max()
.unwrap_or_else(|| panic!("No committed matrices?"))
}
fn verify_batch(
&self,
commit: &Self::Commitment,
dimensions: &[Dimensions],
index: usize,
batch_opening: BatchOpeningRef<T, Self>,
) -> Result<(), Self::Error>;
}
#[derive(Serialize, Deserialize, Clone)]
#[serde(bound(serialize = "T: Serialize"))]
#[serde(bound(deserialize = "T: DeserializeOwned"))]
pub struct BatchOpening<T: Send + Sync + Clone, InputMmcs: Mmcs<T>> {
pub opened_values: Vec<Vec<T>>,
pub opening_proof: InputMmcs::Proof,
}
impl<T: Send + Sync + Clone, InputMmcs: Mmcs<T>> BatchOpening<T, InputMmcs> {
#[inline]
pub fn new(opened_values: Vec<Vec<T>>, opening_proof: InputMmcs::Proof) -> Self {
Self {
opened_values,
opening_proof,
}
}
#[inline]
pub fn unpack(self) -> (Vec<Vec<T>>, InputMmcs::Proof) {
(self.opened_values, self.opening_proof)
}
}
#[derive(Copy, Clone)]
pub struct BatchOpeningRef<'a, T: Send + Sync + Clone, InputMmcs: Mmcs<T>> {
pub opened_values: &'a [Vec<T>],
pub opening_proof: &'a InputMmcs::Proof,
}
impl<'a, T: Send + Sync + Clone, InputMmcs: Mmcs<T>> BatchOpeningRef<'a, T, InputMmcs> {
#[inline]
pub fn new(opened_values: &'a [Vec<T>], opening_proof: &'a InputMmcs::Proof) -> Self {
Self {
opened_values,
opening_proof,
}
}
#[inline]
pub fn unpack(&self) -> (&'a [Vec<T>], &'a InputMmcs::Proof) {
(self.opened_values, self.opening_proof)
}
}
impl<'a, T: Send + Sync + Clone, InputMmcs: Mmcs<T>> From<&'a BatchOpening<T, InputMmcs>>
for BatchOpeningRef<'a, T, InputMmcs>
{
#[inline]
fn from(batch_opening: &'a BatchOpening<T, InputMmcs>) -> Self {
Self::new(&batch_opening.opened_values, &batch_opening.opening_proof)
}
}