OverviewFilesCommitsIssuesDocsReleasesPeers

keet-daemon commits / eff6453

CPP-PORT-DESIGN: M5g-4e-3 design — ss/noise, ss/duplex (streamx core), ss/secret-stream
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
eff64538cf3eb5db7380802a21d8b7fc77b7385e
by plankatron <fleeky@gmail.com> · 2026-10-04T17:12:03.000Z

Changed files (1) +46 -0

docs/CPP-PORT-DESIGN.md +46 -0
……@@ -2667,6 +2667,52 @@ SessionState's truncate / reorg / named-session machinery.
26672667 sets it before `send`);
26682668 - JS ↔ keetd over a pipe in both directions: XX, the `handshake` option, keepalive,
26692669 timeout, a bad header, a tampered frame, `send`.
2670 - **4e-3 design (2026-10-04).**
2671 - **Read in full:**
2672 - @hyperswarm/secret-stream 6.9.2 (index, lib/handshake, lib/bridge);
2673 - noise-handshake 4.2.0 (noise, symmetric-state, cipher, hkdf, hmac, dh);
2674 - noise-curve-ed 2.1.0;
2675 - sodium-secretstream 1.2.0: a thin wrapper over libsodium's
2676 `crypto_secretstream_xchacha20poly1305`, so keetd calls libsodium directly and gets
2677 the same bytes;
2678 - timeout-refresh 2.0.1;
2679 - hypercore-crypto 3.7's `namespace`;
2680 - streamx 2.28.1's Duplex core (index.js 1–1087, lib/errors.js).
2681 - **User decision: the streamx Duplex CONTRACT only.**
2682 - streamx's Duplex core is a bit-flag state machine: WritableState / ReadableState
2683 update loops, the after* callbacks, `destroy` / `_predestroy`, and `newListener`'s
2684 'data' / 'readable' / 'drain'. It is ported LITERALLY (the same flags), which is more
2685 faithful and smaller than re-deriving it.
2686 - NOT ported: pipe / Pipeline, Transform, `from` / async iterators, `setEncoding`,
2687 `map`.
2688 - It runs on an `ss::Loop`: a microtask queue (qmt) plus timers with `refresh` on the
2689 Clock.
2690 - **Randomness, injectable (`ss::Random`).** There are four sources: the static key pair
2691 (`Handshake.keyPair()`), the ephemeral (`curve.generateKeyPair()`), the Push header
2692 (`init_push`), and the send counter (`randombytes`).
2693 - The JS harness patches sodium the same way. `init_push` with a fixed header equals
2694 `init_pull` on that header (libsodium's own derivation).
2695 - Byte-exact transcripts are compared JS vs keetd.
2696 - **Sub-milestones, each with its gate and drill:**
2697 - **4e-3a `ss/noise`:** noise-handshake's whole surface. Patterns NN / NNpsk0 / XX /
2698 XXpsk0 / IK / XK, psk, prologue, preshared keys; both curves (dh.js X25519 and
2699 noise-curve-ed Ed25519); HKDF-expand's double `info`; the 65535 cap; "Insufficient
2700 bytes" / decrypt failures. Gate: vectors from JS with fixed statics and preset
2701 ephemerals, every pattern both ways, mutated messages.
2702 - **4e-3b `ss/duplex`:** the streamx Duplex core. Gate: an event-trace harness. One op
2703 script drives a JS Duplex subclass and keetd's: write / end / push / destroy / pause /
2704 resume / listeners, plus when `_open` / `_write` / `_read` / `_final` / `_destroy`
2705 call back. The ordered events and callbacks must be identical.
2706 - **4e-3c `ss/secret-stream`:**
2707 - `Handshake`;
2708 - `NoiseSecretStream` over a Duplex, with a raw-stream interface (write → drained,
2709 end, destroy, pause / resume, optional setContentSize / send / trySend);
2710 - Bridge;
2711 - keepalive / timeout, header verification, the send box, toJSON, the statics.
2712
2713 Gates: vectors (deterministic, byte-exact wire transcripts for XX and the `handshake`
2714 option), then JS ↔ keetd over a raw pipe in both directions with real randomness,
2715 plus the destroy and timeout paths.
26702716 - **4e-4, `createProtocolStream` / `getProtocolMuxer` / `replicate`.**
26712717 - The four `isInitiator` forms: a muxer, an existing stream, `opts.stream`, or a bool
26722718 → a new NoiseSecretStream.