montana/Android/Внешний-аудит/11-Phase2-Integration.md
2026-05-18 22:11:45 +03:00

8.2 KiB
Raw Blame History

11. Phase 2 — TimeChain-Готовая интеграция (v6.6.0)

Дата: 2026-05-18 (продолжение работы после исходного аудит-пакета v6.5.0)

Обзор изменений

Реализована Phase 2 roadmap из 07-Известные-ограничения.md. Часть P0/высоких findings закрыты, ВПН-балансы переведены на production Rust backend с криптографической аутентификацией heartbeat.

Закрытые findings

Finding Статус Доказательство
F-2 Heartbeat без cryptographic auth Закрыто Ed25519 TOFU pinning + nonce-window replay protection crates/mt-vpn-balance/src/main.rs верификация через ed25519-dalek; Android клиент подписывает через BouncyCastle Ed25519
CF-2 Regex JSON парсер Закрыто Rust типизированным serde_json весь backend в strong typed Rust
CF-5 balances.json race Закрыто tokio::sync::Mutex единый writer atomic state.json через tokio::fs::rename
CF-7 silent JSON swallow Закрыто axum Json<T> extractor malformed → 400 авто
F-7 (частично) BIP39 без shielding Ed25519 секрет вычислен от seed через SHA-256 domain separator — детерминирован, не покидает устройство derived через MontanaBridge.setSignerSeed()

Открытые findings (уменьшение severity)

Finding Старая severity Новая severity Reason
F-4 SPOF Moscow Блокер mainnet Высокий (нужна replication) Rust backend атомарен, persistence файл /var/lib/mt-vpn-balance/state.json; replication на узлы остаётся Phase 3
F-reality-pq Низкий Низкий Не изменилось — upstream xray задача

Новые findings от Phase 2

CF-Phase2-1 — Ed25519 НЕ post-quantum (нарушает [I-1])

Severity: средний (acknowledged явно в коде).

Поверхность: crates/mt-vpn-balance/src/main.rs использует ed25519-dalek для signature verification. Ed25519 уязвим к Shor.

Принятие риска:

  • Falcon-512 JNI binding для Android — отдельный milestone M-VPN-3
  • Pure-Kotlin Falcon реализаций не существует production-ready
  • Альтернатива (pure-Rust на устройстве через JNI) — отдельная инженерная работа

Closure path (Phase 4 M-VPN-3):

  • Заменить ed25519-dalek на pqcrypto-falcon в backend
  • Прокинуть Falcon-512 в Android через NDK + JNI wrapper
  • Обновить deriveAddr → включить публичный ключ Falcon в адрес

Cost estimate: 2-3 недели.

CF-Phase2-2 — TOFU pinning не имеет revocation

Severity: средний.

Поверхность: при первом heartbeat backend пинит pubkey. Если устройство утеряно/скомпрометировано — атакующий с украденным seed может присылать valid heartbeats навсегда.

Closure path:

  • Окно для revocation: подписать message "revoke" с владельческим pubkey → backend помечает аккаунт revoked
  • Recovery flow: timeout ≥ 90 дней inactive → разрешить повторное TOFU

Cost estimate: 1 неделя.

CF-Phase2-3 — Replay через нестрого монотонный nonce

Severity: низкий.

Поверхность: nonce_ms — UNIX timestamp клиента. Backend проверяет монотонность (last_nonce_ms < new_nonce_ms) + okno 30s. Если на устройстве сбился час в прошлое — heartbeats не пройдут до синхронизации.

Mitigation: Android System.currentTimeMillis() обычно NTP-синхронизирован. Окно ±30s покрывает дрифт.

Closure path: перейти на counter-based nonce (uint64 счётчик в state, инкрементируется на client). Phase 3.


Архитектурный апдейт

До Phase 2 (v6.5.0)

Android → Reality → Helsinki haproxy → Cascade exit → montana.quest:443 (Moscow nginx)
                                                             ↓
                                          gunicorn (Flask) ← /api/vpn/heartbeat
                                                             ↓
                            balances.json (file LOCK_EX)

Phase 2 (v6.6.0)

Android (v6.6.0)
  ↓ BIP39 mnemonic → PBKDF2 seed → SHA-256 domain "montana-ed25519-v1:" → Ed25519 secret
  ↓ Каждый heartbeat: signature_hex = Ed25519.sign(secret, "montana-heartbeat-v1:" || address || nonce_ms)
  ↓ POST {address, nonce_ms, pubkey, signature}
Reality cascade → exit → Moscow nginx:443
  ↓ proxy_pass http://127.0.0.1:5009
mt-vpn-balance (Rust, axum + tokio + ed25519-dalek)
  ↓ Verify Ed25519 signature against pinned pubkey (TOFU at first hb)
  ↓ Verify nonce_ms in ±30s window AND > last_nonce
  ↓ Atomic state mutation under tokio::sync::Mutex
  ↓ Persistence: state.json with atomic rename

Verification log

Server-side (Rust backend)

$ ssh montana-moscow 'curl -s http://127.0.0.1:5009/api/vpn/stats'
{
  "wallets": 7,
  "total_juno": 34.16235,
  "total_seconds": 34162.35,
  "active_now": 1,
  "signed_accounts": 1,
  "rate_per_second": 0.001
}

signed_accounts: 1 подтверждает что минимум один клиент сейчас отправляет Ed25519-signed heartbeats и backend верифицирует подпись.

Client-side (Pixel 9 Pro XL)

$ adb logcat -d -s MontanaVPN MontanaBridge
MontanaBridge: ed25519 signer initialized
MontanaJS: signer initialized, pubkey=41780d09d41058cb (truncated)
MontanaVPN: hb: 200 via=true node=helsinki bal=3.535794 ...

Pubkey 41780d09d41058cb… детерминирован от BIP39 seed конкретного кошелька — recovery на другом устройстве даст тот же pubkey.

Unit tests Rust backend

$ cargo test -p mt-vpn-balance
running 5 tests
test tests::test_address_validation ... ok
test tests::test_build_message_deterministic ... ok
test tests::test_credited_arithmetic_overflow_safe ... ok
test tests::test_ed25519_signing_roundtrip ... ok
test tests::test_exit_node_label ... ok

test result: ok. 5 passed; 0 failed; 0 ignored

Что осталось до полного closure

Задача Phase Estimated
Replication state на 3 узла Montana M-VPN-1 (продолжение) 3 дня
Falcon-512 JNI замена Ed25519 M-VPN-3 2-3 недели
Новый opcode 0x06 VpnHeartbeat в Montana Protocol v35.26 M-VPN-2 2-3 недели (включая spec patch + mt-account tests)
Encrypted seed через user passcode Phase 2 1 неделя
Backup verify screen Phase 2 1 день
Automated tests recovery determinism Phase 2 2 дня
CI integration Phase 2 2 дня

Обновлённая оценка готовности

Слой v6.5.0 v6.6.0 Mainnet target
Криптография heartbeat ноль Ed25519 TOFU Falcon-512 (PQ)
Backend production Flask MVP Rust axum Replicated на узлы
Atomic concurrency LOCK_EX flock tokio::sync::Mutex Consensus-driven
State persistence balances.json state.json + tokio::fs atomic TimeChain validator state
Tests 0 5 Rust unit tests 50+ tests, integration, e2e
Replication нет нет rsync daily (Phase 3)
Sybil resistance нет TOFU pin + Ed25519 nonce Falcon + consensus

Готовность к mainnet: ~60% (было ~40%). Phase 3 closure cost: 4-5 недель.