Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Title: Wallet creation + recovery (2-of-3, user+server+guard) Status: draft (superseded by cloud-backup decision, оставляем как архив) Owner: <ник> Goal: Описать опциональный флоу кошелька с recovery через 2/3 SSS: шард пользователя, E2E-зашифрованный шард на сервере, шард гварда. Сервер не способен восстановить без участия гварда/пользователя.

Decisions:

  • Active: wallet/decisions/decision-2026-01-17-cloud-backup-supersedes-sss.md (cloud backup заменяет этот флоу).
  • Archive: wallet/decisions/decision-2026-01-13-recovery-2of3.md, wallet/decisions/decision-2026-01-14-sss-format-and-oob.md.

Open questions (если вернёмся к 2-of-3):

  • Формат SSS-конверта: точный layout/AAD, тест-векторы, негативные тесты на подмену metadata.
  • Протокол E2E: Noise/X3DH детали, double-wrapping S-shard (кто чей pubkey использует, ротация).
  • UX гварда: OOB-канал, подтверждение/отклонение, таймауты, rate-limit попыток.
  • Replay/abort: как инвалидировать старые recovery sessions, защита от re-play уведомлений гварду.
  • Хранение и удаление: сроки retention S-shard ciphertext, когда подчистка, аудит действий.
  • Device posture: требования к устройству гварда (TEE/KeyStore/SE, KDF параметры), политика при смене устройства.
  • KYC/антириск: кто источник, какие сигналы, частота повторного KYC.

Roles:

  • User (U) — владелец кошелька, генерирует сид, держит шард U.
  • Server (S) — курьер шифртекста для шарда S; не имеет ключей к расшифровке.
  • Guard (G) — доверенное лицо/устройство, держит шард G, подтверждает recovery, тревожит владельца.
  • KYC provider — даёт сигнал допуска (не даёт ключи).

Invariants (must hold):

  • Non-custodial: сервер не видит сид/приватные ключи; хранит только шифртекст шарда S и метаданные.
  • SSS k=2, n=3 (classic Shamir): любые 2 из 3 восстанавливают секрет.
  • Share binding: шарды всегда упакованы в аутентифицированную обёртку (AEAD) с wallet_id/sss_profile_id/version/role/index (нельзя незаметно перемешать шарды между кошельками/сессиями).
  • E2E: шарды S и G всегда в шифре под ключи получателей; локальный KDF (Argon2id) + AES-GCM/ChaCha20-Poly1305.
  • Recovery требует участия G (OOB подтверждение) и сессионного ключа U; KYC — только сигнал, не ключ.
  • Таймауты сессий, аудит событий; без участия G и U сервер не способен инициировать/завершить recovery.

Terminology:

  • OOB (out-of-band) подтверждение: гвард подтверждает recovery по независимому каналу (звонок/код/мессенджер/второе устройство), чтобы проверить запрос и тревожить владельца при атаке.

Flow A — обычный кошелёк (без шардов):

  1. U генерирует seed (12/24), локально шифрует бэкап (пароль→Argon2id→AES-GCM).
  2. Нет шардов, нет серверных копий. Потеря seed = невосстановимо.

Flow B — кошелёк с recovery 2/3: Creation:

  1. U генерирует seed локально.
  2. Split seed → classic Shamir SSS 2/3: U-shard, S-shard, G-shard.
  3. U-shard: хранится локально, шифруется паролем (Argon2id).
  4. S-shard: шифруется E2E под pubkey U_recovery и pubkey G (двойное обёртывание или гибрид), отправляется и хранится на сервере как шифртекст. Метаданные: wallet_id, sss_profile_id, sss_format_version, k/n, share_index, guard_id, статус.
  5. G-shard: хранится у гварда локально, шифруется паролем/био-гейтом + KDF.

Recovery (когда утеряно устройство U):

  1. U с новым устройством создаёт recovery session, публикует сессионный pubkey, проходит KYC (сигнал допуска/антириск).
  2. Сервер уведомляет G о запросе (push). G выполняет OOB проверку (звонок/мессенджер/код).
  3. G разблокирует G-shard (паскод+био), шифрует под сессионный pubkey U, отправляет по E2E.
  4. Сервер отдаёт S-shard шифртекст (у него нет ключей), U расшифровывает S-shard локально своим recovery key (который сервер не знает).
  5. U объединяет любые 2 из 3 (обычно G-shard + S-shard) → получает seed → импортирует кошелёк.
  6. Сессия закрывается, сессионные ключи стираются, событие аудита фиксируется.

Anti-abuse / внутренний атакующий:

  • Сервер не имеет ключей для S-shard; без G участие невозможно завершить recovery.
  • Любая попытка «тихого» запуска recovery требует G-активации, которая тревожит владельца.
  • Rate-limit/таймаут recovery-сессий; логирование событий recovery_requested, guard_approved/denied, recovery_completed/failed.

Риски и митигация (остаточные):

  • Компрометация устройства G или слабый KDF → оффлайн-брут G-shard. Требуется жёсткий KDF/био-гейт и защитное хранилище (TEE/KeyStore/Secure Enclave).
  • Социнжиниринг G: смягчать OOB-подтверждением и уведомлением владельца.
  • Потеря и U-shard, и G-shard одновременно при недоступности S-shard → невосстановимо.