-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Problem Description
P256 cryptographic verification tests fail on REVM (local network) with ProviderError: execution reverted when calling the P256 precompile contract. All P256 signature verification operations revert, indicating the P256 (secp256r1) precompile is not implemented or not accessible in the current REVM environment.
Environment
OpenZeppelin Contracts Repository:
- URL: https://github.com/papermoonio/openzeppelin-contracts-revm
- Branch:
test-local-revm
Polkadot SDK (REVM Runtime):
- Repository: https://github.com/paritytech/polkadot-sdk
- Branch:
torsten/gas-fixes - Commit:
d8b2d89d23f052b9f5d1dd19dc0997960fb6686e
How to Reproduce
- Start REVM node (torsten/gas-fixes branch)
- Run P256 tests:
cd openzeppelin-contracts-revm git checkout test-local-revm npm installl npx hardhat test --network local --grep 'P256'
Test Results
222 passing (45s)
78 pending
3 failing
1) P256
with signature
verify valid signature:
ProviderError: execution reverted
at HttpProvider.request (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/node_modules/hardhat/src/internal/core/providers/http.ts:116:21)
at processTicksAndRejections (node:internal/process/task_queues:105:5)
at staticCallResult (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/node_modules/ethers/src.ts/contract/contract.ts:337:22)
at staticCall (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/node_modules/ethers/src.ts/contract/contract.ts:303:24)
at Proxy.$verifyNative (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/node_modules/ethers/src.ts/contract/contract.ts:351:41)
at Context.<anonymous> (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/test/utils/cryptography/P256.test.js:50:7)
2) P256
with signature
reject signature with flipped signature values ([r,s] >> [s,r]):
ProviderError: execution reverted
at HttpProvider.request (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/node_modules/hardhat/src/internal/core/providers/http.ts:116:21)
at processTicksAndRejections (node:internal/process/task_queues:105:5)
at staticCallResult (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/node_modules/ethers/src.ts/contract/contract.ts:337:22)
at staticCall (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/node_modules/ethers/src.ts/contract/contract.ts:303:24)
at Proxy.$verifyNative (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/node_modules/ethers/src.ts/contract/contract.ts:351:41)
at Context.<anonymous> (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/test/utils/cryptography/P256.test.js:118:7)
3) P256
with signature
reject signature with invalid message hash:
ProviderError: execution reverted
at HttpProvider.request (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/node_modules/hardhat/src/internal/core/providers/http.ts:116:21)
at processTicksAndRejections (node:internal/process/task_queues:105:5)
at staticCallResult (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/node_modules/ethers/src.ts/contract/contract.ts:337:22)
at staticCall (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/node_modules/ethers/src.ts/contract/contract.ts:303:24)
at Proxy.$verifyNative (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/node_modules/ethers/src.ts/contract/contract.ts:351:41)
at Context.<anonymous> (/Users/suvi/Documents/paritytech/papermoon/code/openzeppelin-contracts-revm/test/utils/cryptography/P256.test.js:132:7)
Error Details
All three tests fail with the same error pattern:
ProviderError: execution reverted
at HttpProvider.request (.../hardhat/src/internal/core/providers/http.ts:116:21)
at staticCallResult (.../ethers/src.ts/contract/contract.ts:337:22)
at staticCall (.../ethers/src.ts/contract/contract.ts:303:24)
at Proxy.$verifyNative (.../ethers/src.ts/contract/contract.ts:351:41)
at Context.<anonymous> (test/utils/cryptography/P256.test.js:50:7)Failed Test Cases:
- verify valid signature (P256.test.js:50)
- reject signature with flipped signature values (P256.test.js:118)
- reject signature with invalid message hash (P256.test.js:132)
Root Cause Analysis
Contract Code Analysis
The P256 library (contracts/utils/cryptography/P256.sol) uses a precompile call at address 0x100:
function verifyNative(
bytes32 digest,
bytes32 r,
bytes32 s,
bytes32 qx,
bytes32 qy
) internal view returns (bool valid) {
assembly ("memory-safe") {
// ...
valid := staticcall(gas(), 0x100, 0x00, 0xa0, 0x00, 0x20)
// ...
}
}Issue Identification
The staticcall to address 0x100 reverts, which indicates:
- P256 precompile (EIP-7212) is not implemented in the current REVM build
- Precompile address 0x100 is not registered in the REVM runtime
- Calls to non-existent precompiles revert rather than returning false
Invesigation
After investigating the code, I've noticed that secp256r1 feature was added in commit d15be1b2e3bcca98212d0cb7504535cdb72b8c98, but it seems not implemented correctly.
This actually mapped the precompile function to address 100, which is 0x64, but it should be mapped to address 0x100. So it should be:
const MATCHER: BuiltinAddressMatcher = BuiltinAddressMatcher::Fixed(NonZero::new(0x100).unwrap());
After this fixed, all P256 test cases run well.