Group messaging combines sender keys — one symmetric chain per member's
outbound traffic, ratcheted forward through
HKDF every message — with post-quantum rotation: every 100
messages, and on every membership change, a fresh sender key is
encapsulated to each current member via ML-KEM-1024.
Every group message is individually signed under
ML-DSA-87. Removed members cannot decrypt what comes
next; new joiners cannot decrypt what came before.
The construction
SK_{i, n+1} = HKDF(SK_{i, n}, "QERYX_SENDER_KEY_RATCHET_v1", 32)
msg_key_n = HKDF(SK_{i, n}, "QERYX_SENDER_MSG_KEY_v1", 32)
ciphertext = ChaCha20-Poly1305(
key = msg_key_n, nonce = random(12),
aad = group_id || sender_id || index_be32 || epoch_be32)
Bootstrap distributes each member's initial sender key as one
ML-KEM-1024 hybrid ciphertext per recipient, signed under
the sender's identity key. The chain and message-key derivations use
distinct labels, so compromise of one message key reveals neither the
next chain key nor any earlier one — HKDF is one-way in both directions
that matter.
Rotation triggers
- Cadence. Every 100 messages the sender generates a fresh key and re-encapsulates to all current members — post-compromise security at the 100-message boundary, post-quantum because the new distribution rides fresh ML-KEM ciphertexts.
- Membership change. Removal forces rotation before the next outbound message. The new key was never encapsulated to the removed member's KEM key; their old chain ratchets forward into irrelevance.
- Joining is forward-only. A new member receives current-position keys, never past ones. Messages sent before the join are unrecoverable for the joiner — the safe default for a security messenger.
Out-of-order delivery rides a 200-key look-ahead window per (channel, sender) chain; skipped keys are zeroized when consumed or evicted.
Per-message authentication
Every group message carries an individual ML-DSA-87
signature verified against the KTS-bound key for the claimed sender.
This is stronger than shared-key authentication: even if the entire
group's KEM material leaks, forging a message in a member's name still
requires that member's identity secret.
What the server sees
| Visible to the relay | Never visible |
|---|---|
| row counts of distributed key blobs | plaintext of any group message |
| opaque encrypted blob bytes | the relationship between successive sender keys (client-only memory) |
| delivery identifiers needed for fan-out | group names, subjects, avatars — end-to-end encrypted content |
Sender identifiers are stripped from the stored message row per the relay's carrier model; the relay still authenticates the sender at send time, and undelivered messages queue with routing metadata under a published retention ladder. A zero-knowledge membership module exists for high-anonymity deployments and is opt-in, not the default — the honest boundary is stated in §6.
The claims table
| Claim | Mechanism |
|---|---|
| Past messages stay confidential after a sender-key leak | one-way HKDF chain |
| Future messages recover confidentiality after a leak | ML-KEM re-encapsulation every 100 messages |
| Removed members cannot decrypt new traffic | forced rotation to the remaining member set |
| The server cannot decrypt any message | only encapsulated blobs and AEAD ciphertext ever arrive |
| New joiners cannot read history | past sender keys are never re-distributed |
| A stolen sender key cannot forge | per-message ML-DSA-87 identity signature |
Cost at scale: a full rotation for a 100-member group is roughly 600 KiB on the wire once per 100 messages — about 6 KiB per outbound message amortized, the price of post-quantum FS and PCS in groups.
What groups do not defend against
Sender keys bound to a roster answer for the roster. They do not answer for the people on it, and these are the limits that follow from that.
- A compromised member. A current member can leak any plaintext they legitimately received. No group construction defends against this.
- Membership inference at the relay. The default path exposes delivery identifiers to the relay for fan-out. Server-blind membership via the zero-knowledge group module is opt-in for deployments that need it.
References
-
QERYX Protocol Specification §9 —
docs/SPEC/07-group-messaging.md; client implementation in the sender-key service, backend distribution tables in the group migrations. - NIST FIPS 203 (ML-KEM), FIPS 204 (ML-DSA); RFC 8439 (ChaCha20-Poly1305).
- Identity and Key Transparency — the log that authenticates every group signature.