Skip to content

EIP-7951 (RIP-7212-compatible): secp256r1 P256VERIFY precompile#1708

Open
snissn wants to merge 17 commits intofilecoin-project:masterfrom
aaravm:master
Open

EIP-7951 (RIP-7212-compatible): secp256r1 P256VERIFY precompile#1708
snissn wants to merge 17 commits intofilecoin-project:masterfrom
aaravm:master

Conversation

@snissn
Copy link
Contributor

@snissn snissn commented Jan 5, 2026

Summary

  • Add a secp256r1/P-256 ECDSA verification precompile at address 0x0000000000000000000000000000000000000100 (0x0100), implementing EIP-7951 semantics (interface-compatible with RIP-7212).
  • Reserve 0x0100 in the precompile address space and wire it into precompile dispatch.
  • Add unit + integration tests (including a Solidity fixture) for valid/invalid inputs and call-with-value behavior.
  • Update dependencies, including bumping ruint to address RUSTSEC-2025-0137.

Implementation

  • Precompile dispatch and reserved address handling: actors/evm/src/interpreter/precompiles/mod.rs
  • P256VERIFY implementation: actors/evm/src/interpreter/precompiles/secp256r1.rs
    • Input encoding (160 bytes): msg_hash(32) || r(32) || s(32) || pubkey_x(32) || pubkey_y(32)
    • Return value: success => 32 bytes with last byte set to 0x01; failure => empty bytes

EIP-7951 security fixes

EIP-7951 fixes two edge cases present in RIP-7212 verification specs:

  • Point-at-infinity check for the verification point R'.
  • Modular comparison (r' ≡ r (mod n)) to handle cases where the x-coordinate of R' exceeds the curve order n.

This implementation relies on the p256/ecdsa verifier for correctness, and therefore follows the ECDSA verification procedure with these fixes.

Tests

  • cargo test -p fil_actor_evm

Notes / Risk

  • 0x...0100 is now a reserved precompile address; any code that previously treated it as a “normal” EVM address will now execute the precompile instead.

@github-project-automation github-project-automation bot moved this to 📌 Triage in FilOz Jan 5, 2026
@snissn snissn marked this pull request as ready for review January 5, 2026 18:47
Copilot AI review requested due to automatic review settings January 5, 2026 18:47
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements the RIP-7212 secp256r1 (P-256) signature verification precompile at address 0x0100. Note: The PR title mentions "EIP-7951" but the implementation references "RIP-7212" throughout.

Key Changes:

  • Adds secp256r1 ECDSA signature verification precompile using the p256 crate
  • Implements special-case handling for address 0x0100 in precompile lookup logic
  • Includes comprehensive test coverage with test vectors from daimo-eth/p256-verifier

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
actors/evm/src/interpreter/precompiles/secp256r1.rs Core implementation of RIP-7212 precompile with signature verification logic and extensive unit tests
actors/evm/src/interpreter/precompiles/mod.rs Registers the secp256r1 precompile at address 0x0100 with special-case lookup handling
actors/evm/tests/rip7212_precompile.rs Integration tests for precompile functionality including value transfer scenarios
actors/evm/tests/contracts/Secp256r1Precompile.sol Solidity test contract with test cases for valid/invalid signatures and edge cases
actors/evm/tests/contracts/Secp256r1Precompile.hex Compiled bytecode for the Solidity test contract
actors/evm/tests/basic.rs Integration test that invokes all Solidity test functions
actors/evm/Cargo.toml Adds p256 crate dependency for secp256r1 support and rstest for parameterized testing
Cargo.lock Lock file updates for new dependencies (p256, rstest, and transitive dependencies)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@snissn snissn marked this pull request as draft January 5, 2026 19:00
@BigLep BigLep moved this from 📌 Triage to ⌨️ In Progress in FilOz Jan 6, 2026
@snissn snissn marked this pull request as ready for review January 15, 2026 23:49
@codecov-commenter
Copy link

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.24%. Comparing base (2a06959) to head (05d591b).
⚠️ Report is 4 commits behind head on master.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1708      +/-   ##
==========================================
+ Coverage   91.23%   91.24%   +0.01%     
==========================================
  Files         151      152       +1     
  Lines       32006    32060      +54     
==========================================
+ Hits        29200    29254      +54     
  Misses       2806     2806              
Files with missing lines Coverage Δ
actors/evm/src/interpreter/precompiles/mod.rs 91.73% <100.00%> (+1.83%) ⬆️
...ctors/evm/src/interpreter/precompiles/secp256r1.rs 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@snissn snissn changed the title [DRAFT] EIP-7951: secp256r1 Precompile [DRAFT] EIP-7951 (RIP-7212-compatible): secp256r1 P256VERIFY precompile Jan 21, 2026
@snissn snissn changed the title [DRAFT] EIP-7951 (RIP-7212-compatible): secp256r1 P256VERIFY precompile EIP-7951 (RIP-7212-compatible): secp256r1 P256VERIFY precompile Jan 21, 2026
@snissn snissn requested a review from Copilot January 21, 2026 01:54
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@BigLep BigLep moved this from ⌨️ In Progress to 🔎 Awaiting Review in FilOz Jan 27, 2026
@BigLep BigLep requested a review from LesnyRumcajs January 27, 2026 04:33
@BigLep
Copy link
Member

BigLep commented Jan 27, 2026

@LesnyRumcajs : could someone from Forest take a first pass?

@LesnyRumcajs LesnyRumcajs requested review from hanabi1224 and removed request for LesnyRumcajs January 27, 2026 10:03
Copy link

@redpanda-f redpanda-f left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

I would like to understand this better: Why are we introducing tests/contracts/*.sol and *.hex at all? I feel secp256r1.rs should be enough? Am i missing something critical?

@github-project-automation github-project-automation bot moved this from 🔎 Awaiting Review to ⌨️ In Progress in FilOz Feb 24, 2026
@rvagg
Copy link
Member

rvagg commented Feb 25, 2026

Why are we introducing tests/contracts/*.sol and *.hex at all?

They're first-line integration tests. Can the evm actor even decode standard solidity that includes this new opcode and run it as expected. Being able to run it in Rust is one thing, being able to hit it from the Solidity path is another. See https://github.com/filecoin-project/builtin-actors/tree/master/actors/evm/tests/contracts for a bunch of others, and also #1720 that @ZenGround0 added today for the SectorStatus FIP as an integration test to exercise a feature that's supposed to be exposed to smart contracts. The feature might work, but does it work when you call it from a smart contract.

For many of these we'll also do the same in Lotus to integration test at even higher level - it runs here in Rust, but does it run when compiled to WASM, executed in FVM and called from a message in Lotus. See here for recent EVM features that @snissn added (TSTORE and BLS precompiles): https://github.com/filecoin-project/lotus/blob/7741226198083e943a64d917e88a0a77d17aa30e/itests/fevm_test.go#L1831-L1908 -- @wjmelements this might also be interesting on your question of activation, our integration tests can be configured to tick over from one network version to another (see the top of the TSTORE test for example), so for EVM features like this we can say "feature doesn't exist and therefore reverts", then "now it works" within the space of an epoch.

@wjmelements
Copy link

This has pretty good test coverage. I'd like additional testing for when there is excess or truncated calldata.

@snissn
Copy link
Contributor Author

snissn commented Mar 17, 2026

Addressed the remaining code changes in:

  • 0c02741f chore(evm): align P256VERIFY naming with EIP-7951
  • 70b0100d test(evm): cover boundary-length P256VERIFY calldata

@redpanda-f on the .sol / .hex question: those files are intentional FEVM integration coverage for the Solidity staticcall path. secp256r1.rs covers the Rust/unit behavior, while actors/evm/tests/contracts/Secp256r1Precompile.sol plus actors/evm/tests/basic.rs verify that the feature is reachable through compiled contract bytecode and the contract-call harness.

@wjmelements I also added explicit FEVM-level truncated/excess calldata coverage in actors/evm/tests/p256verify_precompile.rs for 159-byte and 161-byte inputs. The existing Solidity short/long cases are still covered via testFailShortInput1 and testFailLongInput in basic.rs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ⌨️ In Progress

Development

Successfully merging this pull request may close these issues.

8 participants