Address: 0x0000000000000000000000000000000000001011
This is the implementation of RIP-7212, which provides a precompiled contract for verifying signatures in the secp256r1 or P-256 elliptic curve.
Overview
The P256 precompile enables efficient signature verification for the secp256r1 curve, which is widely used in modern security systems including:
- Apple’s Secure Enclave
- WebAuthn/FIDO2
- Android Keychain
- Various hardware security modules (HSMs)
- PassKeys
This precompile implementation is significantly more gas efficient (up to 60x) compared to Solidity-based implementations.
Interface
Implementation Library
Here’s a complete implementation of the P256 library that provides a convenient wrapper around the precompile:
Basic Usage
Using the P256 Library
Direct Precompile Usage
For more control, you can call the precompile directly:
The signature verification requires the following components:
digest: 32 bytes of the signed data hash
signature: Contains the r and s components of the signature
publicKey: Contains the x and y coordinates of the public key
The precompile expects these components to be encoded in a specific format:
- First 32 bytes: message hash
- Next 32 bytes:
r component of the signature
- Next 32 bytes:
s component of the signature
- Next 32 bytes:
x coordinate of the public key
- Next 32 bytes:
y coordinate of the public key
Total length: 160 bytes
Gas Costs
The precompile is highly gas efficient compared to Solidity implementations. The exact gas cost per byte of verified data is set to GasCostPerByte = 300, which gives us:
- Total Cost: 300 × 160 = 48,000 gas per verification
- Efficiency: Up to 60x more efficient than pure Solidity implementations
Real-World Use Cases
WebAuthn/PassKeys Authentication
Apple Secure Enclave Integration
Multi-Signature with Hardware Keys
Security Considerations
Important: Always validate public keys and signature components before verification to prevent invalid curve point attacks.
Public Key Validation
Signature Malleability
P256 signatures can be malleable. If your application requires unique signatures, implement additional checks:
JavaScript Integration
Error Handling
The P256 precompile returns no data on failure. Because verify is declared as returning bytes, a high-level Solidity interface call reverts when it tries to decode that empty return data — always use a low-level staticcall (as in the examples above) so invalid signatures resolve to false instead of reverting. Common failure cases include:
- Invalid Input Length: Input must be exactly 160 bytes
- Invalid Public Key: Point not on the P256 curve
- Invalid Signature: r or s values out of valid range
- Verification Failure: Signature doesn’t match message and public key
Testing
Unit Tests
- Gas Efficiency: 48,000 gas per verification vs 2M+ gas for Solidity implementations
- Batch Operations: Consider batching multiple verifications in a single transaction
- Caching: Cache public keys on-chain to reduce calldata for repeated verifications
- Hardware Integration: Particularly efficient for applications using hardware-backed keys