Standard / EIP·EVM
EIP-7212 / RIP-7212 — secp256r1 (P-256) Precompile
Precompiled contract at address `0x0000...0100` that verifies secp256r1 (NIST P-256) ECDSA signatures, enabling cheap on-chain verification of WebAuthn / passkey signatures from Apple Secure Enclave, Android Keystore, and YubiKeys. Status: the L1 EIP-7212 was withdrawn from eips.ethereum.org and migrated to RIP-7212 (Final), shipped on Polygon PoS, OP Stack chains, Arbitrum (Stylus precompile), Base, and others. NOT included in Pectra — L1 inclusion is targeted for a future fork (currently tracked under EIP-7951 for L1 P-256 precompile at 0x0100).
- 01passkey / WebAuthn signing for smart accounts
- 02secure-enclave-backed wallets without ECDSA-over-secp256k1
- 03iOS/Android device-bound keys
- 04ERC-4337 P-256 validators
- pnpm add viem # viem includes p256 utilities for verification fallback
- pnpm add @simplewebauthn/server # server-side WebAuthn
- # Solidity fallback when precompile is unavailable: Daimo's p256-verifier (0xc2b78104907F722DABAc4C69f826a522B2754De4 cross-chain deterministic deploy)
Use the secp256r1 precompile at address `0x0000000000000000000000000000000000000100` to verify P-256 / WebAuthn signatures on-chain. Input is 160 bytes of ABI-packed `(bytes32 messageHash, bytes32 r, bytes32 s, bytes32 x, bytes32 y)`; on success returns 32-byte `0x...01`, on failure returns empty bytes (NOT a revert). In Solidity: `(bool ok, bytes memory ret) = address(0x100).staticcall(abi.encode(hash, r, s, x, y)); return ok && ret.length == 32 && bytes32(ret) == bytes32(uint256(1));`. For chains that have not deployed the precompile, fall back to Daimo's `P256Verifier` contract (same calldata layout, deployed deterministically at `0xc2b78104907F722DABAc4C69f826a522B2754De4`). Combine with ERC-4337 + ERC-7579 to build a passkey validator module that recovers the WebAuthn `clientDataJSON` and `authenticatorData`, hashes them per WebAuthn level 2 spec, then calls the precompile.
- ⚑EIP-7212 (L1) was withdrawn from the EIPs repo; the live spec is RIP-7212 in `ethereum/RIPs`. L1 mainnet has NO secp256r1 precompile yet — Pectra did NOT include it. Track EIP-7951 for the L1 successor.
- ⚑Per-chain availability varies: live on Polygon PoS, OP Stack (OP/Base/Worldchain post-Granite), Arbitrum (via Stylus), zkSync; NOT on Ethereum L1, NOT on most Cosmos EVM chains. Always feature-detect or use the Daimo fallback.
- ⚑Failure returns EMPTY bytes (length 0), not a revert and not 0x...00. A naive `abi.decode(ret, (bool))` reverts on failure — check `ret.length == 32` first.
- ⚑WebAuthn signatures use low-S normalization; some authenticators return high-S which the precompile rejects. Normalize with `s = min(s, n - s)` before submission.
- ⚑The hash input is the raw 32-byte digest, NOT prefixed with `\x19Ethereum Signed Message` — passkey messages are hashed per WebAuthn (sha256 of authenticatorData || sha256(clientDataJSON)).
- ⚑Gas cost is ~3450 (RIP-7212) — much cheaper than Solidity P-256 (~330k+), but factor it into bundler estimation for ERC-4337 validators.