Skip to content

Commit 107de0b

Browse files
authored
Merge pull request #87 from paritytech/refactoring-1
Refactoring 1
2 parents ea8ff08 + 2185b5a commit 107de0b

15 files changed

Lines changed: 251 additions & 146 deletions

File tree

pasta-tree/src/lib.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -170,27 +170,21 @@ mod tests {
170170
use ark_ff::{BigInteger, Field, Zero};
171171
use ark_pallas::PallasConfig;
172172
use ark_poly::DenseUVPolynomial;
173-
use ark_std::iterable::Iterable;
174173
use ark_std::rand::Rng;
175174
use ark_std::{UniformRand, cfg_iter_mut, end_timer, start_timer, test_rng};
176175
use ark_vesta::VestaConfig;
177176
use w3f_pcs::Poly;
178177
use w3f_pcs::pcs::PCS;
179178
use w3f_pcs::pcs::PcsParams;
180-
use w3f_pcs::pcs::commitment::WrappedAffine;
181179
use w3f_pcs::pcs::ipa::IPA;
182-
use w3f_plonk_common::piop::ProverPiop;
183180
use w3f_plonk_common::test_helpers::random_vec;
184-
use w3f_ring_proof::PiopParams;
185181

186182
use crate::auth_path::node::LevelWitness;
187183
use crate::auth_path::path::AuthenticationPath;
188184
#[cfg(feature = "parallel")]
189185
use rayon::prelude::*;
190-
use w3f_plonk_common::domain::Domain;
191186

192187
type PallasIPA = IPA<ark_pallas::Projective>;
193-
type PallasC = WrappedAffine<ark_pallas::Projective>;
194188

195189
fn random_witness<C: CurveGroup, G: AffineRepr<BaseField = C::ScalarField>, R: Rng>(
196190
params: &CycleSideParams<C, G>,
@@ -258,17 +252,6 @@ mod tests {
258252
(leaf, path, root)
259253
}
260254

261-
fn setup<R: Rng, CS: PCS<G::BaseField>, G: AffineRepr<BaseField: PrimeField>>(
262-
rng: &mut R,
263-
domain_size: usize,
264-
) -> (CS::Params, PiopParams<G>) {
265-
let setup_degree = 3 * domain_size;
266-
let pcs_params = CS::setup(setup_degree, rng);
267-
let domain = Domain::new(domain_size, true);
268-
let piop_params = PiopParams::setup(domain, G::rand(rng), G::rand(rng), G::rand(rng));
269-
(pcs_params, piop_params)
270-
}
271-
272255
fn _test_proof<F0, F1, C0, C1>(log_n: usize, height: usize)
273256
where
274257
F0: PrimeField,

w3f-plonk-common/benches/plonk_common.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ fn bench_field_column(c: &mut Criterion) {
4949
},
5050
);
5151

52-
let col = domain.private_column(vals);
52+
let col = domain.column(vals);
5353
group.bench_with_input(BenchmarkId::new("shifted_4x", n), &col, |b, col| {
5454
b.iter(|| col.shifted_4x());
5555
});
@@ -99,8 +99,8 @@ fn bench_inner_prod_gadget(c: &mut Criterion) {
9999
},
100100
);
101101

102-
let a_col = domain.private_column(a);
103-
let b_col = domain.private_column(b_vals);
102+
let a_col = domain.column(a);
103+
let b_col = domain.column(b_vals);
104104
let gadget = InnerProd::<Fq>::init(a_col, b_col, &domain);
105105

106106
group.bench_with_input(
@@ -140,14 +140,14 @@ fn bench_te_cond_add_gadget(c: &mut Criterion) {
140140
|bench, (bitmask, points, domain)| {
141141
bench.iter(|| {
142142
let bitmask_col = BitColumn::init(bitmask.clone(), domain);
143-
let points_col = AffineColumn::private_column(points.clone(), domain);
143+
let points_col = AffineColumn::column(points.clone(), domain);
144144
CondAdd::init(bitmask_col, points_col, seed, domain);
145145
});
146146
},
147147
);
148148

149149
let bitmask_col = BitColumn::init(bitmask, &domain);
150-
let points_col = AffineColumn::private_column(points, &domain);
150+
let points_col = AffineColumn::column(points, &domain);
151151
let gadget = CondAdd::init(bitmask_col, points_col, seed, &domain);
152152

153153
group.bench_with_input(

w3f-plonk-common/src/domain.rs

Lines changed: 117 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::FieldColumn;
2-
use ark_ff::{batch_inversion, FftField, Zero};
2+
use ark_ff::{batch_inversion, FftField, Field, Zero};
33
use ark_poly::univariate::DensePolynomial;
44
use ark_poly::{
55
DenseUVPolynomial, EvaluationDomain, Evaluations, GeneralEvaluationDomain, Polynomial,
@@ -60,90 +60,105 @@ impl<F: FftField> Domains<F> {
6060
#[derive(Clone)]
6161
pub struct Domain<F: FftField> {
6262
pub domains: Domains<F>,
63-
pub hiding: bool,
63+
pub zk_rows: usize,
6464
pub capacity: usize,
6565
pub not_last_row: FieldColumn<F>,
6666
pub l_first: FieldColumn<F>,
6767
pub l_last: FieldColumn<F>,
68-
zk_rows_vanishing_poly: Option<DensePolynomial<F>>,
68+
zk_rows_prod: DensePolynomial<F>,
6969
}
7070

7171
impl<F: FftField> Domain<F> {
7272
pub fn new(n: usize, hiding: bool) -> Self {
73+
if hiding {
74+
Self::with_zk_rows(n, ZK_ROWS)
75+
} else {
76+
Self::with_zk_rows(n, 0)
77+
}
78+
}
79+
80+
pub fn with_zk_rows(n: usize, zk_rows: usize) -> Self {
7381
let domains = Domains::new(n);
7482
let domain_size = domains.x1.size();
75-
let domain_capacity = if hiding {
76-
domain_size - ZK_ROWS
77-
} else {
78-
domain_size
79-
};
80-
let last_row_index = domain_capacity - 1;
83+
let capacity = domain_size - zk_rows;
84+
let last_row_index = capacity - 1;
8185

8286
let l_first = l_i(0, domain_size);
8387
let l_first = domains.column_from_evals(l_first, 0);
8488
let l_last = l_i(last_row_index, domain_size);
8589
let l_last = domains.column_from_evals(l_last, 0);
86-
let not_last_row = vanishes_on_row(last_row_index, domains.x1);
87-
let not_last_row = domains.column_from_poly(not_last_row);
8890

89-
let zk_rows_vanishing_poly = hiding.then(|| vanishes_on_last_3_rows(domains.x1));
91+
let (zk_rows_prod, last_row) = compute_row_polys(domains.x1, zk_rows).unwrap();
92+
let not_last_row = domains.column_from_poly(last_row);
9093

9194
Self {
9295
domains,
93-
hiding,
94-
capacity: domain_capacity,
96+
zk_rows,
97+
capacity,
9598
not_last_row,
9699
l_first,
97100
l_last,
98-
zk_rows_vanishing_poly,
101+
zk_rows_prod,
99102
}
100103
}
101104

102-
pub fn divide_by_vanishing_poly(&self, poly: &DensePolynomial<F>) -> DensePolynomial<F> {
103-
let (quotient, remainder) = if self.hiding {
104-
let exclude_zk_rows = poly * self.zk_rows_vanishing_poly.as_ref().unwrap();
105-
exclude_zk_rows.divide_by_vanishing_poly(self.domains.x1)
105+
pub fn is_hiding(&self) -> bool {
106+
self.zk_rows != 0
107+
}
108+
109+
pub fn compute_quotient(&self, poly: &DensePolynomial<F>) -> Option<DensePolynomial<F>> {
110+
let (q, r) = self.div_by_z_with_remainder(poly);
111+
r.is_zero().then_some(q)
112+
}
113+
114+
fn div_by_z_with_remainder(
115+
&self,
116+
p: &DensePolynomial<F>,
117+
) -> (DensePolynomial<F>, DensePolynomial<F>) {
118+
let dividend = if self.is_hiding() {
119+
&(p * &self.zk_rows_prod)
106120
} else {
107-
poly.divide_by_vanishing_poly(self.domains.x1)
121+
p
108122
};
109-
assert!(remainder.is_zero()); //TODO error-handling
110-
quotient
123+
dividend.divide_by_vanishing_poly(self.domains.x1)
111124
}
112125

113-
pub(crate) fn column(&self, mut values: Vec<F>, hidden: bool) -> FieldColumn<F> {
126+
fn _column(&self, mut values: Vec<F>, public: bool) -> FieldColumn<F> {
114127
let payload_len = values.len();
115-
debug_assert!(payload_len <= self.capacity);
116-
values.resize(self.capacity, F::zero());
117-
if self.hiding && hidden && !cfg!(feature = "test-vectors") {
118-
values.resize_with(
119-
self.domains.x1.size(),
120-
|| F::rand(&mut getrandom_or_panic()),
121-
);
128+
assert!(payload_len <= self.capacity);
129+
let no_blinding = !self.is_hiding() || public || cfg!(feature = "test-vectors");
130+
if no_blinding {
131+
values.resize(self.domain_size(), F::zero());
122132
} else {
123-
values.resize(self.domains.x1.size(), F::zero());
133+
values.resize(self.capacity, F::zero());
134+
let rng = &mut getrandom_or_panic();
135+
values.resize_with(self.domain_size(), || F::rand(rng));
124136
}
125137
self.domains.column_from_evals(values, payload_len)
126138
}
127139

128-
pub fn private_column(&self, values: Vec<F>) -> FieldColumn<F> {
129-
self.column(values, true)
140+
pub fn column(&self, values: Vec<F>) -> FieldColumn<F> {
141+
self._column(values, false)
130142
}
131143

132-
// public column
133-
pub fn public_column(&self, evals: Vec<F>) -> FieldColumn<F> {
134-
self.column(evals, false)
135-
}
136-
137-
pub fn omega(&self) -> F {
138-
self.domains.x1.group_gen()
144+
pub fn public_column(&self, values: Vec<F>) -> FieldColumn<F> {
145+
self._column(values, true)
139146
}
140147

141148
pub fn domain(&self) -> GeneralEvaluationDomain<F> {
142149
self.domains.x1
143150
}
144151

152+
pub fn domain_size(&self) -> usize {
153+
self.domain().size()
154+
}
155+
156+
pub fn omega(&self) -> F {
157+
self.domain().group_gen()
158+
}
159+
145160
pub fn evaluate(&self, zeta: F) -> EvaluatedDomain<F> {
146-
EvaluatedDomain::new(self.domain(), zeta, self.hiding)
161+
EvaluatedDomain::new(self.domain(), zeta, self.zk_rows)
147162
}
148163
}
149164

@@ -153,30 +168,35 @@ fn l_i<F: FftField>(i: usize, n: usize) -> Vec<F> {
153168
l_i
154169
}
155170

156-
// (x - w^i)
157-
fn vanishes_on_row<F: FftField>(
158-
i: usize,
159-
domain: GeneralEvaluationDomain<F>,
160-
) -> DensePolynomial<F> {
161-
assert!(i < domain.size());
162-
let w = domain.group_gen();
163-
let wi = w.pow(&[i as u64]);
164-
let wi = DensePolynomial::from_coefficients_slice(&[wi]);
165-
let x = DensePolynomial::from_coefficients_slice(&[F::zero(), F::one()]);
166-
&x - &wi
171+
/// For the generator `w = domain.group_gen()` of a domain of size `N`, returns `w^{N-1}, w^{N-2}, ..., w^0 = 1`.
172+
fn elements_rev<F: FftField, D: EvaluationDomain<F>>(domain: D) -> impl Iterator<Item = F> {
173+
let w_inv = domain.group_gen_inv();
174+
debug_assert_eq!(w_inv * domain.group_gen(), F::one()); // w^{n-1} = w^{-1}
175+
ark_std::iter::successors(Some(w_inv), move |wi| (!wi.is_one()).then(|| w_inv * wi))
176+
}
177+
178+
/// `Z(c) = X - c`
179+
fn z<F: Field>(c: F) -> DensePolynomial<F> {
180+
DensePolynomial::from_coefficients_vec(vec![-c, F::one()])
181+
}
182+
183+
fn one<F: Field>() -> DensePolynomial<F> {
184+
DensePolynomial::from_coefficients_vec(vec![F::one()])
167185
}
168186

169-
// (x - w^{n - 3}) * (x - w^{n - 2}) * (x - w^{n - 1})
170-
fn vanishes_on_last_3_rows<F: FftField>(domain: GeneralEvaluationDomain<F>) -> DensePolynomial<F> {
171-
let w = domain.group_gen();
172-
let n3 = (domain.size() - ZK_ROWS) as u64;
173-
let w3 = w.pow(&[n3]);
174-
let w2 = w3 * w;
175-
let w1 = w2 * w;
176-
assert_eq!(w1, domain.group_gen_inv());
177-
let x = DensePolynomial::from_coefficients_slice(&[F::zero(), F::one()]); // X
178-
let c = |a: F| DensePolynomial::from_coefficients_slice(&[a]);
179-
&(&(&x - &c(w3)) * &(&x - &c(w2))) * &(&x - &c(w1))
187+
/// For a domain of size `N`, returns `(Z(X), (X - w^{N - zk_rows - 1}))`,
188+
/// where `Z(X) = (X - w^{N-1}) * (X - w^{N-2}) * ... * (X - w^{N - zk_rows})`.
189+
fn compute_row_polys<F: FftField, D: EvaluationDomain<F>>(
190+
domain: D,
191+
zk_rows: usize,
192+
) -> Option<(DensePolynomial<F>, DensePolynomial<F>)> {
193+
if domain.size() < zk_rows + 1 {
194+
return None;
195+
}
196+
let mut wis = elements_rev(domain).map(|wi| z(wi));
197+
let zk_rows_prod = wis.by_ref().take(zk_rows).fold(one(), |acc, x| acc * x);
198+
let last_row = wis.by_ref().next().unwrap();
199+
Some((zk_rows_prod, last_row))
180200
}
181201

182202
pub struct EvaluatedDomain<F: FftField> {
@@ -188,8 +208,7 @@ pub struct EvaluatedDomain<F: FftField> {
188208
}
189209

190210
impl<F: FftField> EvaluatedDomain<F> {
191-
pub fn new(domain: GeneralEvaluationDomain<F>, z: F, hiding: bool) -> Self {
192-
let k = if hiding { ZK_ROWS } else { 0 };
211+
pub fn new(domain: GeneralEvaluationDomain<F>, z: F, zk_rows: usize) -> Self {
193212
let mut z_n = z; // z^n, n=2^d - domain size, so squarings only
194213
for _ in 0..domain.log_size_of_group() {
195214
z_n.square_in_place();
@@ -200,15 +219,15 @@ impl<F: FftField> EvaluatedDomain<F> {
200219
let mut wi = domain.group_gen_inv();
201220
// Vanishing polynomial of zk rows: prod = (z - w^{n-1})...(z - w^{n-k})
202221
let mut prod = F::one();
203-
for _ in 0..k {
222+
for _ in 0..zk_rows {
204223
prod *= z - wi;
205224
wi *= domain.group_gen_inv();
206225
}
207226
// z - w^{n-(k+1)}}
208227
let not_last_row = z - wi;
209228

210229
// w^{k+1}
211-
let wj = domain.group_gen().pow([(k + 1) as u64]);
230+
let wj = domain.group_gen().pow([(zk_rows + 1) as u64]);
212231

213232
let mut inv = [z_n_minus_one, z - F::one(), wj * z - F::one()];
214233
batch_inversion(&mut inv);
@@ -238,12 +257,12 @@ impl<F: FftField> EvaluatedDomain<F> {
238257

239258
#[cfg(test)]
240259
mod tests {
260+
use super::*;
241261
use ark_ed_on_bls12_381_bandersnatch::Fq;
242-
use ark_poly::Polynomial;
262+
use ark_ff::One;
263+
use ark_poly::Radix2EvaluationDomain;
243264
use ark_std::{test_rng, UniformRand};
244265

245-
use crate::domain::Domain;
246-
247266
fn _test_evaluated_domain(hiding: bool) {
248267
let rng = &mut test_rng();
249268

@@ -260,6 +279,34 @@ mod tests {
260279
);
261280
}
262281

282+
#[test]
283+
fn test_domain_zk_rows() {
284+
let log_n = 4;
285+
let n = 1 << log_n;
286+
let domain = Radix2EvaluationDomain::<Fq>::new(n).unwrap();
287+
let w = domain.group_gen();
288+
let (zk_rows_prod, last_row) = compute_row_polys(domain, 0).unwrap();
289+
assert_eq!(zk_rows_prod, one());
290+
assert_eq!(last_row, z(domain.group_gen_inv()));
291+
292+
let zk_rows = 3;
293+
let (zk_rows_prod, last_row) = compute_row_polys(domain, zk_rows).unwrap();
294+
assert_eq!(zk_rows_prod.degree(), zk_rows);
295+
let last_row_index = n - (zk_rows + 1);
296+
assert_eq!(last_row, z(w.pow([last_row_index as u64])));
297+
298+
let zk_rows = n - 1;
299+
let (zk_rows_prod, last_row) = compute_row_polys(domain, zk_rows).unwrap();
300+
assert_eq!(last_row, z(Fq::one()));
301+
assert_eq!(
302+
zk_rows_prod * last_row,
303+
domain.vanishing_polynomial().into()
304+
);
305+
306+
let zk_rows = n;
307+
assert!(compute_row_polys(domain, zk_rows).is_none());
308+
}
309+
263310
#[test]
264311
fn test_evaluated_domain() {
265312
_test_evaluated_domain(false);

w3f-plonk-common/src/gadgets/booleanity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ impl<F: FftField> BitColumn<F> {
2020
.iter()
2121
.map(|&b| if b { F::one() } else { F::zero() })
2222
.collect();
23-
let col = domain.private_column(bits_as_field_elements);
23+
let col = domain.column(bits_as_field_elements);
2424
Self { bits, col }
2525
}
2626

0 commit comments

Comments
 (0)