EIP-7932: Algorithmic Transaction Wrapper
Introduces a new transaction type wrapping transactions in alternative signature algorithms
Abstract
This EIP introduces a new EIP-2718 typed transaction that wraps (contains) another transaction, this EIP nullifies the default signature parameters and appends signature data to the front of the transaction with a selector, this effectively wraps a transaction and swaps out signature data for alternative algorithms and data. It also creates a new precompile to be able to decode these additional signature algorithms.
Motivation
As quantum computers are getting more advanced, several new post-quantum (PQ) algorithms have been designed. These algorithms all contain drawbacks 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 current secp256k1 curve in use (as of 2025-04-12).
This EIP provides a future-proof solution to these 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.
Note: The "verification function" referred to by this EIP is the one specified by additional EIP & their signature types. When calling explicitly the "verification function" implementations MUST NOT call the precompile due to differing gas costs.
Parameters
Constant | Value |
---|---|
ALG_TX_TYPE | Bytes1(0x07) |
GAS_PER_ADDITIONAL_VERIFICATION_BYTE | 16 |
SIGRECOVER_PRECOMPILE_ADDRESS | Bytes20(0x12) |
SIGRECOVER_PRECOMPILE_BASE_GAS | 3000 |
Algorithmic Transaction
This EIP introduces a new EIP-2718 transaction with a TransactionType
of ALG_TX_TYPE
and a TransactionPayload
of the RLP serialization of the AlgTransactionPayloadBody
defined below:
[alg_type, signature_info, parent, additional_info]
The field alg_type
is an unsigned 8-bit integer (uint8) that represents the algorithm used to sign the transaction in the parent
field. This EIP does not define algorithms for use with this transaction type; however, it does specify a NULL algorithm (0xFF) which MUST trigger implementations to verify transaction fields.
The signature_info
field contains information required to verify the signature of the transaction in the parent
field. This is a byte-array of arbitrary length, which would be passed to the verification function.
The parent
field contains another serialized EIP-2718 Typed Transaction Envelope (i.e. the parent
field type is bytes
), which MUST be able to contain every possible TransactionType
, including legacy transactions with a TransactionType
of > 0x7f
, but the only exception to this rule is the Algorithmic Transaction
itself, which MUST NOT be placed within itself.
These parent
transactions all contain y_parity
, r
, s
values, which MUST be set to Bytes0()
if wrapped in a AlgTransactionPayloadBody
, there are two exceptions to this rule however:
- If the
alg_type
is the NULL algorithm, the signature field MUST be left unchanged. - If the transaction type is that of a legacy transaction, where
y_parity
MUST be equal to the chain ID value, the transactions signing data MUST be calculated the same way as EIP-155 specifies
All other transaction values MUST be unchanged from their original values.
The additional_info
field only needs to be populated if additional protocol level signatures are required such as EIP-7702's authorization_list
. This field MUST contain the RLP serialization of a list of the signatures [alg_type, signature_info]
and MUST be repeated for every signature with a null (0x0) r
and v
value inside the transaction, the s
value MUST be set to keccak256(alg_type || signature_info)
. The order of which MUST be the same as the signatures appear in the parent
tx. This signature MUST also be checked to ensure that alg_type
is known and is not the NULL algorithm (0xFF) and len(signature_info) <= alg.MAX_SIZE
. This MUST also be verified using the verify
function for the specific algorithm.
If new transaction types are specified they MUST NOT attempt to build on this EIP but instead MUST include the y_parity
, r
, s
values, this will prevent backwards compatibility issues and ensure that any transaction other than EIP-7932 txs can be safely assumed to be secp256k1.
The Algorithmic Transaction MUST NOT generate a transaction receipt with a TransactionType
of ALG_TX_TYPE
, it MUST emit the receipt of the transaction it is wrapping (the tx in the parent
field). 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 transaction in the parent
field and the tx order calculation (e.g. based on gas price) MUST be done on the transaction in the parent
field. If either transaction is invalid, the entire transaction is invalid and they MUST NOT propagate the transaction to peers.
Algorithm specification
Further algorithms MUST be specified via an additional 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 only account for verification costs, not storage nor signing.
New algorithms MUST also specify how to recover and verify a valid address (bytes20
) from the signature_info
field inside the transaction, the verification function MUST follow the following signature:
def verify(signature_info: bytes, parent_hash: bytes32) -> bytes20
The verify function MUST return 0x0
if there was an error recovering a valid address from the signature, otherwise the function MUST return the address of the signer.
Specifications MUST also justify why their GAS_PENALTY
is high enough to not cause a DOS vector, and MUST include some form of security analysis on the algorithm and that it will not cause potential security issues.
An example of this specification can be found here.
This EIP uses the Algorithms
object to signify final and active algorithms. These are selected via the EIP process and hard-fork inclusion.
Verification
Implementations MUST consider transactions invalid where len(tx.signature_info) > alg.MAX_SIZE
, this also applies for objects inside additional_info
.
The following checks MUST always be made against any type of signature_info
and alg_type
. If the result of these checks do not pass then one of the following apply:
- The transaction is invalid
- If called from the precompile, the precompile MUST return 0x0 as the address.
Transactions MUST also follow all rules outlined in the Specification section.
Gas calculation
All transactions that use more resources than the secp256k1 curve suffer an additional penalty. This penalty MUST be calculated as follows:
The penalty MUST be added onto the 21000
base gas of each transaction BEFORE the transaction is processed. If the wrapped tx's gas_limit
is less then 21000 + calculate_penalty(signing_data, algorithm)
than the transaction MUST be considered invalid and MUST NOT be included within blocks. This transaction also MUST inherit the intrinsics of the wrapped tx's fee structure (e.g. a wrapped EIP-1559 tx would behave as a EIP-1559 tx).
The penalty MUST be applied to every instance of an additional_info
object, which then MUST be added onto the transaction's initial gas. This is done irrespective of whether the signature is used or not.
NULL algorithm
The NULL algorithm (0xFF) MUST be present if the signature parameters inside the wrapped transaction are still valid for secp256k1
, but there are more parameters in the transaction such as EIP-7702's authorization_list
that require swapping out for different algorithms.
The signature_info
field MUST be zero-sized if the NULL algorithm is not present.
The NULL algorithm MUST NOT be present if the transaction does not contain additional signatures.
sigrecover
precompile
This EIP also introduces a new precompile located at SIGRECOVER_PRECOMPILE_ADDRESS
.
This precompile MUST NOT be called when verifying transaction parameters, instead this call should be verified as specified above.
This precompile MUST cost SIGRECOVER_PRECOMPILE_BASE_GAS
when calling even if algorithm does not exist, this price MUST be aggregated with algorithm specific GAS_PENALTY
and the output of calculate_penalty
for the signature data, this penalty is charged once the sigrecover
precompile executes.
The sigrecover
precompile MUST NOT include the NULL algorithm.
The precompile logic executes the following logic:
Rationale
Setting y_parity
, r
, s
values to zero rather than removing them
Keeping the y_parity
, r
, s
values inside the transactions keeps the previous parsing, verification and processing logic the same and allows for minimal modification to the other specifications while still preventing excessive space usage.
Opaque signature_info
type
As each algorithm has unique properties, i.e. signature recovery and key sizes, a object is needed to hold every permutation of every possible key and signature. A bytearray of dynamic size would be able to achieve this goal, this does lead 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 adding the secp256k1
curve
Having a type for secp256k1
allows for several iterations of the same object to be present across the network. Additionally the only purpose for this curve would be for prototyping and testing with client teams, as the resultant receipt, logs and state change would be the same as a non-wrapped transaction.
Not specifying account key-sharing / migration
Allowing a single account to share multiple keys creates a security risk as it reduces the security 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 is not bound by the lowest common denominator, the amount of changes that would have to be made and backwards compatibility issues would be too vast to warrant this.
New precompile over modifying the ecrecover
precompile
Initially, modifying the ecrecover
precompile was going to be selected over creating a new precompile, however, this was ruled out after it took too much complexity to implement or may break backwards compatibility.
Hard fork over EIP‑4337 Account Abstraction
This EIP allows for EIP‑4337 Bundler
s to settle UserOperation
s onchain using a different algorithm which in the future may be the only option if post-quantum issues cause the secp256k1 curve to be phased out.
Backwards Compatibility
Non-EIP-7932 transactions will still be included within blocks and will be treated as the default secp256k1 curve. Therefore there would be no backwards compatibility issues will processing other transactions. However, as a new EIP-2718 transaction has been added non-upgraded clients would not be able to process these transactions nor blocks that include these transactions.
Test Cases
These test cases do not involve processing other types of transactions. Only the wrapping, unwrapping and verification of these transactions without interfacing with the parent
tx.
All the following test cases use the parameters from the example eip specified in the Algorithm Specification Section listed above, in addition a 0xfe
algorithm type is added that will always return 0x0
.
These test cases can be found in JSON format here
Security Considerations
Allowing more ways to potentially create 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 discussing 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 algorithms logic could be specified or implemented incorrectly, which could lead to, in the best case, invalid blocks, or at worst, the ability for anyone to sign a fraudulent transaction for any account. This security consideration is delegated to the algorithms specification, therefore care must be taken when writing these algorithm specifications to avoid critical security flaws.
Copyright
Copyright and related rights waived via CC0.