w3pk 0.10.2 → 0.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,1321 +2,160 @@
2
2
 
3
3
  ## Executive Summary
4
4
 
5
- The w3pk SDK has **strong conventional cryptography** but is vulnerable to future quantum attacks through its ECDSA signature schemes (secp256k1 and P-256). Based on expert consensus, we have **10-15 years** before cryptographically relevant quantum computers (CRQC) pose real threats. Our strategy: **plan deliberately, not panic**.
5
+ w3pk's data-encryption layer is already post-quantum: **ML-KEM-1024** (NIST FIPS 203) ships today for encrypting data at rest and in transit. What remains quantum-vulnerable is **transaction signing** — secp256k1 (Ethereum) and P-256 (WebAuthn passkeys) both fall to Shor's algorithm on a cryptographically relevant quantum computer (CRQC). Expert consensus, including the Ethereum Foundation's own estimate, puts CRQC arrival in the **early-to-mid 2030s**, and no immediate action is required.
6
6
 
7
- This document is aligned with the [Ethereum quantum resistance roadmap](https://x.com/VitalikButerin/status/2027075026378543132) (February 2026), which outlines Ethereum's protocol-level approach to quantum threats.
7
+ Crucially, **the signature problem is not ours to solve unilaterally.** A w3pk transaction is only as quantum-safe as the L1 rules that accept it. Ethereum's own migration — the [lean Ethereum](https://blog.ethereum.org/2025/07/31/lean-ethereum) programme — targets **roughly 2029** for core L1 post-quantum infrastructure (consensus signatures, execution-layer verification), with full ecosystem migration extending past that. w3pk's signature strategy is therefore to track that protocol timeline rather than build a bespoke, pre-standard PQ signature stack that would need to be thrown away once the protocol-native path lands.
8
8
 
9
- ### Current Status: Quantum-Aware Architecture
9
+ The full technical detail behind Ethereum's plan lives with the Ethereum Foundation's own sources — [pq.ethereum.org](https://pq.ethereum.org/), the [lean Ethereum announcement](https://blog.ethereum.org/2025/07/31/lean-ethereum), and the [EF Protocol Architecture roadmap](https://strawmap.org/) — this document summarizes only what drives w3pk decisions.
10
10
 
11
- w3pk can be characterized as:
11
+ ### What w3pk will do when Ethereum is ready
12
12
 
13
- - ✅ **Quantum-aware** - Architecture designed with quantum migration in mind
14
- - ✅ **Quantum-resistant encryption** - AES-256-GCM provides 128-bit quantum security
15
- - ✅ **Migration-ready** - Account abstraction (EIP-7702 / EIP-4337) enables smooth transition
16
- - ⚠️ **Signature vulnerability** - secp256k1 and P-256 vulnerable to Shor's algorithm
17
- - 🔮 **Timeline to full quantum-readiness** - 18-24 months (Phase 2 completion)
13
+ Ethereum's official target for core L1 post-quantum infrastructure is **~2029** (the EF's own planning language; some trackers cite December 2029 as the working milestone). The action w3pk takes is gated on two concrete protocol events, not on the calendar date itself:
18
14
 
19
- ### Risk Assessment
15
+ | Trigger | w3pk action |
16
+ | --- | --- |
17
+ | **EIP-8141 (frame transactions / native account abstraction) ships on mainnet**, with a working PQ signature path (precompile or validation-frame verifier) | Ship an opt-in `quantumSafe` account mode: a validation frame that requires a hybrid classical + PQ signature (secp256k1 + whatever ML-DSA/hash-based scheme Ethereum standardizes). No forced migration — existing EOAs and finalized history remain valid regardless. |
18
+ | **Hybrid mode proves stable in production** (gas costs acceptable, tooling mature, no incidents) | Make `quantumSafe: true` the default for **new** wallets created via `register()`. Existing wallets stay opt-in. |
19
+ | **Ethereum's consensus/execution layers complete PQ migration** (fork milestones L*/M* and beyond) | Offer a one-time, user-initiated migration path from classical-only to hybrid/PQ-only accounts. Never auto-migrate funds or force a breaking change without explicit user action. |
20
20
 
21
- **Low/Moderate Risk Components:**
22
- - ✅ **Encrypted backups** (AES-256-GCM) - Minimal harvest-now-decrypt-later (HNDL) risk
23
- - ✅ **Session encryption** (AES-256-GCM) - Quantum-safe with 128-bit security
24
- - ✅ **PBKDF2** - Moderate risk (Grover's algorithm), easily mitigated
21
+ Until the first trigger fires, w3pk deliberately does **not** deploy interim smart-contract PQ signature verifiers (e.g., pre-standard ERC-4337 PQ verifier contracts). That infrastructure is not part of Ethereum's actual roadmap — the real path is EIP-8141 validation frames — and building on a throwaway interim layer would mean migrating twice. w3pk's only actionable signature-side task today is watching the fork milestones (below) and keeping the SDK's existing [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) account-abstraction support in place, since that's the on-ramp to whatever native AA scheme ships.
25
22
 
26
- **High Risk Components:**
27
- - ⚠️ **Transaction signatures** (secp256k1 ECDSA) - Shor's algorithm enables private key recovery
28
- - ⚠️ **WebAuthn passkeys** (P-256 ECDSA) - Same vulnerability as secp256k1
29
- - ⚠️ **Stealth addresses** (ERC-5564 ECDH) - Key agreement vulnerable to quantum attacks
23
+ ### Current status
30
24
 
31
- ---
32
-
33
- ## Ethereum's Quantum Threat Landscape
34
-
35
- Based on the [Ethereum quantum resistance roadmap](https://x.com/VitalikButerin/status/2027075026378543132), **four components** of Ethereum are quantum-vulnerable:
36
-
37
- 1. **Consensus-layer BLS signatures** - Vulnerable to Shor's algorithm
38
- 2. **Data availability (KZG commitments+proofs)** - Relies on elliptic curve pairings
39
- 3. **EOA signatures (ECDSA)** - **w3pk's primary concern**
40
- 4. **Application-layer ZK proofs (KZG or Groth16)** - Pairing-based cryptography
41
-
42
- **w3pk addresses #3 (EOA signatures)** through account abstraction and hybrid post-quantum signatures.
43
-
44
- ### Ethereum's Protocol-Level Solutions
45
-
46
- | Component | Current State | Quantum-Safe Solution | Status |
47
- |-----------|---------------|----------------------|--------|
48
- | Consensus signatures | BLS12-381 | Hash-based signatures (Winternitz) + STARKs | Research phase |
49
- | Data availability | KZG | STARKs (recursive proofs for blob verification) | Engineering phase |
50
- | EOA signatures | ECDSA (secp256k1) | **Native AA (EIP-8141) + hash/lattice signatures** | Specification phase |
51
- | ZK proofs | KZG/Groth16 | **Protocol-layer recursive proof aggregation** | Research phase |
52
-
53
- **Key insight from the [Ethereum quantum resistance roadmap](https://x.com/VitalikButerin/status/2027075026378543132):** Quantum-resistant signatures are **~200,000 gas** for hash-based (Winternitz) and require **vectorized math precompiles** for lattice-based schemes. Protocol-layer proof aggregation will reduce costs to near-zero by replacing validation frames with STARKs.
54
-
55
- ---
56
-
57
- ## Current Cryptographic Architecture
58
-
59
- ### Cryptographic Primitives in Use
60
-
61
- #### Asymmetric Cryptography (Quantum-Vulnerable)
62
-
63
- | Component | Algorithm | Use Case | Quantum Threat | Ethereum Equivalent |
64
- |-----------|-----------|----------|----------------|---------------------|
65
- | Ethereum Signing | secp256k1 ECDSA | Transaction/message signatures | **HIGH** - Shor's algorithm | EOA signatures (#3) |
66
- | WebAuthn Passkeys | P-256 (ES256) | Authentication signatures | **HIGH** - Shor's algorithm | Not applicable |
67
- | Stealth Addresses | secp256k1 ECDH | Privacy-preserving key exchange | **HIGH** - Shor's algorithm | Application-layer |
68
- | HD Derivation | BIP32/BIP44 | Hierarchical key generation | **HIGH** - Depends on ECDSA | Not applicable |
69
-
70
- #### Symmetric Cryptography (Quantum-Resistant)
25
+ - ✅ **Quantum-resistant encryption, shipped** — ML-KEM-1024 (FIPS 203) + AES-256-GCM, see [ML-KEM Encryption](#ml-kem-encryption) below
26
+ - ✅ **Migration-ready** — [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) account delegation gives a path to whatever account-abstraction scheme Ethereum ships
27
+ - ⚠️ **Signature vulnerability, by design (for now)** — secp256k1 and P-256 signing is classical-only; this tracks Ethereum's own L1 timeline rather than a w3pk-specific one
28
+ - 🔮 **No user action needed today** — nothing here changes what a w3pk integrator or end user does; this is an architecture-tracking document
71
29
 
72
- | Component | Algorithm | Use Case | Quantum Security |
73
- |-----------|-----------|----------|------------------|
74
- | Wallet Encryption | AES-256-GCM | Mnemonic storage | **128-bit** (sufficient) |
75
- | Backup Encryption | AES-256-GCM | Password-based backups | **128-bit** (sufficient) |
76
- | Session Storage | AES-256-GCM | Persistent sessions | **128-bit** (sufficient) |
30
+ ### Risk assessment
77
31
 
78
- #### Key Derivation Functions
32
+ **Low/moderate risk (already mitigated):**
33
+ - ✅ Encrypted backups, session storage (AES-256-GCM) — 128-bit quantum security, negligible harvest-now-decrypt-later (HNDL) exposure
34
+ - ✅ Data encrypted with `mlkemEncrypt`/`mlkemDecrypt` — post-quantum secure today
35
+ - ✅ PBKDF2 key derivation — Grover's algorithm halves effective security; current iteration counts (210k/310k/100k) leave ample margin for the 2030s
79
36
 
80
- | Component | Algorithm | Parameters | Quantum Resistance |
81
- |-----------|-----------|------------|-------------------|
82
- | Wallet Encryption | PBKDF2-SHA256 | 210,000 iterations | **Moderate** (Grover's reduces by ~50%) |
83
- | Backup Encryption | PBKDF2-SHA256 | 310,000 iterations | **Moderate** (Grover's reduces by ~50%) |
84
- | Metadata Encryption | PBKDF2-SHA256 | 100,000 iterations | **Moderate** (Grover's reduces by ~50%) |
85
-
86
- #### Hash Functions
87
-
88
- | Component | Algorithm | Use Case | Quantum Security |
89
- |-----------|-----------|----------|------------------|
90
- | General Hashing | SHA-256 | Checksums, derivation | **128-bit collision** (sufficient) |
91
- | Ethereum Hashing | Keccak-256 | ERC-5564, addresses | **128-bit collision** (sufficient) |
92
-
93
- ### Architecture Diagram
94
-
95
- ```
96
- ┌─────────────────────────────────────────────────────────────┐
97
- │ WebAuthn Passkey │
98
- │ (P-256 ECDSA - Quantum Vulnerable) │
99
- └──────────────────────┬──────────────────────────────────────┘
100
- │ Authentication
101
- ↓
102
- ┌─────────────────────────────────────────────────────────────┐
103
- │ PBKDF2-SHA256 Key Derivation │
104
- │ (210k iterations - Moderate Quantum Risk) │
105
- └──────────────────────┬──────────────────────────────────────┘
106
- │ Derives Encryption Key
107
- ↓
108
- ┌─────────────────────────────────────────────────────────────┐
109
- │ AES-256-GCM Encryption │
110
- │ (128-bit quantum security - SAFE) │
111
- └──────────────────────┬──────────────────────────────────────┘
112
- │ Decrypts Mnemonic
113
- ↓
114
- ┌─────────────────────────────────────────────────────────────┐
115
- │ BIP39 Mnemonic │
116
- │ (12-word seed phrase) │
117
- └──────────────────────┬──────────────────────────────────────┘
118
- │ BIP44 HD Derivation
119
- ↓
120
- ┌─────────────────────────────────────────────────────────────┐
121
- │ secp256k1 Private Keys │
122
- │ (ECDSA - Quantum Vulnerable) │
123
- └──────────────────────┬──────────────────────────────────────┘
124
- │ Public Key Generation
125
- ↓
126
- ┌─────────────────────────────────────────────────────────────┐
127
- │ Ethereum Addresses (Keccak-256) │
128
- │ (Hash function - Quantum Safe) │
129
- └─────────────────────────────────────────────────────────────┘
130
- ```
37
+ **High risk (tracks Ethereum's own timeline, not w3pk's):**
38
+ - ⚠️ Transaction signatures (secp256k1 ECDSA) — broken by Shor's algorithm on a CRQC; fix depends on Ethereum shipping EIP-8141 + a PQ verification path
39
+ - ⚠️ WebAuthn passkeys (P-256 ECDSA) — same underlying vulnerability; FIDO Alliance PQ support is not expected before 2027-2028
40
+ - ⚠️ Stealth addresses (ERC-5564 ECDH) — key agreement step is quantum-vulnerable; no standardized PQ replacement exists yet
131
41
 
132
42
  ---
133
43
 
134
- ## Post-Quantum Migration Strategy
135
-
136
- ### Implementation Plan Using Ethereum's Native AA Roadmap
137
-
138
- We align with the [Ethereum quantum resistance roadmap](https://x.com/VitalikButerin/status/2027075026378543132) for quantum-safe EOA signatures:
139
-
140
- **Ethereum's Native AA Approach (EIP-8141):**
141
- - ✅ **First-class accounts** that can use any signature algorithm
142
- - ✅ **Validation frames** - Isolated signature verification with STARKs
143
- - ✅ **Protocol-layer recursive aggregation** - Reduces gas costs to near-zero
144
- - ✅ **Hash-based signatures** - ~200,000 gas (Winternitz variants)
145
- - ✅ **Lattice-based signatures** - Requires vectorized math precompiles
146
-
147
- **w3pk Interim Solution (Until EIP-8141):**
148
-
149
- We will leverage the **[Ethereum Kohaku](https://github.com/ethereum/kohaku)** `pq-account` package, which provides:
150
-
151
- - ✅ **ERC-4337 Account Abstraction** - Smart contract accounts with custom signature verification
152
- - ✅ **Dilithium & Falcon Support** - NIST-standardized post-quantum signature schemes
153
- - ✅ **Solidity Verifiers** - On-chain signature verification optimized for gas efficiency
154
- - ✅ **Ethereum Foundation Support** - Official post-quantum cryptography roadmap
155
-
156
- **Transition to [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141):** Once native AA is deployed, w3pk will migrate from [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) (bundler-based) to validation frames (protocol-native).
157
-
158
- ### Phase 1: Foundation (0-6 months) - **CURRENT PHASE**
159
-
160
- **Goal:** Establish quantum migration architecture and protect long-term secrets
161
-
162
- #### 1.1 Documentation & Planning ⭐ HIGH PRIORITY
163
- - [x] Document quantum threat model (this document)
164
- - [ ] Create Architecture Decision Record (ADR) for quantum migration
165
- - [ ] Establish monitoring for quantum computing advances
166
- - [ ] Define success criteria for quantum readiness
167
-
168
- #### 1.2 Increase Key Derivation Security ⭐ MEDIUM PRIORITY
169
- **Rationale:** Grover's algorithm reduces PBKDF2 effective security by ~50%
170
-
171
- **Implementation:**
172
- ```typescript
173
- // src/wallet/crypto.ts
174
- const PBKDF2_ITERATIONS = {
175
- backup: {
176
- classical: 310_000,
177
- quantumReady: 500_000, // Double security margin
178
- },
179
- wallet: {
180
- classical: 210_000,
181
- quantumReady: 350_000,
182
- },
183
- metadata: {
184
- classical: 100_000,
185
- quantumReady: 200_000,
186
- }
187
- };
188
-
189
- // Feature flag for gradual rollout
190
- export async function deriveEncryptionKeyFromWebAuthn(
191
- credentialId: string,
192
- publicKey?: string,
193
- quantumReady: boolean = false
194
- ): Promise<CryptoKey> {
195
- const iterations = quantumReady
196
- ? PBKDF2_ITERATIONS.wallet.quantumReady
197
- : PBKDF2_ITERATIONS.wallet.classical;
198
-
199
- return crypto.subtle.deriveKey(
200
- {
201
- name: "PBKDF2",
202
- salt: new Uint8Array(salt),
203
- iterations,
204
- hash: "SHA-256",
205
- },
206
- importedKey,
207
- { name: "AES-GCM", length: 256 },
208
- false,
209
- ["encrypt", "decrypt"]
210
- );
211
- }
212
- ```
213
-
214
- **Timeline:** 3 months
215
- **Breaking Changes:** None (backward compatible with feature flag)
216
-
217
- #### 1.3 Add Crypto-Agility Infrastructure ⭐ HIGH PRIORITY
218
- **Rationale:** Enable algorithm swapping without breaking changes
219
-
220
- **Implementation:**
221
- ```typescript
222
- // src/core/config.ts
223
- export interface CryptoConfig {
224
- version: number;
225
-
226
- signatures: {
227
- ethereum: 'secp256k1' | 'hybrid-pq';
228
- webauthn: 'p256' | 'hybrid-pq';
229
- postQuantum?: 'ml-dsa-87' | 'falcon-1024';
230
- hybridMode: boolean; // Require both classical + PQ
231
- };
232
-
233
- encryption: {
234
- symmetric: 'aes-256-gcm';
235
- kdf: 'pbkdf2-sha256' | 'argon2id';
236
- quantumReady: boolean;
237
- };
238
-
239
- minimumSecurityLevel: 'classical' | 'quantum-resistant';
240
- }
241
-
242
- // Default configuration
243
- export const DEFAULT_CRYPTO_CONFIG: CryptoConfig = {
244
- version: 1,
245
- signatures: {
246
- ethereum: 'secp256k1',
247
- webauthn: 'p256',
248
- hybridMode: false,
249
- },
250
- encryption: {
251
- symmetric: 'aes-256-gcm',
252
- kdf: 'pbkdf2-sha256',
253
- quantumReady: false,
254
- },
255
- minimumSecurityLevel: 'classical',
256
- };
257
- ```
258
-
259
- **Timeline:** 2 months
260
- **Breaking Changes:** None (extends existing config)
261
-
262
- #### 1.4 Audit Current Implementation ⭐ MEDIUM PRIORITY
263
- - [ ] Review all cryptographic code for side-channel vulnerabilities
264
- - [ ] Verify constant-time operations for sensitive comparisons
265
- - [ ] Test backup/recovery edge cases
266
- - [ ] Conduct security audit of WebAuthn integration
267
-
268
- **Timeline:** 3 months
269
- **Cost:** ~$15,000-30,000 for professional audit
270
-
271
- ### Phase 2: Infrastructure (6-18 months) - **PREPARE**
272
-
273
- **Goal:** Integrate Kohaku pq-account and design hybrid signature system
274
-
275
- #### 2.1 Integrate Kohaku PQ Account ⭐ HIGH PRIORITY
276
- **Rationale:** Leverage Ethereum Foundation's official post-quantum implementation
277
-
278
- Kohaku's `pq-account` provides **production-ready ERC-4337 accounts** with:
279
- - ✅ Hybrid signature verification (classical + post-quantum)
280
- - ✅ Multiple PQ algorithms: MLDSA (Dilithium), MLDSAETH, FALCON, ETHFALCON
281
- - ✅ Deployed on Sepolia testnet
282
- - ✅ Gas-optimized Solidity verifiers
283
-
284
- **Kohaku Architecture:**
285
- ```
286
- ┌──────────────────────────────────────────────────────────┐
287
- │ ERC-4337 User Account Contract │
288
- ├──────────────────────────────────────────────────────────┤
289
- │ • pre_quantum_pubkey (Ethereum address or P-256 point) │
290
- │ • post_quantum_pubkey (MLDSA/FALCON public key) │
291
- │ • pre_quantum_logic_contract_address │
292
- │ • post_quantum_logic_contract_address │
293
- │ • hybrid_verifier_logic_contract_address │
294
- └──────────────────────────────────────────────────────────┘
295
- ↓
296
- ┌──────────────────────────────────────────────────────────┐
297
- │ Hybrid Verifier Contract │
298
- │ (Sepolia: 0xD22492F0b9dd284a9EC0fFef3C1675...) │
299
- ├──────────────────────────────────────────────────────────┤
300
- │ Verifies BOTH signatures: │
301
- │ • ECDSA (K1/R1) via precompiles │
302
- │ • PQ signature via logic contracts │
303
- └──────────────────────────────────────────────────────────┘
304
- ```
305
-
306
- **Deployed Verifier Contracts (Sepolia Testnet):**
307
-
308
- | Signature Scheme | Contract Address | Description |
309
- |------------------|------------------|-------------|
310
- | MLDSA (Dilithium) | `0x10c978aacef41c74e35fc30a4e203bf8d9a9e548` | NIST ML-DSA signature verification |
311
- | MLDSAETH | `0x710f295f1715c2b08bccdb1d9841b4f833f6dde4` | Ethereum-optimized ML-DSA |
312
- | FALCON | `0x0724bb7c9e52f3be199964a2d70ff83a103ed99c` | NIST Falcon signature verification |
313
- | ETHFALCON | `0x146f0d9087001995ca63b648e865f6dbbb2d2915` | Ethereum-optimized Falcon |
314
- | ECDSA K1 (secp256k1) | `0xe2c354d06cce8f18fd0fd6e763a858b6963456d1` | Classical Ethereum signatures |
315
- | ECDSA R1 (P-256) | `0x4023f2e318A3c7cbCf2fFAB11A75f99aC9625214` | Classical P-256 (WebAuthn) |
316
- | **Hybrid Verifier** | `0xD22492F0b9dd284a9EC0fFef3C1675deA9f01d85` | **Dual signature verification** |
317
-
318
- **Implementation:**
319
- ```typescript
320
- // src/pq/kohaku-integration.ts
321
- import { ethers } from 'ethers';
322
-
323
- // Kohaku contract addresses (Sepolia testnet)
324
- export const KOHAKU_CONTRACTS = {
325
- sepolia: {
326
- mldsa: '0x10c978aacef41c74e35fc30a4e203bf8d9a9e548',
327
- mldsaeth: '0x710f295f1715c2b08bccdb1d9841b4f833f6dde4',
328
- falcon: '0x0724bb7c9e52f3be199964a2d70ff83a103ed99c',
329
- ethfalcon: '0x146f0d9087001995ca63b648e865f6dbbb2d2915',
330
- ecdsaK1: '0xe2c354d06cce8f18fd0fd6e763a858b6963456d1',
331
- ecdsaR1: '0x4023f2e318A3c7cbCf2fFAB11A75f99aC9625214',
332
- hybridVerifier: '0xD22492F0b9dd284a9EC0fFef3C1675deA9f01d85',
333
- },
334
- arbitrumSepolia: {
335
- mldsa: '0x10c978aacef41c74e35fc30a4e203bf8d9a9e548',
336
- mldsaeth: '0x710f295f1715c2b08bccdb1d9841b4f833f6dde4',
337
- falcon: '0x0724bb7c9e52f3be199964a2d70ff83a103ed99c',
338
- ethfalcon: '0x146f0d9087001995ca63b648e865f6dbbb2d2915',
339
- ecdsaK1: '0xe2c354d06cce8f18fd0fd6e763a858b6963456d1',
340
- ecdsaR1: '0x4023f2e318A3c7cbCf2fFAB11A75f99aC9625214',
341
- hybridVerifier: '0xD22492F0b9dd284a9EC0fFef3C1675deA9f01d85',
342
- },
343
- };
344
-
345
- export type PQAlgorithm = 'mldsa' | 'mldsaeth' | 'falcon' | 'ethfalcon';
346
- export type ClassicalAlgorithm = 'secp256k1' | 'p256';
347
-
348
- export interface PQAccountConfig {
349
- algorithm: PQAlgorithm;
350
- classicalAlgorithm: ClassicalAlgorithm;
351
- chainId: number; // 11155111 (Sepolia) or 421614 (Arbitrum Sepolia)
352
- hybridMode: boolean; // Require both signatures
353
- }
354
-
355
- /**
356
- * Deploy w3pk quantum-safe account using Kohaku infrastructure
357
- * Uses existing Kohaku verifier contracts on Sepolia
358
- */
359
- export async function deployW3PKQuantumAccount(
360
- config: PQAccountConfig,
361
- signer: ethers.Signer
362
- ): Promise<string> {
363
- const network = config.chainId === 11155111 ? 'sepolia' : 'arbitrumSepolia';
364
- const contracts = KOHAKU_CONTRACTS[network];
365
-
366
- // Get classical public key (secp256k1 or P-256)
367
- const classicalAddress = await signer.getAddress();
368
- const classicalPubKey = config.classicalAlgorithm === 'p256'
369
- ? await extractP256PublicKey(signer) // 64 bytes
370
- : classicalAddress; // 20 bytes (Ethereum address)
371
-
372
- // Generate post-quantum keypair (using Kohaku's Python signer or WASM)
373
- const pqKeypair = await generatePQKeypair(config.algorithm);
374
-
375
- // Deploy PK contract for MLDSA/MLDSAETH (stores 20KB public key)
376
- let pqPubKeyRef: string;
377
- if (config.algorithm === 'mldsa' || config.algorithm === 'mldsaeth') {
378
- pqPubKeyRef = await deployPKContract(pqKeypair.publicKey, signer);
379
- } else {
380
- pqPubKeyRef = ethers.hexlify(pqKeypair.publicKey); // FALCON stores directly
381
- }
382
-
383
- // Select logic contract addresses
384
- const preQuantumLogic = config.classicalAlgorithm === 'secp256k1'
385
- ? contracts.ecdsaK1
386
- : contracts.ecdsaR1;
387
- const postQuantumLogic = contracts[config.algorithm];
388
-
389
- // Deploy ERC-4337 account contract
390
- const accountFactory = new ethers.ContractFactory(
391
- KOHAKU_ACCOUNT_ABI,
392
- KOHAKU_ACCOUNT_BYTECODE,
393
- signer
394
- );
395
-
396
- const account = await accountFactory.deploy(
397
- classicalPubKey,
398
- pqPubKeyRef,
399
- preQuantumLogic,
400
- postQuantumLogic,
401
- contracts.hybridVerifier
402
- );
403
-
404
- await account.waitForDeployment();
405
- const accountAddress = await account.getAddress();
406
-
407
- console.log(`✅ Deployed quantum-safe account: ${accountAddress}`);
408
- console.log(` Classical: ${config.classicalAlgorithm} (${preQuantumLogic})`);
409
- console.log(` Post-Quantum: ${config.algorithm} (${postQuantumLogic})`);
410
-
411
- return accountAddress;
412
- }
413
-
414
- /**
415
- * Generate post-quantum keypair using Kohaku Python signer
416
- * Note: Python signer is slow for Falcon (~several seconds)
417
- */
418
- async function generatePQKeypair(algorithm: PQAlgorithm): Promise<{
419
- publicKey: Uint8Array;
420
- privateKey: Uint8Array;
421
- }> {
422
- // Option 1: Use Kohaku Python signer (via child process)
423
- // Option 2: Use WASM implementation (faster, browser-compatible)
424
- // Option 3: Use liboqs-js (comprehensive)
425
-
426
- // Placeholder - integrate with actual Kohaku Python signer
427
- throw new Error('Integrate Kohaku Python signer or WASM alternative');
428
- }
429
-
430
- /**
431
- * Deploy PK contract for MLDSA public key (~20 KB)
432
- * Required because MLDSA public keys are too large for direct storage
433
- */
434
- async function deployPKContract(
435
- publicKey: Uint8Array,
436
- signer: ethers.Signer
437
- ): Promise<string> {
438
- const pkFactory = new ethers.ContractFactory(
439
- PK_CONTRACT_ABI,
440
- PK_CONTRACT_BYTECODE,
441
- signer
442
- );
443
-
444
- const pkContract = await pkFactory.deploy(ethers.hexlify(publicKey));
445
- await pkContract.waitForDeployment();
446
- const pkAddress = await pkContract.getAddress();
447
-
448
- console.log(` Deployed PK contract: ${pkAddress}`);
449
- return pkAddress;
450
- }
451
-
452
- /**
453
- * Sign UserOperation with hybrid signatures (classical + PQ)
454
- */
455
- export async function signUserOpHybrid(
456
- userOp: any, // ERC-4337 UserOperation
457
- classicalWallet: ethers.Wallet,
458
- pqSigner: any, // Kohaku PQ signer
459
- config: PQAccountConfig
460
- ): Promise<string> {
461
- const userOpHash = ethers.keccak256(ethers.AbiCoder.defaultAbiCoder().encode(
462
- ['address', 'uint256', 'bytes32', 'bytes32', 'uint256', 'uint256', 'uint256', 'uint256', 'uint256', 'bytes32'],
463
- [
464
- userOp.sender,
465
- userOp.nonce,
466
- ethers.keccak256(userOp.initCode),
467
- ethers.keccak256(userOp.callData),
468
- userOp.callGasLimit,
469
- userOp.verificationGasLimit,
470
- userOp.preVerificationGas,
471
- userOp.maxFeePerGas,
472
- userOp.maxPriorityFeePerGas,
473
- ethers.keccak256(userOp.paymasterAndData),
474
- ]
475
- ));
476
-
477
- // Classical signature (secp256k1 or P-256)
478
- const classicalSig = await classicalWallet.signMessage(
479
- ethers.getBytes(userOpHash)
480
- );
481
-
482
- // Post-quantum signature (MLDSA, FALCON, etc.)
483
- const pqSig = await pqSigner.sign(ethers.getBytes(userOpHash));
484
-
485
- // Pack hybrid signature
486
- // Format: [flags (1 byte)][classical sig (65 bytes)][pq sig (variable)]
487
- const flags = 0x03; // Both signatures present
488
- const packedSig = ethers.concat([
489
- new Uint8Array([flags]),
490
- ethers.getBytes(classicalSig),
491
- pqSig,
492
- ]);
493
-
494
- return ethers.hexlify(packedSig);
495
- }
496
- ```
497
-
498
- **Example: Deploying w3pk quantum account:**
499
- ```typescript
500
- // Example usage in w3pk SDK
501
- const w3pk = createWeb3Passkey({
502
- quantumSafe: true,
503
- pqAlgorithm: 'mldsaeth', // Ethereum-optimized Dilithium
504
- });
505
-
506
- await w3pk.register({ username: 'alice' });
507
-
508
- // Deploy quantum-safe account on Sepolia
509
- const pqAccountAddress = await w3pk.deployQuantumAccount({
510
- algorithm: 'mldsaeth',
511
- classicalAlgorithm: 'secp256k1',
512
- chainId: 11155111, // Sepolia
513
- hybridMode: true,
514
- });
515
-
516
- // Sign transaction with hybrid signatures
517
- const tx = await w3pk.sendTransaction({
518
- to: '0xRecipient...',
519
- value: ethers.parseEther('1'),
520
- chainId: 11155111,
521
- quantumSafe: true, // Use hybrid signatures
522
- });
523
- ```
524
-
525
- **Gas Costs (Estimated from Kohaku Tests):**
526
-
527
- | Operation | Classical (ECDSA) | Hybrid (ECDSA + MLDSA) | Overhead |
528
- |-----------|-------------------|------------------------|----------|
529
- | Account deployment | ~250,000 gas | ~3,500,000 gas | **14x** |
530
- | Transaction verification | ~21,000 gas | ~800,000 gas | **38x** |
531
- | PK contract deployment | N/A | ~5,000,000 gas | One-time cost |
532
-
533
- **Note:** High gas costs are acceptable because:
534
- 1. Users deploy account only once
535
- 2. PK contract deployed only once per user
536
- 3. Transaction verification happens off-chain via bundlers (ERC-4337)
537
- 4. L2 deployment (Arbitrum Sepolia) reduces costs by ~10x
538
-
539
- **Timeline:** 6 months (integration + testing + mainnet deployment)
540
- **Breaking Changes:** None (opt-in via `quantumSafe: true` flag)
541
-
542
- #### 2.2 Design Smart Contract Account Abstraction ⭐ HIGH PRIORITY
543
- **Rationale:** Enable gradual migration without breaking existing wallets
544
-
545
- **Architecture Note:** This design follows the validation frame concept from [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141), but implemented using current [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) until native AA is available.
546
-
547
- **Smart Contract Architecture:**
548
- ```solidity
549
- // contracts/W3PKQuantumAccount.sol
550
- // SPDX-License-Identifier: GPL-3.0
551
- pragma solidity ^0.8.20;
552
-
553
- import "@kohaku-eth/pq-account/contracts/verifiers/DilithiumVerifier.sol";
554
- import "@account-abstraction/contracts/core/BaseAccount.sol";
555
-
556
- /**
557
- * W3PK Quantum-Safe Smart Contract Account
558
- * Supports hybrid classical + post-quantum signature verification
559
- *
560
- * FUTURE: This will be replaced by EIP-8141 validation frames when available.
561
- * Validation frames enable protocol-layer STARK aggregation, reducing gas costs
562
- * from ~800k to near-zero.
563
- */
564
- contract W3PKQuantumAccount is BaseAccount {
565
- // Legacy secp256k1 owner (backward compatibility)
566
- address public legacyOwner;
567
-
568
- // Post-quantum Dilithium public key (2592 bytes for ML-DSA-87)
569
- bytes public dilithiumPubKey;
570
-
571
- // Migration state
572
- bool public quantumMigrationEnabled;
573
- bool public hybridModeRequired; // Both signatures required
574
-
575
- event QuantumMigrationStarted(address indexed account, bytes pqPubKey);
576
- event HybridModeEnabled(address indexed account);
577
- event SignatureVerified(bool classical, bool postQuantum);
578
-
579
- constructor(
580
- address _legacyOwner,
581
- bytes memory _dilithiumPubKey
582
- ) {
583
- legacyOwner = _legacyOwner;
584
- dilithiumPubKey = _dilithiumPubKey;
585
- quantumMigrationEnabled = false;
586
- hybridModeRequired = false;
587
- }
588
-
589
- /**
590
- * Enable quantum migration (add PQ signature requirement)
591
- */
592
- function enableQuantumMigration(bytes memory _pqPubKey) external {
593
- require(msg.sender == legacyOwner, "Only owner");
594
- dilithiumPubKey = _pqPubKey;
595
- quantumMigrationEnabled = true;
596
- emit QuantumMigrationStarted(address(this), _pqPubKey);
597
- }
598
-
599
- /**
600
- * Enable hybrid mode (require both signatures)
601
- */
602
- function enableHybridMode() external {
603
- require(msg.sender == legacyOwner, "Only owner");
604
- require(quantumMigrationEnabled, "Quantum migration not enabled");
605
- hybridModeRequired = true;
606
- emit HybridModeEnabled(address(this));
607
- }
608
-
609
- /**
610
- * Validate signature (hybrid or single)
611
- */
612
- function _validateSignature(
613
- UserOperation calldata userOp,
614
- bytes32 userOpHash
615
- ) internal virtual override returns (uint256 validationData) {
616
- bytes memory signature = userOp.signature;
617
-
618
- // Parse signature format
619
- (bool hasClassical, bool hasPostQuantum, bytes memory classicalSig, bytes memory pqSig) =
620
- parseHybridSignature(signature);
621
-
622
- bool classicalValid = false;
623
- bool pqValid = false;
624
-
625
- // Verify classical secp256k1 signature
626
- if (hasClassical) {
627
- bytes32 hash = userOpHash.toEthSignedMessageHash();
628
- address recovered = hash.recover(classicalSig);
629
- classicalValid = (recovered == legacyOwner);
630
- }
631
-
632
- // Verify post-quantum Dilithium signature
633
- if (hasPostQuantum) {
634
- pqValid = DilithiumVerifier.verify(
635
- dilithiumPubKey,
636
- abi.encodePacked(userOpHash),
637
- pqSig
638
- );
639
- }
640
-
641
- emit SignatureVerified(classicalValid, pqValid);
642
-
643
- // Validation logic based on mode
644
- if (hybridModeRequired) {
645
- require(classicalValid && pqValid, "Both signatures required");
646
- } else if (quantumMigrationEnabled) {
647
- require(classicalValid || pqValid, "At least one signature required");
648
- } else {
649
- require(classicalValid, "Classical signature required");
650
- }
651
-
652
- return 0; // Valid
653
- }
654
-
655
- /**
656
- * Parse hybrid signature format
657
- * Format: [flags (1 byte)][classical sig (65 bytes)][pq sig (variable)]
658
- */
659
- function parseHybridSignature(bytes memory signature)
660
- internal pure
661
- returns (
662
- bool hasClassical,
663
- bool hasPostQuantum,
664
- bytes memory classicalSig,
665
- bytes memory pqSig
666
- )
667
- {
668
- require(signature.length > 0, "Empty signature");
669
-
670
- uint8 flags = uint8(signature[0]);
671
- hasClassical = (flags & 0x01) != 0;
672
- hasPostQuantum = (flags & 0x02) != 0;
673
-
674
- uint256 offset = 1;
675
-
676
- if (hasClassical) {
677
- classicalSig = new bytes(65);
678
- for (uint i = 0; i < 65; i++) {
679
- classicalSig[i] = signature[offset + i];
680
- }
681
- offset += 65;
682
- }
683
-
684
- if (hasPostQuantum) {
685
- uint256 pqLength = signature.length - offset;
686
- pqSig = new bytes(pqLength);
687
- for (uint i = 0; i < pqLength; i++) {
688
- pqSig[i] = signature[offset + i];
689
- }
690
- }
691
- }
692
- }
693
- ```
694
-
695
- **Timeline:** 8 months (including testing and audit)
696
- **Breaking Changes:** None (opt-in smart contract deployment)
697
-
698
- #### 2.3 Evaluate Post-Quantum Signature Algorithms ⭐ MEDIUM PRIORITY
699
-
700
- **Ethereum Quantum Resistance Roadmap Recommendations:**
701
-
702
- **Hash Function Selection (Critical for Hash-Based Signatures):**
703
- The [Ethereum quantum resistance roadmap](https://x.com/VitalikButerin/status/2027075026378543132) notes this may be "Ethereum's last hash function", with three candidates:
704
- 1. **Poseidon2 + extra rounds** - Potential non-arithmetic layers (eg. Monolith)
705
- 2. **Poseidon1** - Older version, not vulnerable to recent Poseidon2 attacks, but 2x slower
706
- 3. **BLAKE3 or similar** - Most efficient conventional hash
707
-
708
- **Signature Algorithm Options:**
709
-
710
- **Hash-Based Signatures (Winternitz variants):**
711
- - ✅ **~200,000 gas** for verification (Vitalik's estimate)
712
- - ✅ Well-understood security
713
- - ⚠️ Large signature sizes (~1-3 KB per signature)
714
- - ⚠️ Stateful (requires careful nonce management)
715
-
716
- **Lattice-Based Signatures (ML-DSA / Dilithium):**
717
- - ✅ NIST-standardized ([FIPS 204](https://csrc.nist.gov/pubs/fips/204/final))
718
- - ✅ Stateless (no nonce management issues)
719
- - ⚠️ **Extremely high gas costs today** (~800,000 gas)
720
- - ✅ **Future optimization:** Vectorized math precompiles could reduce costs significantly
721
- - ✅ The [Ethereum quantum resistance roadmap](https://x.com/VitalikButerin/status/2027075026378543132) mentions: "vectorized math precompiles for (+, *, %, dot product, NTT/butterfly)"
722
-
723
- **w3pk Strategy:**
724
- 1. **Phase 2 (interim):** Use [Kohaku](https://github.com/ethereum/kohaku)'s Dilithium implementation ([ERC-4337](https://eips.ethereum.org/EIPS/eip-4337))
725
- 2. **Phase 4 (long-term):** Adopt Ethereum's chosen hash function + Winternitz or optimized lattice signatures via [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141) validation frames
726
-
727
- **Candidate Libraries:**
728
- ```typescript
729
- // Option 1: Kohaku (Ethereum Foundation - RECOMMENDED for interim)
730
- import { DilithiumSigner, FalconSigner } from '@kohaku-eth/pq-account';
731
-
732
- // Option 2: Open Quantum Safe (comprehensive, C-based)
733
- import { pqcrypto } from 'liboqs-js';
734
-
735
- // Option 3: Future native support (EIP-8141 validation frames)
736
- // Ethereum protocol will provide vectorized math precompiles
737
- ```
738
-
739
- **Evaluation Matrix:**
740
-
741
- | Algorithm | Gas Cost (current) | Gas Cost (with EIP-8141) | Security | Recommendation |
742
- |-----------|-------------------|-------------------------|----------|----------------|
743
- | **Hash-based (Winternitz)** | N/A | ~200,000 gas | ✅ High | **LONG-TERM** |
744
- | **Dilithium (Kohaku)** | ~800,000 gas | ~10,000 gas (optimized) | ✅ NIST Level 5 | **INTERIM** |
745
- | **Falcon (Kohaku)** | ~250,000 gas | ~5,000 gas (optimized) | ✅ NIST Level 5 | Backup |
746
-
747
- **Timeline:** 3 months
748
- **Cost:** Free (open source)
749
-
750
- #### 2.4 Create Migration Utilities ⭐ MEDIUM PRIORITY
751
- **Rationale:** Enable users to upgrade existing wallets to quantum-safe accounts
752
-
753
- **Implementation:**
754
- ```typescript
755
- // src/pq/migration.ts
756
- export interface MigrationStatus {
757
- phase: 'classical' | 'hybrid-testing' | 'hybrid-active' | 'quantum-only';
758
- classicalKeyActive: boolean;
759
- pqKeyActive: boolean;
760
- accountType: 'EOA' | 'smart-contract';
761
- migrationProgress: number; // 0-100
762
- }
763
-
764
- /**
765
- * Migrate existing w3pk wallet to quantum-safe account
766
- */
767
- export async function migrateToQuantumAccount(
768
- w3pk: Web3Passkey,
769
- options: {
770
- algorithm: 'dilithium' | 'falcon';
771
- testMode?: boolean; // Enable hybrid testing first
772
- }
773
- ): Promise<MigrationResult> {
774
- // 1. Generate PQ keypair
775
- const pqSigner = options.algorithm === 'dilithium'
776
- ? new DilithiumSigner()
777
- : new FalconSigner();
778
- const { publicKey, privateKey } = await pqSigner.generateKeyPair();
779
-
780
- // 2. Deploy smart contract account
781
- const classicalAddress = await w3pk.getAddress('STANDARD');
782
- const pqAccount = await createPQAccount({
783
- algorithm: options.algorithm,
784
- hybridMode: !options.testMode, // Start in test mode
785
- accountAddress: classicalAddress,
786
- });
787
-
788
- // 3. Transfer assets from EOA to smart contract account
789
- // (User must manually transfer funds)
790
-
791
- // 4. Store PQ private key (encrypted with WebAuthn)
792
- await w3pk.storage.saveEncrypted('pq-private-key', privateKey);
793
-
794
- // 5. Update configuration
795
- await w3pk.updateConfig({
796
- signatures: {
797
- ethereum: 'hybrid-pq',
798
- postQuantum: options.algorithm === 'dilithium' ? 'ml-dsa-87' : 'falcon-1024',
799
- hybridMode: !options.testMode,
800
- },
801
- });
802
-
803
- return {
804
- success: true,
805
- newAccountAddress: pqAccount.address,
806
- pqAlgorithm: options.algorithm,
807
- phase: options.testMode ? 'hybrid-testing' : 'hybrid-active',
808
- instructions: [
809
- 'Transfer assets from your existing wallet to new quantum-safe account',
810
- 'Test transactions in hybrid mode',
811
- 'Enable quantum-only mode when ready',
812
- ],
813
- };
814
- }
815
-
816
- /**
817
- * Check migration readiness
818
- */
819
- export async function checkMigrationReadiness(): Promise<ReadinessReport> {
820
- const checks = {
821
- browserSupport: await checkWebAssemblySupport(),
822
- librariesLoaded: await checkKohakuLibraries(),
823
- accountAbstractionSupport: await checkEIP4337Support(),
824
- userFundsAvailable: await checkGasBalance(),
825
- };
826
-
827
- const allPassed = Object.values(checks).every(Boolean);
828
-
829
- return {
830
- ready: allPassed,
831
- checks,
832
- estimatedGasCost: '0.05 ETH', // Approximate deployment cost
833
- recommendedAction: allPassed
834
- ? 'Proceed with migration'
835
- : 'Resolve issues before migrating',
836
- };
837
- }
838
- ```
839
-
840
- **Timeline:** 4 months
841
- **Breaking Changes:** None (opt-in migration)
842
-
843
- ### Phase 3: Transition (18-36 months) - **DEPLOY**
844
-
845
- **Goal:** Deploy hybrid signature system and enable user migration
846
-
847
- **Important:** This phase assumes [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) as interim solution. Timeline may shift based on [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141) native AA deployment.
848
-
849
- #### 3.1 Deploy Quantum-Safe Smart Contract Accounts ⭐ HIGH PRIORITY
850
- - [ ] Audit smart contracts (W3PKQuantumAccount)
851
- - [ ] Deploy to testnets (Sepolia, Holesky)
852
- - [ ] Run bug bounty program
853
- - [ ] Deploy to mainnets (Ethereum, Polygon, Arbitrum)
854
- - [ ] Create deployment scripts and documentation
855
- - [ ] **Monitor EIP-8141 progress** - Prepare migration plan from ERC-4337 to validation frames
856
-
857
- **Timeline:** 12 months (may extend if waiting for EIP-8141)
858
- **Cost:** ~$50,000-100,000 (audits + bug bounty)
859
-
860
- #### 3.2 Launch Hybrid Signature Mode ⭐ HIGH PRIORITY
861
- - [ ] Enable hybrid signatures (classical + PQ) by default for new users
862
- - [ ] Add UI for migration in demo app
863
- - [ ] Create educational content explaining quantum threats
864
- - [ ] Monitor gas costs and optimize verifier contracts
865
-
866
- **Timeline:** 6 months
867
- **Breaking Changes:** None (opt-in for existing users)
868
-
869
- #### 3.3 Update Documentation & Education ⭐ MEDIUM PRIORITY
870
- - [ ] Update API documentation for PQ methods
871
- - [ ] Create migration guides
872
- - [ ] Publish blog posts on quantum readiness
873
- - [ ] Record video tutorials
874
- - [ ] Update integration examples
44
+ ## Ethereum's post-quantum roadmap (summary)
875
45
 
876
- **Timeline:** 3 months
46
+ Full detail: [pq.ethereum.org](https://pq.ethereum.org/) and the [lean Ethereum announcement](https://blog.ethereum.org/2025/07/31/lean-ethereum). This section extracts only what shapes w3pk's decisions.
877
47
 
878
- #### 3.4 Community & Ecosystem Coordination ⭐ MEDIUM PRIORITY
879
- - [ ] Coordinate with Ethereum Foundation [Kohaku](https://github.com/ethereum/kohaku) team
880
- - [ ] **Track [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141) development** - Participate in discussion and testing
881
- - [ ] **Monitor Ethereum's hash function selection** - Prepare to adopt chosen hash ([Poseidon2](https://eprint.iacr.org/2023/323)/[Poseidon1](https://eprint.iacr.org/2019/458)/[BLAKE3](https://github.com/BLAKE3-team/BLAKE3))
882
- - [ ] Participate in [ERC-5564](https://eips.ethereum.org/EIPS/eip-5564) quantum standardization
883
- - [ ] Engage with wallet providers (MetaMask, Rainbow)
884
- - [ ] Present at conferences (Devcon, ETHGlobal)
48
+ Ethereum depends on four families of public-key cryptography broken by Shor's algorithm: ECDSA (secp256k1) for account signatures, BLS signatures for validator attestations, KZG polynomial commitments for blob data availability, and pairing-based SNARKs at the application layer. The EF's [Post-Quantum team](https://pq.ethereum.org/) frames the realistic failure mode as **stolen funds and impersonation**, not rewriting finalized history — past transactions stay valid regardless of what happens later.
885
49
 
886
- **Timeline:** Ongoing
50
+ The response is the **lean Ethereum** programme (Justin Drake, July 2025), which makes the hash function the single cryptographic primitive across consensus, data, and execution:
887
51
 
888
- ### Phase 4: Migration (36+ months) - **COMPLETE**
52
+ | Layer | Current | Post-quantum replacement | Status |
53
+ | --- | --- | --- | --- |
54
+ | Consensus (validator signatures) | BLS12-381 | **leanXMSS** — hash-based, Merkle-tree signatures | Research/spec phase |
55
+ | Aggregation | Native algebraic (BLS) | **leanVM** — Cairo-inspired zkVM producing one SNARK per slot | Reference implementation exists |
56
+ | Execution (account signatures) | ECDSA (secp256k1) | **EIP-8141 frame transactions** — account-defined validation logic | Specification phase |
57
+ | Data availability | KZG commitments (pairing-based) | STARK-style or lattice-based commitments | Not yet efficient at scale |
889
58
 
890
- **Goal:** Complete transition to quantum-safe infrastructure
59
+ **Execution layer — EIP-8141** is the piece that matters most for w3pk. It introduces a new transaction type that decomposes validation into **frames**, letting an account define its own signature-checking logic via an `APPROVE` opcode. This is what gives wallets (including w3pk) the ability to adopt a PQ scheme on their own schedule, without a network-wide flag day. It supersedes most of what ERC-4337 does today with off-chain bundlers.
891
60
 
892
- **Critical Dependency:** This phase assumes [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141) is deployed. If not, continue with [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) solution.
61
+ Whole-scheme verifier drafts already exist: [EIP-8051](https://eips.ethereum.org/EIPS/eip-8051) (`VERIFY_MLDSA`, FIPS 204-compliant, plus a cheaper `VERIFY_MLDSA_ETH` variant), [EIP-8355](https://eips.ethereum.org/EIPS/eip-8355) (extends ML-DSA to security levels III/V), and an older [Falcon](https://eips.ethereum.org/EIPS/eip-7619) proposal. The execution-layer team currently favors a **vector math precompile** (e.g. [EIP-7885](https://eips.ethereum.org/EIPS/eip-7885)) over locking in one whole-scheme verifier, to avoid betting the protocol on an algorithm that later falls to cryptanalysis.
893
62
 
894
- #### 4.1 Migrate to EIP-8141 Validation Frames ⭐ CRITICAL
895
- - [ ] **Adopt native AA** once [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141) is deployed
896
- - [ ] **Integrate with protocol-layer proof aggregation** - Leverage STARK-based validation frame verification
897
- - [ ] **Reduce gas costs to near-zero** - Replace individual signature verifications with aggregated STARKs
898
- - [ ] **Adopt Ethereum's chosen hash function** - Implement Winternitz signatures with selected hash ([Poseidon2](https://eprint.iacr.org/2023/323)/[Poseidon1](https://eprint.iacr.org/2019/458)/[BLAKE3](https://github.com/BLAKE3-team/BLAKE3))
899
- - [ ] **Test vectorized math precompiles** - Optimize lattice-based signature verification if precompiles are available
900
- - [ ] **Deprecate [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) bundler dependency** - Transition to protocol-native validation
63
+ ### Fork milestones
901
64
 
902
- **Key Insight from the [Ethereum quantum resistance roadmap](https://x.com/VitalikButerin/status/2027075026378543132):**
903
- > "Validation frames cannot access the outside world, they can only look at their calldata and return a value... it's possible to replace any validation frame with a STARK that verifies it (potentially a single STARK for all validation frames in a block)."
65
+ These are planning milestones, not commitments — names and ordering may change.
904
66
 
905
- This means transaction validation happens at **mempool layer** with recursive proofs, making w3pk transactions quantum-safe at near-zero gas overhead.
67
+ | Fork | Milestone | Layer |
68
+ | --- | --- | --- |
69
+ | I* | PQ key registry | Consensus |
70
+ | J* | PQ signature precompiles | Execution |
71
+ | L* | PQ attestations, real-time CL proofs, leanVM | Consensus + Data |
72
+ | M* | PQ signature aggregation, PQ blobs | Execution + Data |
73
+ | Longer term | Full PQ consensus, PQ transactions, PQ sampling | All layers |
906
74
 
907
- **Timeline:** 12 months (after [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141) deployment)
908
- **Breaking Changes:** Backend migration, transparent to users
75
+ The nearest real fork is **Hegotá** (targeted 2027), which is not itself a PQ fork but the gate that decides whether later PQ forks land on schedule. Its two must-ship EIPs are [EIP-7805](https://eips.ethereum.org/EIPS/eip-7805) (FOCIL) and **EIP-8141**. If either hits friction, the whole downstream PQ schedule slips — this is the single most important thing for w3pk to watch.
909
76
 
910
- #### 4.2 Sunset Legacy Secp256k1-Only Accounts ⭐ LOW PRIORITY
911
- - [ ] Set deprecation timeline (12 months notice)
912
- - [ ] Notify users of legacy accounts
913
- - [ ] Offer free migration assistance
914
- - [ ] Maintain backward compatibility layer
915
- - [ ] Archive legacy code
77
+ ### Threat model and residual exposure (EF's own ordering)
916
78
 
917
- **Timeline:** 12 months
918
- **Breaking Changes:** Yes (requires user action)
79
+ 1. User accounts — largest pool of value, public keys exposed after first transaction
80
+ 2. High-value operational keys — exchanges, bridges
81
+ 3. Governance multisigs
82
+ 4. Validator keys — affect consensus participation, not direct asset custody
919
83
 
920
- #### 4.3 Default to Post-Quantum for All New Wallets ⭐ HIGH PRIORITY
921
- - [ ] Update `register()` to create PQ accounts by default
922
- - [ ] Update `createWeb3Passkey()` config defaults
923
- - [ ] Remove `quantumReady` feature flags
924
- - [ ] Simplify migration code paths
84
+ "Harvest now, decrypt later" is a **confidentiality** problem, not an ownership one for signatures: recording transactions today doesn't enable retroactive theft, since blockchains are integrity systems built on signatures, not encryption. The forward-looking risk is that exposed public keys become derivable once a CRQC exists — which is exactly the harvest risk `mlkemEncrypt`/`mlkemDecrypt` already close for **data**, since that scheme provides genuine forward confidentiality today.
925
85
 
926
- **Timeline:** 6 months
927
- **Breaking Changes:** None (seamless for new users)
928
-
929
- #### 4.4 Monitor Quantum Computing Progress ⭐ ONGOING
930
- - [ ] Subscribe to [NIST PQC](https://csrc.nist.gov/projects/post-quantum-cryptography) mailing list
931
- - [ ] Track quantum computing announcements critically
932
- - [ ] Update threat models annually
933
- - [ ] **Participate in Ethereum quantum working groups** - Stay aligned with protocol development
934
- - [ ] **Monitor [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141) deployment timeline** - Coordinate w3pk Phase 4 accordingly
935
-
936
- **Timeline:** Continuous
937
-
938
- ---
939
-
940
- ## Technical Implementation Details
941
-
942
- ### Signature Size & Gas Cost Comparison
943
-
944
- | Scheme | Signature Size | Public Key Size | Security Level | Gas Cost (ERC-4337) | Gas Cost (EIP-8141) |
945
- |--------|----------------|-----------------|----------------|---------------------|---------------------|
946
- | **Classical** |
947
- | secp256k1 | 65 bytes | 33 bytes | Classical only | ~21,000 gas | ~21,000 gas |
948
- | P-256 | 64 bytes | 64 bytes | Classical only | ~40,000 gas | ~40,000 gas |
949
- | **Post-Quantum** |
950
- | **Winternitz (hash-based)** | ~1,500 bytes | ~1,000 bytes | Quantum-safe | N/A | **~200,000 gas** ⭐ |
951
- | ML-DSA-65 (Dilithium3) | 3,309 bytes | 1,952 bytes | NIST Level 3 | ~500,000 gas | **~10,000 gas** (w/ precompiles) |
952
- | ML-DSA-87 (Dilithium5) | 4,627 bytes | 2,592 bytes | NIST Level 5 | ~800,000 gas | **~15,000 gas** (w/ precompiles) |
953
- | Falcon-512 | 666 bytes | 897 bytes | NIST Level 1 | ~150,000 gas | **~5,000 gas** (w/ precompiles) |
954
- | Falcon-1024 | 1,280 bytes | 1,793 bytes | NIST Level 5 | ~250,000 gas | **~8,000 gas** (w/ precompiles) |
955
- | **Hybrid (Classical + PQ)** |
956
- | secp256k1 + ML-DSA-87 | 4,692 bytes | 2,625 bytes | Quantum-safe | ~850,000 gas | **Near-zero** (STARK aggregation) |
957
- | secp256k1 + Falcon-1024 | 1,345 bytes | 1,826 bytes | Quantum-safe | ~300,000 gas | **Near-zero** (STARK aggregation) |
958
-
959
- **Key Insights:**
960
- 1. **ERC-4337 (Phase 2-3):** Off-chain bundler verification reduces costs, but still ~300k-850k gas per transaction
961
- 2. **EIP-8141 (Phase 4):** Validation frames + STARK aggregation reduces costs to **near-zero** via mempool-layer proof composition
962
- 3. **Winternitz signatures:** Vitalik's recommended approach (~200k gas) when EIP-8141 is deployed
963
- 4. **Vectorized math precompiles:** Enable efficient lattice-based signatures (Dilithium/Falcon) with 10-100x gas reduction
964
-
965
- ### Hybrid Encryption for Backups
966
-
967
- **Current Implementation:**
968
- ```typescript
969
- // AES-256-GCM only (quantum-resistant symmetric)
970
- const backup = {
971
- encrypted: await encryptWithAES(mnemonic, password),
972
- iv: randomIV,
973
- salt: randomSalt,
974
- };
975
- ```
976
-
977
- **Hybrid Implementation (Future):**
978
- ```typescript
979
- import { Kyber1024 } from '@kohaku-eth/ml-kem';
980
-
981
- // Hybrid: AES-256-GCM + ML-KEM-1024
982
- const kyberKEM = new Kyber1024();
983
- const { publicKey, privateKey } = await kyberKEM.generateKeyPair();
984
-
985
- // Encapsulate AES key with Kyber
986
- const { ciphertext, sharedSecret } = await kyberKEM.encapsulate(publicKey);
987
-
988
- // Encrypt mnemonic with AES (using KEM-derived key)
989
- const aesKey = await deriveKeyFromKEM(sharedSecret);
990
- const backup = {
991
- version: 3,
992
- kemCiphertext: ciphertext, // Kyber encapsulation
993
- kemPublicKey: publicKey, // For decapsulation
994
- aesEncrypted: await encryptWithAES(mnemonic, aesKey),
995
- algorithm: 'hybrid-aes-kyber1024',
996
- };
997
-
998
- // Decapsulation
999
- const recovered = await kyberKEM.decapsulate(privateKey, backup.kemCiphertext);
1000
- const aesKey = await deriveKeyFromKEM(recovered);
1001
- const mnemonic = await decryptWithAES(backup.aesEncrypted, aesKey);
1002
- ```
1003
-
1004
- **Benefits:**
1005
- - ✅ Protects against harvest-now-decrypt-later attacks
1006
- - ✅ Backward compatible (version field)
1007
- - ✅ Only ~1.5 KB overhead
1008
- - ✅ No gas costs (off-chain backups)
1009
-
1010
- **Timeline:** Phase 2 (12-18 months, pending stable ML-KEM libraries)
1011
-
1012
- ### Quantum-Safe Stealth Addresses
1013
-
1014
- **Current ERC-5564 (ECDH-based):**
1015
- ```typescript
1016
- // Vulnerable to quantum attacks
1017
- const sharedSecret = computeECDH(ephemeralPrivKey, viewingPubKey);
1018
- const stealthAddress = deriveAddress(sharedSecret);
1019
- ```
1020
-
1021
- **Quantum-Safe ERC-5564 (ML-KEM-based):**
1022
- ```typescript
1023
- import { Kyber1024 } from '@kohaku-eth/ml-kem';
1024
-
1025
- // Generate ephemeral KEM keypair
1026
- const kem = new Kyber1024();
1027
- const { publicKey: ephemeralPubKey, privateKey: ephemeralPrivKey } =
1028
- await kem.generateKeyPair();
1029
-
1030
- // Encapsulate to recipient's viewing key
1031
- const { ciphertext: kemCiphertext, sharedSecret } =
1032
- await kem.encapsulate(recipientViewingPubKey);
1033
-
1034
- // Derive stealth address from shared secret
1035
- const stealthAddress = deriveAddress(sharedSecret);
1036
-
1037
- // Announcement includes KEM ciphertext instead of ephemeral pubkey
1038
- const announcement = {
1039
- stealthAddress,
1040
- kemCiphertext, // ~1,568 bytes (vs 33 bytes for ECDH)
1041
- viewTag: sharedSecret[0],
1042
- protocol: 'erc5564-pq',
1043
- };
1044
- ```
1045
-
1046
- **Challenges:**
1047
- - ⚠️ Large announcement size (~1,568 bytes vs 33 bytes)
1048
- - ⚠️ Requires ERC-5564 community consensus
1049
- - ⚠️ Not backward compatible
1050
-
1051
- **Timeline:** Phase 4 (36+ months, wait for standards)
1052
-
1053
- ---
1054
-
1055
- ## Quantum Computing Timeline
1056
-
1057
- ### Expert Consensus
1058
-
1059
- Based on research from **a16z crypto**, **NIST**, and **Ethereum Foundation**:
1060
-
1061
- - **Conservative estimate:** 10-15 years to CRQC
1062
- - **Optimistic estimate:** 5-10 years to CRQC
1063
- - **Current risk level:** **Low** (but rising)
1064
-
1065
- ### What is a CRQC?
1066
-
1067
- A **Cryptographically Relevant Quantum Computer** must:
1068
- - Execute Shor's algorithm to break 256-bit ECDSA in <24 hours
1069
- - Maintain ~10,000+ logical qubits with error correction
1070
- - Achieve gate fidelity >99.9%
1071
-
1072
- **Current state (2026):**
1073
- - IBM: ~1,000 physical qubits (noisy, no error correction)
1074
- - Google: ~100 logical qubits (limited coherence time)
1075
- - D-Wave: Quantum annealing (not useful for Shor's algorithm)
1076
-
1077
- ### Risk Prioritization
1078
-
1079
- ```
1080
- Priority Ranking (Today):
1081
- 1. ⚠️ CVE vulnerabilities & implementation bugs - CRITICAL
1082
- 2. ⚠️ Phishing & social engineering attacks - HIGH
1083
- 3. ⚠️ Side-channel attacks (timing, power) - HIGH
1084
- 4. 📊 Monitor quantum computing progress - MEDIUM
1085
- 5. 📋 Plan quantum migration architecture - MEDIUM
1086
- 6. 🔮 Deploy post-quantum cryptography - LOW (future)
1087
- ```
86
+ On timing: the EF is more conservative than headline quantum-computing news. Most engineering roadmaps place cryptographic relevance in the **early-to-mid 2030s**. [Google Quantum AI's March 2026 analysis](https://research.google/blog/safeguarding-cryptocurrency-by-disclosing-quantum-vulnerabilities-responsibly/) lowered the estimate for breaking 256-bit elliptic curve cryptography to roughly 1,200 logical qubits, and NIST anticipates deprecating ECDSA by 2030 and disallowing it by 2035.
1088
87
 
1089
88
  ---
1090
89
 
1091
- ## Integration with Existing Features
1092
-
1093
- ### Account Abstraction (EIP-7702, EIP-4337, EIP-8141)
1094
-
1095
- **Advantage:** w3pk's existing [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) support provides natural quantum migration path
1096
-
1097
- **Migration Path:**
1098
- 1. **Phase 1-2:** [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) (current) - Delegate EOA to smart contract
1099
- 2. **Phase 2-3:** [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) - Bundler-based account abstraction with PQ signatures
1100
- 3. **Phase 4:** [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141) - Native AA with validation frames + STARK aggregation
1101
-
1102
- ```typescript
1103
- // Existing EIP-7702 authorization (classical)
1104
- const auth = await w3pk.signAuthorization({
1105
- contractAddress: '0xSmartContract...',
1106
- chainId: 1,
1107
- nonce: 0n,
1108
- });
1109
-
1110
- // Phase 2-3: Hybrid authorization via ERC-4337 (classical + PQ)
1111
- const hybridAuth = await w3pk.signAuthorizationHybrid({
1112
- contractAddress: '0xQuantumSafeContract...',
1113
- chainId: 1,
1114
- nonce: 0n,
1115
- algorithm: 'ml-dsa-87',
1116
- });
1117
-
1118
- // Phase 4: Native AA with validation frames (EIP-8141)
1119
- const validationFrameAuth = await w3pk.signAuthorizationNativeAA({
1120
- contractAddress: '0xQuantumSafeContract...',
1121
- chainId: 1,
1122
- nonce: 0n,
1123
- algorithm: 'winternitz', // Or 'ml-dsa-87' with vectorized precompiles
1124
- useValidationFrames: true, // Protocol-layer STARK aggregation
1125
- });
1126
- ```
1127
-
1128
- **Phase 2-3: ERC-4337 Smart Contract Verification:**
1129
- ```solidity
1130
- function verifyAuthorization(Authorization memory auth) public view {
1131
- // Verify classical signature
1132
- bool classicalValid = ecrecover(auth.hash, auth.signature) == auth.owner;
1133
-
1134
- // Verify PQ signature
1135
- bool pqValid = DilithiumVerifier.verify(
1136
- auth.pqPublicKey,
1137
- auth.hash,
1138
- auth.pqSignature
1139
- );
1140
-
1141
- require(classicalValid && pqValid, "Hybrid verification failed");
1142
- }
1143
- ```
1144
-
1145
- **Phase 4: EIP-8141 Validation Frame (Pseudocode):**
1146
- ```solidity
1147
- // Validation frame: isolated, cannot access external state
1148
- function validateUserOp(UserOperation calldata userOp) internal pure returns (bool) {
1149
- // Parse hybrid signature from calldata
1150
- (bytes memory classicalSig, bytes memory pqSig) = parseSignature(userOp.signature);
90
+ ## w3pk's current cryptographic architecture
1151
91
 
1152
- // Verify both signatures
1153
- bool classicalValid = verifyECDSA(userOp.hash, classicalSig);
1154
- bool pqValid = verifyWinternitz(userOp.hash, pqSig); // Or lattice-based
92
+ ### Asymmetric cryptography (quantum-vulnerable, by protocol necessity)
1155
93
 
1156
- return classicalValid && pqValid;
1157
- }
94
+ | Component | Algorithm | Use case | Quantum threat |
95
+ | --- | --- | --- | --- |
96
+ | Ethereum signing | secp256k1 ECDSA | Transaction/message signatures | High — Shor's algorithm |
97
+ | WebAuthn passkeys | P-256 (ES256) | Authentication signatures | High — Shor's algorithm |
98
+ | Stealth addresses | secp256k1 ECDH | Privacy-preserving key exchange | High — Shor's algorithm |
99
+ | HD derivation | BIP32/BIP44 | Hierarchical key generation | High — inherits ECDSA's exposure |
1158
100
 
1159
- // Protocol replaces this validation frame with a STARK proof at mempool layer
1160
- // Gas cost: near-zero (single STARK for entire block's validation frames)
1161
- ```
101
+ ### Post-quantum cryptography (shipped)
1162
102
 
1163
- ### External Wallet Integration
103
+ | Component | Algorithm | Use case | Quantum security |
104
+ | --- | --- | --- | --- |
105
+ | Data encryption | ML-KEM-1024 (FIPS 203) + AES-256-GCM | `mlkemEncrypt`/`mlkemDecrypt` — backups, messaging, any data at rest/in transit | Post-quantum secure |
1164
106
 
1165
- **Challenge:** MetaMask, Ledger, etc. don't support PQ signatures yet
107
+ ### Symmetric cryptography (already quantum-resistant)
1166
108
 
1167
- **Solution:** Use [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) delegation to w3pk's PQ account
1168
- ```typescript
1169
- // Delegate external wallet to w3pk's quantum-safe account
1170
- const delegation = await w3pk.requestExternalWalletDelegation({
1171
- chainId: 1,
1172
- nonce: 0n,
1173
- quantumSafe: true, // Use PQ account as delegation target
1174
- });
1175
-
1176
- // External wallet signs classical authorization
1177
- // w3pk's smart contract handles PQ verification
1178
- ```
109
+ | Component | Algorithm | Use case | Quantum security |
110
+ | --- | --- | --- | --- |
111
+ | Wallet/backup/session encryption | AES-256-GCM | Mnemonic storage, backups, sessions | 128-bit (sufficient) |
1179
112
 
1180
- ### WebAuthn & Passkeys
113
+ ### Key derivation
1181
114
 
1182
- **Challenge:** [FIDO Alliance](https://fidoalliance.org/) doesn't support PQ yet
115
+ | Component | Algorithm | Parameters | Quantum resistance |
116
+ | --- | --- | --- | --- |
117
+ | Wallet encryption | PBKDF2-SHA256 | 210,000 iterations | Moderate — Grover's algorithm halves effective security |
118
+ | Backup encryption | PBKDF2-SHA256 | 310,000 iterations | Moderate |
119
+ | Metadata encryption | PBKDF2-SHA256 | 100,000 iterations | Moderate |
1183
120
 
1184
- **FIDO Quantum Roadmap:**
1185
- - 2024: Working group formed
1186
- - 2025-2026: Specification development
1187
- - 2027: First implementations
1188
- - 2028+: Browser support
121
+ ### Hash functions
1189
122
 
1190
- **w3pk Strategy:**
1191
- - ✅ Continue using [P-256](https://eips.ethereum.org/EIPS/eip-7951) for authentication (low risk)
1192
- - ✅ Use PQ for transaction signatures (high risk)
1193
- - ✅ Monitor FIDO specs and update when available
123
+ | Component | Algorithm | Use case | Quantum security |
124
+ | --- | --- | --- | --- |
125
+ | General hashing | SHA-256 | Checksums, derivation | 128-bit collision (sufficient) |
126
+ | Ethereum hashing | Keccak-256 | ERC-5564, addresses | 128-bit collision (sufficient) |
1194
127
 
1195
128
  ---
1196
129
 
1197
- ## Success Metrics
1198
-
1199
- ### Phase 1 Success Criteria (0-6 months)
1200
- - [ ] PBKDF2 iterations increased to quantum-ready levels
1201
- - [ ] Crypto-agility infrastructure deployed
1202
- - [ ] Security audit completed with no critical findings
1203
- - [ ] Quantum migration ADR published
1204
-
1205
- ### Phase 2 Success Criteria (6-18 months)
1206
- - [ ] Kohaku pq-account integrated
1207
- - [ ] Smart contract accounts deployed to testnet
1208
- - [ ] Migration utilities tested with 100+ users
1209
- - [ ] Gas costs optimized below 300,000 per transaction
1210
-
1211
- ### Phase 3 Success Criteria (18-36 months)
1212
- - [ ] 10,000+ users migrated to quantum-safe accounts
1213
- - [ ] Zero critical vulnerabilities in PQ implementation
1214
- - [ ] Average gas cost <200,000 per hybrid transaction
1215
- - [ ] Integration with 5+ major dApps
1216
-
1217
- ### Phase 4 Success Criteria (36+ months)
1218
- - [ ] 90%+ of active users on quantum-safe accounts
1219
- - [ ] Legacy account deprecation completed
1220
- - [ ] Quantum-safe by default for all new registrations
1221
- - [ ] Published research papers on implementation
1222
-
1223
- ---
1224
-
1225
- ## Key Takeaways
1226
-
1227
- ### For Developers
1228
-
1229
- 1. **Don't panic** - You have 10-15 years before quantum computers threaten cryptography
1230
- 2. **Plan now, deploy later** - Architecture decisions matter more than rushing code
1231
- 3. **Follow the [Ethereum quantum resistance roadmap](https://x.com/VitalikButerin/status/2027075026378543132)** - [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141) validation frames will solve gas costs
1232
- 4. **Use [Kohaku](https://github.com/ethereum/kohaku) as interim** - Leverage Ethereum Foundation's PQ implementation until native AA
1233
- 5. **Account abstraction wins** - Smart contract accounts enable smooth migration
1234
- 6. **Hybrid signatures** - Maintain backward compatibility during transition
1235
- 7. **Prepare for validation frames** - Design with protocol-layer aggregation in mind
1236
- 8. **Monitor hash function selection** - Ethereum's choice will impact all applications
1237
-
1238
- ### For Users
1239
-
1240
- 1. **Your funds are safe today** - No immediate quantum threat
1241
- 2. **w3pk is quantum-aware** - We're preparing for the future
1242
- 3. **Backups are protected** - AES-256-GCM is quantum-resistant
1243
- 4. **Migration will be optional** - You control when to upgrade
1244
- 5. **No action needed yet** - We'll notify you when migration is ready
1245
- 6. **Education first** - We'll explain every step of the process
1246
-
1247
- ### For Auditors
1248
-
1249
- 1. **Current implementation is sound** - Standard cryptography best practices
1250
- 2. **Quantum threat is acknowledged** - Clear migration roadmap exists
1251
- 3. **No premature optimization** - Waiting for mature PQ libraries
1252
- 4. **Backward compatibility prioritized** - Hybrid approach prevents breaking changes
1253
- 5. **Gas costs optimized** - Off-chain PQ verification via account abstraction
1254
- 6. **Continuous monitoring** - Regular security audits planned
1255
-
1256
- ---
1257
-
1258
- ## References & Resources
1259
-
1260
- ### Standards & Specifications
1261
-
1262
- - **[EIP-8141: Native Account Abstraction](https://eips.ethereum.org/EIPS/eip-8141)** ⭐ Vitalik's proposed solution for quantum-safe EOAs
1263
- - [EIP-4337: Account Abstraction](https://eips.ethereum.org/EIPS/eip-4337) - Current interim solution
1264
- - [EIP-7702: Set EOA Account Code](https://eips.ethereum.org/EIPS/eip-7702)
1265
- - [EIP-7951: P-256 Signature Verification](https://eips.ethereum.org/EIPS/eip-7951)
1266
- - [ERC-5564: Stealth Address Protocol](https://eips.ethereum.org/EIPS/eip-5564)
1267
- - [NIST FIPS 204: ML-DSA (Dilithium)](https://csrc.nist.gov/pubs/fips/204/final)
1268
- - [NIST FIPS 203: ML-KEM (Kyber)](https://csrc.nist.gov/pubs/fips/203/final)
1269
-
1270
- ### Research & Articles
1271
-
1272
- - **[Ethereum Quantum Resistance Roadmap](https://x.com/VitalikButerin/status/2027075026378543132)** ⭐ February 2026 - Ethereum's official quantum plan
1273
- - [Quantum Computing Misconceptions - a16z crypto](https://a16zcrypto.com/posts/article/quantum-computing-misconceptions-realities-blockchains-planning-migrations/)
1274
- - [Post-Quantum Ethereum - Ethereum Research](https://ethresear.ch/t/the-road-to-post-quantum-ethereum-transaction-is-paved-with-account-abstraction-aa/21783)
1275
- - [Ethereum Kohaku Project](https://github.com/ethereum/kohaku)
1276
- - [Open Quantum Safe Project](https://openquantumsafe.org/)
1277
- - [NIST Post-Quantum Cryptography Project](https://csrc.nist.gov/projects/post-quantum-cryptography)
1278
-
1279
- ### Hash Functions (Ethereum's "Last Hash Function")
1280
-
1281
- - [Poseidon2](https://eprint.iacr.org/2023/323) - ZK-friendly hash with extra security rounds
1282
- - [Poseidon1 (original)](https://eprint.iacr.org/2019/458) - 2x slower but not vulnerable to Poseidon2 attacks
1283
- - [BLAKE3](https://github.com/BLAKE3-team/BLAKE3) - Efficient conventional cryptographic hash
1284
-
1285
- ### Implementation Libraries
1286
-
1287
- - **Ethereum Kohaku** - [`@kohaku-eth/pq-account`](https://github.com/ethereum/kohaku/tree/master/packages/pq-account)
1288
- - **Open Quantum Safe** - [liboqs](https://github.com/open-quantum-safe/liboqs)
1289
- - **PQClean** - [Reference implementations](https://github.com/PQClean/PQClean)
130
+ ## ML-KEM Encryption
1290
131
 
1291
- ---
132
+ w3pk supports **ML-KEM-1024** (NIST FIPS 203) encryption for quantum-resistant data protection, with multi-recipient support and deterministic key derivation from private keys. See [`src/crypto/mlkem.ts`](../src/crypto/mlkem.ts).
1292
133
 
1293
- ## ML-KEM Encryption
134
+ ### How it works
1294
135
 
1295
- w3pk supports ML-KEM-1024 encryption for quantum-resistant data protection with multi-recipient support and deterministic key derivation from private keys.
136
+ 1. A random AES-256 key is generated per message.
137
+ 2. The plaintext is encrypted with AES-256-GCM using that key.
138
+ 3. For each recipient, a shared secret is encapsulated with their ML-KEM-1024 public key, and used to wrap the AES key.
139
+ 4. Each recipient decrypts with their private key to recover the AES key, then decrypts the payload.
1296
140
 
1297
- ### Deterministic Key Derivation
141
+ This is a KEM+DEM hybrid (asymmetric PQ key encapsulation wrapping a symmetric cipher) — not a classical+PQ dual key-exchange combiner. ML-KEM-1024 alone generates the shared secret; there is no secp256k1/X25519 component mixed into the encapsulation step.
1298
142
 
1299
- Derive ML-KEM keypairs deterministically from any private key material (Ethereum keys, random seeds, etc.):
143
+ ### Deterministic key derivation
1300
144
 
1301
145
  ```typescript
1302
146
  import { deriveMLKemKeypair, mlkemEncryptWithKey, mlkemDecryptWithKey } from 'w3pk';
1303
147
 
1304
- // Derive ML-KEM keypair from Ethereum private key
1305
- const ethPrivateKey = '0x1234...'; // Your wallet private key
148
+ const ethPrivateKey = '0x1234...';
1306
149
  const keypair = await deriveMLKemKeypair(ethPrivateKey, 'my-app');
1307
- // Returns: { publicKey: Uint8Array(1568), privateKey: Uint8Array(3168) }
1308
-
1309
- // Share your public key with others
1310
- const publicKeyBase64 = Buffer.from(keypair.publicKey).toString('base64');
150
+ // { publicKey: Uint8Array(1568), privateKey: Uint8Array(3168) }
1311
151
 
1312
- // Later: Recreate keypair from same private key (deterministic!)
152
+ // Same input always produces the same keypair
1313
153
  const sameKeypair = await deriveMLKemKeypair(ethPrivateKey, 'my-app');
1314
- // sameKeypair.publicKey === keypair.publicKey ✅
1315
154
  ```
1316
155
 
1317
- ### Encrypt/Decrypt with w3pk Instance (Recommended)
156
+ Uses HKDF-SHA256 with salt `"mlkem-keypair-v1"` and the provided context string to derive a 64-byte seed, from which the ML-KEM-1024 keypair is generated. All sensitive material is zeroized after use.
1318
157
 
1319
- The easiest way to use ML-KEM encryption - no private key exposure:
158
+ ### Encrypt/decrypt with a w3pk instance (recommended)
1320
159
 
1321
160
  ```typescript
1322
161
  import { createWeb3Passkey } from 'w3pk';
@@ -1324,286 +163,215 @@ import { createWeb3Passkey } from 'w3pk';
1324
163
  const w3pk = createWeb3Passkey();
1325
164
  await w3pk.login();
1326
165
 
1327
- // 1. Share your public key with others
1328
166
  const myPublicKey = await w3pk.deriveMLKemPublicKey();
1329
- // Send myPublicKey to the server or publish it
1330
-
1331
- // 2. Get server's public key
1332
167
  const serverPubKey = await fetch('/api/mlkem-public-key').then(r => r.text());
1333
168
 
1334
- // 3. Encrypt for yourself + server
1335
- const encrypted = await w3pk.mlkemEncrypt(
1336
- 'my secret data',
1337
- [serverPubKey] // Server can decrypt
1338
- );
1339
- // You can also decrypt because you're auto-added as recipient
169
+ const encrypted = await w3pk.mlkemEncrypt('my secret data', [serverPubKey]);
170
+ // You can also decrypt, since you're auto-added as a recipient
1340
171
 
1341
- // 4. Later: Decrypt locally (server never sees plaintext!)
1342
172
  const plaintext = await w3pk.mlkemDecrypt(encrypted);
1343
173
  ```
1344
174
 
1345
- **Security:** Your Ethereum private key never leaves the w3pk instance, matching the security model of `signMessage()` and `sendTransaction()`.
1346
-
1347
- **Supported Modes:**
1348
- - ✅ **STANDARD** (default) - Private key derived internally, not exposed to app
1349
- - ✅ **STRICT** - Same as STANDARD but always requires WebAuthn re-authentication
1350
- - ✅ **YOLO** - Private key available to app
1351
- - ❌ **PRIMARY** - Not supported (uses P-256 WebAuthn keys, not Ethereum keys)
175
+ Your Ethereum private key never leaves the w3pk instance, matching the security model of `signMessage()` and `sendTransaction()`.
1352
176
 
1353
- ### Encrypt/Decrypt with Key Derivation (Low-level API)
177
+ **Supported modes:**
178
+ - ✅ **STANDARD** (default) — private key derived internally
179
+ - ✅ **STRICT** — same as STANDARD, always requires WebAuthn re-authentication
180
+ - ✅ **YOLO** — private key available to app
181
+ - ❌ **PRIMARY** — not supported; uses P-256 WebAuthn keys, not Ethereum keys, so there's no secp256k1 material to derive an ML-KEM seed from
1354
182
 
1355
- For advanced use cases where you manage private keys directly:
183
+ ### Low-level API
1356
184
 
1357
185
  ```typescript
1358
- // Client encrypts for themselves + server
1359
- const serverKeypair = await deriveMLKemKeypair(serverEthKey, 'server');
1360
- const encrypted = await mlkemEncryptWithKey(
1361
- 'my secret data',
1362
- myEthPrivateKey, // Sender's private key (auto-added as recipient)
1363
- [serverKeypair.publicKey], // Additional recipients
1364
- 'client' // Context for sender's key derivation
1365
- );
1366
-
1367
- // Later: Client decrypts locally (no server needed!)
1368
- const plaintext = await mlkemDecryptWithKey(
1369
- encrypted,
1370
- myEthPrivateKey, // Same private key used for encryption
1371
- 'client' // Same context
1372
- );
1373
-
1374
- // Or: Server decrypts for operations
1375
- const plaintext = await mlkemDecryptWithKey(
1376
- encrypted,
1377
- serverEthKey,
1378
- 'server'
1379
- );
1380
- ```
186
+ import { deriveMLKemKeypair, mlkemEncryptWithKey, mlkemDecryptWithKey, mlkemEncrypt, mlkemDecrypt } from 'w3pk';
1381
187
 
1382
- ### Direct Encryption (Without Key Derivation)
1383
-
1384
- For maximum flexibility, use raw public keys directly:
188
+ // Derive-from-key convenience wrappers
189
+ const serverKeypair = await deriveMLKemKeypair(serverEthKey, 'server');
190
+ const encrypted = await mlkemEncryptWithKey('my secret data', myEthPrivateKey, [serverKeypair.publicKey], 'client');
191
+ const plaintext = await mlkemDecryptWithKey(encrypted, myEthPrivateKey, 'client');
1385
192
 
1386
- ```typescript
1387
- import { mlkemEncrypt, mlkemDecrypt } from 'w3pk';
1388
-
1389
- // Single recipient
1390
- const publicKey = 'base64_encoded_public_key...'; // 1568 bytes
1391
- const encrypted = await mlkemEncrypt('my secret data', publicKey);
1392
-
1393
- // Multiple recipients (encrypt once, multiple people can decrypt)
1394
- const encrypted = await mlkemEncrypt('my secret data', [
1395
- publicKey1,
1396
- publicKey2,
1397
- publicKey3
1398
- ]);
1399
- // Returns: { recipients: [...], encryptedData, iv, authTag }
1400
-
1401
- // Decrypt with your private key (auto-detects which recipient you are)
1402
- const privateKey = 'base64_encoded_private_key...'; // 3168 bytes
1403
- const plaintext = await mlkemDecrypt(encrypted, privateKey);
1404
- // Returns: 'my secret data'
1405
-
1406
- // Or specify your public key for faster lookup
1407
- const plaintext = await mlkemDecrypt(encrypted, privateKey, publicKey);
193
+ // Direct, key-management-agnostic API
194
+ const encryptedDirect = await mlkemEncrypt('my secret data', [publicKey1, publicKey2]);
195
+ const plaintextDirect = await mlkemDecrypt(encryptedDirect, privateKey);
1408
196
  ```
1409
197
 
1410
- ### Security Properties
1411
-
1412
- - ✅ **ML-KEM-1024** (NIST FIPS 203) - Post-quantum secure
1413
- - ✅ **AES-256-GCM** - 128-bit quantum security (sufficient)
1414
- - ✅ **Key zeroization** - Shared secrets securely wiped from memory
1415
- - ✅ **Hybrid encryption** - KEM + symmetric cipher for efficiency
1416
- - ✅ **Cross-platform** - Works in browser and Node.js
1417
-
1418
- ### API Reference
1419
-
1420
- #### Instance Methods (Recommended)
1421
-
1422
- These methods work with your w3pk wallet instance - no private key exposure:
198
+ ### API reference
1423
199
 
1424
200
  #### `w3pk.deriveMLKemPublicKey(options?): Promise<string>`
201
+ Derives your ML-KEM-1024 public key (base64, 1568 bytes) for sharing.
202
+ **Options:** `context` (default `'mlkem-v1'`), `mode` (`STANDARD`/`STRICT`/`YOLO`), `tag`, `origin`, `requireAuth`.
1425
203
 
1426
- Derives your ML-KEM-1024 public key that can be shared for encryption.
204
+ #### `w3pk.mlkemEncrypt(plaintext, recipientPublicKeys, options?): Promise<EncryptedPayload>`
205
+ Encrypts for yourself plus additional recipients. Same options as above.
1427
206
 
1428
- **Parameters:**
1429
- - `options.context` - Context string for domain separation (default: `'mlkem-v1'`)
1430
- - `options.mode` - Security mode: `'STANDARD'`, `'STRICT'`, or `'YOLO'` (default: `'STANDARD'`)
1431
- - `options.tag` - Tag for address derivation (default: `'MAIN'`)
1432
- - `options.origin` - Origin for derivation (default: current origin)
1433
- - `options.requireAuth` - Force WebAuthn re-authentication (default: false, always true in STRICT mode)
207
+ #### `w3pk.mlkemDecrypt(payload, options?): Promise<string>`
208
+ Decrypts data encrypted for your wallet. `context`/`mode`/`tag`/`origin`/`requireAuth` must match encryption.
1434
209
 
1435
- **Note:** PRIMARY mode is not supported as it uses P-256 WebAuthn keys instead of Ethereum keys.
210
+ #### `deriveMLKemKeypair(privateKey, context?): Promise<MLKemKeypair>`
211
+ Low-level deterministic keypair derivation. Returns `{ publicKey: Uint8Array(1568), privateKey: Uint8Array(3168) }`.
1436
212
 
1437
- **Returns:** Base64-encoded ML-KEM public key (1568 bytes)
213
+ #### `mlkemEncryptWithKey(plaintext, senderPrivateKey, recipientPublicKeys, senderContext?): Promise<EncryptedPayload>`
214
+ Derives the sender's keypair, then encrypts for sender + recipients (sender's public key is auto-included as first recipient).
1438
215
 
1439
- **Example:**
1440
- ```typescript
1441
- const w3pk = createWeb3Passkey();
1442
- await w3pk.login();
1443
- const pubKey = await w3pk.deriveMLKemPublicKey();
1444
- ```
216
+ #### `mlkemDecryptWithKey(payload, privateKey, context?): Promise<string>`
217
+ Derives a keypair, then decrypts.
1445
218
 
1446
- #### `w3pk.mlkemEncrypt(plaintext: string, recipientPublicKeys: Array<string | Uint8Array>, options?): Promise<EncryptedPayload>`
219
+ #### `mlkemEncrypt(plaintext, publicKeys): Promise<EncryptedPayload>`
220
+ Raw encryption for one or more recipients. Each `publicKeys` entry is base64 or `Uint8Array`, 1568 bytes.
221
+ **Returns:** `{ version: 2, recipients: [{ publicKey, ciphertext }], encryptedData, iv, authTag }` — `ciphertext` is 1608 bytes (1568 KEM + 40 wrapped AES key), `iv` is 12 bytes, `authTag` is 16 bytes.
1447
222
 
1448
- Encrypts data for yourself and additional recipients.
223
+ Each recipient's AES key is wrapped with AES-KW ([RFC 3394](https://datatracker.ietf.org/doc/html/rfc3394)) under a key-encryption key derived from the ML-KEM shared secret with HKDF-SHA256 (empty salt, info `w3pk-mlkem-kek-v2`). Payloads without a `version` field are legacy v1 (AES key XOR-ed with the raw shared secret, 1600-byte `ciphertext`) and still decrypt.
1449
224
 
1450
- **Parameters:**
1451
- - `plaintext` - The data to encrypt
1452
- - `recipientPublicKeys` - Array of recipient ML-KEM public keys (base64 or Uint8Array)
1453
- - `options.context` - Context string (default: `'mlkem-v1'`)
1454
- - `options.mode` - Security mode: `'STANDARD'`, `'STRICT'`, or `'YOLO'` (default: `'STANDARD'`)
1455
- - `options.tag` - Tag for address derivation (default: `'MAIN'`)
1456
- - `options.origin` - Origin (default: current origin)
1457
- - `options.requireAuth` - Force re-authentication (default: false, always true in STRICT mode)
1458
-
1459
- **Returns:** Encrypted payload
1460
-
1461
- **Example:**
1462
- ```typescript
1463
- const encrypted = await w3pk.mlkemEncrypt('secret', [serverPubKey]);
1464
- ```
225
+ #### `mlkemDecrypt(payload, privateKey, publicKey?): Promise<string>`
226
+ Decrypts a payload from `mlkemEncrypt()`, v2 or legacy v1. Passing your `publicKey` (1568 bytes) speeds up recipient lookup; otherwise every recipient entry is tried. The IV must be 12 bytes and the auth tag 16 bytes.
1465
227
 
1466
- #### `w3pk.mlkemDecrypt(payload: EncryptedPayload, options?): Promise<string>`
228
+ ### Security properties
1467
229
 
1468
- Decrypts data encrypted for your wallet.
1469
-
1470
- **Parameters:**
1471
- - `payload` - The encrypted payload
1472
- - `options.context` - Context string (default: `'mlkem-v1'`, must match encryption)
1473
- - `options.mode` - Security mode: `'STANDARD'`, `'STRICT'`, or `'YOLO'` (default: `'STANDARD'`)
1474
- - `options.tag` - Tag (default: `'MAIN'`)
1475
- - `options.origin` - Origin (default: current origin)
1476
- - `options.requireAuth` - Force re-authentication (default: false, always true in STRICT mode)
1477
-
1478
- **Returns:** Decrypted plaintext
1479
-
1480
- **Example:**
1481
- ```typescript
1482
- const plaintext = await w3pk.mlkemDecrypt(encrypted);
1483
- ```
230
+ - ✅ ML-KEM-1024 (NIST FIPS 203) — post-quantum secure key encapsulation
231
+ - ✅ AES-256-GCM — 128-bit quantum security for the payload
232
+ - ✅ HKDF-derived KEK + AES-KW — a tampered wrapped key is rejected before the payload is touched
233
+ - ✅ Key zeroization — shared secrets wiped from memory after use
234
+ - ✅ Cross-platform — browser and Node.js
235
+ - ⚠️ Deterministic derivation from the Ethereum private key means ML-KEM key secrecy is capped by secp256k1 key secrecy — this scheme protects data confidentiality against a future quantum adversary, but does not add independent key-generation entropy beyond the wallet's existing secret
1484
236
 
1485
237
  ---
1486
238
 
1487
- #### Low-Level Functions
1488
-
1489
- These functions require managing private keys directly:
239
+ ## What w3pk is deliberately not doing yet
1490
240
 
1491
- #### `deriveMLKemKeypair(privateKey: string | Uint8Array, context?: string): Promise<MLKemKeypair>`
241
+ - **No interim on-chain PQ signature verifiers.** Pre-EIP-8141 architectures (bundler-based smart-contract accounts with a bolted-on PQ verifier) are not part of Ethereum's actual roadmap and would need to be replaced once EIP-8141 ships. Building on them now means migrating twice for no lasting benefit.
242
+ - **No PQ signing scheme committed in code.** Which exact algorithm to use (ML-DSA via EIP-8051/8355, Falcon via EIP-7619, or a hash-based Winternitz scheme) is still an open execution-layer question upstream. Committing to one now risks shipping the wrong thing.
243
+ - **No changes to WebAuthn/passkey authentication.** FIDO Alliance's own PQ specification work isn't expected to produce browser support before 2027-2028; P-256 stays as-is until that lands.
1492
244
 
1493
- Derives a deterministic ML-KEM-1024 keypair from any private key material using HKDF-SHA256.
1494
-
1495
- **Parameters:**
1496
- - `privateKey` - Private key material (hex string with optional `0x` prefix, or Uint8Array)
1497
- - `context` - Optional context string for domain separation (default: `'mlkem-v1'`)
245
+ ---
1498
246
 
1499
- **Returns:** `MLKemKeypair` object containing:
1500
- - `publicKey` - ML-KEM-1024 public key (Uint8Array, 1568 bytes)
1501
- - `privateKey` - ML-KEM-1024 private key (Uint8Array, 3168 bytes)
247
+ ## Roadmap maturity: closing the gaps
1502
248
 
1503
- **Security:** Uses HKDF with salt `"mlkem-keypair-v1"` and the provided context to derive a 64-byte seed, then generates a deterministic ML-KEM keypair. Same input always produces same output. All sensitive material is zeroized after use.
249
+ The trigger table above tracks Ethereum's protocol schedule, which covers *when w3pk can act* on signatures. It does not by itself cover everything a post-quantum migration roadmap needs (per [NIST SP 1800-38](https://www.nccoe.nist.gov/applied-cryptography/migration-to-pqc) and [CISA's Quantum-Readiness guidance](https://www.cisa.gov/resources-tools/resources/quantum-readiness-migration-post-quantum-cryptography)): an inventory alone isn't a plan, and a plan that only reacts to an external protocol isn't crypto-agile. The items below are owned by w3pk directly, independent of Ethereum's timeline, and get checked at every "Next Review" date above.
1504
250
 
1505
- #### `mlkemEncryptWithKey(plaintext: string, senderPrivateKey: string | Uint8Array, recipientPublicKeys: Array<string | Uint8Array>, senderContext?: string): Promise<EncryptedPayload>`
251
+ ### Internally-owned checkpoints (every review cycle)
1506
252
 
1507
- Convenience function that derives the sender's ML-KEM keypair, then encrypts for sender + recipients.
253
+ - [ ] Re-verify the `mlkem` npm package (currently `mlkem@2.7.0`, [dajiaji/crystals-kyber-js](https://github.com/dajiaji/crystals-kyber-js)) is still maintained, still passes the NIST ML-KEM KAT vectors and the pq-crystals/kyber reference tests, and has no open security advisories.
254
+ - [ ] Re-check the FIDO Alliance's WebAuthn PQ status — no PQ COSE algorithm identifier is registered as of this writing, so P-256 passkeys stay as-is; flag the moment one lands.
255
+ - [ ] Re-check whether `ethers` (currently `^6.0.0`, used for transaction construction and secp256k1 signing) has announced any PQ or hybrid-signing support, since a signing-path change there would predate w3pk's own EIP-8141 integration.
256
+ - [ ] Re-confirm EIP-8141 and the Hegotá fork's status directly against [pq.ethereum.org](https://pq.ethereum.org/) and [strawmap.org](https://strawmap.org/) — don't rely on this document staying current between reviews.
1508
257
 
1509
- **Parameters:**
1510
- - `plaintext` - The data to encrypt
1511
- - `senderPrivateKey` - Sender's private key (hex string or Uint8Array)
1512
- - `recipientPublicKeys` - Array of recipient ML-KEM public keys
1513
- - `senderContext` - Optional context for sender's key derivation (default: `'mlkem-v1'`)
258
+ ### Crypto-agility target design (not yet implemented)
1514
259
 
1515
- **Returns:** `EncryptedPayload` (sender's public key is automatically included as first recipient)
260
+ The SDK has no algorithm-selection config today — signing is hardcoded to secp256k1/P-256, and encryption is hardcoded to ML-KEM-1024 + AES-256-GCM. That's fine while there is only one option to choose from, but it means "add hybrid signing" is currently a code change, not a config flip. Per NIST's crypto-agility guidance (CSWP 39), the target shape before the first EIP-8141 trigger fires should be something like:
1516
261
 
1517
- **Use case:** Encrypt data so both you and a server can decrypt independently.
262
+ ```typescript
263
+ // Target shape — does not exist in src/ yet.
264
+ // Introduce this when the first trigger in "What w3pk will do when Ethereum is ready" fires,
265
+ // not before — there is nothing to make agile until a second signature scheme actually exists.
266
+ interface CryptoConfig {
267
+ version: number;
268
+ signatures: {
269
+ ethereum: 'secp256k1' | 'hybrid-secp256k1-pq';
270
+ postQuantum?: string; // whatever scheme Ethereum standardizes via EIP-8051/8355/7619
271
+ };
272
+ }
273
+ ```
1518
274
 
1519
- #### `mlkemDecryptWithKey(payload: EncryptedPayload, privateKey: string | Uint8Array, context?: string): Promise<string>`
275
+ This is a placeholder for design intent, not a commitment to this exact shape — the real interface depends on which PQ scheme Ethereum's execution layer actually standardizes.
1520
276
 
1521
- Convenience function that derives an ML-KEM keypair, then decrypts the payload.
277
+ ### Operational runbook (draft — to be finalized before the first trigger fires)
1522
278
 
1523
- **Parameters:**
1524
- - `payload` - The encrypted payload
1525
- - `privateKey` - Private key material (hex string or Uint8Array)
1526
- - `context` - Optional context for key derivation (default: `'mlkem-v1'`)
279
+ 1. **Dry run on testnet first.** Hybrid signing gets exercised against a testnet deployment of the relevant EIP-8141 validation frame before any mainnet opt-in ships.
280
+ 2. **ML-KEM context rotation.** `deriveMLKemKeypair`'s `context` parameter already provides domain separation; if the ML-KEM implementation itself ever needs replacing (library vulnerability, algorithm deprecation), bump the default context (e.g. `mlkem-v2`) rather than reusing `mlkem-v1`, and keep the old context decryptable for existing backups rather than breaking them.
281
+ 3. **Fail closed on hybrid mismatch.** If a hybrid account's classical and PQ signatures disagree (one verifies, one doesn't), the transaction is rejected outright. There is no partial-trust mode where either signature alone is accepted once hybrid mode is active for an account.
282
+ 4. **No global cutover switch.** Hybrid mode is opt-in per account via the trigger table above. w3pk does not flip existing wallets to hybrid or PQ-only signing without explicit user action, even after Ethereum completes its own migration (fork milestones L*/M* and beyond).
1527
283
 
1528
- **Returns:** Decrypted plaintext string
284
+ ### Dependency PQ posture
1529
285
 
1530
- **Use case:** Decrypt data using your Ethereum private key without managing separate ML-KEM keys.
286
+ | Dependency | Role | PQ status | What we watch |
287
+ | --- | --- | --- | --- |
288
+ | `mlkem` (`^2.7.0`) | ML-KEM-1024 encryption | Post-quantum today | Maintenance activity, KAT test results, disclosed vulnerabilities |
289
+ | `ethers` (`^6.0.0`) | Transaction construction, secp256k1 signing | Classical only | Any announced hybrid/PQ signing support |
290
+ | WebAuthn / FIDO2 | Passkey authentication (P-256) | Classical only | FIDO Alliance PQ working-group output; no registered PQ COSE algorithm yet |
291
+ | Ethereum L1 (via EIP-8141) | Transaction validation | Classical only, PQ path specified but not shipped | Hegotá fork outcome, EIP-8141 mainnet status |
1531
292
 
1532
- #### `mlkemEncrypt(plaintext: string, publicKeys: (string | Uint8Array) | Array<string | Uint8Array>): Promise<EncryptedPayload>`
293
+ ---
1533
294
 
1534
- Encrypts data using ML-KEM-1024 + AES-256-GCM for one or more recipients.
295
+ ## Quantum computing timeline
1535
296
 
1536
- **Parameters:**
1537
- - `plaintext` - The data to encrypt
1538
- - `publicKeys` - Single public key or array of ML-KEM-1024 public keys (base64 strings or Uint8Arrays, 1568 bytes each)
297
+ - **Conservative estimate:** 10-15 years to a CRQC
298
+ - **EF's own estimate:** early-to-mid 2030s
299
+ - **Google Quantum AI (March 2026):** ~1,200 logical qubits needed to break 256-bit ECC, down from prior estimates
300
+ - **NIST:** deprecating ECDSA by 2030, disallowing it by 2035 (hybrid PQ modes are exempted from the 2035 disallowance per NIST IR 8547, as long as the PQ component is approved)
1539
301
 
1540
- **Returns:** `EncryptedPayload` object containing:
1541
- - `recipients` - Array of recipient entries, each containing:
1542
- - `publicKey` - Base64 recipient public key (1568 bytes)
1543
- - `ciphertext` - Base64 ML-KEM ciphertext for this recipient (1600 bytes: 1568 KEM + 32 encrypted AES key)
1544
- - `encryptedData` - Base64 AES-encrypted data (shared across all recipients)
1545
- - `iv` - Base64 initialization vector (12 bytes)
1546
- - `authTag` - Base64 authentication tag (16 bytes)
302
+ Dormant-funds exposure — the governance question nobody has answered — is much smaller for Ethereum than for Bitcoin: the EF estimates roughly 0.1% of ETH supply is long-dormant, against ~5% of BTC in early address formats. That gap is part of why "do nothing yet" is a defensible position for Ethereum today.
1547
303
 
1548
- **How it works:**
1549
- 1. Generates a random AES-256 key
1550
- 2. Encrypts plaintext with AES-256-GCM using that key
1551
- 3. For each recipient: encapsulates a shared secret with their ML-KEM public key, then XOR-encrypts the AES key with the shared secret
1552
- 4. Each recipient can decrypt using their private key to recover the AES key, then decrypt the data
304
+ ---
1553
305
 
1554
- #### `mlkemDecrypt(payload: EncryptedPayload, privateKey: string | Uint8Array, publicKey?: string | Uint8Array): Promise<string>`
306
+ ## Key takeaways
1555
307
 
1556
- Decrypts data encrypted with `mlkemEncrypt()`.
308
+ ### For developers
309
+ 1. w3pk's data-encryption layer is already post-quantum (ML-KEM-1024) — use it today for anything that needs long-term confidentiality.
310
+ 2. Transaction-signature quantum-safety is gated on Ethereum's own protocol timeline, not on w3pk shipping something early.
311
+ 3. The actionable trigger is **EIP-8141 reaching mainnet with a working PQ verification path** — see [What w3pk will do when Ethereum is ready](#what-w3pk-will-do-when-ethereum-is-ready).
312
+ 4. Watch the **Hegotá** fork (2027) — it's the gate for whether the rest of the PQ schedule holds.
1557
313
 
1558
- **Parameters:**
1559
- - `payload` - The encrypted payload from `mlkemEncrypt()`
1560
- - `privateKey` - ML-KEM-1024 private key (base64 string or Uint8Array, 3168 bytes)
1561
- - `publicKey` - (Optional) Your ML-KEM-1024 public key for faster recipient lookup (base64 string or Uint8Array, 1568 bytes)
314
+ ### For users
315
+ 1. Your funds are safe today; no immediate quantum threat exists.
316
+ 2. Backups and sessions are already quantum-resistant (AES-256-GCM).
317
+ 3. Data you encrypt with `mlkemEncrypt` is already post-quantum secure.
318
+ 4. Any future signature migration will be opt-in — nothing changes without you choosing it.
1562
319
 
1563
- **Returns:** Decrypted plaintext string
320
+ ### For auditors
321
+ 1. Current cryptography follows standard best practice; ML-KEM-1024 usage matches FIPS 203.
322
+ 2. The signature-side gap is acknowledged and explicitly deferred to Ethereum's protocol timeline, not silently ignored.
323
+ 3. No speculative or unverified interim PQ infrastructure has been deployed.
1564
324
 
1565
- **Throws:** Error if decryption fails (invalid key, no matching recipient, corrupted data, or tampered auth tag)
325
+ ---
1566
326
 
1567
- **Note:** If `publicKey` is not provided, the function will try each recipient until it finds a match (slower but convenient)
327
+ ## References
328
+
329
+ ### Standards
330
+ - [NIST FIPS 203: ML-KEM](https://csrc.nist.gov/pubs/fips/203/final) — key encapsulation, used by w3pk today
331
+ - [NIST FIPS 204: ML-DSA](https://csrc.nist.gov/pubs/fips/204/final) — signatures, candidate for Ethereum's execution layer
332
+ - [NIST FIPS 205: SLH-DSA](https://csrc.nist.gov/pubs/fips/205/final) — hash-based signatures
333
+ - [EIP-8141: Frame transactions](https://eips.ethereum.org/EIPS/eip-8141) — the trigger this document tracks
334
+ - [EIP-8051](https://eips.ethereum.org/EIPS/eip-8051), [EIP-8355](https://eips.ethereum.org/EIPS/eip-8355) — `VERIFY_MLDSA` precompile drafts
335
+ - [EIP-7619: Falcon](https://eips.ethereum.org/EIPS/eip-7619)
336
+ - [EIP-7702: Set EOA account code](https://eips.ethereum.org/EIPS/eip-7702)
337
+ - [ERC-5564: Stealth address protocol](https://eips.ethereum.org/EIPS/eip-5564)
338
+
339
+ ### Ethereum's roadmap
340
+ - [pq.ethereum.org](https://pq.ethereum.org/) — EF Post-Quantum team
341
+ - [lean Ethereum announcement](https://blog.ethereum.org/2025/07/31/lean-ethereum)
342
+ - [leanEthereum GitHub organisation](https://github.com/leanEthereum)
343
+ - [strawmap.org](https://strawmap.org/) — EF Protocol Architecture roadmap
344
+
345
+ ### Other
346
+ - [Google Quantum AI: safeguarding cryptocurrency](https://research.google/blog/safeguarding-cryptocurrency-by-disclosing-quantum-vulnerabilities-responsibly/)
347
+ - [NIST Post-Quantum Cryptography Project](https://csrc.nist.gov/projects/post-quantum-cryptography)
348
+ - [pqaudit.org](https://pqaudit.org/) — independent PQC standards/audit-firm index
1568
349
 
1569
350
  ---
1570
351
 
1571
352
  ## Document Maintenance
1572
353
 
1573
- **Version:** 1.2
1574
- **Last Updated:** 2026-03-21
1575
- **Next Review:** 2026-09-21 (6 months)
354
+ **Version:** 2.1
355
+ **Last Updated:** 2026-09-13
356
+ **Next Review:** 2027-03-13 (6 months, or sooner if the Hegotá fork's EIP-8141 status changes)
1576
357
  **Maintained By:** Julien Béranger ([@julienbrg](https://github.com/julienbrg))
1577
358
 
1578
359
  **Changelog:**
360
+ - 2026-09-13: Added "Roadmap maturity: closing the gaps" — internally-owned review checkpoints, a labeled not-yet-implemented crypto-agility target design, a draft operational runbook (testnet dry run, ML-KEM context rotation, fail-closed hybrid verification, no global cutover), and a dependency PQ-posture table (`mlkem`, `ethers`, WebAuthn/FIDO2), per NIST SP 1800-38 and CISA quantum-readiness guidance
361
+ - 2026-09-13: Complete rewrite aligned with the Ethereum Foundation's public post-quantum roadmap (pq.ethereum.org, the lean Ethereum announcement, and the EIPs cited above)
362
+ - Replaced speculative/unverifiable content (interim ERC-4337 PQ verifier contracts, unconfirmed testnet addresses) with Ethereum's actual documented roadmap (lean Ethereum, leanXMSS, leanVM, EIP-8141, fork milestones)
363
+ - Added an explicit action-trigger table: what w3pk does, and when, gated on EIP-8141 reaching mainnet with a working PQ verification path
364
+ - Replaced the "Ethereum quantum resistance roadmap" tweet citation with the EF's actual public sources (pq.ethereum.org, lean Ethereum blog post, strawmap.org)
365
+ - Corrected the ML-KEM "future" backup/stealth-address examples that referenced a nonexistent `@kohaku-eth/ml-kem` package — w3pk's `mlkemEncrypt`/`mlkemDecrypt` already is that hybrid scheme, using the shipped `mlkem` npm package
366
+ - Added a dedicated "what w3pk is deliberately not doing yet" section explaining why no interim PQ signature infrastructure is being built
1579
367
  - 2026-03-21: Added ML-KEM encryption utilities with deterministic key derivation
1580
- - Documented `deriveMLKemKeypair()` function for HKDF-based key derivation from private keys
1581
- - Documented `mlkemEncryptWithKey()` and `mlkemDecryptWithKey()` convenience functions
1582
- - Documented `mlkemEncrypt()` function for direct post-quantum encryption
1583
- - Documented `mlkemDecrypt()` function for decryption
1584
- - Added security properties and comprehensive API reference
1585
- - Linked to NIST FIPS 203 (ML-KEM) standard
1586
- - 2026-02-27: **Updated to align with [Ethereum quantum resistance roadmap](https://x.com/VitalikButerin/status/2027075026378543132)** (February 2026)
1587
- - Added Ethereum's four quantum-vulnerable components
1588
- - Integrated [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141) (native AA) as long-term solution
1589
- - Added validation frames + STARK aggregation approach
1590
- - Updated gas cost estimates for EIP-8141 (near-zero with aggregation)
1591
- - Added hash function selection discussion ([Poseidon2](https://eprint.iacr.org/2023/323)/[Poseidon1](https://eprint.iacr.org/2019/458)/[BLAKE3](https://github.com/BLAKE3-team/BLAKE3))
1592
- - Clarified w3pk uses [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) as interim solution until [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141)
1593
- - Added Phase 4.1: Migration to validation frames
1594
- - Added active links throughout document for all standards, specifications, and resources
1595
- - 2026-02-26: Initial version, comprehensive quantum readiness assessment
1596
- - 2026-02-26: Added [Kohaku](https://github.com/ethereum/kohaku) pq-account integration plan
1597
- - 2026-02-26: Defined 4-phase migration roadmap with timelines
368
+ - 2026-02-27: Updated to reference Ethereum's quantum roadmap; added EIP-8141 discussion
369
+ - 2026-02-26: Initial version
1598
370
 
1599
371
  ---
1600
372
 
1601
373
  ## Questions or Feedback?
1602
374
 
1603
- If you have questions about w3pk's quantum readiness:
1604
-
1605
375
  1. Open an issue: [GitHub Issues](https://github.com/w3hc/w3pk/issues)
1606
376
  2. Join the discussion: [Element Matrix](https://matrix.to/#/@julienbrg:matrix.org)
1607
- 3. Email: See [README.md](../README.md) for contact details
1608
-
1609
- **Remember:** Quantum computing is an exciting challenge, not a panic-inducing crisis. We're prepared. 🔐
377
+ 3. Email: see [README.md](../README.md) for contact details