mirror of
https://github.com/logos-storage/dynamic-data-experiments.git
synced 2026-04-18 00:33:07 +00:00
improve the kzg commitment
This commit is contained in:
parent
6daf47889f
commit
7242c37107
263
src/kzg.rs
263
src/kzg.rs
@ -1,263 +0,0 @@
|
|||||||
use ark_ff::{One, PrimeField};
|
|
||||||
use std::ops::{Add, AddAssign};
|
|
||||||
use ark_poly::univariate::DensePolynomial;
|
|
||||||
use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain};
|
|
||||||
use ark_poly_commit::{
|
|
||||||
PolynomialCommitment,
|
|
||||||
LabeledPolynomial,
|
|
||||||
LabeledCommitment,
|
|
||||||
marlin_pc::{ Commitment, Randomness},
|
|
||||||
};
|
|
||||||
use ark_std::{end_timer, start_timer, test_rng};
|
|
||||||
use anyhow::{anyhow, Result};
|
|
||||||
use ark_bls12_381::Bls12_381;
|
|
||||||
use ark_crypto_primitives::sponge::CryptographicSponge;
|
|
||||||
use ark_ec::CurveGroup;
|
|
||||||
use ark_ec::pairing::Pairing;
|
|
||||||
use ark_poly_commit::marlin_pc::MarlinKZG10;
|
|
||||||
use ark_poly_commit::sonic_pc::UniversalParams;
|
|
||||||
use crate::byte_data::Params;
|
|
||||||
use crate::field_matrix::Matrix;
|
|
||||||
use crate::traits::{PolynomialCommitmentScheme, DataMatrix};
|
|
||||||
use ark_crypto_primitives::sponge::poseidon::{PoseidonSponge, PoseidonConfig};
|
|
||||||
use ark_poly_commit::kzg10::Proof;
|
|
||||||
|
|
||||||
pub type E = Bls12_381;
|
|
||||||
pub type F = <E as Pairing>::ScalarField;
|
|
||||||
pub type UniPoly381 = DensePolynomial<F>;
|
|
||||||
pub type PCS = MarlinKZG10<E, UniPoly381>;
|
|
||||||
|
|
||||||
pub struct KZGSRS{
|
|
||||||
pub ploycommit_domain: GeneralEvaluationDomain<F>,
|
|
||||||
pub pp: UniversalParams<E>
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct KZGPolyComm{
|
|
||||||
params: Params,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PolynomialCommitmentScheme for KZGPolyComm {
|
|
||||||
type Params = Params;
|
|
||||||
type Field = F;
|
|
||||||
type FieldMatrix<F> = Matrix<Self::Field>;
|
|
||||||
type SRS = KZGSRS;
|
|
||||||
type Commitment = KZGCommitments;
|
|
||||||
type Proof = Proof<E>;
|
|
||||||
|
|
||||||
fn new(params: Params) -> Self{
|
|
||||||
Self{
|
|
||||||
params,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setup(&self) -> Result<Self::SRS> {
|
|
||||||
let rng = &mut test_rng();
|
|
||||||
let pp = PCS::setup(self.params.m,None, rng)?;
|
|
||||||
let ploycommit_domain = EvaluationDomain::<F>::new(self.params.m).ok_or(anyhow!("polycommit domain error"))?;
|
|
||||||
Ok(KZGSRS{
|
|
||||||
ploycommit_domain,
|
|
||||||
pp,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn commit(&self, srs: &Self::SRS, matrix: &Self::FieldMatrix<F>) -> Result<Self::Commitment> {
|
|
||||||
let rng = &mut test_rng();
|
|
||||||
let degree = self.params.m;
|
|
||||||
let (ck, _vk) = PCS::trim(&srs.pp, degree, degree, Some(&[degree]))?;
|
|
||||||
let mut row_polynomials = vec![];
|
|
||||||
let timer = start_timer!(|| format!("Poly evaluations and interpolation for {} rows", degree));
|
|
||||||
for i in 0..matrix.params.n{
|
|
||||||
let row = matrix.get_row(i)?.to_vec();
|
|
||||||
let poly_evals = Evaluations::from_vec_and_domain(row, srs.ploycommit_domain.clone());
|
|
||||||
let row_poly = poly_evals.interpolate();
|
|
||||||
let label = String::from(format!("row_poly_{}", i));
|
|
||||||
let labeled_poly = LabeledPolynomial::new(
|
|
||||||
label,
|
|
||||||
row_poly,
|
|
||||||
Some(degree),
|
|
||||||
Some(degree),
|
|
||||||
);
|
|
||||||
row_polynomials.push(labeled_poly);
|
|
||||||
}
|
|
||||||
end_timer!(timer);
|
|
||||||
let timer = start_timer!(|| format!("KZG commitment for {} columns", degree));
|
|
||||||
let (labeled_comms, states) = PCS::commit(&ck, &row_polynomials, Some(rng)).unwrap();
|
|
||||||
end_timer!(timer);
|
|
||||||
Ok(
|
|
||||||
KZGCommitments::new(row_polynomials, labeled_comms, states)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn open(comms: &Self::Commitment, srs: &Self::SRS, row: usize, col: usize) -> Result<Self::Proof> {
|
|
||||||
// point
|
|
||||||
let z = srs.ploycommit_domain.element(col);
|
|
||||||
|
|
||||||
// trim the srs
|
|
||||||
let m = srs.ploycommit_domain.size();
|
|
||||||
let (ck, _vk) = PCS::trim(&srs.pp, m, m, Some(&[m]))?;
|
|
||||||
|
|
||||||
let (polys, comms_vec, states) = comms.get_refs();
|
|
||||||
let poly = &polys[row];
|
|
||||||
let commit = &comms_vec[row];
|
|
||||||
let state = &states[row];
|
|
||||||
|
|
||||||
let mut sponge = test_sponge::<F>();
|
|
||||||
|
|
||||||
let proof = PCS::open(
|
|
||||||
&ck,
|
|
||||||
std::iter::once(poly),
|
|
||||||
std::iter::once(commit),
|
|
||||||
&z,
|
|
||||||
&mut sponge,
|
|
||||||
&mut std::iter::once(state),
|
|
||||||
None,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(proof)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn batch_open(_: &Self::Commitment, _: &Self::SRS, _rows: Vec<usize>, _cols: Vec<usize>) -> Result<Vec<Self::Proof>> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn verify(
|
|
||||||
comms: &Self::Commitment,
|
|
||||||
srs: &Self::SRS,
|
|
||||||
row: usize,
|
|
||||||
col: usize,
|
|
||||||
value: F,
|
|
||||||
proof: &Self::Proof,
|
|
||||||
) -> Result<bool> {
|
|
||||||
let z = srs.ploycommit_domain.element(col);
|
|
||||||
|
|
||||||
let m = srs.ploycommit_domain.size();
|
|
||||||
let (_ck, vk) = PCS::trim(&srs.pp, m, m, Some(&[m]))?;
|
|
||||||
|
|
||||||
// get labeled commitment
|
|
||||||
let (_polys, commits, _states) = comms.get_refs();
|
|
||||||
let commit = &commits[row];
|
|
||||||
|
|
||||||
let mut sponge = test_sponge::<F>();
|
|
||||||
Ok( PCS::check(
|
|
||||||
&vk,
|
|
||||||
std::iter::once(commit),
|
|
||||||
&z,
|
|
||||||
std::iter::once(value),
|
|
||||||
proof,
|
|
||||||
&mut sponge,
|
|
||||||
None,
|
|
||||||
)? )
|
|
||||||
}
|
|
||||||
|
|
||||||
fn batch_verify(_comms: &Self::Commitment, _srs: &Self::SRS, _rows: Vec<usize>, _cols: Vec<usize>, _values: Vec<F>, _proof: &Vec<Self::Proof>) -> Result<bool> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_commitments(
|
|
||||||
srs: &KZGSRS,
|
|
||||||
comm: &mut KZGCommitments,
|
|
||||||
row_idx: usize,
|
|
||||||
old_row: &[F],
|
|
||||||
new_row: &[F],
|
|
||||||
) -> Result<()> {
|
|
||||||
|
|
||||||
let n = comm.poly.len();
|
|
||||||
let domain = &srs.ploycommit_domain;
|
|
||||||
let m = domain.size();
|
|
||||||
let (ck, _vk) = PCS::trim(&srs.pp, m, 2, Some(&[m]))?;
|
|
||||||
// Bounds and length checks
|
|
||||||
assert!(row_idx < n, "row_idx {} out of bounds ({} rows)", row_idx, n);
|
|
||||||
assert_eq!(old_row.len(), m, "old_row must have length {}", m);
|
|
||||||
assert_eq!(new_row.len(), m, "new_row must have length {}", m);
|
|
||||||
|
|
||||||
let deltas: Vec<F> = old_row.iter()
|
|
||||||
.zip(new_row.iter())
|
|
||||||
.map(|(o, n)| *n - *o)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let delta_poly: DensePolynomial<F> =
|
|
||||||
Evaluations::from_vec_and_domain(deltas, domain.clone())
|
|
||||||
.interpolate();
|
|
||||||
|
|
||||||
let label = format!("row_diff_{}", row_idx);
|
|
||||||
let labeled = LabeledPolynomial::new(label, delta_poly.clone(), Some(m), None);
|
|
||||||
let rng = &mut test_rng();
|
|
||||||
let (diff_comms, diff_rands) = PCS::commit(&ck, std::iter::once(&labeled), Some(rng))?;
|
|
||||||
let diff_comm = &diff_comms[0];
|
|
||||||
let diff_rand = &diff_rands[0];
|
|
||||||
|
|
||||||
let f_row = comm.poly[row_idx].polynomial_mut();
|
|
||||||
f_row.add_assign(&delta_poly);
|
|
||||||
|
|
||||||
let mut cmt = comm.comm[row_idx].commitment().clone();
|
|
||||||
let main_patch = diff_comm.commitment().comm.0;
|
|
||||||
cmt.comm.0 = cmt.comm.0.add(&main_patch).into_affine();
|
|
||||||
if let (Some(mut shifted), Some(diff_shifted)) = (
|
|
||||||
cmt.shifted_comm.clone(),
|
|
||||||
diff_comm.commitment().shifted_comm.clone(),
|
|
||||||
) {
|
|
||||||
shifted.0 = shifted.0.add(&diff_shifted.0).into_affine();
|
|
||||||
cmt.shifted_comm = Some(shifted);
|
|
||||||
}
|
|
||||||
let lbl = comm.comm[row_idx].label().to_string();
|
|
||||||
let dgb = comm.comm[row_idx].degree_bound();
|
|
||||||
comm.comm[row_idx] = LabeledCommitment::new(lbl, cmt, dgb);
|
|
||||||
|
|
||||||
comm.rand[row_idx].add_assign((F::one(), diff_rand));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_sponge<F: PrimeField>() -> PoseidonSponge<F> {
|
|
||||||
let full_rounds = 8;
|
|
||||||
let partial_rounds = 31;
|
|
||||||
let alpha = 17;
|
|
||||||
|
|
||||||
let mds = vec![
|
|
||||||
vec![F::one(), F::zero(), F::one()],
|
|
||||||
vec![F::one(), F::one(), F::zero()],
|
|
||||||
vec![F::zero(), F::one(), F::one()],
|
|
||||||
];
|
|
||||||
|
|
||||||
let mut v = Vec::new();
|
|
||||||
let mut ark_rng = test_rng();
|
|
||||||
|
|
||||||
for _ in 0..(full_rounds + partial_rounds) {
|
|
||||||
let mut res = Vec::new();
|
|
||||||
|
|
||||||
for _ in 0..3 {
|
|
||||||
res.push(F::rand(&mut ark_rng));
|
|
||||||
}
|
|
||||||
v.push(res);
|
|
||||||
}
|
|
||||||
let config = PoseidonConfig::new(full_rounds, partial_rounds, alpha, mds, v, 2, 1);
|
|
||||||
PoseidonSponge::new(&config)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct KZGCommitments{
|
|
||||||
pub poly: Vec<LabeledPolynomial<F, UniPoly381>>,
|
|
||||||
pub comm: Vec<LabeledCommitment<Commitment<E>>>,
|
|
||||||
pub rand: Vec<Randomness<F, UniPoly381>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl KZGCommitments {
|
|
||||||
pub fn new(
|
|
||||||
poly: Vec<LabeledPolynomial<F, UniPoly381>>,
|
|
||||||
comm: Vec<LabeledCommitment<Commitment<E>>>,
|
|
||||||
rand: Vec<Randomness<F, UniPoly381>>,
|
|
||||||
) -> Self{
|
|
||||||
Self{
|
|
||||||
poly,
|
|
||||||
comm,
|
|
||||||
rand,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn get_refs(&self) ->(
|
|
||||||
&Vec<LabeledPolynomial<F, UniPoly381>>,
|
|
||||||
&Vec<LabeledCommitment<Commitment<E>>>,
|
|
||||||
&Vec<Randomness<F, UniPoly381>>,
|
|
||||||
){
|
|
||||||
(&self.poly, &self.comm, &self.rand)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
233
src/kzg10.rs
Normal file
233
src/kzg10.rs
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
use ark_poly::univariate::DensePolynomial;
|
||||||
|
use ark_poly::{DenseUVPolynomial, EvaluationDomain, GeneralEvaluationDomain};
|
||||||
|
use ark_poly_commit::{
|
||||||
|
LabeledPolynomial,
|
||||||
|
};
|
||||||
|
use ark_std::test_rng;
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
|
use ark_bls12_381::Bls12_381;
|
||||||
|
use ark_ec::pairing::Pairing;
|
||||||
|
use ark_ec::{AffineRepr, CurveGroup};
|
||||||
|
use ark_ff::{PrimeField, Zero};
|
||||||
|
use crate::traits::{CommitOutputTrait, PolyCommScheme, SRSTrait};
|
||||||
|
use ark_poly_commit::kzg10::{KZG10, Proof, UniversalParams, Powers, VerifierKey, Commitment, Randomness};
|
||||||
|
|
||||||
|
pub type E = Bls12_381;
|
||||||
|
pub type F = <E as Pairing>::ScalarField;
|
||||||
|
pub type UniPoly381 = DensePolynomial<F>;
|
||||||
|
pub type PCS = KZG10<E, UniPoly381>;
|
||||||
|
|
||||||
|
pub struct KZG10SRS {
|
||||||
|
pub poly_domain: GeneralEvaluationDomain<F>,
|
||||||
|
pub pp: UniversalParams<E>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SRSTrait<F> for KZG10SRS{
|
||||||
|
type PP = UniversalParams<E>;
|
||||||
|
type Domain = GeneralEvaluationDomain<F>;
|
||||||
|
|
||||||
|
fn get_pp(&self) -> &Self::PP {
|
||||||
|
&self.pp
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_domain(&self) -> &Self::Domain {
|
||||||
|
&self.poly_domain
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_domain_element(&self, idx:usize) -> F {
|
||||||
|
self.poly_domain.element(idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_domain_size(&self) -> usize{
|
||||||
|
self.poly_domain.size()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct KZG10PolyComm {}
|
||||||
|
|
||||||
|
pub struct KZG10CommitOutput {
|
||||||
|
pub poly: LabeledPolynomial<F, UniPoly381>,
|
||||||
|
pub comm: Commitment<E>,
|
||||||
|
pub rand: Randomness<F, UniPoly381>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KZG10CommitOutput {
|
||||||
|
pub fn new(
|
||||||
|
poly: LabeledPolynomial<F, UniPoly381>,
|
||||||
|
comm: Commitment<E>,
|
||||||
|
rand: Randomness<F, UniPoly381>,
|
||||||
|
) -> Self{
|
||||||
|
Self{
|
||||||
|
poly,
|
||||||
|
comm,
|
||||||
|
rand,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl CommitOutputTrait for KZG10CommitOutput {
|
||||||
|
type Poly = LabeledPolynomial<F, UniPoly381>;
|
||||||
|
type Comm = Commitment<E>;
|
||||||
|
type Rand = Randomness<F, UniPoly381>;
|
||||||
|
|
||||||
|
fn get_poly(&self) -> &LabeledPolynomial<F, UniPoly381>{
|
||||||
|
&self.poly
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_comm(&self) -> &Commitment<E>{
|
||||||
|
&self.comm
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_rand(&self) -> &Randomness<F, UniPoly381>{
|
||||||
|
&self.rand
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KZG10PolyComm{
|
||||||
|
fn commit_single(srs: &KZG10SRS, input: F, index: usize) -> Result<Commitment<E>> {
|
||||||
|
let power = &srs.pp.powers_of_g[index];
|
||||||
|
|
||||||
|
let c = power.mul_bigint(input.into_bigint());
|
||||||
|
|
||||||
|
Ok(
|
||||||
|
Commitment::<E>(c.into_affine())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PolyCommScheme<F> for KZG10PolyComm {
|
||||||
|
type SRS = KZG10SRS;
|
||||||
|
type VK = VerifierKey<E>;
|
||||||
|
type CommitOutput = KZG10CommitOutput;
|
||||||
|
type Comm = Commitment<E>;
|
||||||
|
type Proof = Proof<E>;
|
||||||
|
|
||||||
|
fn setup(degree: usize) -> Result<Self::SRS> {
|
||||||
|
let rng = &mut test_rng();
|
||||||
|
let pp = PCS::setup(degree,false, rng)?;
|
||||||
|
let poly_domain = EvaluationDomain::<F>::new(degree).ok_or(anyhow!("polycommit domain error"))?;
|
||||||
|
Ok(KZG10SRS {
|
||||||
|
poly_domain,
|
||||||
|
pp,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn commit(srs: &Self::SRS, input: Vec<F>) -> Result<Self::CommitOutput> {
|
||||||
|
let rng = &mut test_rng();
|
||||||
|
let degree = srs.poly_domain.size();
|
||||||
|
let powers = get_powers(&srs.pp, degree)?;
|
||||||
|
|
||||||
|
// input are poly coeffs
|
||||||
|
let input_poly = DensePolynomial::<F>::from_coefficients_vec(input);
|
||||||
|
let label = String::from("row_poly");
|
||||||
|
let labeled_poly = LabeledPolynomial::new(
|
||||||
|
label,
|
||||||
|
input_poly,
|
||||||
|
Some(degree),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
let (comm, rand) = PCS::commit(&powers, &labeled_poly, None, Some(rng))?;
|
||||||
|
|
||||||
|
Ok(
|
||||||
|
KZG10CommitOutput::new(labeled_poly, comm, rand)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_commitment(srs: &Self::SRS, original_comm: &mut Self::CommitOutput, original_cell: F, new_cell:F, index: usize) -> Result<()> {
|
||||||
|
// check if there is difference,
|
||||||
|
if new_cell.clone() - original_cell.clone() == F::zero() {
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// commit to original and new cells
|
||||||
|
let original_cell_comm = Self::commit_single(srs, original_cell, index)?;
|
||||||
|
let new_cell_comm = Self::commit_single(srs, new_cell.clone(), index)?;
|
||||||
|
|
||||||
|
// compute delta
|
||||||
|
let delta_comm = (new_cell_comm.0-original_cell_comm.0).into_affine();
|
||||||
|
// update the commitment
|
||||||
|
let mut tmp = original_comm.comm.0.clone().into_group();
|
||||||
|
tmp += &delta_comm;
|
||||||
|
original_comm.comm.0 = tmp.into_affine();
|
||||||
|
// update the poly
|
||||||
|
let original_poly = original_comm.poly.polynomial_mut();
|
||||||
|
original_poly.coeffs[index] = new_cell;
|
||||||
|
// no update to rand because we assume it is empty i.e. no hiding
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn open(
|
||||||
|
comm: &KZG10CommitOutput,
|
||||||
|
srs: &KZG10SRS,
|
||||||
|
point: F,
|
||||||
|
) -> Result<Self::Proof> {
|
||||||
|
|
||||||
|
// powers from the srs
|
||||||
|
let m = srs.poly_domain.size();
|
||||||
|
let powers= get_powers(&srs.pp, m)?;
|
||||||
|
|
||||||
|
// get row poly and rand
|
||||||
|
let poly = &comm.poly;
|
||||||
|
let rand = &comm.rand;
|
||||||
|
|
||||||
|
let proof = PCS::open(
|
||||||
|
&powers,
|
||||||
|
poly,
|
||||||
|
point,
|
||||||
|
rand,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(proof)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn verify(
|
||||||
|
vk: &Self::VK,
|
||||||
|
comm: &Self::Comm,
|
||||||
|
point: F,
|
||||||
|
value: F,
|
||||||
|
proof: &Self::Proof,
|
||||||
|
) -> Result<bool> {
|
||||||
|
|
||||||
|
Ok( PCS::check(
|
||||||
|
&vk,
|
||||||
|
comm,
|
||||||
|
point,
|
||||||
|
value,
|
||||||
|
proof,
|
||||||
|
)? )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- Utils -----------------
|
||||||
|
|
||||||
|
/// get `degree` number of powers from the universal params
|
||||||
|
fn get_powers(
|
||||||
|
pp: &UniversalParams<E>,
|
||||||
|
degree: usize,
|
||||||
|
) -> Result<Powers<E>> {
|
||||||
|
let powers_of_g = pp.powers_of_g[..=degree].to_vec();
|
||||||
|
let powers_of_gamma_g = (0..=degree)
|
||||||
|
.map(|i| pp.powers_of_gamma_g[&i])
|
||||||
|
.collect();
|
||||||
|
let powers = Powers {
|
||||||
|
powers_of_g: ark_std::borrow::Cow::Owned(powers_of_g),
|
||||||
|
powers_of_gamma_g: ark_std::borrow::Cow::Owned(powers_of_gamma_g),
|
||||||
|
};
|
||||||
|
Ok(powers)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_vk(
|
||||||
|
pp: &UniversalParams<E>,
|
||||||
|
) -> Result<VerifierKey<E>> {
|
||||||
|
let vk = VerifierKey {
|
||||||
|
g: pp.powers_of_g[0],
|
||||||
|
gamma_g: pp.powers_of_gamma_g[&0],
|
||||||
|
h: pp.h,
|
||||||
|
beta_h: pp.beta_h,
|
||||||
|
prepared_h: pp.prepared_h.clone(),
|
||||||
|
prepared_beta_h: pp.prepared_beta_h.clone(),
|
||||||
|
};
|
||||||
|
Ok(vk)
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
pub mod byte_data;
|
pub mod byte_data;
|
||||||
pub mod kzg;
|
|
||||||
pub mod field_matrix;
|
pub mod field_matrix;
|
||||||
pub mod test;
|
pub mod test;
|
||||||
pub mod traits;
|
pub mod traits;
|
||||||
pub mod encoder;
|
pub mod encoder;
|
||||||
|
pub mod kzg10;
|
||||||
|
pub mod matrix_commit;
|
||||||
87
src/matrix_commit.rs
Normal file
87
src/matrix_commit.rs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
use std::marker::PhantomData;
|
||||||
|
use anyhow::Result;
|
||||||
|
use ark_ff::Field;
|
||||||
|
use crate::field_matrix::Matrix;
|
||||||
|
use crate::traits::{MatrixPolyCommScheme, DataMatrix, PolyCommScheme, SRSTrait, MatrixCommitOutput};
|
||||||
|
|
||||||
|
|
||||||
|
pub struct MatrixPolyComm<F, P: PolyCommScheme<F>> {
|
||||||
|
phantom_data: PhantomData<(F,P)>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: Field + Clone, P: PolyCommScheme<F>> MatrixPolyCommScheme<F, P> for MatrixPolyComm<F, P> {
|
||||||
|
type FieldMatrix = Matrix<F>;
|
||||||
|
|
||||||
|
/// setup takes `m`=`number of columns` in the matrix
|
||||||
|
fn setup(m: usize) -> Result<P::SRS> {
|
||||||
|
P::setup(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn commit(srs: &P::SRS, matrix: &Self::FieldMatrix) -> Result<MatrixCommitOutput<F, P>> {
|
||||||
|
|
||||||
|
let mut row_comm_output = vec![];
|
||||||
|
for i in 0..matrix.params.n{
|
||||||
|
let row = matrix.get_row(i)?;
|
||||||
|
let output = P::commit(srs,row)?;
|
||||||
|
row_comm_output.push(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(
|
||||||
|
MatrixCommitOutput::new(row_comm_output)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// updates the row commitments after updating/modifying columns
|
||||||
|
/// since the data DataMatrix should only allow column updates
|
||||||
|
/// and since we commit to rows
|
||||||
|
/// this means we update all row commitments that are affected by the data matrix update
|
||||||
|
fn update_commitments(
|
||||||
|
srs: &P::SRS,
|
||||||
|
comm: &mut MatrixCommitOutput<F, P>,
|
||||||
|
col_idx: usize,
|
||||||
|
old_col: &[F],
|
||||||
|
new_col: &[F],
|
||||||
|
) -> Result<()> {
|
||||||
|
// check input is consistent
|
||||||
|
assert_eq!(old_col.len(), new_col.len(), "col sizes don't match");
|
||||||
|
assert_eq!(srs.get_domain_size(), new_col.len(), "domain size is incorrect");
|
||||||
|
|
||||||
|
// loop through all new_col elements to see if there is an update at each cell
|
||||||
|
// if there is, then update the commitment
|
||||||
|
for r in 0..new_col.len(){
|
||||||
|
let original_cell: F = old_col[r].clone();
|
||||||
|
let new_cell: F = new_col[r].clone();
|
||||||
|
P::update_commitment(srs, &mut comm.comm_output[r], original_cell, new_cell, col_idx)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn open(comm: &MatrixCommitOutput<F, P>, srs: &P::SRS, row: usize, col: usize) -> Result<P::Proof> {
|
||||||
|
// the point we want to open
|
||||||
|
let point = srs.get_domain_element(col);
|
||||||
|
|
||||||
|
let proof = P::open(&comm.comm_output[row], srs, point)?;
|
||||||
|
|
||||||
|
Ok(proof)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn verify(
|
||||||
|
vk: &P::VK,
|
||||||
|
comm: &P::Comm,
|
||||||
|
point: F,
|
||||||
|
value: F,
|
||||||
|
proof: &P::Proof,
|
||||||
|
) -> Result<bool> {
|
||||||
|
|
||||||
|
Ok( P::verify(
|
||||||
|
&vk,
|
||||||
|
comm,
|
||||||
|
point,
|
||||||
|
value,
|
||||||
|
proof,
|
||||||
|
)? )
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
135
src/traits.rs
135
src/traits.rs
@ -1,3 +1,4 @@
|
|||||||
|
use std::marker::PhantomData;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use crate::byte_data::Params;
|
use crate::byte_data::Params;
|
||||||
|
|
||||||
@ -26,51 +27,109 @@ pub trait Encoder<T>{
|
|||||||
fn reconstruct(params: Params, matrix_opts: &mut Vec<Option<Vec<T>>>) -> Result<()>;
|
fn reconstruct(params: Params, matrix_opts: &mut Vec<Option<Vec<T>>>) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait CommitOutputTrait {
|
||||||
|
type Poly;
|
||||||
|
type Comm;
|
||||||
|
type Rand;
|
||||||
|
|
||||||
|
fn get_poly(&self) -> &Self::Poly;
|
||||||
|
|
||||||
|
fn get_comm(&self) -> &Self::Comm;
|
||||||
|
|
||||||
|
fn get_rand(&self) -> &Self::Rand;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SRSTrait<F>{
|
||||||
|
// public/universal params
|
||||||
|
type PP;
|
||||||
|
// domain type
|
||||||
|
type Domain;
|
||||||
|
|
||||||
|
fn get_pp(&self) -> &Self::PP;
|
||||||
|
fn get_domain(&self) -> &Self::Domain;
|
||||||
|
fn get_domain_element(&self, idx: usize) -> F;
|
||||||
|
fn get_domain_size(&self) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
/// Polynomial Commitment scheme (e.g. KZG) trait
|
/// Polynomial Commitment scheme (e.g. KZG) trait
|
||||||
pub trait PolynomialCommitmentScheme{
|
pub trait PolyCommScheme<F>{
|
||||||
type Params;
|
type SRS: SRSTrait<F>;
|
||||||
type Field;
|
type VK;
|
||||||
type FieldMatrix<F>;
|
type CommitOutput: CommitOutputTrait;
|
||||||
type SRS;
|
type Comm;
|
||||||
type Commitment;
|
|
||||||
type Proof;
|
type Proof;
|
||||||
|
|
||||||
fn new(_params: Self::Params) -> Self;
|
fn setup(degree: usize) -> Result<Self::SRS>;
|
||||||
fn setup(&self) -> Result<Self::SRS>;
|
fn commit(srs: &Self::SRS, input:Vec<F>) -> Result<Self::CommitOutput>;
|
||||||
fn commit(&self, _srs: &Self::SRS, _matrix:&Self::FieldMatrix<Self::Field>) -> Result<Self::Commitment>;
|
fn update_commitment(srs: &Self::SRS, original_comm: &mut Self::CommitOutput, original_cell: F, new_cell:F, index: usize) -> Result<()>;
|
||||||
fn update_commitments(
|
|
||||||
srs: &Self::SRS,
|
|
||||||
comm: &mut Self::Commitment,
|
|
||||||
row_idx: usize,
|
|
||||||
old_row: &[Self::Field],
|
|
||||||
new_row: &[Self::Field],
|
|
||||||
) -> Result<()>;
|
|
||||||
fn open(
|
fn open(
|
||||||
_: &Self::Commitment,
|
comm: &Self::CommitOutput,
|
||||||
_: &Self::SRS,
|
srs: &Self::SRS,
|
||||||
_row: usize,
|
point: F
|
||||||
_col: usize,
|
|
||||||
) -> Result<Self::Proof>;
|
) -> Result<Self::Proof>;
|
||||||
fn batch_open(
|
|
||||||
_: &Self::Commitment,
|
|
||||||
_: &Self::SRS,
|
|
||||||
_rows: Vec<usize>,
|
|
||||||
_cols: Vec<usize>,
|
|
||||||
) -> Result<Vec<Self::Proof>>;
|
|
||||||
fn verify(
|
fn verify(
|
||||||
comms: &Self::Commitment,
|
vk: &Self::VK,
|
||||||
srs: &Self::SRS,
|
comm: &Self::Comm,
|
||||||
row: usize,
|
point: F,
|
||||||
col: usize,
|
value: F,
|
||||||
value: Self::Field,
|
|
||||||
proof: &Self::Proof,
|
proof: &Self::Proof,
|
||||||
) -> Result<bool>;
|
) -> Result<bool>;
|
||||||
fn batch_verify(
|
}
|
||||||
comms: &Self::Commitment,
|
|
||||||
srs: &Self::SRS,
|
/// Polynomial Commitment scheme for a field Matrix
|
||||||
rows: Vec<usize>,
|
/// it commits to the rows of the Matrix
|
||||||
cols: Vec<usize>,
|
/// and allows updating the row commitments
|
||||||
values: Vec<Self::Field>,
|
pub trait MatrixPolyCommScheme<F, P:PolyCommScheme<F>>{
|
||||||
proof: &Vec<Self::Proof>,
|
type FieldMatrix: DataMatrix<F>;
|
||||||
|
|
||||||
|
fn setup(m: usize) -> Result<P::SRS>;
|
||||||
|
fn commit(srs: &P::SRS, matrix:&Self::FieldMatrix) -> Result<MatrixCommitOutput<F, P>>;
|
||||||
|
fn update_commitments(
|
||||||
|
srs: &P::SRS,
|
||||||
|
comm: &mut MatrixCommitOutput<F, P>,
|
||||||
|
col_idx: usize,
|
||||||
|
old_col: &[F],
|
||||||
|
new_col: &[F],
|
||||||
|
) -> Result<()>;
|
||||||
|
fn open(
|
||||||
|
comm: &MatrixCommitOutput<F, P>,
|
||||||
|
srs: &P::SRS,
|
||||||
|
row: usize,
|
||||||
|
col: usize,
|
||||||
|
) -> Result<P::Proof>;
|
||||||
|
fn verify(
|
||||||
|
vk: &P::VK,
|
||||||
|
comm: &P::Comm,
|
||||||
|
point: F,
|
||||||
|
value: F,
|
||||||
|
proof: &P::Proof,
|
||||||
) -> Result<bool>;
|
) -> Result<bool>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MatrixCommitOutput<F, P: PolyCommScheme<F>> {
|
||||||
|
pub comm_output: Vec<P::CommitOutput>,
|
||||||
|
phantom_data: PhantomData<F>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, P: PolyCommScheme<F>> MatrixCommitOutput<F, P> {
|
||||||
|
pub fn new(
|
||||||
|
comm_output: Vec<P::CommitOutput>
|
||||||
|
) -> Self{
|
||||||
|
Self{
|
||||||
|
comm_output,
|
||||||
|
phantom_data:PhantomData::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_poly(&self, idx: usize) -> &<P::CommitOutput as CommitOutputTrait>::Poly{
|
||||||
|
&self.comm_output[idx].get_poly()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_comm(&self, idx: usize) -> &<P::CommitOutput as CommitOutputTrait>::Comm{
|
||||||
|
&self.comm_output[idx].get_comm()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_rand(&self, idx: usize) -> &<P::CommitOutput as CommitOutputTrait>::Rand{
|
||||||
|
&self.comm_output[idx].get_rand()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user