Skip to content
Open
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
136 changes: 136 additions & 0 deletions FIPS/fip-0113.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
---
fip: 0113
title: secp256r1 (P-256) P256VERIFY Precompile for FEVM
author: "Aarav Mehta (@aaravm), Michael Seiler (@snissn)"
discussions-to: https://github.com/filecoin-project/FIPs/discussions/1227
status: Draft
type: Technical
category: Core
created: 2026-01-20
spec-sections:
---

# FIP: secp256r1 (P-256) `P256VERIFY` Precompile for FEVM

## Simple Summary
This proposal introduces a new FEVM precompile for efficient ECDSA signature verification over the secp256r1 (P-256) elliptic curve, as specified by Ethereum’s [EIP-7951](https://eips.ethereum.org/EIPS/eip-7951). This enables practical verification of signatures produced by common secure hardware and standards such as WebAuthn/passkeys, and improves compatibility with EVM ecosystems that already standardize on this interface.

## Abstract
This FIP proposes adding a `P256VERIFY` precompile at Ethereum address `0x0000000000000000000000000000000000000100` (i.e., `0x0100`) to the FEVM. The precompile verifies an ECDSA signature `(r,s)` against a 32-byte message hash and an uncompressed public key `(x,y)` on the secp256r1 curve, returning `0x…01` on success and an empty byte array on failure.

For Filecoin’s purposes, **EIP-7951 and [RIP-7212](https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md) should be understood as addressing the same user-facing feature**: a `P256VERIFY` precompile at `0x0100`. At the EVM interface level they are equivalent: same address, same 160-byte input format, and same return values/failure behavior. The key difference is that EIP-7951 tightens validation/verification requirements (notably: a point-at-infinity check and a modular comparison `r' ≡ r (mod n)`), while Ethereum’s fixed *EVM gas schedule* for this precompile is not directly applicable to FEVM’s gas accounting model.

Accordingly, this FIP targets EIP-7951 semantics while remaining interface-compatible with RIP-7212-style callers.

## Change Motivation
Many modern authentication and key-management systems rely on secp256r1, including WebAuthn/FIDO2 passkeys and device secure enclaves. Without a precompile, verifying secp256r1 signatures in Solidity is expensive, complex, and often impractical.

Adding a native precompile:
- Enables account abstraction patterns and authentication flows backed by passkeys and secure hardware.
- Improves portability of applications and libraries that already target EIP-7951 / RIP-7212 style verification.
- Provides a simpler alternative to custom signature schemes for user authentication in FEVM dApps.

EIP-7951 is now live on Ethereum mainnet (Fusaka, activated December 3, 2025; see announcement [here](https://blog.ethereum.org/2025/11/06/fusaka-mainnet-announcement)), making the `0x0100` interface an increasingly standard dependency in EVM tooling. Supporting the same interface in FEVM reduces friction for cross-chain portability and ecosystem reuse.

## Specification

### Precompile Address
This FIP adds the following precompile to the FEVM:

| Operation | Address | Description |
|------------|----------|----------------------------------------------|
| `P256VERIFY` | `0x0100` | secp256r1 (P-256) ECDSA signature verification |

The address `0x0100` MUST be treated as a reserved precompile address (i.e., it is not deployable via the EAM).

### ABI

#### Input
The precompile expects exactly 160 bytes of input, interpreted as the concatenation:

`msg_hash(32) || r(32) || s(32) || pubkey_x(32) || pubkey_y(32)`

All values are unsigned, big-endian encoded.

The `msg_hash` is the 32-byte hash of the signed message (i.e., the precompile performs verification on a pre-hashed message).

#### Output
- If the signature is valid, the precompile returns 32 bytes equal to:
`0x0000000000000000000000000000000000000000000000000000000000000001`
- Otherwise (including malformed input), it returns an empty byte array.

The precompile MUST NOT revert under any circumstances due to malformed input or signature failure.

### EIP-7951 / RIP-7212 Interface Compatibility
EIP-7951 intentionally retains the RIP-7212 interface. For FEVM, this means:
- Same address: `0x0100`
- Same input format: 160 bytes (`msg_hash || r || s || x || y`)
- Same output format: 32 bytes on success, empty bytes on failure
- Same return values and “no-revert” failure semantics

EIP-7951 additionally tightens validation/verification requirements (security fixes). Ethereum specifies a fixed EVM gas cost for the precompile; FEVM uses Filecoin gas accounting instead (see “Gas Accounting”).

### Validation and Verification Rules
The precompile MUST implement the validation rules described in EIP-7951, including:
- Input length MUST be exactly 160 bytes.
- Signature components `r` and `s` MUST satisfy `0 < r < n` and `0 < s < n`, where `n` is the curve subgroup order.
- Public key coordinates `x` and `y` MUST satisfy `0 ≤ x < p` and `0 ≤ y < p`, where `p` is the base field modulus.
- The point `(x, y)` MUST be on the secp256r1 curve and MUST NOT be the point at infinity.
- Signature verification MUST follow ECDSA verification for secp256r1 and MUST be deterministic across implementations, including:
- Rejecting cases where the recovered point `R'` (in the ECDSA verification procedure) is the point at infinity.
- Comparing `r'` to `r` modulo `n` (i.e., `r' ≡ r (mod n)`).

### Gas Accounting
FEVM gas accounting follows Filecoin mechanics (not Ethereum’s), as described in [FIP-0054](./fip-0054.md).

EIP-7951 specifies an Ethereum gas cost for `P256VERIFY`, and RIP-7212 specifies a different Ethereum gas cost for the same interface. **FEVM does not adopt Ethereum’s fixed gas schedule for precompiles**, so this FIP does not specify an Ethereum-style gas number. Instead, it introduces the precompile and specifies its input/output semantics and validation behavior.

An implementation must not introduce a special syscall/pricelist gas charge for this operation. Execution is charged via FEVM’s normal instrumented Wasm instruction accounting, so the observed cost depends on the Wasm-level execution cost of the precompile implementation.

## Design Rationale
This FIP adopts the EIP-7951/RIP-7212 `0x0100` interface to maximize compatibility with existing EVM tooling and contracts.

EIP-7951 supersedes RIP-7212 by keeping the same interface while fixing edge cases that can lead to incorrect or implementation-dependent behavior. This FIP therefore specifies EIP-7951’s stricter validation and verification rules while preserving full interface compatibility with RIP-7212-style callers.

The precompile performs verification (not public key recovery) because secp256r1 signing stacks commonly expose verification APIs and do not universally produce recovery identifiers.

## Backwards Compatibility
This FIP introduces a new reserved precompile address at `0x0100`. Any existing contract calls to this address that previously executed deployed bytecode (if such bytecode exists) will instead execute the precompile after the upgrade. While creating a contract at this exact address is extremely unlikely in practice, it is possible (e.g., via `CREATE2`) prior to the address being reserved.

Contracts that do not use `0x0100` are unaffected.

## Test Cases
An implementation of this FIP SHOULD include:
- Unit tests using known-good secp256r1 ECDSA verification vectors (success and failure cases), including EIP-7951 test vectors from https://eips.ethereum.org/assets/eip-7951/test-vectors.json.
- Integration tests that invoke the precompile from Solidity, including:
- Valid signature verification returning `0x…01`.
- Invalid inputs returning empty output (without reverting).
- Calls with non-zero value, ensuring transfer semantics match FEVM precompile behavior.

## Security Considerations
This precompile verifies signatures over untrusted inputs and MUST be implemented carefully to avoid consensus-critical discrepancies across clients. In particular:
- Validation MUST reject invalid encodings, out-of-range values, invalid points, and infinity edge cases in a deterministic manner.
- The precompile interface does not enforce non-malleability checks (e.g., “low-s” normalization); applications that require non-malleability SHOULD enforce it at a higher layer.
- Implementations are not required to be constant-time, but must be safe with respect to malformed input and must not panic or exhibit undefined behavior.

## Incentive Considerations
This FIP introduces no changes to Filecoin consensus incentives. It enables new applications and authentication patterns in FEVM smart contracts.

## Product Considerations
This precompile makes passkey/WebAuthn-backed authentication and device-secure signing practical for FEVM applications. It also improves compatibility with Ethereum ecosystems adopting the same precompile interface, reducing friction for developers porting contracts and libraries to Filecoin.

## Implementation
Reference implementation is available and ready for review:
- builtin-actors: https://github.com/filecoin-project/builtin-actors/pull/1708
- Lotus (integration test): TODO

Node implementations (e.g., Lotus, Forest) will need to consume the updated built-in actors bundle in a network upgrade.

## TODO
- Decide the target network upgrade / actor bundle version for activation.
- Benchmark gas for representative `P256VERIFY` calls under FEVM’s Wasm-instrumented gas accounting.
- Validate EIP-7951 test vectors against a deployed `0x0100` precompile once available in a target network.
- Check whether `0x0100` has been occupied on relevant networks prior to reserving it, and document findings.

## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,4 @@ This improvement protocol helps achieve that objective for all members of the Fi
| [0109](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0109.md) | Enable smart contract notifications for Direct Data Onboarding (DDO) | FIP | Rod Vagg (@rvagg) | Final |
| [0110](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0110.md) | Allow Shorter Deal Durations | FIP | Will Scott (@willscott) | Draft |
| [0111](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0111.md) | Add Support for EIP-7702 (Set Code for EOAs) in the FEVM | FIP | Michael Seiler (@snissn), Aarav Mehta (@aaravm) | Draft |

| [0113](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0113.md) | secp256r1 (P-256) P256VERIFY Precompile for FEVM | FIP | Aarav Mehta (@aaravm), Michael Seiler (@snissn) | Draft |