This EIP extends the delegation designator system introduced by EIP-7702 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 Ed25519 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 Ed25519-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) for keyless contract deployment.
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:
0xef01XX designators.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 and RFC 8174.
| 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 |
ED25519_DESIGNATION |
0xef0101 |
3-byte code prefix for Ed25519 native key accounts |
PER_NATIVE_AUTH_BASE_COST |
12500 |
Gas charged per native key authorization tuple (matches EIP-7702 PER_AUTH_BASE_COST) |
PER_EMPTY_ACCOUNT_COST |
25000 |
Additional gas if the authority account was previously empty (same as EIP-7702) |
ED25519_VERIFY_COST |
3450 |
Intrinsic gas for Ed25519 signature verification |
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) |
0xef0101 |
35 bytes | Ed25519 native key (this EIP) |
0xef0102–0xef01ff |
varies | Reserved for future signature schemes |
An account whose code is exactly 0xef0101 || pubkey (35 bytes) is a native-key account. The 32-byte pubkey is an Ed25519 public key used for all subsequent transaction authentication.
0x06)A new EIP-2718 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. 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 Ed25519 mode |
signature |
bytes |
65-byte ECDSA signature or 64-byte Ed25519 signature |
The sender field determines the transaction's authentication 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.sender is 20 bytes): The transaction is signed with Ed25519 by the native-key account at sender. signature is 64 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 Ed25519 mode where sender is 20 bytes.
The native_key_authorization_list supports two tuple formats: ECDSA-signed tuples for initial key migration, and Ed25519-signed tuples for key rotation. Tuples are distinguished by element count: 6 elements for ECDSA, 5 for Ed25519. Tuples with any other element count are invalid.
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).
Each Ed25519-signed entry has the form:
ed25519_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 Ed25519 key is used for verification. The authority address is included in the signed message to prevent cross-account replay.
Future EIPs may modify this verification procedure to account for non-ed25519 native key delegations.
If sender is empty (ECDSA mode):
signature is exactly 65 bytes. Otherwise the transaction is invalid.y_parity = signature[0], r = signature[1..33], s = signature[33..65].ecrecover(tx_hash, y_parity, r, s). If recovery fails, the transaction is invalid.If sender is 20 bytes (Native Key mode):
sender's code begins with ED25519_DESIGNATION and is exactly 35 bytes. Otherwise the transaction is invalid.sender to accessed_addresses (as defined by EIP-2929).pubkey = sender.code[3..35].Ed25519_Verify(pubkey, tx_hash, signature) using cofactorless verification per RFC 8032 §5.1.7, with the following additional constraints:pubkey MUST be a canonical encoding of a point on Ed25519. Non-canonical encodings MUST be rejected.s component of signature MUST satisfy s < L, where L is the Ed25519 group order (2^252 + 27742317777372353535851937790883648493). Signatures with s >= L MUST be rejected.pubkey.[8][s]B = [8]R + [8][k]A, NOT [s]B = R + [k]A. If verification fails, the transaction is invalid.nonce == sender.nonce. Otherwise the transaction is invalid.ED25519_VERIFY_COST is added to the transaction's intrinsic gas cost in Ed25519 mode, replacing the implicit ecrecover cost.
If sender is any other length, the transaction is invalid.
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:
chain_id is 0 or equals the current chain ID. Otherwise skip.pubkey is exactly 32 bytes. Otherwise skip.nonce < 2^64 - 1. Otherwise skip.s <= secp256k1n / 2, as per EIP-2. Otherwise skip.msg_hash = keccak256(NATIVE_KEY_MAGIC || rlp([chain_id, pubkey, nonce])).authority = ecrecover(msg_hash, y_parity, r, s). If recovery fails, skip.authority's code is empty or begins with 0xef0100. Otherwise skip.authority's nonce equals nonce. Otherwise skip.authority to accessed_addresses (as defined by EIP-2929).authority's nonce by one.authority's code to 0xef0101 || pubkey.PER_NATIVE_AUTH_BASE_COST gas, plus PER_EMPTY_ACCOUNT_COST if the account was previously empty.For each Ed25519-signed tuple [chain_id, new_pubkey, nonce, authority, signature], in order:
chain_id is 0 or equals the current chain ID. Otherwise skip.new_pubkey is exactly 32 bytes. Otherwise skip.nonce < 2^64 - 1. Otherwise skip.authority's code begins with ED25519_DESIGNATION and is exactly 35 bytes. Otherwise skip.current_pubkey = authority.code[3..35].msg_hash = keccak256(NATIVE_KEY_MAGIC || rlp([chain_id, new_pubkey, nonce, authority])).Ed25519_Verify(current_pubkey, msg_hash, signature) using the same verification constraints as Type 0x06 Ed25519 mode. If verification fails, skip.authority's nonce equals nonce. Otherwise skip.authority to accessed_addresses (as defined by EIP-2929).authority's nonce by one.authority's code to ED25519_DESIGNATION || new_pubkey.PER_NATIVE_AUTH_BASE_COST gas.If multiple tuples (of either type) target the same authority, the last valid tuple wins.
Once an account's code is set to 0xef0101 || pubkey:
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 Ed25519-signed authorization tuples, not ECDSA.
An account MAY be created where no party has ever possessed the ECDSA private key:
(sk, pk).msg_hash = keccak256(NATIVE_KEY_MAGIC || rlp([chain_id, pk, 0]))
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.authority = ecrecover(msg_hash, y_parity, r, s). This yields a deterministic address for which no party knows the private key.authority with ETH.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 Ed25519 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.
This EIP extends the EIP-3607 exception established by EIP-7702: accounts whose code begins with 0xef0101 MAY originate transactions (via Type 0x06 in Ed25519 mode), in addition to accounts whose code begins with 0xef0100.
A native-key account holder MAY rotate their Ed25519 key by including an Ed25519-signed authorization tuple in a Type 0x06 transaction. The tuple [chain_id, new_pubkey, nonce, authority, signature] is signed by the currently installed Ed25519 key and, when processed, replaces the account's code with ED25519_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.
| 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 Ed25519-signed authorization tuple |
| Opcode | Behavior for 0xef0101 accounts |
|---|---|
EXTCODESIZE (0x3b) |
Returns 35 |
EXTCODECOPY (0x3c) |
Copies from the 35-byte designator |
EXTCODEHASH (0x3f) |
Returns keccak256 of the 35-byte designator |
CODESIZE (0x38) |
Within the account's own context: 35 |
CODECOPY (0x39) |
Within the account's own context: copies the designator |
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.
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 Ed25519 private key can always rotate to a new key via an Ed25519-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.
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:
ef0100 pointers. Native key accounts are terminal — no indirection.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.
This EIP is not itself a post-quantum resistance mechanism. Ed25519 is vulnerable to the same quantum attacks as secp256k1 ECDSA. The purpose of this EIP is to establish a credible, tested migration route — not to provide the final destination.
Adding Ed25519 as the first native key scheme may appear counterintuitive given its quantum vulnerability. But Ed25519 is immediately useful (hardware support, key hygiene, provable rootlessness), and the migration mechanism it exercises is exactly the mechanism a future post-quantum scheme will use. A post-quantum emergency that requires migrating billions of dollars of account value is not the time to deploy an untested migration path. By deploying the framework with Ed25519 first, the ecosystem gains real-world experience with the migration flow — wallet UX, tooling, client implementation, edge cases — before the stakes become existential. Without a tested route, any real post-quantum migration is strictly riskier.
The migration path itself is straightforward. A single Type 0x06 transaction (in ECDSA mode) atomically replaces an account's authentication scheme. Because the 0xef01XX prefix space is extensible, a future post-quantum designator (e.g., 0xef0103 for a hash-based or lattice-based scheme) slots 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 a post-quantum scheme, bypassing ECDSA entirely. The combination of in-place migration for existing accounts and native creation for new accounts provides a credible migration path without requiring a new account model or a hard fork beyond the initial activation of the relevant 0xef01XX designator.
secp256r1 (P-256) ECDSA was considered as the initial scheme. However, secp256r1 verification is well served by precompile availability (e.g., RIP-7212), which allows any EIP-7702 delegate or smart contract wallet to verify secp256r1 signatures without protocol-level account changes. A precompile is the correct abstraction for "make this signature scheme available to the EVM." Native key delegation is the correct abstraction for "replace the account's authentication primitive." Ed25519 is not available via precompile on Ethereum mainnet and provides distinct benefits (simpler implementation, deterministic signatures, no malleability, widespread hardware support) that justify protocol-level integration.
Using distinct 3-byte prefixes per scheme (0xef0101 for Ed25519, 0xef0102 for a future scheme, etc.) rather than a generic prefix with a scheme byte:
This EIP uses a single transaction type (0x06) for both setting native keys (ECDSA mode) and originating transactions from native-key accounts (Ed25519 mode). The sender field acts as the discriminant: empty for ECDSA, 20 bytes for Ed25519. This avoids consuming two EIP-2718 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 Ed25519 signing). In Ed25519 mode, an empty list is the common case — a native-key account simply sending a transaction.
Ed25519 does not support public key recovery from signatures. The sender address must be stated explicitly in Ed25519 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.
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 use identical cryptographic reasoning for keyless contract deployment.
This EIP deliberately omits EIP-7702 code delegation and EIP-4844 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 Ed25519 authentication with blob fields. Both are deferred to keep this EIP focused on the authentication primitive.
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.
0xef0101). No conflict with 0xef0100 or pre-EIP-3541 contracts, which cannot have 0xef-prefixed code.0x06). Standard EIP-2718 typed transaction rollout. Unrecognized types are ignored by older clients.0xef0100 and 0xef0101 code prefixes.The post-quantum threat to Ethereum accounts is not uniform. It depends on whether the account's public key has been exposed on-chain:
Any account whose authentication key is exposed on-chain is vulnerable at rest to a quantum attacker who can recover the private key. This applies uniformly to ECDSA-signed transactions (which expose the secp256k1 public key), EIP-7702 delegations (which can be overwritten by recovering the authorizing ECDSA key), and Ed25519 native-key delegations (whose public key is embedded in the account's code field). 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.
Delegations to a post-quantum scheme are not vulnerable in flight or at rest, as neither the authorization signature nor the installed key is quantum-recoverable. For all other delegation types, security in flight depends on the resource cost of quantum key recovery remaining high relative to the time the authorization is pending inclusion. This EIP does not change that assumption — it provides the framework through which a post-quantum scheme can be deployed when one is ready.
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.
The Ed25519 verification algorithm is specified precisely in the Type 0x06 Ed25519 mode validation rules to avoid the ambiguities in RFC 8032 that have caused consensus failures in other protocols (notably Zcash and Solana). The specification requires cofactorless verification with explicit rejection of non-canonical encodings, s >= L signatures, and small-order public keys. This corresponds to the "strict" verification mode.
By contrast, the permissive verification mode relaxes several of these constraints: it accepts non-canonical point encodings (where the y-coordinate is unreduced modulo 2^255 - 19), permits small-order points for both the public key A and the signature component R, and requires only the cofactored equation [8][S]B = [8]R + [8][k]A to hold. This mode enables batch verification compatibility, but its permissive acceptance criteria create a larger equivalence class of valid signatures for a given (key, message) pair. This EIP explicitly rejects these semantics: all points must be canonically encoded, small-order public keys are forbidden, and the scalar s must be reduced below the group order L.
Consensus-critical divergence between Ed25519 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 implement different verification strictness levels.
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.
chain_id in both authorization tuples and type 0x06 transactions. Setting chain_id = 0 in an authorization permits intentional multi-chain use.Native key delegation is irreversible by design. Loss of the Ed25519 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.
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 Ed25519 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.
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.
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.
Copyright and related rights waived via CC0.