Skip to content

feat(evm): add RIP-7212 P256VERIFY (secp256r1) precompile at 0x100 - #392

Open
sfffaaa wants to merge 1 commit into
devfrom
feature/blk-1007-precompile-p256
Open

feat(evm): add RIP-7212 P256VERIFY (secp256r1) precompile at 0x100#392
sfffaaa wants to merge 1 commit into
devfrom
feature/blk-1007-precompile-p256

Conversation

@sfffaaa

@sfffaaa sfffaaa commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a native EVM precompile for P-256 (secp256r1) signature verification at address 0x100, interface-compatible with Ethereum RIP-7212.

The EVM's built-in ecrecover (0x01) verifies secp256k1 only. P-256 — the curve used by passkeys/WebAuthn, Apple Secure Enclave, Android Keystore and HSMs — currently requires a pure-Solidity verifier at roughly 200k–330k gas per verification. This precompile does the same work for 3,450 gas, and contracts written against OpenZeppelin's P256 library (which probes 0x100 and falls back to Solidity) switch to the cheap path automatically once this activates, with no code change.

Interface (exact RIP-7212)

Address 0x0000000000000000000000000000000000000100 (RIP-7212 standard)
Input 160 bytes: msgHash(32) ‖ r(32) ‖ s(32) ‖ pubX(32) ‖ pubY(32)
Output 32-byte 1 if valid; empty if invalid/malformed; never reverts
Gas 3,450 flat

Denial-of-service pricing (reviewer attention)

3,450 gas is the RIP-7212 constant, far below the real cost of the elliptic-curve work, so the block-weight meter is separately charged the actual verification cost via record_external_cost (P256VerifyWeight). Pricing the meter by gas alone would let a caller fill blocks with underpriced verification.

That weight is now measured rather than borrowed. The same p256 verify path was compiled to wasm32 and executed under Cranelift — the runtime's own execution mode:

value
Measured on a development machine 2.79 ms median, 3.22 ms p90
That machine vs reference hardware ~1.25x slower (derived by running the committed parachain_staking::payout_collator benchmark on both)
Reference-hardware equivalent ~2.24 ms median, ~2.58 ms p90
Constant set to 2.5 ms (2_500_000_000 ps)

This is ~1.4x higher than the figure published for the same crate elsewhere, which an earlier revision of this branch used; on these measurements that figure under-charges the meter. A benchmark generated on peaq reference hardware is still preferable and the constant should be replaced when one exists — the code comment says so.

Capacity impact is negligible: at 2.5 ms a block still admits roughly 800 verifications, far beyond any legitimate load, so the more conservative value costs nothing in practice.

Changes

New crate precompiles/p256verify (p256 0.13.2, no_std), wired into the peaq, peaq-dev and krest runtimes with the standard Ethereum precompile checks. No spec_version bump (release process owns it).

Testing

  • Crate unit tests; all three runtimes compile standalone on this commit (stack base for the Ed25519 PR).
  • End-to-end against a live dev network built from this branch: the official RIP-7212 test vectors pass byte-for-byte (valid → 0x…01; corrupted hash and wrong-length input → empty, no revert). Test suite lives in peaq-bc-test branch feature/sig-precompile-tests.

Interim availability note

Until this activates, P-256 verification is already possible via the audited Daimo verifier deployed at the canonical cross-chain address 0xc2b78104907F722DABAc4C69f826a522B2754De4 on peaq mainnet and agung (~330k gas).

@peaq-coolify

peaq-coolify Bot commented Aug 15, 2026

Copy link
Copy Markdown

The preview deployment for peaqnetwork/peaq-network-node:ci/012453_add-auto-upgrade-on-preview-environment-iswg08ckww0c4k48oggoo400 is ready. 🟢

Open Preview | Open Build Logs

Last updated at: 2026-08-18 14:02:08 CET

On-chain secp256r1 (P-256 / NIST P-256) ECDSA verification in the EVM,
enabling passkey/WebAuthn/secure-enclave signatures and P-256 account
abstraction. secp256k1 (ecrecover at 0x01) cannot verify P-256 -- it is a
different curve.

- New crate pallet-evm-precompile-p256verify, ported from Moonbeam's
  implementation (p256 0.13.2, ecdsa, no_std); passes the official RIP-7212
  test vectors (2 valid + 3 invalid).
- Registered at address 0x100 with 3450 gas (RIP-7212 spec value) on the
  peaq, peaq-dev and krest runtimes.
- The block-weight DoS meter is charged the real ~1.6 ms verify cost via
  record_external_cost (mirroring Moonbeam's benchmark), so the 3450 gas
  cannot be used to under-price the operation and grief block production.

Additive only: new precompile at a previously-unused address; no storage
migration and no change to existing precompiles. spec_version is left for
the release process to bump.
@sfffaaa
sfffaaa force-pushed the feature/blk-1007-precompile-p256 branch from 2ecf8ad to cc4d135 Compare August 18, 2026 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant