This document describes the implementation of Ethereum precompiled contracts in EVM.lua.
Precompiled contracts are special contracts at addresses 0x01 through 0x09 (and beyond in later forks) that provide native implementations of commonly used cryptographic and utility functions. Unlike regular contracts, they are implemented directly in the EVM client for performance and complexity reasons.
| Address | Name | Status | Description |
|---|---|---|---|
| 0x01 | ECRecover | ✅ Stub | ECDSA signature recovery (placeholder) |
| 0x02 | SHA2-256 | ✅ Complete | SHA-256 hash function |
| 0x03 | RIPEMD-160 | ✅ Stub | RIPEMD-160 hash function (placeholder) |
| 0x04 | Identity | ✅ Complete | Data copy function |
| 0x05 | ModExp | ✅ Stub | Modular exponentiation (placeholder) |
| 0x06 | ECAdd | ✅ Stub | Elliptic curve point addition (placeholder) |
| 0x07 | ECMul | ✅ Stub | Elliptic curve scalar multiplication (placeholder) |
| 0x08 | ECPairing | ✅ Stub | Elliptic curve pairing check (placeholder) |
| 0x09 | Blake2F | ✅ Stub | Blake2b compression function (placeholder) |
Status: Stub implementation
Input: 128 bytes
- 32 bytes: message hash
- 32 bytes: v (recovery id)
- 32 bytes: r (signature component)
- 32 bytes: s (signature component)
Output: 32 bytes (20-byte address padded to 32 bytes)
TODO: Requires secp256k1 elliptic curve library for full implementation.
Status:
Input: Variable length data
Output: 32 bytes (SHA-256 hash)
Implementation: Pure Lua implementation using bit operations compatible with Redis Lua environment.
Known Issues: Current implementation produces hashes but doesn't match NIST test vectors. Needs debugging and verification.
TODO: Verify and fix SHA-256 algorithm implementation to match standard test vectors.
Status: Stub implementation
Input: Variable length data
Output: 32 bytes (20-byte RIPEMD-160 hash padded to 32 bytes)
TODO: Implement RIPEMD-160 hashing algorithm.
Status: ✅ Fully implemented
Input: Variable length data
Output: Same as input (data copy)
Use Case: Simple data copying, often used for testing or as a placeholder.
Status: Stub implementation (Byzantium fork)
Input: Variable length
- 32 bytes: base length
- 32 bytes: exponent length
- 32 bytes: modulus length
- Variable: base
- Variable: exponent
- Variable: modulus
Output: Result of (base^exponent) % modulus
TODO: Implement big integer arithmetic for modular exponentiation.
Status: Stub implementation (Byzantium fork)
Input: 128 bytes (two alt_bn128 curve points)
- 32 bytes: x1
- 32 bytes: y1
- 32 bytes: x2
- 32 bytes: y2
Output: 64 bytes (resulting point x, y)
TODO: Implement alt_bn128 curve point addition.
Status: Stub implementation (Byzantium fork)
Input: 96 bytes
- 32 bytes: point x
- 32 bytes: point y
- 32 bytes: scalar s
Output: 64 bytes (resulting point x, y)
TODO: Implement alt_bn128 curve scalar multiplication.
Status: Stub implementation (Byzantium fork)
Input: Multiple of 192 bytes (pairs of G1 and G2 points)
Output: 32 bytes (1 if pairing is valid, 0 otherwise)
TODO: Implement alt_bn128 pairing check.
Status: Stub implementation (Istanbul fork)
Input: 213 bytes
- 4 bytes: rounds
- 64 bytes: h (state vector)
- 128 bytes: m (message block)
- 16 bytes: t (offset counters)
- 1 byte: f (final block indicator)
Output: 64 bytes (final hash state)
TODO: Implement Blake2F compression function.
Precompiles are integrated into the EVM execution flow through the execute_contract_call function. When a CALL, STATICCALL, or DELEGATECALL targets an address in the range 0x01-0x09, the EVM:
- Checks if precompiles are enabled (
EVM.ENABLE_PRECOMPILESflag) - Detects the precompile address
- Routes to the appropriate precompile function
- Executes the native implementation
- Returns the result in
state.return_data
Precompiles can be enabled or disabled using the EVM.ENABLE_PRECOMPILES flag in evm.lua:
-- Feature flags
EVM.ENABLE_PRECOMPILES = true -- Set to false to disable precompiled contractsDefault: true (enabled)
When disabled, calls to precompile addresses (0x01-0x09) are treated as calls to regular accounts with no code (EOA), which succeed but return no data.
Run precompile tests:
make test-precompilesOr directly:
cd tests && ./test-precompiles.shTest the feature flag:
cd tests && ./test-precompile-flag.sh-
ECRecover (0x01): Critical for signature verification in many contracts
- Requires secp256k1 library integration
- Used by wallet contracts, multisig, etc.
-
ModExp (0x05): Important for RSA verification and other cryptographic operations
- Requires big integer arithmetic library
- Used by some bridge contracts
-
ECAdd, ECMul, ECPairing (0x06-0x08): Required for zkSNARK verification
- Requires alt_bn128 curve implementation
- Used by privacy protocols (Tornado Cash, etc.)
-
Blake2F (0x09): Used by some bridge contracts
- Relatively straightforward to implement
-
RIPEMD-160 (0x03): Less commonly used but part of Bitcoin compatibility
- Used by some Bitcoin bridge contracts