From 5bfb415830d3f3604518fb5749759d2dfb611724 Mon Sep 17 00:00:00 2001 From: randogoth Date: Sat, 26 Sep 2026 16:41:16 +0300 Subject: [PATCH] docs: reserve Reply-To and document sender anonymity for receivers --- README.md | 2 ++ SPEC.md | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5d95c46..bb85d43 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ The short form is typeable. The long form carries the key itself, so an address Keys learned from a server are pinned on first use. Later changes need a rotation certificate signed by the previous key, or explicit confirmation. +Recipients learn only the sender's key, never a name: a first contact arrives as a bare fingerprint until its address is known. A client may carry its full `smol://` address in a signed `Reply-To` field so first contacts can be answered; receivers bind it only when its key matches the message's signer (SPEC.md §5.7). + ## Cryptography Ed25519 · X25519 · ChaCha20-Poly1305 · SHA-256. Four established primitives, no novel cryptography, nothing else anywhere in the protocol. Transport is TCP with a Noise handshake — no certificates, no CA, no expiry. diff --git a/SPEC.md b/SPEC.md index 41ae165..aa9dc48 100644 --- a/SPEC.md +++ b/SPEC.md @@ -135,7 +135,7 @@ Body text starts here. One `Key: value` per line. Key is 1–64 bytes of `[A-Za-z0-9-]`; value is the remainder of the line after `:`, trimmed of surrounding spaces. No nesting, arrays, multi-line values, quoting, comments or type coercion. Where a key repeats, the first occurrence wins. Maximum 4 KiB and 64 keys. A malformed line invalidates the whole block, which is then displayed as ordinary body text — frontmatter fails closed toward display, never toward silent discard. -`Subject` and `In-Reply-To` (a message id as 32 lowercase hex characters) are reserved. Unknown keys MUST be preserved, MAY be displayed, and MUST NOT alter client behaviour. A body whose text genuinely begins with `---` is escaped by emitting an empty block first. +`Subject`, `In-Reply-To` (a message id as 32 lowercase hex characters) and `Reply-To` (§5.7) are reserved. Unknown keys MUST be preserved, MAY be displayed, and MUST NOT alter client behaviour. A body whose text genuinely begins with `---` is escaped by emitting an empty block first. **This grammar is not YAML; do not use a YAML parser.** It is flat so that a correct parser is twenty dependency-free lines, in a code path that handles attacker-controlled input. @@ -143,6 +143,12 @@ One `Key: value` per line. Key is 1–64 bytes of `[A-Za-z0-9-]`; value is the r Because `esk` is wiped, a sender cannot decrypt what they sent. To keep a Sent folder, a client seals a second copy of the payload to the sender's own identity key with a fresh ephemeral and stores it locally. This is a client convention and involves no server. +### 5.7 Sender addresses + +Nothing on the wire names a sender. A receiver learns only the signing key of §5.3, so a first contact is identified by nothing but its fingerprint, and replying needs an address the sender supplied somewhere: out of band, or in the message itself. + +Like the sent copies of §5.6 this is a client convention and involves no server: a sender MAY include a `Reply-To` field holding its own full `smol://` address. The value sits inside the sealed, signed payload, so the signature binds the claim. A receiver that acts on it MUST check that the key carried in the URI equals the message's `sender`, MUST treat anything else as ordinary text, and MUST NOT let it replace a key already bound to that address (§8) — it is a first-contact aid, not a trust upgrade. + ## 6. Operations | Type | Op | Auth | Request → response | @@ -202,6 +208,7 @@ A client MUST likewise retain every private key it has rotated away from. Sealin | --- | --- | | Home server key from a trusted channel | Authenticated, pinned, mismatch detected | | Contact key from `smol://` or a QR code | Strong; requires no server trust | +| Sender's `Reply-To` field, key equal to the signer (§5.7) | Strong; the sender's own signed claim, but never overrides a pinned key | | `RESOLVE` over a pinned session | Trust on first use, as good as that server | | `RESOLVE` over an unpinned session | Trust on first use, interceptable at first contact; MUST be shown as unverified | | Key change with a valid chain | Accepted, surfaced in the interface |