# Ambiguous Point at Infinity Handling in EIP-2537 Could Lead to Network Split and Mass Val- idator Slashing

EIP-2537's ambiguous point-at-infinity rule for BLS12-381 pairing precompile causes Nethermind to accept pairings other clients reject, risking consensus split and validator slashing.

- Payout: Contest reward
- Severity: high
- Program: Ethereum Pectra Protocol Specification
- Credited: NDKoo
- Disclosed: 2025-07-21
- Write-up quality: 7/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_ethereum_pectra_protocol_specification.pdf#3.1.1
- Library page: https://bugbountylibrary.com/r/cantina%3Aethereum_pectra_protocol_specification%3A3.1.1
- Tags: domain:web3 impact:dos impact:integrity kind:contest platform:cantina sev:high tech:evm technique:parser-differential technique:source-review vuln:crypto vuln:misconfiguration

**Target:** EIP-2537 BLS12-381 pairing check precompile (0x0f)
**Root cause:** Spec says 'if any input is the infinity point, pairing result will be 1' without defining whether that applies per-pair or to the final product, so clients diverge: Nethermind short-circuits any pair containing infinity to true, while execution-specs multiplies pairings and compares the product to one.
**Steps:**
1. Read EIP-2537 pairing precompile spec and note the ambiguous infinity clause.
2. Compare execution-specs bls12_381_pairing.py (result *= pairing(...); compare FQ12.one()) against Nethermind PairingCheckPrecompile.cs (if x.IsInf()||y.IsInf() -> hasInf=true; continue; verified = hasInf || acc.FinalExp().IsOne()).
3. Craft 384-byte-per-pair inputs where one pair has G1 or G2 at infinity and remaining pairs do not multiply to identity, e.g. `data2` (G1 point 2 = infinity) and `data3` (G2 point 2 = infinity).
4. Run Nethermind test `dotnet test Nethermind.Evm.Test.csproj --filter FullyQualifiedName=Nethermind.Evm.Test.BlsPairingCheckPrecompileTests` and the python PoC in execution-specs; observe Nethermind returns 1 while spec returns 0.
**How found:** Code-reading comparison of the EIP text against two client implementations; noticed the spec's infinity sentence is mathematically ambiguous for multi-pairing products, then diffed execution-specs vs Nethermind logic and built test vectors with infinity points in one pair.
**Exploitation:** No direct theft; a crafted precompile call yields divergent return values across clients. If a consensus-critical protocol (e.g. BLS signature verification in a contract) relies on the pairing result, the same transaction/block validates on Nethermind but fails on other clients, splitting the chain and slashing validators on the minority fork.
**Escalation:** Divergence in a precompile reachable from any contract can be embedded in a transaction that only some clients accept, amplifying to chain split and mass slashing.
**Insight:** When a spec defines a special-case return value ('result will be 1') for degenerate inputs, check whether each client applies it per-element or to the aggregate — differential-test multi-element inputs mixing degenerate and normal elements, since single-element tests pass everywhere.
