From 68f305beeb3503387b0a979d597168d4c532cd3c Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Fri, 17 May 2024 16:32:33 +0300 Subject: [PATCH] fix(precompile): ignore infinity points in G1 MSM --- crates/precompile/src/bls12_381/g1_msm.rs | 20 ++++++++++++++++---- crates/precompile/src/bls12_381/g2_msm.rs | 6 +++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/crates/precompile/src/bls12_381/g1_msm.rs b/crates/precompile/src/bls12_381/g1_msm.rs index 503a7b74f9..c8d086abb6 100644 --- a/crates/precompile/src/bls12_381/g1_msm.rs +++ b/crates/precompile/src/bls12_381/g1_msm.rs @@ -41,13 +41,20 @@ pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let mut g1_points: Vec = Vec::with_capacity(k); let mut scalars: Vec = Vec::with_capacity(k * SCALAR_LENGTH); for i in 0..k { + let slice = + &input[i * g1_mul::INPUT_LENGTH..i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH]; + + // BLST batch API for p1_affines blows up when you pass it a point at infinity and returns + // point at infinity so we just skip the element, and return 128 bytes in the response + if slice.iter().all(|i| *i == 0) { + continue; + } + // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. // // So we set the subgroup_check flag to `true` - let p0_aff = &extract_g1_input( - &input[i * g1_mul::INPUT_LENGTH..i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH], - true, - )?; + let p0_aff = &extract_g1_input(slice, true)?; + let mut p0 = blst_p1::default(); // SAFETY: p0 and p0_aff are blst values. unsafe { blst_p1_from_affine(&mut p0, p0_aff) }; @@ -62,6 +69,11 @@ pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { ); } + // return infinity point if all points are infinity + if g1_points.is_empty() { + return Ok((required_gas, [0; 128].into())); + } + let points = p1_affines::from(&g1_points); let multiexp = points.mult(&scalars, NBITS); diff --git a/crates/precompile/src/bls12_381/g2_msm.rs b/crates/precompile/src/bls12_381/g2_msm.rs index 0becd2b5db..85f8208fde 100644 --- a/crates/precompile/src/bls12_381/g2_msm.rs +++ b/crates/precompile/src/bls12_381/g2_msm.rs @@ -43,8 +43,8 @@ pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { for i in 0..k { let slice = &input[i * g2_mul::INPUT_LENGTH..i * g2_mul::INPUT_LENGTH + G2_INPUT_ITEM_LENGTH]; - // BLST batch API for p2_affines blows up when you pass it a point at infinity and returns point at infinity - // so we just skip the element, and return 256 bytes in the response + // BLST batch API for p2_affines blows up when you pass it a point at infinity and returns + // point at infinity so we just skip the element, and return 256 bytes in the response if slice.iter().all(|i| *i == 0) { continue; } @@ -71,7 +71,7 @@ pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { // return infinity point if all points are infinity if g2_points.is_empty() { - return Ok((required_gas, vec![0; 256].into())); + return Ok((required_gas, [0; 256].into())); } let points = p2_affines::from(&g2_points);