---
eip: 8164
title: Native Key Delegation for EOAs
description: Allows EOAs to permanently replace ECDSA with alternative signature schemes via an extended delegation designator.
author: Gregory Markou (@GregTheGreek) <gregorymarkou@gmail.com>, James Prestwich (@prestwich) <james@prestwi.ch>
discussions-to: https://ethereum-magicians.org/t/eip-8164-native-key-delegation/27770
status: Draft
type: Standards Track
category: Core
created: 2026-02-17
requires: 2, 2718, 2929, 3541, 3607, 4844, 7702
---

## Abstract

This EIP extends the delegation designator system introduced by [EIP-7702](./eip-7702.md) to support **native key delegation** — permanently converting an EOA's authentication from ECDSA over secp256k1 to an alternative signature scheme. A new code prefix `0xef0101` designates an account whose authentication key is an ML-DSA-44 public key embedded directly in the account's code field. Once set, the original ECDSA key is rendered permanently inert. A single new transaction type supports both ECDSA-signed key migration and ML-DSA-44-authenticated transaction origination. Accounts may be created without any party ever possessing the ECDSA private key, using a crafted-signature technique analogous to Nick's method ([ERC-2470](./eip-2470.md)) for keyless contract deployment.

## Motivation

EIP-7702 brought code delegation to EOAs but retained ECDSA over secp256k1 as the sole native authentication mechanism. This constrains the ecosystem to a single signature scheme with known limitations:

- **Quantum vulnerability.** secp256k1 ECDSA is vulnerable to quantum attacks. Native key delegation with ML-DSA-44, a NIST-standardized post-quantum scheme, directly addresses this threat. The framework generalizes to future post-quantum schemes via additional `0xef01XX` designators.
- **Hardware ecosystem mismatch.** Secure enclaves and hardware security modules increasingly ship with native support for signature schemes beyond secp256k1. Forcing ECDSA introduces bridging complexity and enlarges the trusted computing base.
- **Smart contract wallet overhead.** Smart contract wallets and EIP-7702 code delegation can achieve alternative authentication today, but at the cost of EVM execution for every transaction validation. Native key delegation moves signature verification into the protocol, eliminating per-transaction contract overhead.
- **Provably rootless accounts.** The crafted-signature creation path produces accounts where the ECDSA private key *never existed*, providing a cryptographic guarantee — not merely a procedural one — that no backdoor key can override the installed scheme.

## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119) and [RFC 8174](https://www.rfc-editor.org/rfc/rfc8174).

### Constants

| Name | Value | Description |
|------|-------|-------------|
| `NATIVE_KEY_TX_TYPE` | `Bytes1(0x06)` | Transaction type for native key operations |
| `NATIVE_KEY_MAGIC` | `0x07` | Domain separator for native key authorization signing |
| `ML_DSA_44_DESIGNATION` | `0xef0101` | 3-byte code prefix for ML-DSA-44 native key accounts |
| `PER_NATIVE_AUTH_BASE_COST` | `12500` | Gas charged per native key authorization tuple (matches [EIP-7702](./eip-7702.md) `PER_AUTH_BASE_COST`) |
| `PER_EMPTY_ACCOUNT_COST` | `25000` | Additional gas if the authority account was previously empty (same as [EIP-7702](./eip-7702.md)) |
| `ML_DSA_44_VERIFY_COST` | `50000` | Intrinsic gas for ML-DSA-44 signature verification |

### Delegation Designator Space

EIP-7702 defines the code prefix `0xef0100` for code delegation. This EIP extends the `0xef01XX` namespace:

| Prefix | Code length | Semantics |
|--------|-------------|-----------|
| `0xef0100` | 23 bytes | Code delegation ([EIP-7702](./eip-7702.md)) |
| `0xef0101` | 1,315 bytes | ML-DSA-44 native key (this EIP) |
| `0xef0102`–`0xef01ff` | varies | Reserved for future signature schemes |

An account whose code is exactly `0xef0101 || pubkey` (1,315 bytes) is a **native-key account**. The 1,312-byte `pubkey` is an ML-DSA-44 public key used for all subsequent transaction authentication.

### Native Key Transaction (Type `0x06`)

A new [EIP-2718](./eip-2718.md) transaction type serves both native key migration and native-key-authenticated transaction origination:

```
0x06 || rlp([
    chain_id,
    nonce,
    max_priority_fee_per_gas,
    max_fee_per_gas,
    gas_limit,
    to,
    value,
    data,
    access_list,
    native_key_authorization_list,
    sender,
    signature
])
```

The fields `chain_id`, `nonce`, `max_priority_fee_per_gas`, `max_fee_per_gas`, `gas_limit`, `to`, `value`, `data`, and `access_list` follow the same semantics as [EIP-4844](./eip-4844.md). A null `to` is not valid.

| Field | Type | Description |
|-------|------|-------------|
| `native_key_authorization_list` | `list` | Authorization tuples for setting native keys (may be empty) |
| `sender` | `bytes` | Empty for ECDSA mode, or 20-byte address for native key mode |
| `signature` | `bytes` | 65-byte ECDSA signature or 2,420-byte ML-DSA-44 signature |

The `sender` field determines the transaction's authentication mode:

- **ECDSA mode** (`sender` is empty): The transaction is signed with ECDSA. `signature` is 65 bytes, encoding `y_parity || r || s`. The transaction sender is recovered via `ecrecover`. Any EOA may submit this transaction; the submitter need not be the authority whose key is being set.
- **ML-DSA-44 mode** (`sender` is 20 bytes): The transaction is signed with ML-DSA-44 by the native-key account at `sender`. `signature` is 2,420 bytes.

The signing payload for both modes is:

```
tx_hash = keccak256(NATIVE_KEY_TX_TYPE || rlp([
    chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas,
    gas_limit, to, value, data, access_list,
    native_key_authorization_list, sender
]))
```

In ECDSA mode, `sender` is empty in the payload, so the signing domain is distinct from ML-DSA-44 mode where `sender` is 20 bytes.

#### Native Key Authorization Tuple

The `native_key_authorization_list` supports two tuple formats: ECDSA-signed tuples for initial key migration, and native-key-signed tuples for key rotation. Tuples are distinguished by element count: 6 elements for ECDSA, 5 for native key. Tuples with any other element count are invalid.

##### ECDSA-Signed Authorization (Key Migration)

Each ECDSA-signed entry has the form:

```
ecdsa_auth = [chain_id, pubkey, nonce, y_parity, r, s]
```

| Field | Type | Description |
|-------|------|-------------|
| `chain_id` | `uint256` | Target chain ID, or `0` for any chain |
| `pubkey` | `bytes` | Native public key to install |
| `nonce` | `uint64` | Current nonce of the authority account |
| `y_parity` | `uint8` | ECDSA recovery parameter |
| `r` | `uint256` | ECDSA signature component |
| `s` | `uint256` | ECDSA signature component |

The authorization message is:

```
msg_hash = keccak256(NATIVE_KEY_MAGIC || rlp([chain_id, pubkey, nonce]))
```

The **authority** is recovered via `ecrecover(msg_hash, y_parity, r, s)`.

##### Native Key Authorization (Key Rotation)

Each native-key-signed entry has the form:

```
native_key_auth = [chain_id, new_pubkey, nonce, authority, signature]
```

| Field | Type | Description |
|-------|------|-------------|
| `chain_id` | `uint256` | Target chain ID, or `0` for any chain |
| `new_pubkey` | `bytes` | New public key to install |
| `nonce` | `uint64` | Current nonce of the authority account |
| `authority` | `address` | Address of the native-key account authorizing rotation |
| `signature` | `bytes` | Signature by the currently installed key |

The authorization message is:

```
msg_hash = keccak256(NATIVE_KEY_MAGIC || rlp([chain_id, new_pubkey, nonce, authority]))
```

The **authority** is stated explicitly. Its currently installed native key is used for verification. The `authority` address is included in the signed message to prevent cross-account replay.

#### Transaction Validation

Future EIPs may modify this verification procedure to account for non-ML-DSA-44 native key delegations.

If `sender` is empty (ECDSA mode):

1. Verify `signature` is exactly 65 bytes. Otherwise the transaction is invalid.
2. Parse `y_parity = signature[0]`, `r = signature[1..33]`, `s = signature[33..65]`.
3. Recover the transaction sender via `ecrecover(tx_hash, y_parity, r, s)`. If recovery fails, the transaction is invalid.
4. Proceed with standard sender validation (nonce, balance, etc.).

If `sender` is 20 bytes (Native Key mode):

1. Verify `sender`'s code begins with `ML_DSA_44_DESIGNATION` and is exactly 1,315 bytes. Otherwise the transaction is invalid.
2. Add `sender` to `accessed_addresses` (as defined by [EIP-2929](./eip-2929.md)).
3. Extract `pubkey = sender.code[3..1315]`.
4. Verify `ML_DSA_44_Verify(pubkey, tx_hash, signature)` per FIPS 204[^1] Section 6 (Algorithm 3). The following strictness requirements apply:
   - All encodings MUST be canonical per FIPS 204. Non-canonical encodings of public keys or signatures MUST be rejected.
   - The signature vector `z` coefficients MUST satisfy the norm bound check as specified in FIPS 204. Implementations MUST NOT skip or relax this check.
   - The hint vector `h` MUST have exactly the number of ones indicated by the signature metadata; duplicate or out-of-order indices MUST be rejected.
   - Implementations MUST produce identical accept/reject decisions for every possible `(pubkey, message, signature)` triple. Implementors should validate against a shared test vector suite and should not rely on library defaults.
   If verification fails, the transaction is invalid.
5. Verify `nonce == sender.nonce`. Otherwise the transaction is invalid.
6. Proceed with standard transaction execution.

`ML_DSA_44_VERIFY_COST` is added to the transaction's intrinsic gas cost in native key mode, replacing the implicit ecrecover cost.

If `sender` is any other length, the transaction is invalid.

#### Authorization List Processing

The `native_key_authorization_list` is processed before transaction execution but after the sender's nonce is incremented, mirroring EIP-7702 semantics. The list MAY be empty.

For each ECDSA-signed tuple `[chain_id, pubkey, nonce, y_parity, r, s]`, in order:

1. Verify `chain_id` is `0` or equals the current chain ID. Otherwise skip.
2. Verify `pubkey` is exactly 1,312 bytes. Otherwise skip.
3. Verify `nonce < 2^64 - 1`. Otherwise skip.
4. Verify `s <= secp256k1n / 2`, as per [EIP-2](./eip-2.md). Otherwise skip.
5. Set `msg_hash = keccak256(NATIVE_KEY_MAGIC || rlp([chain_id, pubkey, nonce]))`.
6. Set `authority = ecrecover(msg_hash, y_parity, r, s)`. If recovery fails, skip.
7. Verify `authority`'s code is empty or begins with `0xef0100`. Otherwise skip.
8. Verify `authority`'s nonce equals `nonce`. Otherwise skip.
9. Add `authority` to `accessed_addresses` (as defined by [EIP-2929](./eip-2929.md)).
10. Increment `authority`'s nonce by one.
11. Set `authority`'s code to `ML_DSA_44_DESIGNATION || pubkey`.
12. Charge `PER_NATIVE_AUTH_BASE_COST` gas, plus `PER_EMPTY_ACCOUNT_COST` if the account was previously empty.

For each native-key-signed tuple `[chain_id, new_pubkey, nonce, authority, signature]`, in order:

1. Verify `chain_id` is `0` or equals the current chain ID. Otherwise skip.
2. Verify `new_pubkey` is exactly 1,312 bytes. Otherwise skip.
3. Verify `nonce < 2^64 - 1`. Otherwise skip.
4. Verify `authority`'s code begins with `ML_DSA_44_DESIGNATION` and is exactly 1,315 bytes. Otherwise skip.
5. Extract `current_pubkey = authority.code[3..1315]`.
6. Set `msg_hash = keccak256(NATIVE_KEY_MAGIC || rlp([chain_id, new_pubkey, nonce, authority]))`.
7. Verify `ML_DSA_44_Verify(current_pubkey, msg_hash, signature)` using the same verification constraints as Type `0x06` native key mode. If verification fails, skip.
8. Verify `authority`'s nonce equals `nonce`. Otherwise skip.
9. Add `authority` to `accessed_addresses` (as defined by [EIP-2929](./eip-2929.md)).
10. Increment `authority`'s nonce by one.
11. Set `authority`'s code to `ML_DSA_44_DESIGNATION || new_pubkey`.
12. Charge `PER_NATIVE_AUTH_BASE_COST` gas.

If multiple tuples (of either type) target the same authority, the last valid tuple wins.

### ECDSA Rejection Rule

Once an account's code is set to `0xef0101 || pubkey`:

- ECDSA-signed transactions (Types 0x00–0x04, and Type 0x06 in ECDSA mode) whose recovered sender is a native-key account MUST be rejected during transaction validation.
- EIP-7702 authorization tuples whose recovered authority is a native-key account MUST be rejected.

The account is permanently governed by its embedded native key. The ECDSA private key — whether unknown, destroyed, or still held — has no protocol significance. Key rotation is accomplished via native-key-signed authorization tuples, not ECDSA.

### Keyless Account Creation (Crafted-Signature Method)

An account MAY be created where **no party has ever possessed the ECDSA private key**:

1. The creator generates an ML-DSA-44 keypair `(sk, pk)`.
2. The creator computes the authorization message for a fresh (nonce-0) account:

   ```
   msg_hash = keccak256(NATIVE_KEY_MAGIC || rlp([chain_id, pk, 0]))
   ```

3. The creator selects `r` as the x-coordinate of a secp256k1 curve point whose discrete logarithm is unknown (e.g., output of hash-to-curve on a public seed), and selects an arbitrary non-zero `s`.
4. The creator computes `authority = ecrecover(msg_hash, y_parity, r, s)`. This yields a deterministic address for which no party knows the private key.
5. Any party funds `authority` with ETH.
6. Any party submits a Type `0x06` transaction (ECDSA mode) containing the authorization tuple `[chain_id, pk, 0, y_parity, r, s]`.

The account at `authority` is now authenticated exclusively by the ML-DSA-44 key `pk`. Because deriving the ECDSA private key from the recovered public key requires solving the Elliptic Curve Discrete Logarithm Problem, the account is **provably rootless** — no ECDSA backdoor exists.

The `authority` address is deterministic given `(chain_id, pk, r, s, y_parity)`, enabling counterfactual address computation and pre-funding before the Type `0x06` transaction is submitted.

**Recommended construction for `r`:** Compute `r_seed = keccak256("nkd-v1" || chain_id || pk)`, then find the smallest valid secp256k1 x-coordinate ≥ `r_seed mod p`. Set `s = 1`. This makes the derivation publicly verifiable: anyone can reproduce the computation and confirm that no trapdoor was used.

#### Transaction Origination

This EIP extends the [EIP-3607](./eip-3607.md) exception established by EIP-7702: accounts whose code begins with `0xef0101` MAY originate transactions (via Type `0x06` in ML-DSA-44 mode), in addition to accounts whose code begins with `0xef0100`.

### Key Rotation

A native-key account holder MAY rotate their native key by including a native-key-signed authorization tuple in a Type `0x06` transaction. The tuple `[chain_id, new_pubkey, nonce, authority, signature]` is signed by the currently installed native key and, when processed, replaces the account's code with `ML_DSA_44_DESIGNATION || new_pubkey`.

Key rotation does not require the original ECDSA key and works identically for ephemeral-key and crafted-signature (rootless) accounts. The rotation is atomic: it is applied during authorization list processing, before transaction execution.

Because the authorization tuple is included in a Type `0x06` transaction, the rotation may be submitted by any party — the native-key account holder need not be the transaction sender. This enables gas sponsorship for key rotation.

### Interaction with EIP-7702

| From | To | Permitted? |
|------|----|-----------|
| Empty / EOA | `0xef0101` (native key) | Yes, via Type `0x06` authorization list |
| `0xef0100` (code delegation) | `0xef0101` (native key) | Yes, via Type `0x06` authorization list (ECDSA-signed) |
| `0xef0101` (native key) | `0xef0100` (code delegation) | **No.** ECDSA signatures are permanently rejected. |
| `0xef0101` (native key) | `0xef0101` (new key) | Yes, via native-key-signed authorization tuple |

#### Code-Reading Operations

| Opcode | Behavior for `0xef0101` accounts |
|--------|----------------------------------|
| `EXTCODESIZE` (`0x3b`) | Returns `1315` |
| `EXTCODECOPY` (`0x3c`) | Copies from the 1,315-byte designator |
| `EXTCODEHASH` (`0x3f`) | Returns keccak256 of the 1,315-byte designator |
| `CODESIZE` (`0x38`) | Within the account's own context: `1315` |
| `CODECOPY` (`0x39`) | Within the account's own context: copies the designator |

#### Code-Execution Operations

`CALL` (`0xf1`), `CALLCODE` (`0xf2`), `DELEGATECALL` (`0xf4`), and `STATICCALL` (`0xfa`) targeting a native-key account execute no code. The account behaves as an EOA for execution purposes.

## Rationale

### Permanent Delegation

Native key delegation is permanent. Once an account's code is set to `0xef0101 || pubkey`, the ECDSA key is dead — the protocol will never accept it again. This is a deliberate and safe design choice for two reasons.

First, permanence is safe because the new key is the root key. The holder of the installed ML-DSA-44 private key can always rotate to a new key via a native-key-signed authorization tuple. There is no loss of authority: the account owner retains full, exclusive control through the current native key. Reverting to ECDSA would only re-introduce a weaker authentication scheme with no benefit.

Second, permanence eliminates the entire class of "dormant key" attacks. If the conversion were revocable, a leaked or quantum-broken ECDSA key could always hijack the account by reverting the delegation. Irreversibility means there is no second key to protect, no fallback to worry about, and no ambiguity about which key controls the account. For crafted-signature accounts this is a mathematical guarantee (the ECDSA key never existed). For ephemeral-key accounts it is a protocol-enforced guarantee independent of key destruction procedures.

The permanence also simplifies the security model: validators need only check the account's code prefix to determine the authentication scheme. There is no need to track historical key states or handle mixed-mode authentication.

### Embedded Keys vs. Contract Delegation

EIP-7702 delegates to code at an address. Native key delegation embeds the key directly in the account's code field. This is the correct design because:

1. **No code execution is involved.** The key authenticates transactions at the protocol level. There is no contract to delegate to.
2. **Self-contained verification.** Validators verify signatures without loading external code or crossing the EVM boundary.
3. **No delegation chain concerns.** EIP-7702 must handle chains of `ef0100` pointers. Native key accounts are terminal — no indirection.
4. **Minimal storage.** 1,315 bytes per account vs. a full contract deployment.

### Native-Key Accounts as Pure EOAs

Native-key accounts intentionally have no code execution capability. They cannot use EIP-7702 code delegation for batching, sponsorship, or privilege de-escalation. This is a deliberate scope constraint, not an oversight.

The purpose of this EIP is to replace the authentication primitive, not to replicate the full EIP-7702 feature set. Combining native key authentication with code delegation is a valid goal but introduces significant complexity: the account's code field would need to encode both a delegation target and an authentication key, and the interaction between the two must be carefully specified. A future EIP may define a combined designator (e.g., one that embeds both a pubkey and a delegation address) or allow `0xef0101` accounts to also carry `0xef0100` delegation. This EIP provides the authentication foundation that such extensions would build on.

### Post-Quantum Readiness

This EIP directly addresses the post-quantum threat by deploying ML-DSA-44, a NIST-standardized post-quantum signature scheme (FIPS 204[^1]), as the first native key scheme. Deploying post-quantum authentication before quantum computers threaten existing cryptography gives the ecosystem time to migrate accounts at its own pace rather than under emergency conditions.

The migration path is straightforward. A single Type `0x06` transaction (in ECDSA mode) atomically replaces an account's authentication scheme. Because the `0xef01XX` prefix space is extensible, future signature schemes slot directly into the same framework. The migration is one transaction, one block, one atomic state change — no intermediate contract deployments, no multi-step approval chains, and no window during which the account is authenticated by both the old and new key.

The crafted-signature path further strengthens this: new accounts can be created directly under ML-DSA-44, bypassing ECDSA entirely. The combination of in-place migration for existing accounts and native creation for new accounts provides a complete migration path without requiring a new account model or a hard fork beyond the initial activation of the relevant `0xef01XX` designator.

### Choice of ML-DSA-44

ML-DSA-44 (FIPS 204[^1]) was selected as the initial native key scheme for the following reasons:

1. **Post-quantum security.** ML-DSA-44 provides NIST Level 1 security (128-bit post-quantum), comparable to the ~128-bit classical security of secp256k1 ECDSA. Unlike Ed25519 or secp256r1, it is not vulnerable to quantum attacks.
2. **NIST standardization.** FIPS 204 is a finalized, published standard with an established ecosystem of implementations. This provides the normative stability required for a consensus-critical specification.
3. **Implementation maturity.** ML-DSA has the broadest library support of any post-quantum signature scheme, reducing the risk of consensus-critical implementation divergence across Ethereum clients.
4. **Reasonable size tradeoffs.** ML-DSA-44 public keys (1,312 bytes) and signatures (2,420 bytes) are larger than classical schemes but remain practical for on-chain use. Future schemes with better size profiles (e.g., FN-DSA under FIPS 206, when finalized) can be added via new `0xef01XX` designators without modifying this EIP.

secp256r1 (P-256) ECDSA was considered but rejected: it is not post-quantum, and its verification is already well served by existing precompile proposals. Ed25519 was considered but provides no quantum resistance, and the "test the migration path with a non-PQ scheme first" argument is weaker than deploying quantum resistance directly.

### Scheme-Specific Prefixes

Using distinct 3-byte prefixes per scheme (`0xef0101` for ML-DSA-44, `0xef0102` for a future scheme, etc.) rather than a generic prefix with a scheme byte:

1. **Fixed code sizes.** Each scheme has a known pubkey length. The code size is fixed and can be validated without parsing.
2. **Independent activation.** Each scheme is its own EIP. Consensus clients can support schemes incrementally.
3. **No version negotiation.** The prefix fully determines the verification algorithm.

### Single Transaction Type with Dual Authentication Mode

This EIP uses a single transaction type (`0x06`) for both setting native keys (ECDSA mode) and originating transactions from native-key accounts (ML-DSA-44 mode). The `sender` field acts as the discriminant: empty for ECDSA, 20 bytes for native key mode. This avoids consuming two [EIP-2718](./eip-2718.md) type numbers and enables a capability that two separate types could not: a native-key account can submit migration authorizations for other accounts in the same transaction it uses to send value or call contracts.

The `native_key_authorization_list` may be empty in either mode. In ECDSA mode, a transaction with an empty list is invalid (there is no reason to use Type `0x06` without authorizations or ML-DSA-44 signing). In ML-DSA-44 mode, an empty list is the common case — a native-key account simply sending a transaction.

ML-DSA-44 does not support public key recovery from signatures. The `sender` address must be stated explicitly in ML-DSA-44 mode. This is a departure from Ethereum's "recover sender from signature" convention, but provides a tangible benefit: transaction deserialization no longer requires an elliptic curve operation.

This EIP was initially specified as two transaction types, `0x5` to set native key delegations, and `0x6` to dispatch transactions from native key delegated accounts. Making a single tx type to serve both needs and all future extensions reduces protocol complexity footprint.

### Crafted-Signature Creation

The crafted-signature method is strictly stronger than the ephemeral-key method:

| Property | Ephemeral key | Crafted signature |
|----------|--------------|-------------------|
| ECDSA key ever existed in memory | Yes | No |
| Requires secure key destruction | Yes | No |
| Side-channel risk during signing | Yes | No |
| Verifiable by third parties | No | Yes (reproducible `r` derivation) |

The technique is battle-tested: Nick's method and [ERC-2470](./eip-2470.md) use identical cryptographic reasoning for keyless contract deployment.

### Omitted Features

This EIP deliberately omits [EIP-7702](./eip-7702.md) code delegation and [EIP-4844](./eip-4844.md) blob carrying for native-key accounts. Neither omission is fundamental. Code delegation could be added via a new delegation designator that embeds both a pubkey and a delegation target. Blob support could be added via a new transaction type that combines ML-DSA-44 authentication with blob fields. Both are deferred to keep this EIP focused on the authentication primitive.

## Backwards Compatibility

This EIP introduces new behavior gated behind a new transaction type and an explicit opt-in authorization. No existing accounts or transaction types are affected unless the account owner explicitly converts via a native key authorization.

1. **New delegation designator** (`0xef0101`). No conflict with `0xef0100` or pre-[EIP-3541](./eip-3541.md) contracts, which cannot have `0xef`-prefixed code.
2. **New transaction type** (`0x06`). Standard [EIP-2718](./eip-2718.md) typed transaction rollout. Unrecognized types are ignored by older clients.
3. **Extended [EIP-3607](./eip-3607.md) exception.** Transaction origination is now permitted for both `0xef0100` and `0xef0101` code prefixes.
4. **ECDSA rejection for converted accounts.** This is a new validation rule, but applies only to accounts that explicitly opted in. No existing account is affected without an explicit on-chain authorization.

## Test Cases

Pending.

## Security Considerations

### Post-Quantum Threat Model

The post-quantum threat to Ethereum accounts is not uniform. It depends on whether the account's authentication key is exposed on-chain:

Any account whose authentication key is quantum-vulnerable and exposed on-chain is vulnerable at rest to a quantum attacker who can recover the private key. This applies to ECDSA-signed transactions (which expose the secp256k1 public key) and EIP-7702 delegations (which can be overwritten by recovering the authorizing ECDSA key). Native-key accounts delegated to ML-DSA-44 are not vulnerable at rest or in flight, as ML-DSA-44 is a post-quantum scheme — neither the authorization signature nor the installed key is quantum-recoverable. Only accounts that have never exposed a public key on-chain (nonce-0 EOAs) and native-key accounts delegated to a post-quantum `0xef01XX` scheme are safe at rest.

### ECDSA Key Exposure Window (Ephemeral Key Path)

When creating an account via the ephemeral key path, the ECDSA private key exists in memory for the duration of the authorization signing. Implementors should prefer the crafted-signature path. When using ephemeral keys, implementors must generate and destroy the key in a secure, memory-safe context and must not persist the key to disk.

### ML-DSA-44 Implementation Correctness

The ML-DSA-44 verification algorithm is specified precisely in the Type `0x06` native key mode validation rules to prevent consensus-critical divergence between implementations. The specification requires canonical encoding of all values, strict norm bound checking for signature coefficients, and rejection of malformed hint vectors (including duplicate or out-of-order indices). This last requirement addresses a known malleability vector in ML-DSA implementations.

Consensus-critical divergence between ML-DSA-44 implementations is a chain-split risk. All implementations must produce identical accept/reject decisions for every possible (pubkey, message, signature) triple. Implementors should validate against a shared test vector suite and should not rely on library defaults, as different libraries may implement different strictness levels for encoding validation.

### Front-Running

Native key authorization tuples can be observed in the mempool and front-run. The impact is limited: the front-runner can cause the native key to be set earlier than intended, but the resulting account state is identical (the pubkey is embedded in the tuple). A front-runner cannot substitute a different key.

### Replay Protection

- **Cross-chain.** `chain_id` in both authorization tuples and type `0x06` transactions. Setting `chain_id = 0` in an authorization permits intentional multi-chain use.
- **Same-chain.** Nonce in both authorization tuples and transactions.

### Account Recovery

Native key delegation is irreversible by design. Loss of the ML-DSA-44 private key results in permanent loss of access to the account and all associated assets. This is the same failure mode as losing a secp256k1 key for a standard EOA.

Native-key accounts as specified in this EIP have no on-chain recovery path. Because they cannot execute code (no EIP-7702 delegation), smart-contract-based social recovery is not available. Users who require recovery guarantees should evaluate whether native key delegation is appropriate for their use case, or wait for a future EIP that combines native key authentication with code delegation.

### Cross-Chain Authorization Replay

Authorization tuples with `chain_id = 0` are valid on all EVM chains. For the crafted-signature creation path, this means an attacker who observes the authorization tuple can replay it on any chain, establishing the same account (same address, same native key) on chains the creator did not intend. The account state on those chains (pre-existing balance, nonce, or code) may differ from the creator's expectations.

Creators who do not intend multi-chain deployment should set `chain_id` to the target chain. Creators who intentionally use `chain_id = 0` for multi-chain deployment should be aware that any party can trigger the migration on any chain once the authorization tuple is public.

### Transaction Pool Considerations

Native-key accounts share the same transaction pool challenges as EIP-7702 delegated accounts: a key rotation could invalidate pending transactions. Clients should accept at most one pending Type `0x06` transaction per native-key account to minimize the number of transactions that can be invalidated by a single state change.

### Deterministic Keyless Addresses

The crafted-signature method produces addresses that depend on `(chain_id, pk, r, s, y_parity)`. Users should use the recommended deterministic `r` construction to ensure addresses are publicly reproducible. Non-deterministic `r` values are not unsafe but prevent third-party verification that the account is provably rootless.

[^1]:

  ```csl-json
  {
    "type": "standard",
    "id": 1,
    "author": [
      {
        "literal": "National Institute of Standards and Technology"
      }
    ],
    "title": "Module-Lattice-Based Digital Signature Standard",
    "DOI": "10.6028/NIST.FIPS.204",
    "URL": "https://csrc.nist.gov/pubs/fips/204/final",
    "original-date": {
      "date-parts": [
        [2024, 8, 13]
      ]
    }
  }
  ```

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
