Skip to content

BLS_G1_ADD precompile missing top byte validation #570

@advaita-saha

Description

@advaita-saha

Issue found while integrating constantine into nimbus-eth1 status-im/nimbus-eth1#3587
Constantine precompile eth_evm_bls12381_g1add implements part of the spec from https://eips.ethereum.org/EIPS/eip-2537

On reading the spec for the encoding of point, mentioned https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2537.md#field-elements-encoding

Note on the top 16 bytes being zero: it is required that an encoded element is "in a field", which means strictly < modulus. In BigEndian encoding it automatically means that for a modulus that is just 381 bit long the top 16 bytes in 64 bytes encoding are zeroes and this must be checked even if only a subslice of input data is used for actual decoding.

But constantine implementation of eth_evm_bls12381_g1add doesn't do this additional checking.
This issue was verified further after having test vectors verified from all other clients with the help of @spencer-tb from the EF STEEL Team

Test Input to check

0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000108b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1

EIP-2537 requires each Fp element to be encoded as 64 bytes big-endian with the top 16 bytes all zero, and the integer must be < p. A G1 point is x || y (128 bytes), so G1ADD expects 256 bytes: x1||y1||x2||y2

256-byte blob splits into four 64-byte chunks:

  • x1 = 0000…0000 17f1…c6bb ✅ top 16 bytes are 0
  • y1 = 0000…00000108b3…e7e1 ❌ the 16th byte is 0x01 (not zero)
  • x2 = 0000…0000 17f1…c6bb ✅
  • y2 = 0000…0000 08b3…e7e1 ✅

That y1 leading byte (…0000000000000000000000000000000108b3…) violates the spec’s “top 16

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions