Standardizes the introduction of several new algorithms for signing data.
Introduces a new EIP-6404 transaction profile that can modify the signature data of a contained transaction to a different signature algorithm.
Introduces a precompile at address 0x12 for decoding these newly introduced algorithms.
Motivation
As quantum computers become more advanced, several new post-quantum (PQ) algorithms have been designed. These algorithms all have certain issues, such as large key sizes (>1KiB), large signature sizes, or long verification times. These issues make them more expensive to compute and store than the currently used secp256k1 curve.
This EIP provides a solution to the diversity in algorithms by adding a standardized way to represent alternative algorithms within a transaction.
Specification
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.
Unless explicitly noted, integer encoding MUST be in big-endian format.
Parameters
Constant
Value
MAX_ADDITIONAL_INFO
255
GAS_PER_ADDITIONAL_VERIFICATION_BYTE
16
SIGRECOVER_PRECOMPILE_ADDRESS
Bytes20(0x12)
SIGRECOVER_PRECOMPILE_BASE_GAS
3000
SECP256K1_SIGNATURE_SIZE is defined from EIP-6404.
ExecutionAddress is defined from EIP-6466.
Algorithmic Transaction
TransactionPayload is defined as any type that derives its type from Profile[TransactionPayload].
This EIP introduces a new EIP-6404 transaction profile of SSZ type AlgorithmicTransaction defined below:
The field algorithm_type represents the algorithm used to sign the transaction in the payload field.
This EIP does not define algorithms for use with this transaction type apart from secp256k1 which may only be used under specific circumstances.
The hash of the payload MUST be calculated using the compute_ssz_sig_hash function below:
The transaction signature MUST be verified using the verify function for the algorithm denoted via algorithm_type.
The additional_signatures field only needs to be populated if additional protocol level signatures are required such as EIP-7702’s authorization_list.
If a signature is being overridden via an additional_signatures entry, the Secp256k1ExecutionSignature MUST be set to keccak256(algorithm_type + signature_info + index) and right-padded with 33 zero bytes where both algorithm_type and index are of type uint8 and index is the index at which the AdditionalSignature is present in the additional_signatures list. This MUST be verified during transaction validation and each entry MUST NOT be of type secp256k1.
The Algorithmic Transaction MUST generate an EIP-6466 receipt of only the payload, not of the AlgorithmicTransaction. Implementations MUST NOT be able to differentiate between an unwrapped and wrapped transaction by receipts alone.
When clients receive an Algorithmic Transaction via gossip or RPC they MUST validate both the Algorithmic Transaction and the object in the payload field, if either the transaction or the payload is invalid, the entire transaction is invalid.
Any discrimination of transactions MUST occur only with the payload, e.g. gas prices for block ordering.
identify_transaction_profile modifications
An additional section is added to the start of the identify_transaction_profile helper from EIP-6404:
Further algorithms MUST be specified via a distinct EIP.
Each type of algorithm MUST specify the following fields:
| Field Name | Description |
|-|-|
|ALG_TYPE| The uint8 of the algorithm unique ID |
|MAX_SIZE| The maximum size of signature_info field in a transaction |
|GAS_PENALTY| The additional gas penalty from verification of the signature |
The GAS_PENALTY field MUST be assumed to be worst-case scenario and MUST only account for verification costs, not storage nor signing GAS_PENALTY.
New algorithms MUST also specify how to recover and verify a valid address (ExecutionAddress) from the signature_info field inside the transaction, the verification function MUST have the following signature:
The verify function MUST return either an error or return the address of the signer.
Specifications MUST include some form of security analysis on the provided algorithm and basic benchmarks justifying gas costs.
An example of this specification can be found here.
Algorithm Living EIP
This EIP uses the Algorithms object to signify algorithms that have been included within a hard fork.
A living EIP MAY be created on finalization of this EIP to track currently active algorithms across forks, this living EIP MUST contain a formal definition of the Algorithms object.
Verification
Implementations MUST check that transactions pass the following checks:
The length of the signature_info is less than algorithm’s defined MAX_SIZE, including additional_signatures entries.
The algorithm_type field points to a known algorithm.
If any checks fail, then the transaction containing them is invalid. If called from the precompile, the precompile MUST return bytes20(0x0).
All transactions that use more resources than the secp256k1 curve suffer an additional penalty which MUST be calculated
as specified in the calculate_penalty function.
The penalty MUST be added onto the 21000 base gas of each transaction before the transaction is processed. A penalty MUST also be added for every instance of an additional_signatures object. This MUST be done irrespective of whether the signature is used or not. If the payload’s gas_limit is less than 21000 + penalty then the transaction MUST be invalidated.
This transaction also MUST inherit the intrinsics of the wrapped transaction’s fee structure (e.g. a wrapped EIP-1559 payload would behave as an EIP-1559 transaction).
secp256k1 algorithm
Field
Value
ALG_TYPE
0xFF
MAX_SIZE
SECP256K1_SIGNATURE_SIZE
GAS_PENALTY
0
secp256k1_validate, SECP256K1_SIGNATURE_SIZE and secp256k1_recover_signer are defined from EIP-6404.
This algorithm MUST ONLY be used if the transaction’s signature is secp256k1 but the additional_signatures field contains more than (or equal to) one entry. It MUST NOT be present if the transaction does not contain additional signatures. secp256k1 MUST NOT be present in any additional_signatures entry.
sigrecover precompile
This EIP also introduces a new precompile located at SIGRECOVER_PRECOMPILE_ADDRESS.
This precompile MUST cost SIGRECOVER_PRECOMPILE_BASE_GAS when called regardless of validity, this cost MUST be aggregated with calculate_penalty(signature_info, algorithm), this penalty is charged before the sigrecover precompile executes.
The precompile MUST output the 20-byte address of the signer provided. Callers MUST assume all zero bytes as a failure.
The precompile logic contains the following logic:
defsigrecover_precompile(input:Bytes)->Bytes:# Recover signature length and type
assert(len(input)>=64)hash:Hash32=input[:32]algorithm_type:uint8=input[32]sig_length:uint248=int.from_bytes(input[33:64],"big")# Ensure the algorithm exists and signature is correct size
ifalgorithm_typenotinAlgorithms:returnExecutionAddress(0x0)alg=Algorithms[algorithm_type]# Sig length must be smaller than alg.MAX_SIZE and
# equal to the remaining call data
ifsig_length>alg.MAX_SIZEorsig_length!=(len(input)-64):returnExecutionAddress(0x0)# Run verify function
try:alg.verify(input[64:64+sig_length],hash)except:returnExecutionAddress(0x0)
Rationale
Opaque signature_info type
As each algorithm has unique properties, e.g. signature recovery and key sizes, the object needs to hold every permutation of every possible signature and additional recovery information. A bytearray of a dynamic size would be able to achieve this goal. However, this leads to a DoS vector which the Gas penalties section solves along with the MAX_SIZE parameter.
Gas penalties
Having multiple different algorithms results in multiple different signature sizes and verification costs. Hence, every signature algorithm that is more expensive than the default ECDSA secp256k1 curve incurs an additional gas penalty. This is to discourage the use of overly expensive algorithms for no specific reason.
The GAS_PER_ADDITIONAL_VERIFICATION_BYTE value being 16 was taken from the calldata cost of a transaction, as it is a similar datatype and must persist indefinitely to ensure later verification.
Not specifying account key-sharing / migration
Allowing a single account to share multiple keys creates a security risk as it reduces the security of all addresses to the weakest algorithm. This is also out of scope for this EIP and could be implemented via a future EIP.
Keeping a similar address rather than introducing a new address format
While adding a new address format for every new algorithm would ensure that collisions never happen and that security would not be bound by the lowest common denominator, it creates an excessively large burden on client and tooling developers.
New precompile over modifying the ecrecover precompile
Initially, modifying the ecrecover precompile seemed prudent over creating a new precompile. However, after an initial attempt, it proved too hacky for production use.
This EIP allows for EIP‑4337Bundlers to settle UserOperations on-chain using a different algorithm. sigrecover also complements Account Abstraction well by reducing on-chain verification costs via sigrecover.
Backwards Compatibility
Non-EIP-7932 transactions will still be processed as the default secp256k1 curve. Therefore, there would be no backwards compatibility issues in processing other transactions.
Test Cases
Security Considerations
Allowing more ways to potentially sign transactions for a single account may decrease overall security for that specific account, however this is partially mitigated by the increase in processing power required to trial all algorithms. Even still, adding additional algorithms may need further discussion to ensure that the security of the network would not be compromised.
Having signature_info be of no concrete type creates a chance that an algorithm’s decoding logic could be specified or implemented incorrectly, which could lead to, in the best case, invalid blocks or, at worst, enabling anyone to sign a fraudulent transaction for any account. This security consideration is delegated to the algorithm’s specification, and so care must be taken when writing these specifications to avoid critical security flaws.