This page is a placeholder. All examples on this page are currently AI-generated and are not correct. This documentation will be completed in the future with accurate, tested examples.
Overview
Precompiled contracts are special Ethereum addresses (0x01-0x13+) that execute optimized native code instead of EVM bytecode. They provide gas-efficient implementations of computationally expensive operations like cryptographic primitives, hashing, and elliptic curve operations.
Voltaire provides low-level tree-shakable implementations of all standard precompiles in both TypeScript and Zig, with WASM compilation support for portable high-performance execution. For complete spec-compliant EVM implementations that use these precompiles, see evmts/guillotine and evmts/tevm-monorepo.
Complete Precompile Reference
| Address | Name | Gas Cost | Hardfork | Category | Description |
|---|
| 0x01 | ECRECOVER | 3,000 | Frontier | Crypto | Recover ECDSA signer address |
| 0x02 | SHA256 | 60 + 12/word | Frontier | Hash | SHA-256 hash function |
| 0x03 | RIPEMD160 | 600 + 120/word | Frontier | Hash | RIPEMD-160 hash function |
| 0x04 | IDENTITY | 15 + 3/word | Frontier | Data | Copy input to output |
| 0x05 | MODEXP | Dynamic | Byzantium | Math | Modular exponentiation |
| 0x06 | BN254_ADD | 150 | Byzantium | zkSNARKs | BN254 G1 point addition |
| 0x07 | BN254_MUL | 6,000 | Byzantium | zkSNARKs | BN254 G1 scalar multiplication |
| 0x08 | BN254_PAIRING | 45,000 + 34,000k | Byzantium | zkSNARKs | BN254 pairing check |
| 0x09 | BLAKE2F | Dynamic | Istanbul | Hash | BLAKE2b compression function |
| 0x0A | POINT_EVALUATION | 50,000 | Cancun | Blobs | KZG point evaluation (EIP-4844) |
| 0x0B | BLS12_G1_ADD | 500 | Prague | ETH2 | BLS12-381 G1 point addition |
| 0x0C | BLS12_G1_MUL | 12,000 | Prague | ETH2 | BLS12-381 G1 scalar multiplication |
| 0x0D | BLS12_G1_MSM | Variable | Prague | ETH2 | BLS12-381 G1 multi-scalar multiplication |
| 0x0E | BLS12_G2_ADD | 800 | Prague | ETH2 | BLS12-381 G2 point addition |
| 0x0F | BLS12_G2_MUL | 45,000 | Prague | ETH2 | BLS12-381 G2 scalar multiplication |
| 0x10 | BLS12_G2_MSM | Variable | Prague | ETH2 | BLS12-381 G2 multi-scalar multiplication |
| 0x11 | BLS12_PAIRING | 115,000 + 23,000k | Prague | ETH2 | BLS12-381 pairing check |
| 0x12 | BLS12_MAP_FP_TO_G1 | 5,500 | Prague | ETH2 | Map field element to G1 (hash-to-curve) |
| 0x13 | BLS12_MAP_FP2_TO_G2 | 75,000 | Prague | ETH2 | Map Fp2 element to G2 (hash-to-curve) |
Precompile Categories
Cryptography (0x01)
ECRECOVER recovers the Ethereum address from an ECDSA signature. Essential for transaction validation and signature verification.
- Gas: 3,000 (fixed)
- Input: 128 bytes (hash, v, r, s)
- Output: 20-byte address
- Use: Transaction signing, off-chain authentication
Hashing (0x02, 0x03, 0x09)
SHA256, RIPEMD160, BLAKE2F provide standard cryptographic hash functions.
- SHA256: Bitcoin compatibility, Merkle trees
- RIPEMD160: Bitcoin address generation
- BLAKE2F: High-performance modern hash (Zcash)
Data Operations (0x04)
IDENTITY is a simple memcpy operation, mainly used for:
- Gas benchmarking
- Data copying in complex contracts
- ABI encoding/decoding optimization
Mathematics (0x05)
MODEXP performs modular exponentiation: (base^exp) mod modulus
- RSA signature verification
- Zero-knowledge proof systems
- Cryptographic protocols
- Dynamic gas based on input sizes
zkSNARKs - BN254 Curve (0x06-0x08)
BN254 precompiles enable efficient zero-knowledge proofs:
- ADD (150 gas): Point addition for proof verification
- MUL (6,000 gas): Scalar multiplication
- PAIRING (45k + 34k/pair): Bilinear pairing checks
Used by: Zcash, Tornado Cash, zkSync, StarkNet, Polygon zkEVM
Security: ~100-bit (sufficient but aging)
Ethereum 2.0 - BLS12-381 Curve (0x0B-0x13)
BLS12-381 precompiles power Ethereum 2.0 consensus:
G1 Operations (128-byte points)
- G1_ADD (500 gas): Fast point addition
- G1_MUL (12,000 gas): Scalar multiplication
- G1_MSM (variable): Batch operations with discounts
G2 Operations (256-byte points)
- G2_ADD (800 gas): Extension field addition
- G2_MUL (45,000 gas): More expensive than G1
- G2_MSM (variable): Batch operations
Pairing & Hash-to-Curve
- PAIRING (115k + 23k/pair): Signature verification
- MAP_FP_TO_G1 (5,500 gas): Hash messages to G1
- MAP_FP2_TO_G2 (75,000 gas): Hash messages to G2
Security: 128-bit (future-proof)
Applications:
- Validator signature aggregation
- BLS multi-signatures
- Threshold cryptography
- Advanced zkSNARKs
Blob Data (0x0A)
POINT_EVALUATION verifies KZG commitments for EIP-4844 blob transactions:
- Gas: 50,000 (fixed)
- Enables proto-danksharding
- Reduces rollup costs by 10-100x
- Critical for Ethereum scalability
Gas Cost Patterns
Fixed Cost
Simple operations with predictable computation:
- ECRECOVER: 3,000
- BLS12_G1_ADD: 500
- POINT_EVALUATION: 50,000
Linear Cost
Scales with input size:
- SHA256: 60 + 12 per word
- IDENTITY: 15 + 3 per word
Dynamic Cost
Complex calculation based on inputs:
- MODEXP: Based on base/exp/mod sizes
- BLS12_MSM: Batch discounts
Multi-Element Cost
Per-item pricing:
- BN254_PAIRING: 45,000 + 34,000 per pair
- BLS12_PAIRING: 115,000 + 23,000 per pair
Elliptic Curve Operations
| Operation | BN254 | BLS12-381 | Security | Use Case |
|---|
| Point Add | 150 | 500 (G1) / 800 (G2) | 100-bit / 128-bit | zkSNARKs / ETH2 |
| Scalar Mul | 6,000 | 12,000 (G1) / 45,000 (G2) | 100-bit / 128-bit | Proofs / Signatures |
| Pairing | 45k+34k/pair | 115k+23k/pair | 100-bit / 128-bit | Verification |
| Function | Gas/KB | Speed | Use Case |
|---|
| SHA256 | ~380 | Fast | Bitcoin compat |
| RIPEMD160 | ~3,750 | Slower | Legacy |
| BLAKE2F | Variable | Fastest | Modern |
| Keccak256 | ~1,000 | Fast | Native EVM |
Usage Statistics
Most frequently used precompiles by gas consumption:
- ECRECOVER (0x01) - Every transaction signature
- BLS12_PAIRING (0x11) - ETH2 consensus (thousands per block)
- POINT_EVALUATION (0x0A) - Blob transactions
- BN254_PAIRING (0x08) - zkRollup proofs
- SHA256 (0x02) - Bridge verifications
Least used:
- RIPEMD160 (0x03) - Legacy Bitcoin compatibility
- IDENTITY (0x04) - Specialized optimization
Implementation Guide
TypeScript
import { execute, PrecompileAddress } from '@tevm/voltaire/precompiles';
import { Hardfork } from '@tevm/voltaire/primitives/Hardfork';
// Execute any precompile
const result = execute(
PrecompileAddress.ECRECOVER,
input, // Uint8Array
gasLimit, // bigint
Hardfork.CANCUN
);
if (result.success) {
console.log('Output:', result.output);
console.log('Gas used:', result.gasUsed);
} else {
console.error('Error:', result.error);
}
Zig
const std = @import("std");
const precompiles = @import("precompiles");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// Execute precompile
const result = try precompiles.ecrecover.execute(
allocator,
input, // []const u8
gas_limit, // u64
);
defer result.deinit(allocator);
if (result.success) {
std.debug.print("Output: {any}\n", .{result.output});
}
}
WASM
All precompiles available via WASM. Import and use like the TypeScript implementation.
Security Considerations
All precompiles validate:
- Input length (exact or range)
- Field element bounds (curve operations)
- Point validity (on curve, in subgroup)
- Gas sufficiency (before computation)
Invalid inputs return error, not false results.
Constant-Time Execution
Cryptographic precompiles use constant-time algorithms:
- ECRECOVER: Prevents timing attacks on signatures
- BN254/BLS12-381: Side-channel resistant scalar multiplication
- MODEXP: Protects secret exponents
Gas DoS Protection
Dynamic gas prevents abuse:
- MODEXP: Exponential cost for large inputs
- MSM operations: Bounded by block gas limit
- Pairing: Linear cost per pair
Curve Security
| Curve | Security | Status | Notes |
|---|
| secp256k1 | 128-bit | Mature | Bitcoin/Ethereum standard |
| BN254 | ~100-bit | Aging | Sufficient for current zkSNARKs |
| BLS12-381 | 128-bit | Future-proof | ETH2, modern protocols |
Hardfork Availability
import { Hardfork } from '@tevm/voltaire/primitives/Hardfork';
// Check precompile availability
const precompiles = {
[Hardfork.FRONTIER]: [0x01, 0x02, 0x03, 0x04],
[Hardfork.BYZANTIUM]: [0x05, 0x06, 0x07, 0x08],
[Hardfork.ISTANBUL]: [0x09],
[Hardfork.CANCUN]: [0x0A],
[Hardfork.PRAGUE]: [0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13],
};
Always check hardfork before calling newer precompiles.
Implementation Status
Zig: Complete
All precompiles fully implemented with native C library integration:
- secp256k1: libsecp256k1
- BN254: arkworks (Rust FFI)
- BLS12-381: blst
- KZG: c-kzg-4844
- Hashes: libwally-core
TypeScript: Functional
- Production-ready: ECRECOVER, SHA256, RIPEMD160, IDENTITY, BLAKE2F
- Stubs (use WASM): BLS12-381 operations (return correct size, calculate gas, no crypto)
- Working: BN254 via @noble/curves, MODEXP, POINT_EVALUATION via c-kzg
For security-critical operations, always use Zig/WASM implementations.
Curve Documentation
Cryptography
Primitives
References
-
EIPs:
-
Standards:
-
Libraries:
Contributing
Precompile implementations require:
- Exact adherence to EIP specifications
- Comprehensive test vectors
- Gas cost validation
- Security audits for crypto operations
- Cross-language parity (TypeScript ↔ Zig)
See CONTRIBUTING.md