@@ -7,8 +7,6 @@ use ark_poly::{
77use ark_std:: { vec, vec:: Vec } ;
88use getrandom_or_panic:: getrandom_or_panic;
99
10- pub const ZK_ROWS : usize = 3 ;
11-
1210// Domains for performing calculations with constraint polynomials of degree up to 4.
1311#[ derive( Clone ) ]
1412pub struct Domains < F : FftField > {
@@ -69,14 +67,14 @@ pub struct Domain<F: FftField> {
6967}
7068
7169impl < F : FftField > Domain < F > {
72- 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- }
70+ /// Returns a "non-blinding" domain of full `capacity = N`.
71+ pub fn no_zk ( n : usize ) -> Self {
72+ Self :: with_zk_rows ( n, 0 )
7873 }
7974
75+ /// Returns a domain that blinds (column) polynomials.
76+ /// The highest `zk_rows` evaluations (aka Lagrange coefficients) are set random.
77+ /// After interpolation that is equivallent to adding `r(X).Z'(X)`, for a random `deg(r) = zk_rows - 1`.
8078 pub fn with_zk_rows ( n : usize , zk_rows : usize ) -> Self {
8179 let domains = Domains :: new ( n) ;
8280 let domain_size = domains. x1 . size ( ) ;
@@ -88,7 +86,7 @@ impl<F: FftField> Domain<F> {
8886 let l_last = l_i ( last_row_index, domain_size) ;
8987 let l_last = domains. column_from_evals ( l_last, 0 ) ;
9088
91- let ( zk_rows_prod, last_row) = compute_row_polys ( domains. x1 , zk_rows) . unwrap ( ) ;
89+ let ( zk_rows_prod, last_row) = compute_row_polys ( domains. x1 , zk_rows) ;
9290 let not_last_row = domains. column_from_poly ( last_row) ;
9391
9492 Self {
@@ -102,6 +100,18 @@ impl<F: FftField> Domain<F> {
102100 }
103101 }
104102
103+ #[ cfg( test) ]
104+ pub const ZK_ROWS_TEST : usize = 3 ;
105+
106+ #[ cfg( test) ]
107+ pub fn test_domain ( n : usize , hiding : bool ) -> Self {
108+ if hiding {
109+ Self :: with_zk_rows ( n, Self :: ZK_ROWS_TEST )
110+ } else {
111+ Self :: with_zk_rows ( n, 0 )
112+ }
113+ }
114+
105115 pub fn is_hiding ( & self ) -> bool {
106116 self . zk_rows != 0
107117 }
@@ -176,27 +186,27 @@ fn elements_rev<F: FftField, D: EvaluationDomain<F>>(domain: D) -> impl Iterator
176186}
177187
178188/// `Z(c) = X - c`
179- fn z < F : Field > ( c : F ) -> DensePolynomial < F > {
189+ fn z_poly < F : Field > ( c : F ) -> DensePolynomial < F > {
180190 DensePolynomial :: from_coefficients_vec ( vec ! [ -c, F :: one( ) ] )
181191}
182192
183193fn one < F : Field > ( ) -> DensePolynomial < F > {
184194 DensePolynomial :: from_coefficients_vec ( vec ! [ F :: one( ) ] )
185195}
186196
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})`.
197+ /// For a domain of size `N` returns the vanishing polynomial `Z` of its suffix, `deg(Z) = zk_rows`,
198+ /// `Z(X) = (X - w^{N-1}) * (X - w^{N-2}) * ... * (X - w^{N-zk_rows})`,
199+ /// and the following not included term `X - w^{N-zk_rows-1}`.
189200fn compute_row_polys < F : FftField , D : EvaluationDomain < F > > (
190201 domain : D ,
191202 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) )
203+ ) -> ( DensePolynomial < F > , DensePolynomial < F > ) {
204+ assert ! ( domain. size( ) >= 1 + zk_rows, "0 domain" ) ;
205+ let ws_rev_iter = elements_rev ( domain) ; // `w^{N-1},...,0 = w^N`
206+ let mut z_polys = ws_rev_iter. map ( |wi| z_poly ( wi) ) ;
207+ let zk_rows_prod = z_polys. by_ref ( ) . take ( zk_rows) . fold ( one ( ) , |acc, x| acc * x) ;
208+ let last_row = z_polys. next ( ) . unwrap ( ) ;
209+ ( zk_rows_prod, last_row)
200210}
201211
202212pub struct EvaluatedDomain < F : FftField > {
@@ -268,7 +278,7 @@ mod tests {
268278
269279 // let domain = GeneralEvaluationDomain::new(1024);
270280 let n = 1024 ;
271- let domain = Domain :: new ( n, hiding) ;
281+ let domain = Domain :: test_domain ( n, hiding) ;
272282 let z = Fq :: rand ( rng) ;
273283 let domain_eval = domain. evaluate ( z) ;
274284 assert_eq ! ( domain. l_first. poly. evaluate( & z) , domain_eval. l_first) ;
@@ -280,31 +290,32 @@ mod tests {
280290 }
281291
282292 #[ test]
293+ #[ should_panic( expected = "0 domain" ) ]
283294 fn test_domain_zk_rows ( ) {
284295 let log_n = 4 ;
285296 let n = 1 << log_n;
286297 let domain = Radix2EvaluationDomain :: < Fq > :: new ( n) . unwrap ( ) ;
287298 let w = domain. group_gen ( ) ;
288- let ( zk_rows_prod, last_row) = compute_row_polys ( domain, 0 ) . unwrap ( ) ;
299+ let ( zk_rows_prod, last_row) = compute_row_polys ( domain, 0 ) ;
289300 assert_eq ! ( zk_rows_prod, one( ) ) ;
290- assert_eq ! ( last_row, z ( domain. group_gen_inv( ) ) ) ;
301+ assert_eq ! ( last_row, z_poly ( domain. group_gen_inv( ) ) ) ;
291302
292303 let zk_rows = 3 ;
293- let ( zk_rows_prod, last_row) = compute_row_polys ( domain, zk_rows) . unwrap ( ) ;
304+ let ( zk_rows_prod, last_row) = compute_row_polys ( domain, zk_rows) ;
294305 assert_eq ! ( zk_rows_prod. degree( ) , zk_rows) ;
295306 let last_row_index = n - ( zk_rows + 1 ) ;
296- assert_eq ! ( last_row, z ( w. pow( [ last_row_index as u64 ] ) ) ) ;
307+ assert_eq ! ( last_row, z_poly ( w. pow( [ last_row_index as u64 ] ) ) ) ;
297308
298309 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( ) ) ) ;
310+ let ( zk_rows_prod, last_row) = compute_row_polys ( domain, zk_rows) ;
311+ assert_eq ! ( last_row, z_poly ( Fq :: one( ) ) ) ;
301312 assert_eq ! (
302313 zk_rows_prod * last_row,
303314 domain. vanishing_polynomial( ) . into( )
304315 ) ;
305316
306317 let zk_rows = n;
307- assert ! ( compute_row_polys( domain, zk_rows) . is_none ( ) ) ;
318+ compute_row_polys ( domain, zk_rows) ;
308319 }
309320
310321 #[ test]
0 commit comments