EIP-2537 (BLS12 precompile) discussion thread

Reference thread from the EIP itself.


Doing a testing pass:

  • First, can you provide a test vector for pairings where in the pairing contract “Any of G1 or G2 points are not in the correct subgroup” is triggered? All the test vectors are happy path. Not on G1 or G2 is trivial to produce, subgroup is a bit more involved. This will be needed for reference tests.
  • Second, does the padded space need to be zeros only? i.e. is ff00000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee a valid G1 point for the contract? (the first set of zeros has junk data in it)

Just saw that the EIP now has a section about " Prevention of DDoS on error handling" . Can someone explain what distributed denial of service attack can be carried out if we blow all gas on a subroutine error (like we do on all other types of errors, always?)

Hello Martin.

EIP text actually will be updated because now (in latest commit in master) it reflects a “desired” behavior for calls to the precompile (only nominal cost is burned), but such desired behavior will not be implemented.

In any case, there is no DDoS vector if precompile burns all the gas of the current frame (what was sent along with a staticcall) and supplied gas is more than a gas cost from the schedule.

Negative vectors are also available in 1962 repo (in “negative” folder), there are cases with invalid subgroup there.

Padding with zeroes should be enforced with ABI because field element is required to be “in the field”, so it must be strictly less than modulus, and if leading bytes are non-zero (and we use BE encoding) the element will be not “in a field”.

Hey, we are implementing the multiExp precompiles at EthereumJS. The gas used is not very clear to me.

In the pairing precompile it is clear that if the input length is 0, or the length of the input is not of an expected length, then we use the base gas. However, what should this be if I input an empty byte to multiExp? 0 gas (this is what Geth does)? What if I input 1 byte (i.e. the length is not a multiple of 160 bytes). Should I also use 0 gas here? What if I input 161 bytes? Should I deduct the “corresponding gas” (1 pair) or also 0 gas? Geth seems to floor the division of the input (i.e. floor(len(input)/160)), calculate the gas, and then deduct this if the len(input) % 160 != 0. (To be clear: in this case thus more than 0 gas is deducted)

Hello @jochem-brouwer

A PR with the clarification and explicit formulas for variable length cases is pending the bot approval at the moment, but you can still access the document here.

Sincerely, Alexander

1 Like

Thanks Alexander for the update!

I have a question about the encoding of Fp points. Sorry for my ignorance about this. Is the only check necessary for a Fp point to be on the curve that it is strictly less than the base field modulus? (I.e. < 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab).

Does the same apply for Fp2 points (c0 is less than the base field modulus)? Is there any requirement for the c1 point of Fp2?

Kind regards,

Field elements (either Fp or Fp2) in pairs for the affine coordinates (x, y) of the curve point. They must satisfy the equation like y^2 = x^3 + b for the BLS12-381 curve (b coefficient can be found in the EIP itself). Then point is “on curve” and this check is always performed during deserialization. c0 and c1 elements of Fp2 element are just Fp elements, so all corresponding encoding rules apply.

The input to the mapToG1 precompile takes 64 bytes (top 16 bytes are zero). This is a single number. I don’t see how I can then check if they satisfy that equation? Shouldn’t this strictly less check as mentioned before be the sole check?

mapToG1 takes as an input a single Fp element (not a curve point) and outputs a valid curve point. So the only check here is that input element must be “in the field” (properly encoded).