- Add hkdf = "0.12" dependency for Double Ratchet key derivation
- Extend mesh/crypto.rs with hkdf_sha256, hkdf_sha256_32, hkdf_sha256_64,
and generate_x25519_ephemeral() for DH ratchet steps
- Create mesh/x3dh.rs: full X3DH key agreement protocol
- PrekeyBundle generation with Ed25519-signed prekeys
- 3-way (or 4-way) ECDH → HKDF-SHA256 → root key
- Initiator and responder sides derive identical root key
- CBOR encoding for mesh transmission
- Bundle signature verification
- 5 unit tests: generate+verify, both-sides-same-key,
without-one-time-prekey, cbor-roundtrip, tamper-detection
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
139 lines
6.2 KiB
Markdown
139 lines
6.2 KiB
Markdown
# Phase 3 & 4: Encrypted Mesh Messaging + Off-Grid Bitcoin Operations
|
|
|
|
## Context
|
|
|
|
Phase 1 built the mesh radio layer (Meshcore protocol, serial driver, basic chat). Phase 2 added transport abstraction (Mesh>LAN>Tor routing, CBOR delta sync, Reed-Solomon chunking). Current encryption is static X25519 shared secret per peer — no forward secrecy, no message type discrimination, no store-and-forward.
|
|
|
|
Phase 3 adds Signal-style Double Ratchet for forward secrecy, typed messages (ALERT, INVOICE, COORDINATE, PSBT_HASH), and store-and-forward relay. Phase 4 adds off-grid Bitcoin operations: block header relay, transaction relay, Lightning invoice relay, and emergency alert system with dead man's switch.
|
|
|
|
## Dependencies to Add
|
|
|
|
```toml
|
|
hkdf = "0.12" # KDF for Double Ratchet chains
|
|
lightning-invoice = "0.34" # BOLT11 parsing (LDK standard, MIT)
|
|
```
|
|
|
|
Custom Double Ratchet from existing crypto (ed25519-dalek, curve25519-dalek, chacha20poly1305, sha2, hmac) — no DR crate needed.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
mesh/
|
|
├── x3dh.rs — X3DH key agreement (prekey bundles, 3-way ECDH)
|
|
├── ratchet.rs — Double Ratchet state machine (forward secrecy)
|
|
├── session.rs — Per-peer session manager (ratchet state persistence)
|
|
├── prekey.rs — Prekey store (signed + one-time prekeys, rotation)
|
|
├── message_types.rs — Typed message envelope (TEXT/ALERT/INVOICE/COORDINATE/PSBT_HASH)
|
|
├── outbox.rs — Store-and-forward queue (24h TTL, relay hops)
|
|
├── bitcoin_relay.rs — TX relay, Lightning relay, block header announce
|
|
├── alerts.rs — Emergency alerts, dead man's switch
|
|
└── (existing files extended: crypto.rs, listener.rs, types.rs, mod.rs)
|
|
```
|
|
|
|
## Implementation Steps
|
|
|
|
### Week 1: X3DH + HKDF Foundation
|
|
|
|
**New**: `mesh/x3dh.rs`, `mesh/prekey.rs`
|
|
**Modify**: `Cargo.toml` (+hkdf), `mesh/crypto.rs`, `mesh/mod.rs`
|
|
|
|
- `PrekeyBundle`: identity_key + signed_prekey + one_time_prekeys (CBOR, ~200B)
|
|
- `PrekeyStore`: disk persistence at `{data_dir}/prekeys/`, rotation, consumption
|
|
- X3DH: 3-way ECDH → HKDF-SHA256 → root key for Double Ratchet
|
|
- ARCHY:3 identity broadcast with embedded prekey bundle
|
|
|
|
### Week 2: Double Ratchet Protocol
|
|
|
|
**New**: `mesh/ratchet.rs` (~500 LOC), `mesh/session.rs` (~300 LOC)
|
|
|
|
`RatchetState`: DH ratchet keypair, root key, send/recv chain keys, counters, skipped keys (max 100). HKDF-SHA256 chains + ChaCha20-Poly1305 per-message.
|
|
|
|
Wire format: 40B header (DH pub + counters) + 12 nonce + ciphertext + 16 tag = 68B overhead. Single frame: 64B plaintext. Chunked: ~2.4KB.
|
|
|
|
`SessionManager`: HashMap<DID, RatchetState>, lazy load from `{data_dir}/ratchet/{did_hash}.json`. Backward compat: falls back to static shared secret for ARCHY:2 peers.
|
|
|
|
### Week 3: Typed Messages + Store-and-Forward
|
|
|
|
**New**: `mesh/message_types.rs`, `mesh/outbox.rs`
|
|
**Modify**: `mesh/types.rs`, `mesh/listener.rs`
|
|
|
|
CBOR envelope: `[0x02] [{ t: u8, v: bytes, ts: u32, sig?: bytes }]`
|
|
|
|
Types: TEXT(0), ALERT(1), INVOICE(2), PSBT_HASH(3), COORDINATE(4), PREKEY_BUNDLE(5), SESSION_INIT(6)
|
|
|
|
GPS as `Coordinate { lat_microdeg: i32, lng_microdeg: i32 }` — integer only, no float.
|
|
|
|
`MeshOutbox`: VecDeque, 24h TTL, max 3 relay hops, disk persistence. Checked every 10s tick.
|
|
|
|
### Week 4: RPC Endpoints + Session Bootstrap
|
|
|
|
**Modify**: `api/rpc/mesh.rs`, `api/rpc/mod.rs`, `mesh/listener.rs`
|
|
|
|
New RPC: `mesh.send-invoice`, `mesh.send-coordinate`, `mesh.send-alert`, `mesh.outbox`, `mesh.session-status`, `mesh.rotate-prekeys`
|
|
|
|
Prekey distribution via ARCHY:3 broadcasts. Session init via X3DH on first message to new peer.
|
|
|
|
### Week 5: Off-Grid Bitcoin (Phase 4)
|
|
|
|
**New**: `mesh/bitcoin_relay.rs`, `mesh/block_headers.rs`
|
|
**Modify**: `Cargo.toml` (+lightning-invoice), `api/rpc/mesh.rs`
|
|
|
|
Block header relay: Internet node broadcasts `BlockHeaderAnnouncement` (height, hash, Ed25519 sig) on new block. Mesh-only peers display "SPV sync via mesh".
|
|
|
|
TX relay: Mesh-only node sends raw tx hex → internet peer calls `sendrawtransaction` → returns txid.
|
|
|
|
Lightning relay: Create invoice → send bolt11 → peer pays → proof-of-payment returned.
|
|
|
|
### Week 6: Emergency Alerts + Dead Man's Switch
|
|
|
|
**New**: `mesh/alerts.rs`
|
|
|
|
`DeadManSwitch`: Background task, configurable interval (default 6h), broadcasts signed ALERT with GPS to emergency contacts when triggered. Auto-check-in on any authenticated RPC.
|
|
|
|
RPC: `mesh.alert-configure`, `mesh.alert-checkin`, `mesh.alert-test`, `mesh.alert-status`
|
|
|
|
### Week 7: Frontend
|
|
|
|
**Modify**: `stores/mesh.ts`, `views/Mesh.vue`, `mock-backend.js`
|
|
|
|
Message rendering by type: invoice (orange card + Pay button), alert (red card), coordinate (blue card + OSM link), psbt_hash (gray card + Review).
|
|
|
|
Session indicator: shield icon (green=ratchet, yellow=static, gray=none).
|
|
|
|
Block height in off-grid banner. Alert config panel. Dead man switch toggle.
|
|
|
|
### Week 8: Integration Test + Deploy
|
|
|
|
E2E on .228 (internet) + .198 (mesh-only): X3DH handshake, 50-message ratchet, invoice relay, TX relay, block headers, dead man switch. Deploy to both servers.
|
|
|
|
## New Files (8)
|
|
|
|
1. `core/archipelago/src/mesh/x3dh.rs`
|
|
2. `core/archipelago/src/mesh/prekey.rs`
|
|
3. `core/archipelago/src/mesh/ratchet.rs`
|
|
4. `core/archipelago/src/mesh/session.rs`
|
|
5. `core/archipelago/src/mesh/message_types.rs`
|
|
6. `core/archipelago/src/mesh/outbox.rs`
|
|
7. `core/archipelago/src/mesh/bitcoin_relay.rs`
|
|
8. `core/archipelago/src/mesh/alerts.rs`
|
|
|
|
## Modified Files (8)
|
|
|
|
1. `core/archipelago/Cargo.toml` — +hkdf, +lightning-invoice
|
|
2. `core/archipelago/src/mesh/crypto.rs` — +hkdf_sha256, +ephemeral keygen
|
|
3. `core/archipelago/src/mesh/types.rs` — +message_type, +typed payloads
|
|
4. `core/archipelago/src/mesh/listener.rs` — typed dispatch, session bootstrap, relay
|
|
5. `core/archipelago/src/mesh/mod.rs` — new submodules, new MeshService methods
|
|
6. `core/archipelago/src/api/rpc/mesh.rs` — ~12 new RPC endpoints
|
|
7. `core/archipelago/src/api/rpc/mod.rs` — register new routes
|
|
8. `neode-ui/src/views/Mesh.vue` — typed rendering, alert UI, session badges
|
|
|
|
## Verification
|
|
|
|
```bash
|
|
cargo test --all-features -- mesh::ratchet mesh::x3dh mesh::session
|
|
cargo clippy --all-targets --all-features
|
|
cd neode-ui && npm run type-check
|
|
./scripts/deploy-to-target.sh --both
|
|
```
|