# Incomplete elliptic curve point validation

On-curve check skipped or unbound; subgroup/range tests pass for off-curve or inconsistent points

_Area: Memory corruption and native code. Seen in 2 disclosed reports; latest 2025-07-21. Updated 2026-10-23._

## How it works
Elliptic-curve code must establish several independent facts about a point: that it is on the curve, that it lies in the correct subgroup, and that its coordinates are correctly decoded. These are separate properties. The bug is treating one as implying another. A subgroup/endomorphism test, a per-limb range check, or a byte-decoding helper can all pass while the point is off-curve or the limbs do not recompose to the claimed value. The assumption that breaks is "if the cheap check passes, the expensive/other check is unnecessary."

## Where it shows up
- On-curve check placed inside a failure branch of a subgroup test rather than as a precondition [E1](https://bugbountylibrary.com/r/cantina%3Aethereum_pectra_besu%3A3.1.2.md)
- Precompiles (MSM, pairing) that delegate validation to a library and trust its ordering [E1](https://bugbountylibrary.com/r/cantina%3Aethereum_pectra_besu%3A3.1.2.md)
- Hint/advice functions whose internal bounds are mistaken for constraints [E2](https://bugbountylibrary.com/r/c4%3A2025-09-succinct%3AH-01.md)
- Range checks that constrain limb bitlengths but never assert recomposition to the source value [E2](https://bugbountylibrary.com/r/c4%3A2025-09-succinct%3AH-01.md)
- Hardcoded generator/neg-generator constants decoded with a shared helper whose endianness differs [E3](https://bugbountylibrary.com/r/cantina%3Aopenvm_january2025%3A3.1.18.md)
- Curve arithmetic that ignores a curve parameter (e.g. curve_a) [E3](https://bugbountylibrary.com/r/cantina%3Aopenvm_january2025%3A3.1.18.md)

## How to review
For every point-accepting entry point, confirm the invariant: a point is accepted only if it is on the curve AND in the subgroup AND its coordinates decode correctly. Check ordering: the on-curve test must be a precondition, not a fallback. In hint-based circuits, confirm an explicit equality constraint binds hinted limbs to the source value; a hint's internal check is not a constraint [E2](https://bugbountylibrary.com/r/c4%3A2025-09-succinct%3AH-01.md). For hardcoded constants, diff endianness against an external reference and verify the decoded point is on-curve [E3](https://bugbountylibrary.com/r/cantina%3Aopenvm_january2025%3A3.1.18.md).

## Variants seen
- Subgroup endomorphism test passes for off-curve points; on-curve check only in failure branch [E1](https://bugbountylibrary.com/r/cantina%3Aethereum_pectra_besu%3A3.1.2.md)
- Limb range check without recomposition assertion, letting a malicious prover supply inconsistent witnesses [E2](https://bugbountylibrary.com/r/c4%3A2025-09-succinct%3AH-01.md)
- Wrong-endianness generator constants yielding off-curve points that still compile [E3](https://bugbountylibrary.com/r/cantina%3Aopenvm_january2025%3A3.1.18.md)

## Impact and severity
E1 caused a chain split between clients — high severity, consensus-critical. E2 enabled invalid witnesses from a malicious prover. E3 broke all P256 group operations. Severity rises when the check guards consensus or proof soundness, and when the gap is silent (compiles, passes cheap tests).

## Why fixes fail
E1's fix pattern is fragile: moving the on-curve check out of the failure branch is required, but any later refactor that reorders validation can regress it.

## Evidence
- E1: https://bugbountylibrary.com/r/cantina%3Aethereum_pectra_besu%3A3.1.2.md
- E2: https://bugbountylibrary.com/r/c4%3A2025-09-succinct%3AH-01.md
- E3: https://bugbountylibrary.com/r/cantina%3Aopenvm_january2025%3A3.1.18.md
