Skip to content

Commit

Permalink
fix(precompile): ignore infinity points in G1 MSM (#1432)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rjected authored May 17, 2024
1 parent 8fd85f1 commit 30c6362
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 7 deletions.
20 changes: 16 additions & 4 deletions crates/precompile/src/bls12_381/g1_msm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,20 @@ pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult {
let mut g1_points: Vec<blst_p1> = Vec::with_capacity(k);
let mut scalars: Vec<u8> = 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) };
Expand All @@ -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);

Expand Down
6 changes: 3 additions & 3 deletions crates/precompile/src/bls12_381/g2_msm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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);
Expand Down

0 comments on commit 30c6362

Please sign in to comment.