From 6cf21a019963468cb853e5c763ef0097115efa46 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Thu, 10 Sep 2026 17:30:22 +0200 Subject: refactor(common): delete the sender-key implementation nothing uses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `senderkeys.py` and its 13 tests implemented Signal-style sender keys, and production has never called them: chat is a key per group, per epoch, per device, derived by name. The reasoning that ruled the ratchet out stays where it belongs — in `chatbox.py`, at the top of the module that replaced it — because the argument is the useful part, and it now stands on its own instead of pointing at a file to compare against. Kept code that nothing calls is worse than absent code: it reads as an alternative somebody may reach for, and it has to be maintained past every refactor to stay compiling, which is maintenance spent on a decision already made. The three comments naming `GroupSenderKeyStore` are rewritten to say the thing they were illustrating. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01AsoWC3GmhNdwVFomW3QjH3 --- packages/meshbay-common/src/meshbay_common/chatbox.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'packages/meshbay-common/src/meshbay_common/chatbox.py') diff --git a/packages/meshbay-common/src/meshbay_common/chatbox.py b/packages/meshbay-common/src/meshbay_common/chatbox.py index f3cfc76..740e829 100644 --- a/packages/meshbay-common/src/meshbay_common/chatbox.py +++ b/packages/meshbay-common/src/meshbay_common/chatbox.py @@ -4,13 +4,13 @@ Chat message encryption and sender authentication. Design A of `docs/chat-sender-keys.md`, decided 2026-09-07. What it is, and what it deliberately is not, in the order the decisions were made: -**Not a ratchet.** `senderkeys.py` implements Signal-style sender keys and is -unused by production. With sender keys distributed under the group key and a -node that serves history to devices which were not present, the node must retain -and hand out each chain's *earliest* key — and a chain key at iteration *i* -yields every message key from *i* onward by pure HKDF. Forward secrecy is then -zero, and the ratchet is computing HKDF over a value every member already holds. -The property is given up on the record rather than inherited by accident. +**Not a ratchet, and not sender keys.** With per-sender chains distributed under +the group key, and a node that serves history to devices which were not present, +the node must retain and hand out each chain's *earliest* key — and a chain key +at iteration *i* yields every message key from *i* onward by pure HKDF. Forward +secrecy is then zero, and the ratchet is computing HKDF over a value every +member already holds. The property is given up on the record rather than +inherited by accident. **A key per group, per epoch, per device.** The node generates an epoch key and delivers it to members wrapped under the current group key. Each device derives @@ -18,9 +18,8 @@ its *own* subkey from it, by name, so: * two *keys* never share a subkey, and — the part that actually matters — **there is no mutable sending state at all**, so nothing can be advanced - twice. §15.0b wanted per-device chains because two devices advancing one - chain produce key and nonce reuse (C1, one level down, and exactly what - `GroupSenderKeyStore` got wrong). Derivation plus a *random* nonce removes + twice. Two devices advancing one chain produce key and nonce reuse, which is + the failure this design cannot have; derivation plus a *random* nonce removes the hazard rather than partitioning it; Be precise about what that does **not** say, because the obvious stronger -- cgit v1.2.3