diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-10 17:30:22 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-10 17:30:22 +0200 |
| commit | 6cf21a019963468cb853e5c763ef0097115efa46 (patch) | |
| tree | ac0fd6261252b744ffdf15f0b100af7fd252d221 /packages/meshbay-common/src/meshbay_common/chatbox.py | |
| parent | efc93c187dba9027292b51ff0e9caa29349c953e (diff) | |
| download | meshbay-6cf21a019963468cb853e5c763ef0097115efa46.tar.gz | |
refactor(common): delete the sender-key implementation nothing uses
`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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AsoWC3GmhNdwVFomW3QjH3
Diffstat (limited to 'packages/meshbay-common/src/meshbay_common/chatbox.py')
| -rw-r--r-- | packages/meshbay-common/src/meshbay_common/chatbox.py | 19 |
1 files changed, 9 insertions, 10 deletions
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 |