Examples
- Recover Public Key - Recover public key from signature (ecRecover)
- Sign Transaction - Sign and recover sender address
Secp256k1 Public Key Recovery
Recover the signer’s public key from an ECDSA signature and message hash. This is the core mechanism of Ethereum’secRecover precompile and enables address-based authentication without storing public keys on-chain.
Overview
ECDSA signatures contain enough information to recover the signer’s public key:- Signature (r, s, v) - 65 bytes
- Message hash - 32 bytes
- ecRecover precompile - On-chain signature verification (address 0x01)
- Transaction authentication - Derive sender address from transaction signature
- Message signing - Verify signed messages (EIP-191, EIP-712)
- Compact storage - Store signatures instead of public keys
API
recoverPublicKey(signature, messageHash)
Recover the 64-byte public key from a signature and message hash.
Parameters:
signature(BrandedSignature) - Signature with r, s, v componentsmessageHash(HashType) - 32-byte hash that was signed
Uint8Array - 64-byte uncompressed public key (x || y)
Throws:
InvalidSignatureError- Invalid signature format or recovery failedInvalidHashError- Hash wrong length
Algorithm Details
ECDSA Public Key Recovery
Given signature (r, s, v) and message hash e:-
Reconstruct R point from r:
ris the x-coordinate of ephemeral point R = k * G- Solve for y:
y² = x³ + 7 mod p(curve equation) - Two possible y values (positive and negative)
- Recovery ID v selects which y to use
-
Calculate helper values:
r_inv = r^-1 mod n(modular inverse of r)e_neg = -e mod n(negation of message hash)
-
Recover public key:
Where:
Ris the reconstructed pointGis the generator point*denotes scalar multiplication
-
Verify recovery:
- Check recovered key is valid curve point
- Optionally verify signature with recovered key
Why Recovery Works
The signature was created as:public_key = private_key * G and R = k * G:
Recovery ID (v)
The recovery ID v resolves ambiguities in recovery: Two y-coordinates: For each x-coordinate r, there are two possible y-values satisfying the curve equation (y and p - y). The recovery ID selects which one. Ethereum format:- v = 27: Use y with even parity (y & 1 == 0)
- v = 28: Use y with odd parity (y & 1 == 1)
- v = 0: Even parity
- v = 1: Odd parity
- v = chainId * 2 + 35: Even parity
- v = chainId * 2 + 36: Odd parity
Ethereum Integration
ecRecover Precompile
Ethereum provides a precompiled contract at address0x0000000000000000000000000000000000000001 for on-chain recovery:
Solidity:
Transaction Sender Recovery
Every Ethereum transaction signature enables sender recovery:EIP-191 Personal Sign
Recover signer from personal_sign messages:EIP-712 Typed Data
Recover signer from typed structured data:Security Considerations
Recovery Uniqueness
Critical: Recovery is only unique with the correct v value. Wrong v recovers a different (invalid) public key.Malleability Protection
Signature malleability affects recovery: Original signature:Invalid Signature Handling
Invalid signatures can:- Return incorrect public keys
- Throw errors during recovery
- Recover keys not on the curve
Test Vectors
Basic Recovery
Recovery ID Selection
EIP-191 Personal Sign
Invalid Signature Recovery
Performance
Public key recovery is more expensive than verification:- Verification: Requires 2 scalar multiplications
- Recovery: Requires 2 scalar multiplications + modular square root
- TypeScript (@noble/curves): ~1-2ms per signature
- Zig (native): ~0.5-1ms per signature
- WASM (portable): ~2-4ms per signature
- EVM (ecRecover precompile): 3000 gas (~60µs at 50M gas/sec)
verify() with known public key over recovery.
Implementation Notes
TypeScript
Uses@noble/curves/secp256k1:
- Implements recovery via point reconstruction
- Handles both standard (0/1) and Ethereum (27/28) v values
- Validates recovered keys before returning
- Constant-time operations
Zig
Custom implementation:- ⚠️ UNAUDITED - Not security reviewed
- Implements modular square root for y recovery
- Basic validation only
- Educational purposes only
Related
- Signing - Create signatures with private keys
- Verification - Verify signatures with known public keys
- Key Derivation - Derive public keys from private keys
- Usage Patterns - Transaction and message signing examples
- EIP-191 - Signed data standard
- EIP-712 - Typed structured data hashing and signing

