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: PAIRING_CHECK repricing #9145

Closed
wants to merge 1 commit into from

Conversation

mratsim
Copy link
Contributor

@mratsim mratsim commented Dec 16, 2024

Follow-up to:

On a Ryzen 7840U:

Before

--------------------------------------------------------------------------------------------------------------------------------
BLS12_PAIRINGCHECK 1      108000 gas     218.30 MGas/s        2021.309 ops/s       494729 ns/op      1629483 CPU cycles (approx)
BLS12_PAIRINGCHECK 2      151000 gas     222.94 MGas/s        1476.422 ops/s       677313 ns/op      2230872 CPU cycles (approx)
BLS12_PAIRINGCHECK 3      194000 gas     222.72 MGas/s        1148.038 ops/s       871051 ns/op      2868990 CPU cycles (approx)
BLS12_PAIRINGCHECK 4      237000 gas     223.83 MGas/s         944.446 ops/s      1058822 ns/op      3487463 CPU cycles (approx)
BLS12_PAIRINGCHECK 5      280000 gas     222.68 MGas/s         795.285 ops/s      1257411 ns/op      4141559 CPU cycles (approx)
BLS12_PAIRINGCHECK 6      323000 gas     224.12 MGas/s         693.859 ops/s      1441214 ns/op      4746960 CPU cycles (approx)
BLS12_PAIRINGCHECK 7      366000 gas     223.12 MGas/s         609.628 ops/s      1640344 ns/op      5402839 CPU cycles (approx)
BLS12_PAIRINGCHECK 8      409000 gas     223.75 MGas/s         547.073 ops/s      1827909 ns/op      6020628 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------

After

--------------------------------------------------------------------------------------------------------------------------------
BLS12_PAIRINGCHECK 1       33500 gas      72.73 MGas/s        2171.067 ops/s       460603 ns/op      1516963 CPU cycles (approx)
BLS12_PAIRINGCHECK 2       50000 gas      79.67 MGas/s        1593.476 ops/s       627559 ns/op      2067001 CPU cycles (approx)
BLS12_PAIRINGCHECK 3       66500 gas      82.81 MGas/s        1245.245 ops/s       803055 ns/op      2645035 CPU cycles (approx)
BLS12_PAIRINGCHECK 4       83000 gas      84.13 MGas/s        1013.575 ops/s       986607 ns/op      3249599 CPU cycles (approx)
BLS12_PAIRINGCHECK 5       99500 gas      85.30 MGas/s         857.262 ops/s      1166505 ns/op      3842124 CPU cycles (approx)
BLS12_PAIRINGCHECK 6      116000 gas      71.85 MGas/s         619.379 ops/s      1614520 ns/op      5317666 CPU cycles (approx)
BLS12_PAIRINGCHECK 7      132500 gas      75.60 MGas/s         570.603 ops/s      1752531 ns/op      5772145 CPU cycles (approx)
BLS12_PAIRINGCHECK 8      149000 gas      77.11 MGas/s         517.504 ops/s      1932352 ns/op      6364178 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------

Comparison with EIP-4844

This change is very motivated by the KZG_POINT_PRECOMPILE from EIP-4844 priced at 50000 gas that does a double pairing check + extras.

| `POINT_EVALUATION_PRECOMPILE_GAS` | `50000` |

EIPs/EIPS/eip-4844.md

Lines 200 to 224 in ca581e3

The precompile costs `POINT_EVALUATION_PRECOMPILE_GAS` and executes the following logic:
```python
def point_evaluation_precompile(input: Bytes) -> Bytes:
"""
Verify p(z) = y given commitment that corresponds to the polynomial p(x) and a KZG proof.
Also verify that the provided commitment matches the provided versioned_hash.
"""
# The data is encoded as follows: versioned_hash | z | y | commitment | proof | with z and y being padded 32 byte big endian values
assert len(input) == 192
versioned_hash = input[:32]
z = input[32:64]
y = input[64:96]
commitment = input[96:144]
proof = input[144:192]
# Verify commitment matches versioned_hash
assert kzg_to_versioned_hash(commitment) == versioned_hash
# Verify KZG proof with z and y in big endian format
assert verify_kzg_proof(commitment, z, y, proof)
# Return FIELD_ELEMENTS_PER_BLOB and BLS_MODULUS as padded 32 byte big endian values
return Bytes(U256(FIELD_ELEMENTS_PER_BLOB).to_be_bytes32() + U256(BLS_MODULUS).to_be_bytes32())
```

And from the consensus specs: https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/polynomial-commitments.md#verify_kzg_proof_impl

def verify_kzg_proof(commitment_bytes: Bytes48,
                     z_bytes: Bytes32,
                     y_bytes: Bytes32,
                     proof_bytes: Bytes48) -> bool:
    """
    Verify KZG proof that ``p(z) == y`` where ``p(z)`` is the polynomial represented by ``polynomial_kzg``.
    Receives inputs as bytes.
    Public method.
    """
    assert len(commitment_bytes) == BYTES_PER_COMMITMENT
    assert len(z_bytes) == BYTES_PER_FIELD_ELEMENT
    assert len(y_bytes) == BYTES_PER_FIELD_ELEMENT
    assert len(proof_bytes) == BYTES_PER_PROOF

    return verify_kzg_proof_impl(bytes_to_kzg_commitment(commitment_bytes),
                                 bytes_to_bls_field(z_bytes),
                                 bytes_to_bls_field(y_bytes),
                                 bytes_to_kzg_proof(proof_bytes))

def verify_kzg_proof_impl(commitment: KZGCommitment,
                          z: BLSFieldElement,
                          y: BLSFieldElement,
                          proof: KZGProof) -> bool:
    """
    Verify KZG proof that ``p(z) == y`` where ``p(z)`` is the polynomial represented by ``polynomial_kzg``.
    """
    # Verify: P - y = Q * (X - z)
    X_minus_z = bls.add(
        bls.bytes96_to_G2(KZG_SETUP_G2_MONOMIAL[1]),
        bls.multiply(bls.G2(), -z),
    )
    P_minus_y = bls.add(bls.bytes48_to_G1(commitment), bls.multiply(bls.G1(), -y))
    return bls.pairing_check([
        [P_minus_y, bls.neg(bls.G2())],
        [bls.bytes48_to_G1(proof), X_minus_z]
    ])

i.e. if using the same backend for EIP-2537 and EIP-4844, KZG_POINT_PRECOMPILE 50k gas should be the ceiling for double pairing.

To be in-line with EIP-4844 KZG point precompile
@mratsim mratsim requested a review from eth-bot as a code owner December 16, 2024 16:24
@github-actions github-actions bot added c-update Modifies an existing proposal s-review This EIP is in Review t-core labels Dec 16, 2024
@eth-bot
Copy link
Collaborator

eth-bot commented Dec 16, 2024

File EIPS/eip-2537.md

Requires 1 more reviewers from @asanso, @ineffectualproperty, @ralexstokes, @shamatar

@eth-bot eth-bot added the a-review Waiting on author to review label Dec 16, 2024
@eth-bot eth-bot changed the title Update eip-2537: PAIRING_CHECK repricing Update EIP-2537: PAIRING_CHECK repricing Dec 16, 2024
@mratsim
Copy link
Contributor Author

mratsim commented Dec 16, 2024

Closing in favor of #9098

@mratsim mratsim closed this Dec 16, 2024
Copy link
Contributor

@MarekM25 MarekM25 left a comment

Choose a reason for hiding this comment

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

This pricing might be too aggressive for clients using BLST and GNARK. We usually use ecRecover as a baseline. I would be curious to hear how it performs compared to BLST/GNARK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a-review Waiting on author to review c-update Modifies an existing proposal s-review This EIP is in Review t-core
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants