Skip to content

Commit

Permalink
Merge pull request #6 from davxy/extendend-with-te
Browse files Browse the repository at this point in the history
Cond Add extendend with TE
  • Loading branch information
davxy authored Nov 2, 2024
2 parents 86e3ce0 + 6e45942 commit 5e9ba2d
Show file tree
Hide file tree
Showing 24 changed files with 1,116 additions and 514 deletions.
52 changes: 35 additions & 17 deletions common/src/domain.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use ark_ff::{batch_inversion, FftField, Zero};
use ark_poly::{DenseUVPolynomial, EvaluationDomain, Evaluations, GeneralEvaluationDomain, Polynomial};
use ark_poly::univariate::DensePolynomial;
use ark_poly::{
DenseUVPolynomial, EvaluationDomain, Evaluations, GeneralEvaluationDomain, Polynomial,
};
use ark_std::{vec, vec::Vec};

use crate::FieldColumn;
Expand All @@ -16,8 +18,10 @@ struct Domains<F: FftField> {

impl<F: FftField> Domains<F> {
fn new(n: usize) -> Self {
let x1 = GeneralEvaluationDomain::<F>::new(n).unwrap_or_else(|| panic!("No domain of size {}", n));
let x4 = GeneralEvaluationDomain::<F>::new(4 * n).unwrap_or_else(|| panic!("No domain of size {}", 4 * n));
let x1 = GeneralEvaluationDomain::<F>::new(n)
.unwrap_or_else(|| panic!("No domain of size {}", n));
let x4 = GeneralEvaluationDomain::<F>::new(4 * n)
.unwrap_or_else(|| panic!("No domain of size {}", 4 * n));
Self { x1, x4 }
}

Expand All @@ -26,15 +30,25 @@ impl<F: FftField> Domains<F> {
let evals = Evaluations::from_vec_and_domain(evals, self.x1);
let poly = evals.interpolate_by_ref();
let evals_4x = poly.evaluate_over_domain_by_ref(self.x4);
FieldColumn { len, poly, evals, evals_4x }
FieldColumn {
len,
poly,
evals,
evals_4x,
}
}

fn column_from_poly(&self, poly: DensePolynomial<F>, len: usize) -> FieldColumn<F> {
assert!(poly.degree() < self.x1.size());
let evals_4x = self.amplify(&poly);
let evals = evals_4x.evals.iter().step_by(4).cloned().collect();
let evals = Evaluations::from_vec_and_domain(evals, self.x1);
FieldColumn { len, poly, evals, evals_4x }
FieldColumn {
len,
poly,
evals,
evals_4x,
}
}

// Amplifies the number of the evaluations of the polynomial so it can be multiplied in linear time.
Expand Down Expand Up @@ -81,13 +95,12 @@ impl<F: FftField> Domain<F> {
}
}

pub(crate) fn divide_by_vanishing_poly<>(
&self,
poly: &DensePolynomial<F>,
) -> DensePolynomial<F> {
pub(crate) fn divide_by_vanishing_poly(&self, poly: &DensePolynomial<F>) -> DensePolynomial<F> {
let (quotient, remainder) = if self.hiding {
let exclude_zk_rows = poly * self.zk_rows_vanishing_poly.as_ref().unwrap();
exclude_zk_rows.divide_by_vanishing_poly(self.domains.x1).unwrap() //TODO error-handling
exclude_zk_rows
.divide_by_vanishing_poly(self.domains.x1)
.unwrap() //TODO error-handling
} else {
poly.divide_by_vanishing_poly(self.domains.x1).unwrap() //TODO error-handling
};
Expand All @@ -100,7 +113,9 @@ impl<F: FftField> Domain<F> {
assert!(len <= self.capacity);
if self.hiding && hidden && !cfg!(feature = "test-vectors") {
evals.resize(self.capacity, F::zero());
evals.resize_with(self.domains.x1.size(), || F::rand(&mut getrandom_or_panic::getrandom_or_panic()));
evals.resize_with(self.domains.x1.size(), || {
F::rand(&mut getrandom_or_panic::getrandom_or_panic())
});
} else {
evals.resize(self.domains.x1.size(), F::zero());
}
Expand Down Expand Up @@ -132,7 +147,10 @@ fn l_i<F: FftField>(i: usize, n: usize) -> Vec<F> {
}

// (x - w^i)
fn vanishes_on_row<F: FftField>(i: usize, domain: GeneralEvaluationDomain<F>) -> DensePolynomial<F> {
fn vanishes_on_row<F: FftField>(
i: usize,
domain: GeneralEvaluationDomain<F>,
) -> DensePolynomial<F> {
assert!(i < domain.size());
let w = domain.group_gen();
let wi = w.pow(&[i as u64]);
Expand Down Expand Up @@ -202,10 +220,7 @@ impl<F: FftField> EvaluatedDomain<F> {
}
}

pub(crate) fn divide_by_vanishing_poly_in_zeta<>(
&self,
poly_in_zeta: F,
) -> F {
pub(crate) fn divide_by_vanishing_poly_in_zeta(&self, poly_in_zeta: F) -> F {
poly_in_zeta * self.vanishing_polynomial_inv
}

Expand All @@ -232,7 +247,10 @@ mod tests {
let domain_eval = EvaluatedDomain::new(domain.domain(), z, hiding);
assert_eq!(domain.l_first.poly.evaluate(&z), domain_eval.l_first);
assert_eq!(domain.l_last.poly.evaluate(&z), domain_eval.l_last);
assert_eq!(domain.not_last_row.poly.evaluate(&z), domain_eval.not_last_row);
assert_eq!(
domain.not_last_row.poly.evaluate(&z),
domain_eval.not_last_row
);
}

#[test]
Expand Down
15 changes: 5 additions & 10 deletions common/src/gadgets/booleanity.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
use ark_ff::{FftField, Field, Zero};
use ark_poly::{Evaluations, GeneralEvaluationDomain};
use ark_poly::univariate::DensePolynomial;
use ark_poly::{Evaluations, GeneralEvaluationDomain};
use ark_std::{vec, vec::Vec};

use crate::{Column, const_evals, FieldColumn};
use crate::domain::Domain;
use crate::gadgets::VerifierGadget;
use crate::{const_evals, Column, FieldColumn};

#[derive(Clone)]
pub struct BitColumn<F: FftField> {
pub bits: Vec<bool>,
pub col: FieldColumn<F>,
}


impl<F: FftField> BitColumn<F> {
pub fn init(bits: Vec<bool>, domain: &Domain<F>) -> Self {
let bits_as_field_elements = bits.iter()
let bits_as_field_elements = bits
.iter()
.map(|&b| if b { F::one() } else { F::zero() })
.collect();
let col = domain.private_column(bits_as_field_elements);
Self { bits, col }
}
}


impl<F: FftField> Column<F> for BitColumn<F> {
fn domain(&self) -> GeneralEvaluationDomain<F> {
self.col.domain()
Expand All @@ -39,12 +38,10 @@ impl<F: FftField> Column<F> for BitColumn<F> {
}
}


pub struct Booleanity<F: FftField> {
bits: BitColumn<F>,
}


impl<'a, F: FftField> Booleanity<F> {
pub fn init(bits: BitColumn<F>) -> Self {
Self { bits }
Expand All @@ -63,15 +60,13 @@ impl<'a, F: FftField> Booleanity<F> {
}
}


pub struct BooleanityValues<F: Field> {
pub bits: F,
}


impl<F: Field> VerifierGadget<F> for BooleanityValues<F> {
fn evaluate_constraints_main(&self) -> Vec<F> {
let c = self.bits * (F::one() - self.bits);
vec![c]
}
}
}
72 changes: 72 additions & 0 deletions common/src/gadgets/cond_add.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use ark_ec::AffineRepr;
use ark_ff::{FftField, Field};

use crate::domain::Domain;
use crate::gadgets::booleanity::BitColumn;
use crate::{AffineColumn, FieldColumn};

use super::{ProverGadget, VerifierGadget};

/// Affine point with conditional add implementation.
///
/// Currently supported for Arkworks Short Weierstrass and Twisted Edwards affine points.
pub trait AffineCondAdd: AffineRepr
where
FieldFor<Self>: FftField,
{
/// Conditional addition operation
type CondAddT: CondAdd<FieldFor<Self>, Self>;
}

// Conditional affine addition.
//
// If the bit is set for a point, add the point to the acc and store,
// otherwise copy the acc value
pub trait CondAdd<F, P>: ProverGadget<F>
where
F: FftField,
P: AffineRepr<BaseField = F>,
{
type Values: CondAddValues<F>;

fn init(bitmask: BitColumn<F>, points: AffineColumn<F, P>, seed: P, domain: &Domain<F>)
-> Self;

fn evaluate_assignment(&self, z: &F) -> Self::Values;

fn get_acc(&self) -> AffineColumn<F, P>;

fn get_result(&self) -> P;
}

pub trait CondAddValues<F>: VerifierGadget<F>
where
F: Field,
{
fn acc_coeffs_1(&self) -> (F, F);

fn acc_coeffs_2(&self) -> (F, F);

fn init(bitmask: F, points: (F, F), not_last: F, acc: (F, F)) -> Self;
}

type FieldFor<P> = <P as AffineRepr>::BaseField;

pub struct CondAddGen<P>
where
P: AffineRepr,
<P as AffineRepr>::BaseField: FftField,
{
pub(super) bitmask: BitColumn<FieldFor<P>>,
pub(super) points: AffineColumn<FieldFor<P>, P>,
pub(super) not_last: FieldColumn<FieldFor<P>>,
pub acc: AffineColumn<FieldFor<P>, P>,
pub result: P,
}

pub struct CondAddValuesGen<P: AffineRepr> {
pub bitmask: FieldFor<P>,
pub points: (FieldFor<P>, FieldFor<P>),
pub not_last: FieldFor<P>,
pub acc: (FieldFor<P>, FieldFor<P>),
}
20 changes: 12 additions & 8 deletions common/src/gadgets/fixed_cells.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use ark_ff::{FftField, Field, Zero};
use ark_poly::Evaluations;
use ark_poly::univariate::DensePolynomial;
use ark_poly::Evaluations;
use ark_std::{vec, vec::Vec};

use crate::{Column, const_evals, FieldColumn};
use crate::domain::Domain;
use crate::gadgets::VerifierGadget;
use crate::{const_evals, Column, FieldColumn};

pub struct FixedCells<F: FftField> {
col: FieldColumn<F>,
Expand All @@ -15,7 +15,6 @@ pub struct FixedCells<F: FftField> {
l_last: FieldColumn<F>,
}


pub struct FixedCellsValues<F: Field> {
pub col: F,
pub col_first: F,
Expand All @@ -24,15 +23,20 @@ pub struct FixedCellsValues<F: Field> {
pub l_last: F,
}


impl<F: FftField> FixedCells<F> {
pub fn init(col: FieldColumn<F>, domain: &Domain<F>) -> Self {
assert_eq!(col.len, domain.capacity);
let col_first = col.evals.evals[0];
let col_last = col.evals.evals[domain.capacity - 1];
let l_first = domain.l_first.clone();
let l_last = domain.l_last.clone();
Self { col, col_first, col_last, l_first, l_last }
Self {
col,
col_first,
col_last,
l_first,
l_last,
}
}

pub fn constraints(&self) -> Vec<Evaluations<F>> {
Expand All @@ -52,10 +56,10 @@ impl<F: FftField> FixedCells<F> {
}
}


impl<F: Field> VerifierGadget<F> for FixedCellsValues<F> {
fn evaluate_constraints_main(&self) -> Vec<F> {
let c = (self.col - self.col_first) * self.l_first + (self.col - self.col_last) * self.l_last;
let c =
(self.col - self.col_first) * self.l_first + (self.col - self.col_last) * self.l_last;
vec![c]
}
}
}
20 changes: 10 additions & 10 deletions common/src/gadgets/inner_prod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use ark_ff::{FftField, Field};
use ark_poly::{Evaluations, GeneralEvaluationDomain};
use ark_poly::univariate::DensePolynomial;
use ark_poly::{Evaluations, GeneralEvaluationDomain};
use ark_std::{vec, vec::Vec};

use crate::{Column, FieldColumn};
use crate::domain::Domain;
use crate::gadgets::{ProverGadget, VerifierGadget};
use crate::{Column, FieldColumn};

pub struct InnerProd<F: FftField> {
a: FieldColumn<F>,
Expand All @@ -21,7 +21,6 @@ pub struct InnerProdValues<F: Field> {
pub acc: F,
}


impl<F: FftField> InnerProd<F> {
pub fn init(a: FieldColumn<F>, b: FieldColumn<F>, domain: &Domain<F>) -> Self {
assert_eq!(a.len, domain.capacity - 1); // last element is not constrained
Expand All @@ -30,7 +29,12 @@ impl<F: FftField> InnerProd<F> {
let mut acc = vec![F::zero()];
acc.extend(inner_prods);
let acc = domain.private_column(acc);
Self { a, b, not_last: domain.not_last_row.clone(), acc }
Self {
a,
b,
not_last: domain.not_last_row.clone(),
acc,
}
}

/// Returns a[0]b[0], a[0]b[0] + a[1]b[1], ..., a[0]b[0] + a[1]b[1] + ... + a[n-1]b[n-1]
Expand Down Expand Up @@ -71,15 +75,13 @@ impl<F: FftField> ProverGadget<F> for InnerProd<F> {
}
}


impl<F: Field> VerifierGadget<F> for InnerProdValues<F> {
fn evaluate_constraints_main(&self) -> Vec<F> {
let c = (-self.acc - self.a * self.b) * self.not_last;
vec![c]
}
}


#[cfg(test)]
mod tests {
use ark_ed_on_bls12_381_bandersnatch::Fq;
Expand All @@ -94,9 +96,7 @@ mod tests {

fn inner_prod<F: Field>(a: &[F], b: &[F]) -> F {
assert_eq!(a.len(), b.len());
a.iter().zip(b)
.map(|(a, b)| *a * b)
.sum()
a.iter().zip(b).map(|(a, b)| *a * b).sum()
}

fn _test_inner_prod_gadget(hiding: bool) {
Expand Down Expand Up @@ -130,4 +130,4 @@ mod tests {
_test_inner_prod_gadget(false);
_test_inner_prod_gadget(true);
}
}
}
Loading

0 comments on commit 5e9ba2d

Please sign in to comment.