-
-
Notifications
You must be signed in to change notification settings - Fork 60
Description
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