feat: implement YAW/2.1 forward-secret signaling

Upgrades the signaling layer from static X25519 (2.0) to per-session
ephemeral X25519 (2.1). Recorded signaling traffic cannot be decrypted
even if long-term Ed25519 keys later leak, because esk is zeroed on
session close.

Protocol:
- Each peer generates a fresh X25519 keypair (esk/epk) per session.
- Peers exchange signed `ekey` messages sealed under static keys before
  the offer/answer. Offer/answer/candidate payloads are then sealed with
  ephemeral keys (crypto_box(·, peer_epk, my_esk)).
- ekey sig binds both peer IDs and the epk to prevent replay to third parties.
- Offerer waits up to 2 s for the peer's ekey; if none arrives it falls back
  to YAW/2.0 static-key sealing and logs "2.0 fallback offer".
- 2.0 peers silently ignore the unknown `ekey` kind — full interop preserved.

Implementation:
- crypto.go: add EphemeralKey.PublicRaw/PrivateRaw/Wipe helpers.
- proto.go: add SigEkey kind; EPK/V/EkeySig fields on SignalingPayload.
- anchor/client.go: replace flat pcs map with peerSession struct tracking
  ephemeral keys, peerEPK, and fs flag; openBoxAuto tries ephemeral then
  static; sealAndSend chooses seal based on session state.
- test-network.sh: pipe daemon stderr through tee to daemon.log; add
  YAW/2.1 FS verification section.
- test-tui.sh: same daemon.log capture.
- README.md: document 2.1 forward secrecy, file transfer IPC, updated roadmap.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Fredrik Johansson
2026-06-22 14:45:15 +02:00
parent 13b30ca0cb
commit 274ff423f6
6 changed files with 375 additions and 64 deletions

View File

@@ -100,17 +100,20 @@ ANCHOR_URL="ws://127.0.0.1:${ANCHOR_PORT}/ws"
# Daemons
"$DATA_ROOT/bin/waste-daemon" -alias alice -data-dir "$DATA_ROOT/alice" \
-ipc-port "$ALICE_IPC" -anchor "$ANCHOR_URL" \
-share-dir "$DATA_ROOT/alice/share" 2>/dev/null &
-share-dir "$DATA_ROOT/alice/share" \
2>"$DATA_ROOT/alice/daemon.log" &
PIDS+=($!)
"$DATA_ROOT/bin/waste-daemon" -alias bob -data-dir "$DATA_ROOT/bob" \
-ipc-port "$BOB_IPC" -anchor "$ANCHOR_URL" \
-share-dir "$DATA_ROOT/bob/share" 2>/dev/null &
-share-dir "$DATA_ROOT/bob/share" \
2>"$DATA_ROOT/bob/daemon.log" &
PIDS+=($!)
"$DATA_ROOT/bin/waste-daemon" -alias charlie -data-dir "$DATA_ROOT/charlie" \
-ipc-port "$CHARLIE_IPC" -anchor "$ANCHOR_URL" \
-share-dir "$DATA_ROOT/charlie/share" 2>/dev/null &
-share-dir "$DATA_ROOT/charlie/share" \
2>"$DATA_ROOT/charlie/daemon.log" &
PIDS+=($!)
wait_port "$ALICE_IPC"