EIP-7932: Secondary Signature Algorithms

Discussion topic for EIP-7932 GitHub PR

This EIP introduces a new Introduces a new EIP-6404 transaction profile with the express purpose of allowing signing of transaction payloads with alternative signature algorithms. It also creates a new precompile to be able to decode these additional signature algorithms.

Update Log

  • 2025-04-12: initial draft PR
  • 2025-06-03: Move to review state: PR
  • 2025-06-21: Identified an issue where the additional_info is not signed and can be modified. Fixed via setting r to 0, but s to keccak256(alg_type || signature_info).
  • 2025-08-06: Reworked the abstract and the title to be more descriptive
  • 2025-08-07: Huge rework to be EIP-6404 based rather than RLP (moved back to draft)
  • 2025-10-04: Reintroduced RLP support and made several smaller modifications to fix some malleability concerns
  • 2025-11-05: Removed SSZ support (as it may be handled natively by EIP-6404) and clarified some missing details PR

External Reviews

Outstanding Issues

None as of 2025-04-12.

EIP-7702 defines a transaction type with nested signatures. You should probably explain how 7702 and this proposal interact.

1 Like

I’d extend this proposal with support for patching ecrecover as well. Fixing the outer transaction signature without fixing ecrecover will only solve part of the PQ problem.

One approach that’s been tossed around is to embed a list of tuples in the transaction that contain a mapping from the ecrecover arguments to the real signature/algorithm data. I haven’t thought that through entirely, but hopefully it’s a starting point.

2 Likes

The EIP-7702 problem was solved by adding space for additional signatures after the transaction, I don’t know how practical this would be but it was one of my better solutions. (edit: I also added the NULL algorithm for edge cases where the initial signature is secp256k1 but the others are not)

I also patched ecrecover instead of using a mapping as that seemed a bit too complex, I made any v recovery value v > 0xFF && v <= 0xFFFF trigger the contract to be treated as an Algorithmic. Might still need to work on the name, but for now Algorithmic transaction rolls of the tounge. I am going to introduce a new precompile, with a name similar to sigrecover as the “overload the v value” seemed somewhat hacky and may break some implementations.

I have moved this EIP to it’s review state, PR for anyone interested (also specified in update log above).

After a conversation with a member of the Ethereum Foundation, I have rebased this EIP onto EIP-6404. I’d like some feedback on the newer version before merging it into the main repo.

If the length of the input is already known, we don’t need to encode the length of the signature part. You can just assume that input[33:] is the signature.

def sigrecover_precompile(input: Bytes) -> Bytes:
  # Recover signature length and type
  assert(len(input) >= 33)
  hash: Hash32 = input[:32]
  algorithm_type: uint8 = input[32]
  signature: Bytes = input[33:] # len(signature) == len(input) - 33

  # Ensure the algorithm exists and signature is correct size
  if algorithm_type not in Algorithms:
    return ExecutionAddress(0x0)

  alg = Algorithms[algorithm_type]

  # Sig length must be smaller than alg.MAX_SIZE and
  # equal to the remaining call data
  if len(signature) > alg.MAX_SIZE:
    return ExecutionAddress(0x0)

  # Run verify function
  try:
    return alg.verify(signature, hash)
  except:
    return ExecutionAddress(0x0)
1 Like

This would be a better idea. I believe I initally put in the checks as a sort of anti-DOS measure, but that is obtained via memory and calldata costs. I’ll redo the sigrecover section.