Replaces the RIPEMD-160 (0x03), MODEXP (0x05), BLAKE2f (0x09), BLS12_MAP_FP_TO_G1 (0x10), and BLS12_MAP_FP2_TO_G2 (0x11) precompiles. At the start of executing the block in which this change activates, deploy EVM bytecode at each precompile address that provides equivalent functionality. This follows the same approach as EIP-7666, which EVMifies the identity precompile (0x04).
Ethereum's precompiles impose ongoing maintenance costs and increase the risk of consensus bugs across client implementations. Some also represent a significant barrier for zkEVM implementations since each precompile usually requires a separate, optimized non-EVM implementation.
EIP-7666 demonstrates this approach with the identity precompile. This EIP extends the same technique to five additional precompiles that either see limited use or can be evmified with a small cost:
0x03): A hash function with minimal on-chain usage. Its primary historical use case (Bitcoin-style address derivation) is not common in Ethereum contracts.0x05): Modular exponentiation. In our analysis, we saw that 99.99% of modexp usage came from 256 bit modulus for SNARK verification, whereas the very rarely used RSA modulis occupied the rest.0x09): The BLAKE2 compression function. Our analysis shows that this is now predominantly used by a single contract.0x10): Maps a base field element to a G1 point on the BLS12-381 curve. This is pure field arithmetic that can be implemented in EVM.0x11): Maps an extension field element to a G2 point on the BLS12-381 curve. This is pure field arithmetic that can be implemented in EVM.Replacing these precompiles with EVM bytecode reduces the number of special-cased implementations that every Ethereum client must maintain, simplifying the protocol and making it more accessible to new client implementations.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
| Parameter | Value |
|---|---|
RIPEMD160_ADDRESS |
0x0000000000000000000000000000000000000003 |
MODEXP_ADDRESS |
0x0000000000000000000000000000000000000005 |
BLAKE2F_ADDRESS |
0x0000000000000000000000000000000000000009 |
BLS12_MAP_FP_TO_G1_ADDRESS |
0x0000000000000000000000000000000000000010 |
BLS12_MAP_FP2_TO_G2_ADDRESS |
0x0000000000000000000000000000000000000011 |
RIPEMD160_EVM_CODE |
<-- TODO: bytecode --> |
MODEXP_EVM_CODE |
<-- TODO: bytecode --> |
BLAKE2F_EVM_CODE |
<-- TODO: bytecode --> |
BLS12_MAP_FP_TO_G1_EVM_CODE |
<-- TODO: bytecode --> |
BLS12_MAP_FP2_TO_G2_EVM_CODE |
<-- TODO: bytecode --> |
At the start of the block in which this fork activates, for each precompile address and its corresponding EVM code listed above:
EVM_CODE.After activation, calls to these addresses are charged according to standard EVM execution costs rather than the precompile-specific gas formulas. The expected gas cost differences are documented below.
The current precompile charges 600 + 120 * ceil(len(data) / 32) gas. The EVM implementation will charge the sum of the opcodes executed, which is expected to differ.
<-- TODO: gas comparison with bytecode version -->
The current precompile uses a complex formula based on the lengths of the base, exponent, and modulus, as well as the iteration count derived from the exponent. The EVM implementation will charge standard opcode costs. Due to the complexity of modular exponentiation in EVM, gas costs are expected to be higher for large inputs.
<-- TODO: gas comparison with bytecode version -->
The current precompile charges rounds gas (the number of rounds specified in the input). The EVM implementation will charge the sum of the opcodes executed.
<-- TODO: gas comparison with bytecode version -->
The current precompile charges 5500 gas. The EVM implementation will charge the sum of the opcodes executed.
<-- TODO: gas comparison with bytecode version -->
The current precompile charges 23800 gas. The EVM implementation will charge the sum of the opcodes executed.
<-- TODO: gas comparison with bytecode version -->
This EIP follows the same deployment mechanism established by EIP-7666: deploying EVM bytecode directly at the precompile address at fork time. This preserves backward compatibility for contracts that call these addresses, as they continue to work with the same interface.
Rather than attempting to replicate the exact gas formulas of the original precompiles, this EIP accepts the natural EVM execution gas costs. Gas repricings have been done in the Ethereum ecosystem several times before and their effects are well understood. Nevertheless, we will carry out an impact analysis of each precompile.
Deploying the bytecode directly at the existing precompile address ensures that all existing contracts calling these addresses continue to function without modification. Alternative approaches such as removing the precompile and expecting callers to use library contracts at other addresses would break backward compatibility of already deployed contracts.
The functionality at each address is preserved. Gas costs will differ from the current precompile-specific formulas, which may affect contracts that depend on precise gas calculations when calling these precompiles. We have updated the gas cost of precompiles in the past and have accepted that contracts relying on hardcoded gas costs for precompiles is bad practice.
<-- TODO -->
The change in gas costs could affect contracts that rely on specific gas behavior when calling these precompiles. Contracts that pass a fixed gas amount to these addresses may revert if the EVM implementation costs more than the precompile did.
The EVM bytecode deployed at each address must be thoroughly tested and audited to ensure it produces identical outputs to the original precompile for all valid inputs, and handles invalid inputs in the same way.
Copyright and related rights waived via CC0.