Skip to content

Commit

Permalink
Update EIP-2537: Fix some nits
Browse files Browse the repository at this point in the history
Merged by EIP-Bot.
  • Loading branch information
jtraglia committed Jun 7, 2024
1 parent 0e75ac9 commit f6112d0
Showing 1 changed file with 27 additions and 35 deletions.
62 changes: 27 additions & 35 deletions EIPS/eip-2537.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@ The motivation of this precompile is to add a cryptographic primitive that allow

### Constants

|Name|Value|Comment|
| --- |--- | --- |
|`FORK_TIMESTAMP` | *TBD* | Mainnet |
|BLS12_G1ADD | 0x0b | precompile address |
|BLS12_G1MUL | 0x0c | precompile address |
|BLS12_G1MSM | 0x0d | precompile address |
|BLS12_G2ADD | 0x0e | precompile address |
|BLS12_G2MUL | 0x0f | precompile address |
|BLS12_G2MSM | 0x10 | precompile address |
|BLS12_PAIRING | 0x11 | precompile address |
|BLS12_MAP_FP_TO_G1 | 0x12 | precompile address |
|BLS12_MAP_FP2_TO_G2 | 0x13 | precompile address |
| Name | Value | Comment |
|---------------------|-------|--------------------|
| `FORK_TIMESTAMP` | *TBD* | Mainnet |
| BLS12_G1ADD | 0x0b | precompile address |
| BLS12_G1MUL | 0x0c | precompile address |
| BLS12_G1MSM | 0x0d | precompile address |
| BLS12_G2ADD | 0x0e | precompile address |
| BLS12_G2MUL | 0x0f | precompile address |
| BLS12_G2MSM | 0x10 | precompile address |
| BLS12_PAIRING | 0x11 | precompile address |
| BLS12_MAP_FP_TO_G1 | 0x12 | precompile address |
| BLS12_MAP_FP2_TO_G2 | 0x13 | precompile address |

If `block.timestamp >= FORK_TIMESTAMP` we introduce *nine* separate precompiles to perform the following operations:

Expand All @@ -60,7 +60,7 @@ Base field modulus = p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d
Fp - finite field of size p
Curve Fp equation: Y^2 = X^3+B (mod p)
B coefficient = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004
Main subgroup order = q =0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
Main subgroup order = q = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
Extension tower
Fp2 construction:
Fp quadratic non-residue = nr2 = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa
Expand Down Expand Up @@ -192,7 +192,6 @@ Error cases:
- An input is on the G2 elliptic curve but not in the correct subgroup
- Input has invalid length


#### ABI for G2 MSM

G2 MSM call expects `288*k` (`k` being a **positive** integer) bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of MSM operation result - a single G2 point (`256` bytes).
Expand All @@ -213,7 +212,7 @@ Pairing call expects `384*k` (`k` being a **positive** integer) bytes as an in

Each point is expected to be in the subgroup of order `q`.

Output is a `32` bytes where first `31` bytes are equal to `0x00` and the last byte is `0x01` if pairing result is equal to the multiplicative identity in a pairing target field and `0x00` otherwise.
Output is `32` bytes where first `31` bytes are equal to `0x00` and the last byte is `0x01` if pairing result is equal to the multiplicative identity in a pairing target field and `0x00` otherwise.

Error cases:

Expand All @@ -237,14 +236,13 @@ Error cases:

#### ABI for mapping Fp2 element to G2 point

Field-to-curve call expects `128` bytes as an input that is interpreted as a an element of Fp2. Output of this call is `256` bytes and is an encoded G2 point.
Field-to-curve call expects `128` bytes as an input that is interpreted as an element of Fp2. Output of this call is `256` bytes and is an encoded G2 point.

Error cases:

- Input has invalid length
- Input is not correctly encoded


### Gas burning on error

Following the current state of all other precompiles, if a call to one of the precompiles in this EIP results in an error then all the gas supplied along with a `CALL` or `STATICCALL` is burned.
Expand Down Expand Up @@ -275,7 +273,7 @@ Assuming a constant `30 MGas/second`, the following prices are suggested.

#### G1/G2 MSM

MSMs are expected to be performed by the Pippenger algorithm (we can also say that is **must** be performed by Pippenger algorithm to have a speedup that results in a discount over naive implementation by multiplying each pair separately and adding the results). For this case there was a table prepared for discount in case of `k <= 128` points in the MSM with a discount cup `max_discount` for `k > 128`.
MSMs are expected to be performed by Pippenger's algorithm (we can also say that it **must** be performed by Pippenger's algorithm to have a speedup that results in a discount over naive implementation by multiplying each pair separately and adding the results). For this case there was a table prepared for discount in case of `k <= 128` points in the MSM with a discount cup `max_discount` for `k > 128`.

To avoid non-integer arithmetic, the call cost is calculated as `(k * multiplication_cost * discount) / multiplier` where `multiplier = 1000`, `k` is a number of (scalar, point) pairs for the call, `multiplication_cost` is a corresponding single multiplication call cost for G1/G2.

Expand Down Expand Up @@ -310,15 +308,12 @@ Define a constant `LEN_PER_PAIR` that is equal to `160` for G1 operation and to
The following pseudofunction reflects how gas should be calculated:

```
k = floor(len(input) / LEN_PER_PAIR);
if k == 0 {
return 0;
}
gas_cost = k * multiplication_cost * discount(k) / multiplier;
return gas_cost;
k = floor(len(input) / LEN_PER_PAIR);
if k == 0 {
return 0;
}
gas_cost = k * multiplication_cost * discount(k) / multiplier;
return gas_cost;
```

We use floor division to get the number of pairs. If the length of the input is not divisible by `LEN_PER_PAIR` we still produce *some* result, but later on the precompile will return an error. Also, the case when `k = 0` is safe: `CALL` or `STATICCALL` cost is non-zero, and the case with formal zero gas cost is already used in `Blake2f` precompile. In any case, the main precompile routine **must** produce an error on such an input because it violated encoding rules.
Expand All @@ -330,12 +325,9 @@ Define a constant `LEN_PER_PAIR = 384`;
The following pseudofunction reflects how gas should be calculated:

```
k = floor(len(input) / LEN_PER_PAIR);
gas_cost = 43000*k + 65000;
return gas_cost;
k = floor(len(input) / LEN_PER_PAIR);
gas_cost = 43000*k + 65000;
return gas_cost;
```

We use floor division to get the number of pairs. If the length of the input is not divisible by `LEN_PER_PAIR` we still produce *some* result, but later on the precompile will return an error (the precompile routine **must** produce an error on such an input because it violated encoding rules).
Expand All @@ -346,7 +338,7 @@ The motivation section covers a total motivation to have operations over the BLS

### MSM as a separate call

Explicit separate MSM operation that allows one to save execution time (so gas) by both the algorithm used (namely the Pippenger algorithm) and (usually forgotten) by the fact that `CALL` operation in Ethereum is expensive (at the time of writing), so one would have to pay non-negigible overhead if e.g. for MSM of `100` points would have to call the multiplication precompile `100` times and addition for `99` times (roughly `138600` would be saved).
Explicit separate MSM operation that allows one to save execution time (so gas) by both the algorithm used (namely Pippenger's algorithm) and (usually forgotten) by the fact that `CALL` operation in Ethereum is expensive (at the time of writing), so one would have to pay non-negligible overhead if e.g. for MSM of `100` points would have to call the multiplication precompile `100` times and addition for `99` times (roughly `138600` would be saved).

## Backwards Compatibility

Expand All @@ -356,7 +348,7 @@ There are no backward compatibility questions.

Scalar multiplications, MSMs and pairings MUST perform a subgroup check.
Implementations SHOULD use the optimized subgroup check method detailed in a dedicated [document](../assets/eip-2537/fast_subgroup_checks.md).
On any input that fail the subgroup check, the precompile MUST return an error.
On any input that fails the subgroup check, the precompile MUST return an error.
As endomorphism acceleration requires input on the correct subgroup, implementers MAY use endomorphism acceleration.

### Field to curve mapping
Expand Down

0 comments on commit f6112d0

Please sign in to comment.