evstack / evstack/ev-rs

Native key delegation framework for multi-scheme EOA authentication

Open
#18 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Rust
Stars
4
Forks
0
PR merge metrics
No merged PRs in 30d

Description

## Summary

Add a framework for EOAs to authenticate with non-ECDSA signature schemes (Ed25519, P-256, post-quantum), including the ability to migrate an existing ECDSA EOA to an alternative key type. Inspired by EIP-8164 (Native Key Delegation for EOAs) but adapted to ev-rs's account-driven architecture.

## Motivation

- **Post-quantum readiness**: secp256k1 ECDSA is vulnerable to quantum attacks. A key migration path is needed before it becomes urgent.
- **Passkey/WebAuthn support**: Issue #14 adds P-256 as a one-off. A framework avoids repeating that work for every new scheme.
- **ZK-friendly signatures**: Ed25519 and Schnorr are cheaper to verify in zkVM guests than ECDSA (relevant to #4).
- **Key rotation**: Users should be able to migrate to a new key without changing their account identity.

## Why ev-rs is well-positioned

Unlike Ethereum (where EOAs are permanently bound to secp256k1), ev-rs already separates the relevant concerns:

| Concern | Current state | What it enables |
|---------|--------------|-----------------|
| `SignatureVerifierRegistry` | Pluggable per tx type byte | Register new verifiers without touching existing code |
| Domain-tagged identity | `keccak256(domain_tag \|\| payload)` | New key types get new domains, coexist cleanly |
| `authenticate()` on accounts | Account code defines auth logic | Key type/migration logic lives in the account, not the protocol |
| Registry-based identity resolution | Address → AccountId via storage | Same AccountId can be reachable from multiple address derivations |

EIP-8164 needs a new tx type and special bytecode prefix to work around Ethereum's constraints. ev-rs can do this at the account code level with a new tx envelope variant and verifier registration.

## Scope

### 1. Signature scheme trait and registry extensions

- [ ] Define `KeyType` enum: `Secp256k1`, `Ed25519`, `Secp256r1` (P-256), extensible
- [ ] Add `ed25519-dalek` crate dependency for Ed25519 verification
- [ ] Implement `SignatureVerifier` for Ed25519
- [ ] Evaluate whether new schemes get new tx type bytes (e.g. `0x04`) or a single "multi-sig-type" envelope that carries key type + signature

### 2. Transaction envelope extension

- [ ] Add new `TxEnvelope` variant (or generic typed envelope) that carries: key type identifier, public key, signature, and standard tx fields
- [ ] Extend `TxEnvelope::decode_from()` to handle the new type byte
- [ ] For Ed25519: public key is explicit in tx (no recovery like ECDSA), so `TypedTransaction::sender()` derives address from the embedded pubkey

### 3. Identity derivation for new key types

- [ ] Add domain tags: `DOMAIN_EOA_ED25519_V1 = b"eoa:ed25519:v1"`, `DOMAIN_EOA_P256_V1 = b"eoa:p256:v1"`
- [ ] Add `derive_ed25519_eoa_account_id(pubkey)` and equivalent for P-256
- [ ] Extend EOA registry (`eoa_registry.rs`) to handle new key type registrations
- [ ] Ensure same `AccountId` is NOT derivable from different key types (domain separation guarantees this)

### 4. Account-level key delegation (migration)

This is the EIP-8164 equivalent: an existing ECDSA EOA permanently delegates to a new key.

- [ ] EOA account code stores active key type + public key in account storage
- [ ] `authenticate()` verifies against the stored active key, not hardcoded ECDSA
- [ ] Migration transaction: signed by current key, sets new key type + pubkey
- [ ] Once migrated, old ECDSA key can no longer authenticate (permanent delegation)
- [ ] Consider: revocation/recovery mechanism? Multi-key threshold?

### 5. Bootstrap and sender resolution

- [ ] `SenderBootstrap` in `stf_traits` needs to handle non-ECDSA account init
- [ ] `resolve_sender_account()` must work for new key type address derivations
- [ ] First tx from a new Ed25519 key should auto-create the EOA account (same as current ECDSA bootstrap flow)

### 6. Gas/fee considerations

- [ ] Ed25519 verification is ~2x faster than secp256k1 in software — could price lower
- [ ] P-256 is ~20-40% slower than secp256k1 (see #14) — price higher
- [ ] `verify_signatures_parallel()` already handles heterogeneous verifiers via the registry

## Design decisions to make

1. **Single envelope vs per-scheme envelopes**: One new tx type `0x04` with a key-type discriminator, or separate type bytes per scheme? Single envelope is more extensible; separate types allow tighter RLP schemas.

2. **Account identity on migration**: When an ECDSA EOA migrates to Ed25519, does the `AccountId` change? It shouldn't — the account ID should be stable. The new key's address becomes an alias in the registry pointing to the same AccountId.

3. **Interaction with EIP-7702 delegation**: EIP-7702 lets EOAs delegate to contract code. Key delegation is orthogonal (changes *how* you sign, not *what* your account does). But if ev-rs supports both, need to define ordering: key delegation first, then code delegation? Or combined?

4. **ZK proving cost**: Ed25519 verification in a zkVM is significantly cheaper than ECDSA. If #4 (ZK proving) is a priority, this influences which schemes to prioritize.

## Non-goals

- Custom/arbitrary signature schemes at the protocol level (accounts can implement anything in `authenticate()` already)
- Changing the Ethereum-compatible RPC surface — JSON-RPC still accepts ECDSA-signed txs as before
- Multi-sig or threshold schemes at the protocol level (this is account code territory)

## Relationship to other issues

- **#14 (WebAuthn/P-256)**: P-256 becomes one key type in this framework rather than a standalone addition. #14's scope (WebAuthn payload parsing, gas pricing) feeds into Section 1 here.
- **#4 (ZK Proving)**: Ed25519/Schnorr are cheaper in zkVM circuits. This framework enables switching to ZK-friendly signatures.

## References

- EIP-8164: Native Key Delegation for EOAs
- EIP-7702: Set EOA Account Code
- EIP-665: Ed25519 Precompile
- `ed25519-dalek` crate for Rust Ed25519 implementation

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.