From d8542c41a64f4a1d106c681ab20c8d0f81ea82be Mon Sep 17 00:00:00 2001 From: Fangyan Shi Date: Sat, 28 Sep 2024 13:38:49 +0000 Subject: [PATCH] fix: snark prove and verify check product to be 1 --- hyperplonk/src/snark.rs | 21 +++++++++++++++++++-- subroutines/src/poly_iop/perm_check/mod.rs | 7 +++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/hyperplonk/src/snark.rs b/hyperplonk/src/snark.rs index 72c3a884..672dbffb 100644 --- a/hyperplonk/src/snark.rs +++ b/hyperplonk/src/snark.rs @@ -520,6 +520,13 @@ where )); } + // check product check subclaim + if prod_evals[3] != perm_check_sub_claim.product_check_sub_claim.final_query.1 { + return Err(HyperPlonkErrors::InvalidVerifier( + "product of product check is not one".to_string(), + )); + } + end_timer!(step); // ======================================================================= // 3. Verify the opening against the commitment @@ -734,17 +741,27 @@ mod tests { >>::verify(&bad_vk, &pi.0, &proof,)?); // bad path 2: wrong witness - let mut w1_bad = w1; + let mut w1_bad = w1.clone(); w1_bad.0[0] = E::ScalarField::one(); assert!( as HyperPlonkSNARK>>::prove( &pk, &pi.0, - &[w1_bad, w2], + &[w1_bad, w2.clone()], ) .is_err() ); + // bad path 3: permutation and witness mismatch + let permutation = random_permutation(nv, num_witnesses, &mut rng); + assert!( + as HyperPlonkSNARK>>::prove( + &pk, + &permutation, + &[w1, w2], + ).is_err() + ); + Ok(()) } } diff --git a/subroutines/src/poly_iop/perm_check/mod.rs b/subroutines/src/poly_iop/perm_check/mod.rs index 1d0f3f70..944aa824 100644 --- a/subroutines/src/poly_iop/perm_check/mod.rs +++ b/subroutines/src/poly_iop/perm_check/mod.rs @@ -12,6 +12,7 @@ use crate::{ poly_iop::{errors::PolyIOPErrors, prelude::ProductCheck, PolyIOP}, }; use ark_ec::pairing::Pairing; +use ark_ff::One; use ark_poly::DenseMultilinearExtension; use ark_std::{end_timer, start_timer}; use std::sync::Arc; @@ -161,6 +162,12 @@ where transcript, )?; + if prod_poly.evaluations[(1 << num_vars) - 2] != E::ScalarField::one() { + return Err(PolyIOPErrors::InvalidProof( + "Product should be one".to_string(), + )); + } + end_timer!(start); Ok((proof, prod_poly, frac_poly)) }