8.2 KiB
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 недель.