# quacker ④+① 実装設計 — master_seed custody/復旧 + did:webvh identity 親 = direction 決定 `n_01KSZE9ARMR9H8Y7Y9T5APMRW4`。本 post は実装設計の正本(不可逆前提 + 既存資産前提 + build 順)。`docs/e2e-implementation-design.md` への追記の下書きを兼ねる。 ## 不可逆な前提(確定・変更不可) - **Tier0 frozen**:X25519 per-group 派生 `HKDF-SHA256(seed, "quacker.x25519.group:"+group_id, salt=none)` → x25519 clamp → age bech32(`keys.rs` / `e2e-implementation-design.md §1`)。触らない。SPA への TS port は **byte 一致 + cross-impl golden vector 必須**。 - **D-A 確定**:Ed25519 identity 派生 `HKDF-SHA256(seed, "quacker.ed25519.identity:v1", salt=none)` → 32B → Ed25519 署名鍵。X25519 と domain 分離・**additive**(既存 X25519 を壊さない)。version 付き(回転=`:v2` + did:webvh update + pre-rotation)。 - **D-B 確定**:復旧は 2 部 — 鍵=seed(BIP-39、決定論)/ DID identity=event log(inception entry の versionTime は seed から再現不可、SCID が timestamp を hash する)。versionTime を seed 由来にする hack はしない(spec 違反)。owner の手控え = **BIP-39 のみ**、DID は event log backup に乗る。 ## 既存資産前提(コスト削減 ~6-7 割) - 暗号/envelope:**age + typage**(`age-encryption` は既に SPA 依存、Rust 0.11 と同フォーマット)。 - 派生/復旧:**`@noble/hashes`(HKDF)+ `@scure/bip39` + `@noble/curves`(x25519/ed25519)**、Rust は `hkdf`/`x25519-dalek`/`ed25519-dalek`/`bip39`。RFC 決定論で Rust↔JS 一致(label/param 固定 + golden vector)。 - passkey:typage `age.webauthn`(PRF native)+ `@simplewebauthn`。**PRF は client 完結 = server 無関与**。 - 保管:**non-extractable CryptoKey + `idb-keyval`**(XSS 耐性)。 - ① log:**`didwebvh-rs`**(DIF、mint/update/rotate/pre-rotation/verify をライブラリ化、pluggable signer)。`ssi` 全部 / Veramo は過剰で不採用。 ## 可逆(今ロックしない・lean) - custody envelope = **age 中心(2 段:unlock-key を passphrase-blob と passkey/recovery-blob に分置)** ← scrypt 排他制約の回避。後で WebCrypto-vault に変更可。 - unlock = **passphrase 一級常設 + PRF 日和見**(Linux/Bitwarden の PRF 穴を回避)。multi-KEK で後から増減自由。 - seed を browser に保持(wrapped、unlock 時のみメモリ展開)= 現「POST 後 null」姿勢の反転を許容。平文 seed は不揮発化しない。 ## build 順(残作業) 1. **④ custody/復旧(L・最大)**:seed→鍵派生 TS port(keys.rs と byte 一致 + cross-impl golden vector)/ BIP-39 / age 2 段 envelope / non-extractable CryptoKey + IndexedDB / passphrase 一級・PRF 日和見 unlock UX。→ SPA decrypt(PR #255 配線)が実際に動く。複数デバイス(QR mnemonic)は follow-up。 2. **① did:webvh(M)**:seed→Ed25519(D-A)→ `didwebvh-rs` で inception mint(pre-rotation ON / witness OFF)、`did.jsonl` を axum self-serve。owner_did と DID を併走(rewrite まだ)。 3. **D-C migration(M・one-shot, gated)**:owner_did→did:webvh を event log で clean rewrite(旧 log 保持で rollback)。④+① 完了後・最後。 4. **② OAuth 降格 + 鍵 challenge ログイン + atrium-* 撤去(M)**。 ## open - Q1:既存 encrypted post 件数(classifier 復旧後 run_sql)。 - D-C 詳細(① の段で)。 - cross-impl golden vector の具体値(④ で確定)。 参照 memory:`project_quacker_identity_account_direction` / `project_quacker_e2e_master_seed`。