Skip to content

Commit 4ed3bec

Browse files
committed
allow 2 PIs
1 parent 21a1e11 commit 4ed3bec

20 files changed

Lines changed: 464 additions & 230 deletions

File tree

plonk/src/nightfall/accumulation/circuit/atomic_gadgets.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,8 @@ mod tests {
322322
circuit
323323
.finalize_for_recursive_mle_arithmetization::<RescueCRHF<FqBn254>>()
324324
.unwrap();
325-
let pi = circuit.public_input().unwrap()[0];
326-
circuit.check_circuit_satisfiability(&[pi]).unwrap();
325+
let pi = circuit.public_input().unwrap();
326+
circuit.check_circuit_satisfiability(&pi).unwrap();
327327
}
328328

329329
#[test]
@@ -450,8 +450,8 @@ mod tests {
450450
circuit
451451
.finalize_for_recursive_mle_arithmetization::<RescueCRHF<FrBn254>>()
452452
.unwrap();
453-
let pi = circuit.public_input().unwrap()[0];
454-
circuit.check_circuit_satisfiability(&[pi]).unwrap();
453+
let pi = circuit.public_input().unwrap();
454+
circuit.check_circuit_satisfiability(&pi).unwrap();
455455
let srs_size = circuit.num_gates().ilog2() as usize;
456456
let srs = Zeromorph::<UnivariateIpaPCS<Grumpkin>>::gen_srs_for_testing(&mut rng, srs_size)
457457
.unwrap();

plonk/src/nightfall/circuit/plonk_partial_verifier/gadgets.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use super::{
3333
#[allow(clippy::too_many_arguments)]
3434
pub fn compute_scalars_for_native_field<F: PrimeField + RescueParameter>(
3535
circuit: &mut PlonkCircuit<F>,
36-
pi: &Variable,
36+
pi: &[Variable; 2],
3737
challenges: &ChallengesVar,
3838
proof_evals: &ProofEvalsVarNative,
3939
lookup_evals: &Option<PlookupEvalsVarNative>,
@@ -275,7 +275,7 @@ pub fn compute_scalars_for_native_field<F: PrimeField + RescueParameter>(
275275
#[allow(clippy::too_many_arguments)]
276276
pub(crate) fn compute_scalars_for_native_field_base<F: PrimeField + RescueParameter>(
277277
circuit: &mut PlonkCircuit<F>,
278-
pi: &Variable,
278+
pi: &[Variable; 2],
279279
challenges: &ChallengesVar,
280280
proof_evals: &ProofEvalsVarNative,
281281
lookup_evals: &Option<PlookupEvalsVarNative>,
@@ -307,6 +307,7 @@ pub(crate) fn compute_scalars_for_native_field_base<F: PrimeField + RescueParame
307307
let evals = poly::evaluate_poly_helper_native_base(
308308
circuit,
309309
challenges.zeta,
310+
vk_var.domain.gen,
310311
gen_inv_var,
311312
vk_var.domain.domain_size,
312313
max_domain_size,
@@ -767,26 +768,35 @@ mod test {
767768
// 5. Verification
768769

769770
for (i, proof) in proofs.iter().enumerate() {
770-
let pi = public_inputs[i][0];
771+
let pi = public_inputs[i].clone();
771772
let mut transcript = <RescueTranscript<F> as Transcript>::new_transcript(b"mle_plonk");
772-
let mle_challenges = MLEChallenges::new_recursion(&proof.proof, &[pi], &mut transcript)
773+
let mle_challenges = MLEChallenges::new_recursion(&proof.proof, &pi, &mut transcript)
773774
.map_err(|_| {
774-
CircuitError::ParameterError("MLE challenge generation failed".to_string())
775-
})?;
775+
CircuitError::ParameterError("MLE challenge generation failed".to_string())
776+
})?;
776777

777778
let mut plonk_circuit = PlonkCircuit::<F>::new_ultra_plonk(RANGE_BIT_LEN_FOR_TEST);
778779
let mle_proof_var = SAMLEProofVar::from_struct::<P>(&mut plonk_circuit, &proof.proof)?;
779780

780781
let mut transcript_var = RescueTranscriptVar::<F>::new_transcript(&mut plonk_circuit);
781-
let pi_var = plonk_circuit.create_emulated_variable(pi)?;
782+
let pi_vars: [EmulatedVariable<P::ScalarField>; 2] = pi
783+
.iter()
784+
.map(|val| plonk_circuit.create_emulated_variable(*val))
785+
.collect::<Result<Vec<_>, CircuitError>>()?
786+
.try_into()
787+
.map_err(|_| {
788+
CircuitError::ParameterError(
789+
"Couldn't convert public inputs to fixed length array".to_string(),
790+
)
791+
})?;
782792
let mle_challenges_var =
783793
EmulatedMLEChallenges::<E::ScalarField>::compute_challenges_vars::<
784794
PCS,
785795
P,
786796
RescueTranscriptVar<F>,
787797
>(
788798
&mut plonk_circuit,
789-
&pi_var,
799+
&pi_vars,
790800
&mle_proof_var,
791801
&mut transcript_var,
792802
)?;

plonk/src/nightfall/circuit/plonk_partial_verifier/mod.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,9 @@ mod test {
936936
circuit
937937
.finalize_for_recursive_arithmetization::<RescueCRHF<P::ScalarField>>()
938938
.unwrap();
939-
let pi = circuit.public_input().unwrap()[0];
939+
let pi: [P::ScalarField; 2] = circuit.public_input()?.try_into().map_err(|_| {
940+
CircuitError::ParameterError("Couldn't convert to fixed length array".to_string())
941+
})?;
940942
let max_degree = circuit.srs_size(blind)?;
941943
let srs = FFTPlonk::<PCS>::universal_setup_for_testing(max_degree, rng).unwrap();
942944

@@ -954,7 +956,7 @@ mod test {
954956
let pcs_info = verifier
955957
.prepare_pcs_info::<RescueTranscript<P::BaseField>>(
956958
&vk,
957-
&[pi],
959+
&pi,
958960
&proof.proof,
959961
&None,
960962
blind,
@@ -969,7 +971,7 @@ mod test {
969971

970972
let challenges = FFTVerifier::<PCS>::compute_challenges::<
971973
RescueTranscript<P::BaseField>,
972-
>(&vk, &[pi], &proof.proof, &None)?;
974+
>(&vk, &pi, &proof.proof, &None)?;
973975

974976
let mut circuit = PlonkCircuit::<P::ScalarField>::new_turbo_plonk();
975977
let tau = circuit.create_variable(challenges.tau)?;
@@ -999,11 +1001,20 @@ mod test {
9991001
&proof.proof.plookup_proof.as_ref().unwrap().poly_evals,
10001002
)?;
10011003

1002-
let pi_var = circuit.create_variable(pi)?;
1004+
let pi_vars: [Variable; 2] = pi
1005+
.iter()
1006+
.map(|val| circuit.create_variable(*val))
1007+
.collect::<Result<Vec<Variable>, CircuitError>>()?
1008+
.try_into()
1009+
.map_err(|_| {
1010+
CircuitError::ParameterError(
1011+
"Couldn't convert to fixed length array".to_string(),
1012+
)
1013+
})?;
10031014

10041015
let scalars = compute_scalars_for_native_field::<P::ScalarField>(
10051016
&mut circuit,
1006-
&pi_var,
1017+
&pi_vars,
10071018
&challenges_var,
10081019
&proof_evals,
10091020
&Some(lookup_evals),
@@ -1083,7 +1094,7 @@ mod test {
10831094
let vk_k = vec![Fr254::zero(); 6];
10841095
let scalars = compute_scalars_for_native_field::<Fr254>(
10851096
&mut circuit,
1086-
&0,
1097+
&[0, 0],
10871098
&challenges_var,
10881099
&proof_evals,
10891100
&Some(lookup_evals),

plonk/src/nightfall/circuit/plonk_partial_verifier/poly.rs

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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>
142142
where
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

199215
pub(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>
206223
where
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>
438475
where
@@ -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>
588625
where
@@ -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
)?;

plonk/src/nightfall/circuit/plonk_partial_verifier/proof_to_var.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ pub struct Bn254OutputScalarsAndBasesVar {
278278
/// The proof generated by the recursive prover.
279279
pub proof: Bn254ProofScalarsandBasesVar,
280280
/// The hash of the public inputs to this proof stored in the clear.
281-
pub pi_hash: Fr254,
281+
pub pi_hash: [Fr254; 2],
282282
/// The transcript of the proof stored in the clear.
283283
pub transcript: RescueTranscript<Fr254>,
284284
}

0 commit comments

Comments
 (0)