From 51596f81511a0506cbb7c49810fd90aac7f8a124 Mon Sep 17 00:00:00 2001 From: zhenfei Date: Tue, 3 May 2022 13:57:00 -0400 Subject: [PATCH 1/7] improve KZG10 verification speed --- src/kzg10/mod.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/kzg10/mod.rs b/src/kzg10/mod.rs index fd1bcd71..43b79265 100644 --- a/src/kzg10/mod.rs +++ b/src/kzg10/mod.rs @@ -291,13 +291,15 @@ where if let Some(random_v) = proof.random_v { inner -= &vk.gamma_g.mul(random_v); } - let lhs = E::pairing(inner, vk.h); - - let inner = vk.beta_h.into_projective() - &vk.h.mul(point); - let rhs = E::pairing(proof.w, inner); - - end_timer!(check_time, || format!("Result: {}", lhs == rhs)); - Ok(lhs == rhs) + let inner2 = vk.beta_h.into_projective() - &vk.h.mul(point); + + let pairing_prod_inputs:Vec<(E::G1Prepared, E::G2Prepared)> = vec![ + ((-inner).into_affine().into(), vk.h.into()), + (proof.w.into(), inner2.into_affine().into()), + ]; + let res = E::product_of_pairings(pairing_prod_inputs.iter()) == E::Fqk::one(); + end_timer!(check_time, || format!("Result: {}", res)); + Ok(res) } /// Check that each `proof_i` in `proofs` is a valid proof of evaluation for From a9ca644192bb10311f5242bc858dbebf01352e42 Mon Sep 17 00:00:00 2001 From: zhenfei Date: Tue, 3 May 2022 14:01:42 -0400 Subject: [PATCH 2/7] update change log --- CHANGELOG.md | 2 ++ src/kzg10/mod.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9203dcd4..13f96b7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ ### Improvements +- [\#98](https://github.com/arkworks-rs/poly-commit/pull/98) Improve KZG10 verification speed. + ### Bug fixes ## v0.3.0 diff --git a/src/kzg10/mod.rs b/src/kzg10/mod.rs index 43b79265..98a770d5 100644 --- a/src/kzg10/mod.rs +++ b/src/kzg10/mod.rs @@ -293,7 +293,7 @@ where } let inner2 = vk.beta_h.into_projective() - &vk.h.mul(point); - let pairing_prod_inputs:Vec<(E::G1Prepared, E::G2Prepared)> = vec![ + let pairing_prod_inputs: Vec<(E::G1Prepared, E::G2Prepared)> = vec![ ((-inner).into_affine().into(), vk.h.into()), (proof.w.into(), inner2.into_affine().into()), ]; From 8bcd0a86443eca56c6e84c27b97cdbda6f8af29e Mon Sep 17 00:00:00 2001 From: zhenfei Date: Fri, 20 May 2022 12:10:01 -0400 Subject: [PATCH 3/7] pairing-product for ML-KZG; update change log --- CHANGELOG.md | 2 ++ src/multilinear_pc/mod.rs | 46 +++++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13f96b7b..89bae257 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Pending +- [\#98](https://github.com/arkworks-rs/poly-commit/pull/98) Use pairing-product to accelerate `KZG` and `multilinear_pc` verifications. + ### Breaking changes - [\#82](https://github.com/arkworks-rs/poly-commit/pull/82) Function parameter `opening_challenge: F` for `open`, diff --git a/src/multilinear_pc/mod.rs b/src/multilinear_pc/mod.rs index 8473a7b9..5d214d28 100644 --- a/src/multilinear_pc/mod.rs +++ b/src/multilinear_pc/mod.rs @@ -194,39 +194,39 @@ impl MultilinearPC { value: E::Fr, proof: &Proof, ) -> bool { - let left = E::pairing( - commitment.g_product.into_projective() - &vk.g.mul(value), - vk.h, - ); let scalar_size = E::Fr::MODULUS_BIT_SIZE as usize; let window_size = FixedBase::get_mul_window_size(vk.nv); - let g_table = FixedBase::get_window_table(scalar_size, window_size, vk.g.into_projective()); - let g_mul: Vec = FixedBase::msm(scalar_size, window_size, &g_table, point); + let g_table = FixedBase::get_window_table( + scalar_size, + window_size, + vk.g.into_projective(), + ); + let g_mul: Vec = + FixedBase::msm(scalar_size, window_size, &g_table, point); - let pairing_lefts: Vec<_> = (0..vk.nv) - .map(|i| vk.g_mask_random[i].into_projective() - &g_mul[i]) - .collect(); - let pairing_lefts: Vec = - E::G1Projective::batch_normalization_into_affine(&pairing_lefts); - let pairing_lefts: Vec = pairing_lefts - .into_iter() - .map(|x| E::G1Prepared::from(x)) + let mut g1_vec: Vec<_> = (0..vk.nv) + .map(|i| vk.g_mask_random[i].into_projective() - g_mul[i]) .collect(); + g1_vec.push(vk.g.mul(value) - commitment.g_product.into_projective()); - let pairing_rights: Vec = proof - .proofs - .iter() - .map(|x| E::G2Prepared::from(*x)) - .collect(); + let g1_vec: Vec = E::G1Projective::batch_normalization_into_affine(&g1_vec); + let tmp = g1_vec[vk.nv]; - let pairings: Vec<_> = pairing_lefts + let mut pairings: Vec<_> = g1_vec .into_iter() - .zip(pairing_rights.into_iter()) + .take(vk.nv) + .map(E::G1Prepared::from) + .zip(proof.proofs.iter().map(|&x| E::G2Prepared::from(x))) .collect(); - let right = E::product_of_pairings(pairings.iter()); - left == right + + pairings.push(( + E::G1Prepared::from(tmp), + E::G2Prepared::from(vk.h), + )); + + E::product_of_pairings(pairings.iter()) == E::Fqk::one() } } From 696f2a10dc7fc5b386f1d9d5c4e85d8540cb067a Mon Sep 17 00:00:00 2001 From: zhenfei Date: Fri, 20 May 2022 13:29:48 -0400 Subject: [PATCH 4/7] Update src/kzg10/mod.rs Co-authored-by: Pratyush Mishra --- src/kzg10/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kzg10/mod.rs b/src/kzg10/mod.rs index 98a770d5..1d2760c6 100644 --- a/src/kzg10/mod.rs +++ b/src/kzg10/mod.rs @@ -293,7 +293,7 @@ where } let inner2 = vk.beta_h.into_projective() - &vk.h.mul(point); - let pairing_prod_inputs: Vec<(E::G1Prepared, E::G2Prepared)> = vec![ + let pairing_prod_inputs: [(E::G1Prepared, E::G2Prepared); 2] = [ ((-inner).into_affine().into(), vk.h.into()), (proof.w.into(), inner2.into_affine().into()), ]; From ecb874f1c5e4524904e8ae5be33a6591afebf5c3 Mon Sep 17 00:00:00 2001 From: zhenfei Date: Fri, 20 May 2022 13:29:53 -0400 Subject: [PATCH 5/7] Update src/kzg10/mod.rs Co-authored-by: Pratyush Mishra --- src/kzg10/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kzg10/mod.rs b/src/kzg10/mod.rs index 1d2760c6..11ed944e 100644 --- a/src/kzg10/mod.rs +++ b/src/kzg10/mod.rs @@ -297,7 +297,7 @@ where ((-inner).into_affine().into(), vk.h.into()), (proof.w.into(), inner2.into_affine().into()), ]; - let res = E::product_of_pairings(pairing_prod_inputs.iter()) == E::Fqk::one(); + let res = E::product_of_pairings(pairing_prod_inputs.iter()).is_one(); end_timer!(check_time, || format!("Result: {}", res)); Ok(res) } From 1cefc477d08adf6d1aee331f3114a27f3b438eef Mon Sep 17 00:00:00 2001 From: zhenfei Date: Fri, 20 May 2022 13:31:40 -0400 Subject: [PATCH 6/7] use is_one instead of Fqk::one --- src/multilinear_pc/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/multilinear_pc/mod.rs b/src/multilinear_pc/mod.rs index 5d214d28..44ca3e79 100644 --- a/src/multilinear_pc/mod.rs +++ b/src/multilinear_pc/mod.rs @@ -226,7 +226,7 @@ impl MultilinearPC { E::G2Prepared::from(vk.h), )); - E::product_of_pairings(pairings.iter()) == E::Fqk::one() + E::product_of_pairings(pairings.iter()).is_one() } } From e047a92d87475036e8b51690170d2b76f602a23c Mon Sep 17 00:00:00 2001 From: zhenfei Date: Fri, 20 May 2022 14:14:57 -0400 Subject: [PATCH 7/7] formatter --- src/multilinear_pc/mod.rs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/multilinear_pc/mod.rs b/src/multilinear_pc/mod.rs index 44ca3e79..5618eaa1 100644 --- a/src/multilinear_pc/mod.rs +++ b/src/multilinear_pc/mod.rs @@ -194,17 +194,11 @@ impl MultilinearPC { value: E::Fr, proof: &Proof, ) -> bool { - let scalar_size = E::Fr::MODULUS_BIT_SIZE as usize; let window_size = FixedBase::get_mul_window_size(vk.nv); - let g_table = FixedBase::get_window_table( - scalar_size, - window_size, - vk.g.into_projective(), - ); - let g_mul: Vec = - FixedBase::msm(scalar_size, window_size, &g_table, point); + let g_table = FixedBase::get_window_table(scalar_size, window_size, vk.g.into_projective()); + let g_mul: Vec = FixedBase::msm(scalar_size, window_size, &g_table, point); let mut g1_vec: Vec<_> = (0..vk.nv) .map(|i| vk.g_mask_random[i].into_projective() - g_mul[i]) @@ -221,10 +215,7 @@ impl MultilinearPC { .zip(proof.proofs.iter().map(|&x| E::G2Prepared::from(x))) .collect(); - pairings.push(( - E::G1Prepared::from(tmp), - E::G2Prepared::from(vk.h), - )); + pairings.push((E::G1Prepared::from(tmp), E::G2Prepared::from(vk.h))); E::product_of_pairings(pairings.iter()).is_one() }