@@ -120,7 +120,7 @@ where
120120/// This helper function generate the variables for the following data
121121/// - Circuit evaluation of vanishing polynomial at point `zeta` i.e., output =
122122/// zeta ^ domain_size - 1 mod Fr::modulus
123- /// - Evaluations of the first and the last lagrange polynomial at point `zeta`
123+ /// - Evaluations of the first, second and last lagrange polynomial at point `zeta`
124124///
125125/// Note that outputs and zeta are both Fr element
126126/// so this needs to be carried out over a non-native circuit
@@ -138,7 +138,7 @@ pub(super) fn evaluate_poly_helper_native<F>(
138138 zeta_var : Variable ,
139139 gen_inv : F ,
140140 domain_size : usize ,
141- ) -> Result < [ Variable ; 4 ] , CircuitError >
141+ ) -> Result < [ Variable ; 5 ] , CircuitError >
142142where
143143 F : PrimeField + RescueParameter ,
144144{
@@ -158,10 +158,16 @@ where
158158
159159 // ================================
160160 // evaluate lagrange at 1
161- // lagrange_1_eval = (zeta^n - 1) / (zeta - 1) / domain_size
161+ // lagrange_1_eval = (zeta^n - 1) / (domain_size * ( zeta - 1))
162162 //
163163 // which is proven via
164164 // domain_size * lagrange_1_eval * (zeta - 1) = zeta^n - 1 mod Fr::modulus
165+ //
166+ // similarly we calculate
167+ // lagrange_2_eval = (zeta^n - 1) * omega / (domain_size * (zeta - omega)) = (zeta^n - 1) / (domain_size * (zeta * omega^{-1} - 1))
168+ // and
169+ // lagrange_n_eval = (zeta^n - 1) * omega^{-1} / (domain_size * (zeta - omega^{-1})) = (zeta^n - 1) / (domain_size * (zeta * omega - 1))
170+ //
165171 // ================================
166172
167173 let domain_size = F :: from ( domain_size as u64 ) ;
@@ -178,31 +184,42 @@ where
178184 // Constrain the lagrange_1_eval to be correct.
179185 circuit. mul_gate ( divisor_var, lagrange_1_eval_var, zeta_n_minus_one_var) ?;
180186
187+ // Compute lagrange_2_eval
188+ let divisor_var = circuit. lin_comb ( & [ domain_size * gen_inv] , & ( -domain_size) , & [ zeta_var] ) ?;
189+ let divisor = circuit. witness ( divisor_var) ?;
190+ let lagrange_2_eval = zeta_n_minus_one / divisor;
191+ let lagrange_2_eval_var = circuit. create_variable ( lagrange_2_eval) ?;
192+ // Constrain the lagrange_2_eval to be correct.
193+ circuit. mul_gate ( divisor_var, lagrange_2_eval_var, zeta_n_minus_one_var) ?;
194+
195+ let gen = gen_inv
196+ . inverse ( )
197+ . ok_or ( CircuitError :: ParameterError ( "Inverse Failed" . to_string ( ) ) ) ?;
181198 // Compute lagrange_n_eval
182- let divisor_var = circuit. lin_comb ( & [ domain_size] , & ( -domain_size * gen_inv) , & [ zeta_var] ) ?;
183- let numerator_var = circuit. mul_constant ( zeta_n_minus_one_var, & gen_inv) ?;
199+ let divisor_var = circuit. lin_comb ( & [ domain_size * gen] , & ( -domain_size) , & [ zeta_var] ) ?;
184200 let divisor = circuit. witness ( divisor_var) ?;
185- let numerator = circuit. witness ( numerator_var) ?;
186- let lagrange_n_eval = numerator / divisor;
201+ let lagrange_n_eval = zeta_n_minus_one / divisor;
187202 let lagrange_n_eval_var = circuit. create_variable ( lagrange_n_eval) ?;
188203 // Constrain the lagrange_n_eval to be correct.
189- circuit. mul_gate ( divisor_var, lagrange_n_eval_var, numerator_var ) ?;
204+ circuit. mul_gate ( divisor_var, lagrange_n_eval_var, zeta_n_minus_one_var ) ?;
190205
191206 Ok ( [
192207 zeta_n_var,
193208 zeta_n_minus_one_var,
194209 lagrange_1_eval_var,
210+ lagrange_2_eval_var,
195211 lagrange_n_eval_var,
196212 ] )
197213}
198214
199215pub ( super ) fn evaluate_poly_helper_native_base < F > (
200216 circuit : & mut PlonkCircuit < F > ,
201217 zeta_var : Variable ,
218+ gen_var : Variable ,
202219 gen_inv_var : Variable ,
203220 domain_size_var : Variable ,
204221 max_domain_size : usize ,
205- ) -> Result < [ Variable ; 4 ] , CircuitError >
222+ ) -> Result < [ Variable ; 5 ] , CircuitError >
206223where
207224 F : PrimeField + RescueParameter ,
208225{
@@ -216,10 +233,16 @@ where
216233
217234 // ================================
218235 // evaluate lagrange at 1
219- // lagrange_1_eval = (zeta^n - 1) / (zeta - 1) / domain_size
236+ // lagrange_1_eval = (zeta^n - 1) / (domain_size * ( zeta - 1))
220237 //
221238 // which is proven via
222239 // domain_size * lagrange_1_eval * (zeta - 1) = zeta^n - 1 mod Fr::modulus
240+ //
241+ // similarly we calculate
242+ // lagrange_2_eval = (zeta^n - 1) * omega / (domain_size * (zeta - omega))
243+ // and
244+ // lagrange_n_eval = (zeta^n - 1) * omega^{-1} / (domain_size * (zeta - omega^{-1}))
245+ //
223246 // ================================
224247
225248 // lagrange_1_eval
@@ -237,6 +260,19 @@ where
237260 // Constrain the lagrange_1_eval to be correct.
238261 circuit. mul_gate ( divisor_var, lagrange_1_eval_var, zeta_n_minus_one_var) ?;
239262
263+ // Compute lagrange_2_eval
264+ let divisor_var = circuit. mul_add (
265+ & [ domain_size_var, zeta_var, domain_size_var, gen_var] ,
266+ & [ F :: one ( ) , -F :: one ( ) ] ,
267+ ) ?;
268+ let numerator_var = circuit. mul ( zeta_n_minus_one_var, gen_var) ?;
269+ let divisor = circuit. witness ( divisor_var) ?;
270+ let numerator = circuit. witness ( numerator_var) ?;
271+ let lagrange_2_eval = numerator / divisor;
272+ let lagrange_2_eval_var = circuit. create_variable ( lagrange_2_eval) ?;
273+ // Constrain the lagrange_n_eval to be correct.
274+ circuit. mul_gate ( divisor_var, lagrange_2_eval_var, numerator_var) ?;
275+
240276 // Compute lagrange_n_eval
241277 let divisor_var = circuit. mul_add (
242278 & [ domain_size_var, zeta_var, domain_size_var, gen_inv_var] ,
@@ -254,6 +290,7 @@ where
254290 zeta_n_var,
255291 zeta_n_minus_one_var,
256292 lagrange_1_eval_var,
293+ lagrange_2_eval_var,
257294 lagrange_n_eval_var,
258295 ] )
259296}
@@ -431,8 +468,8 @@ pub(super) fn compute_lin_poly_constant_term_circuit_native<F>(
431468 gen_inv : & F ,
432469 challenges : & ChallengesVar ,
433470 proof_evals : & ProofEvalsVarNative ,
434- pi : & Variable ,
435- evals : & [ Variable ; 4 ] ,
471+ pi : & [ Variable ; 2 ] ,
472+ evals : & [ Variable ; 5 ] ,
436473 lookup_evals : & Option < PlookupEvalsVarNative > ,
437474) -> Result < Variable , CircuitError >
438475where
@@ -493,7 +530,7 @@ where
493530 prod = circuit. mul ( tmp, prod) ?;
494531
495532 // r_plonk
496- let pi_eval = circuit. mul ( * pi , evals[ 2 ] ) ?;
533+ let pi_eval = circuit. mul_add ( & [ pi [ 0 ] , evals[ 2 ] , pi [ 1 ] , evals [ 3 ] ] , & [ F :: one ( ) , F :: one ( ) ] ) ?;
497534 let wires = [ pi_eval, prod, evals[ 2 ] , challenges. alphas [ 1 ] ] ;
498535 let non_lookup = circuit. gen_quad_poly (
499536 & wires,
@@ -512,7 +549,7 @@ where
512549 ] ;
513550 let tmp = circuit. lc ( & wires, & [ F :: one ( ) , -F :: one ( ) , -F :: one ( ) , F :: zero ( ) ] ) ?;
514551 let term_one = circuit. mul_add (
515- & [ evals[ 3 ] , tmp, evals[ 2 ] , challenges. alphas [ 0 ] ] ,
552+ & [ evals[ 4 ] , tmp, evals[ 2 ] , challenges. alphas [ 0 ] ] ,
516553 & [ F :: one ( ) , -F :: one ( ) ] ,
517554 ) ?;
518555
@@ -581,8 +618,8 @@ pub(super) fn compute_lin_poly_constant_term_circuit_native_base<F>(
581618 gen_inv_var : & Variable ,
582619 challenges : & ChallengesVar ,
583620 proof_evals : & ProofEvalsVarNative ,
584- pi : & Variable ,
585- evals : & [ Variable ; 4 ] ,
621+ pi : & [ Variable ; 2 ] ,
622+ evals : & [ Variable ; 5 ] ,
586623 lookup_evals : & Option < PlookupEvalsVarNative > ,
587624) -> Result < Variable , CircuitError >
588625where
@@ -643,7 +680,7 @@ where
643680 prod = circuit. mul ( tmp, prod) ?;
644681
645682 // r_plonk
646- let pi_eval = circuit. mul ( * pi , evals[ 2 ] ) ?;
683+ let pi_eval = circuit. mul_add ( & [ pi [ 0 ] , evals[ 2 ] , pi [ 1 ] , evals [ 3 ] ] , & [ F :: one ( ) , F :: one ( ) ] ) ?;
647684 let wires = [ pi_eval, prod, evals[ 2 ] , challenges. alphas [ 1 ] ] ;
648685 let non_lookup = circuit. gen_quad_poly (
649686 & wires,
@@ -662,7 +699,7 @@ where
662699 ] ;
663700 let tmp = circuit. lc ( & wires, & [ F :: one ( ) , -F :: one ( ) , -F :: one ( ) , F :: zero ( ) ] ) ?;
664701 let term_one = circuit. mul_add (
665- & [ evals[ 3 ] , tmp, evals[ 2 ] , challenges. alphas [ 0 ] ] ,
702+ & [ evals[ 4 ] , tmp, evals[ 2 ] , challenges. alphas [ 0 ] ] ,
666703 & [ F :: one ( ) , -F :: one ( ) ] ,
667704 ) ?;
668705
@@ -760,7 +797,7 @@ pub fn linearization_scalars_circuit_native<F>(
760797 circuit : & mut PlonkCircuit < F > ,
761798 vk_k : & [ F ] ,
762799 challenges : & ChallengesVar ,
763- evals : & [ Variable ; 4 ] ,
800+ evals : & [ Variable ; 5 ] ,
764801 poly_evals : & ProofEvalsVarNative ,
765802 lookup_evals : & Option < PlookupEvalsVarNative > ,
766803 gen_inv : & F ,
@@ -1004,7 +1041,7 @@ where
10041041 challenges. alphas [ 0 ] ,
10051042 evals[ 2 ] ,
10061043 challenges. alphas [ 1 ] ,
1007- evals[ 3 ] ,
1044+ evals[ 4 ] ,
10081045 ] ,
10091046 & [ F :: one ( ) , F :: one ( ) ] ,
10101047 ) ?;
@@ -1081,7 +1118,7 @@ pub fn linearization_scalars_circuit_native_base<F>(
10811118 circuit : & mut PlonkCircuit < F > ,
10821119 vk_k : & [ Variable ] ,
10831120 challenges : & ChallengesVar ,
1084- evals : & [ Variable ; 4 ] ,
1121+ evals : & [ Variable ; 5 ] ,
10851122 poly_evals : & ProofEvalsVarNative ,
10861123 lookup_evals : & Option < PlookupEvalsVarNative > ,
10871124 gen_inv_var : & Variable ,
@@ -1318,7 +1355,7 @@ where
13181355 challenges. alphas [ 0 ] ,
13191356 evals[ 2 ] ,
13201357 challenges. alphas [ 1 ] ,
1321- evals[ 3 ] ,
1358+ evals[ 4 ] ,
13221359 ] ,
13231360 & [ F :: one ( ) , F :: one ( ) ] ,
13241361 ) ?;
0 commit comments