Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update EIP-2537: Added MSM and pairings precompiles without subgroup checks #8965

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 43 additions & 50 deletions EIPS/eip-2537.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,30 @@ 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_CHECK | 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:
| Name | Value | Comment |
|----------------------------|-------|--------------------|
| `FORK_TIMESTAMP` | *TBD* | Mainnet |
| BLS12_G1ADD | 0x0b | precompile address |
| BLS12_G1MSM | 0x0c | precompile address |
| BLS12_G1MSM_UNSAFE | 0x0d | precompile address |
| BLS12_G2ADD | 0x0e | precompile address |
| BLS12_G2MSM | 0x0f | precompile address |
| BLS12_G2MSM_UNSAFE | 0x10 | precompile address |
| BLS12_PAIRING_CHECK | 0x11 | precompile address |
| BLS12_PAIRING_CHECK_UNSAFE | 0x12 | precompile address |
| BLS12_MAP_FP_TO_G1 | 0x13 | precompile address |
| BLS12_MAP_FP2_TO_G2 | 0x14 | precompile address |

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

- BLS12_G1ADD - to perform point addition in G1 (curve over base prime field) with a gas cost of `500` gas
- BLS12_G1MUL - to perform point multiplication in G1 (curve over base prime field) with a gas cost of `12000` gas
- BLS12_G1MSM - to perform multi-scalar-multiplication (MSM) in G1 (curve over base prime field) with a gas cost formula defined in the corresponding section
- BLS12_G1MSM - to perform multi-scalar-multiplication (MSM) in G1 (curve over base prime field) with a gas cost formula defined in the corresponding section. In the base case of one point this will be a simple point multiplication.
- BLS12_G1MSM_UNSAFE - identical to BLS12_G1MSM except that subgroup checks will **not** be performed.
- BLS12_G2ADD - to perform point addition in G2 (curve over quadratic extension of the base prime field) with a gas cost of `800` gas
- BLS12_G2MUL - to perform point multiplication in G2 (curve over quadratic extension of the base prime field) with a gas cost of `45000` gas
- BLS12_G2MSM - to perform multi-scalar-multiplication (MSM) in G2 (curve over quadratic extension of the base prime field) with a gas cost formula defined in the corresponding section
- BLS12_G2MSM - to perform multi-scalar-multiplication (MSM) in G2 (curve over quadratic extension of the base prime field) with a gas cost formula defined in the corresponding section. In the base case of one point this will be a simple point multiplication.
- BLS12_G2MSM_UNSAFE - identical to BLS12_G2MSM except that subgroup checks will **not** be performed.
- BLS12_PAIRING_CHECK - to perform a pairing operations between a set of *pairs* of (G1, G2) points a gas cost formula defined in the corresponding section
- BLS12_PAIRING_CHECK_UNSAFE - identical to BLS12_PAIRING_CHECK except that subgroup checks will **not** be performed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is no-starter. How are you going to define this operation for points outside of the main prime subgroup?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

totally agree with @chfast here!!

- BLS12_MAP_FP_TO_G1 - maps base field element into the G1 point with a gas cost of `5500` gas
- BLS12_MAP_FP2_TO_G2 - maps extension field element into the G2 point with a gas cost of `75000` gas

Expand Down Expand Up @@ -145,17 +147,6 @@ Note:

There is no subgroup check for the G1 addition precompile.

#### ABI for G1 multiplication

G1 multiplication call expects `160` bytes as an input that is interpreted as byte concatenation of encoding of a G1 point (`128` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of the multiplication operation result - a single G1 point (`128` bytes).

Error cases:

- Invalid coordinate encoding
- An input is neither a point on the G1 elliptic curve nor the infinity point
- An input is on the G1 elliptic curve but not in the correct subgroup
- Input has invalid length

#### ABI for G1 MSM

G1 MSM call expects `160*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 a G1 point (`128` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of MSM operation result - a single G1 point (`128` bytes).
Expand All @@ -181,17 +172,6 @@ Note:

There is no subgroup check for the G2 addition precompile.

#### ABI for G2 multiplication

G2 multiplication call expects `288` bytes as an input that is interpreted as byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of multiplication operation result - single G2 point (`256` bytes).

Error cases:

- Invalid coordinate encoding
- An input is neither a point on the G2 elliptic curve nor the infinity point
- 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 Down Expand Up @@ -225,6 +205,10 @@ Note:

If any input is the infinity point, pairing result will be 1. Protocols may want to check and reject infinity points prior to calling the precompile.

#### ABI for unsafe operations

Identical to the normal operation ABI except for the case of an input that is not in the correct subgroup. In this case the MSM operation will be performed and there will **not** be an error.

#### ABI for mapping Fp element to G1 point

Field-to-curve call expects `64` bytes as an input that is interpreted as an element of Fp. Output of this call is `128` bytes and is an encoded G1 point.
Expand Down Expand Up @@ -259,23 +243,15 @@ Assuming a constant `30 MGas/second`, the following prices are suggested.

`500` gas

#### G1 multiplication

`12000` gas

#### G2 addition

`800` gas

#### G2 multiplication

`45000` gas

#### G1/G2 MSM

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 cap `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.
To avoid non-integer arithmetic, the call cost is calculated as `(k * multiplication_cost * discount) / multiplier` where `multiplier = TBD`, `k` is a number of (scalar, point) pairs for the call, `multiplication_cost` is a corresponding single multiplication call cost for G1/G2.

Discounts table as a vector of pairs `[k, discount]`:

Expand All @@ -285,10 +261,18 @@ Discounts table as a vector of pairs `[k, discount]`:

`max_discount = 174`

#### Unsafe G1/G2 MSM

See cost of normal MSM precompiles with `multiplier = 1000`.

#### Pairing check operation

The cost of the pairing check operation is `43000*k + 65000` where `k` is a number of pairs.

#### Unsafe pairing check operation

The cost of the unsafe pairing check operation is `TBD` where `k` is a number of pairs.

#### Fp-to-G1 mapping operation

Fp -> G1 mapping is `5500` gas.
Expand Down Expand Up @@ -340,17 +324,24 @@ The motivation section covers a total motivation to have operations over the BLS

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).

### Unsafe precompiles

In many cases the caller of the precompile may be confident that the points are in the correct subgroup, so performing expensive subgroup checks is not necessary. In such cases the unsafe precompiles can be used to reduce gas costs. Using these precompiles on points outside of the subgroup can result in security vulnerabilities in applications, and so the name 'unsafe' is used to highlight that they should be used with caution.

## Backwards Compatibility

There are no backward compatibility questions.

### Subgroup checks

Scalar multiplications, MSMs and pairings MUST perform a subgroup check.
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 fails the subgroup check, the precompile MUST return an error.
As endomorphism acceleration requires input on the correct subgroup, implementers MAY use endomorphism acceleration.

Unsafe versions of MSM and pairings SHOULD NOT perform a subgroup check, but SHOULD return the correct result for inputs outside of the subgroup.
Therefore implementers SHOULD NOT use endomorphism acceleration for these precompiles.

### Field to curve mapping

The algorithms and set of parameters for SWU mapping method are provided by a separate [document](../assets/eip-2537/field_to_curve.md)
Expand Down Expand Up @@ -396,6 +387,8 @@ Strictly following the spec will eliminate security implications or consensus im

Important topic is a "constant time" property for performed operations. We explicitly state that this precompile **IS NOT REQUIRED** to perform all the operations using constant time algorithms.

Incorrect use of the unsafe precompiles can lead to security vulnerabilities in applications. Users of these precompiles are assumed to be advanced and aware of the risks.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
4 changes: 2 additions & 2 deletions assets/eip-2537/bench_vectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ G1 addition example input =
0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee000000000000000000000000000000000001101098f5c39893765766af4512a0c74e1bb89bc7e6fdf14e3e7337d257cc0f94658179d83320b99f31ff94cd2bac0000000000000000000000000000000003e1a9f9f44ca2cdab4f43a1a3ee3470fdf90b2fc228eb3b709fcd72f014838ac82a6d797aeefed9a0804b22ed1ce8f7
G2 addition example input =
0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d938800000000000000000000000000000000192fa5d8732ff9f38e0b1cf12eadfd2608f0c7a39aced7746837833ae253bb57ef9c0d98a4b69eeb2950901917e99d1e0000000000000000000000000000000009aeb10c372b5ef1010675c6a4762fda33636489c23b581c75220589afbc0cc46249f921eea02dd1b761e036ffdbae220000000000000000000000000000000002d225447600d49f932b9dd3ca1e6959697aa603e74d8666681a2dca8160c3857668ae074440366619eb8920256c4e4a00000000000000000000000000000000174882cdd3551e0ce6178861ff83e195fecbcffd53a67b6f10b4431e423e28a480327febe70276036f60bb9c99cf7633
G1 mul double and add worst case =
G1 MSM 1 pair double and add worst case =
0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
G2 mul double and add worst case =
G2 MSM 1 pair double and add worst case =
00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79beffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Pairing case for 2 pairs =
0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be
Expand Down
Loading