Delete 8 Noise-specific documentation pages (noise-xx.md,
transport-keys.md, adr-001/003/006, framing-codec.md) and update
~30 remaining wiki pages to reflect QUIC+TLS as the sole transport.
Remove obsolete Noise-based integration tests (auth_service.rs,
mls_group.rs). Code-side Noise removal was done in f334ed3.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
12 KiB
Why This Design, Not Signal/Matrix/...
This page compares quicnprotochat's protocol choices against two widely deployed secure messaging systems -- the Signal Protocol and the Matrix ecosystem (Olm/Megolm) -- to explain why a different architecture was chosen. The comparison covers four dimensions: group key agreement, transport, serialisation, and overall trade-offs.
Group key agreement
The choice of group key agreement protocol is the most consequential architectural decision in any end-to-end encrypted group messenger. It determines the cryptographic properties available to the application, the cost of group operations, and the complexity of the client state machine.
Signal Protocol (Double Ratchet + X3DH + Sender Keys)
The Signal Protocol was designed for 1:1 messaging and later extended to groups via Sender Keys.
1:1 (Double Ratchet + X3DH):
- X3DH performs an initial key agreement between two parties using prekey bundles (analogous to MLS KeyPackages).
- The Double Ratchet derives per-message keys using a combination of a Diffie-Hellman ratchet and a symmetric hash ratchet.
- Provides forward secrecy (past messages are protected after key compromise) and post-compromise security (future messages are protected after a compromise is healed by a new DH exchange).
- Well-studied and battle-tested for over a decade. Formal security analysis by Cohn-Gordon et al. (2017).
Groups (Sender Keys):
- Each group member generates a Sender Key and distributes it to all other members via pairwise Double Ratchet channels.
- Sender Keys provide a symmetric ratchet for forward secrecy, but no post-compromise security. If a Sender Key is compromised, all future messages from that sender are compromised until the key is manually rotated.
- Group membership changes require O(n) pairwise Sender Key distributions. Adding or removing a member requires the affected member to generate a new Sender Key and distribute it to all n-1 other members.
- The pairwise key exchange for initial setup is O(n^2): each of n members must establish a Double Ratchet session with each of the other n-1 members.
Limitations for quicnprotochat's use case:
- O(n^2) pairwise setup cost limits practical group size.
- No post-compromise security for groups is a significant gap.
- The protocol requires a central server for X3DH prekey bundle distribution (similar to quicnprotochat's AS, but tightly coupled to the Signal server).
Matrix / Olm / Megolm
The Matrix ecosystem uses two distinct cryptographic protocols:
Olm (1:1):
- An implementation of the Double Ratchet, similar to Signal's 1:1 protocol.
- Used to establish pairwise encrypted channels between devices.
- Provides forward secrecy and post-compromise security for 1:1 sessions.
Megolm (groups):
- A symmetric sender ratchet. Each sender in a group generates a Megolm session and distributes the initial ratchet state to all other members via Olm channels.
- The ratchet is forward-only: it provides forward secrecy (a compromised ratchet state cannot decrypt past messages) but no post-compromise security (a compromised ratchet state decrypts all future messages from that sender until a new Megolm session is created).
- Session rotation is typically triggered by membership changes or periodic timers, but it is not cryptographically enforced.
Additional Matrix-specific considerations:
- Federation adds significant complexity. Messages may traverse multiple homeservers, each of which sees encrypted ciphertext but also metadata (sender, recipient, room ID, timestamps). Federation increases metadata exposure compared to a single-server architecture.
- Eventually consistent state model means that room membership, key sharing, and message ordering can diverge between homeservers. The client must reconcile these inconsistencies, adding complexity to the state machine.
- Device verification is a persistent UX challenge. The cross-signing mechanism is powerful but difficult for users to understand.
Limitations for quicnprotochat's use case:
- No post-compromise security for groups (same limitation as Signal's Sender Keys).
- Federation adds latency, metadata exposure, and state management complexity that quicnprotochat does not need.
- JSON-based wire format is inefficient (see serialisation comparison below).
quicnprotochat: MLS (RFC 9420)
quicnprotochat uses the Messaging Layer Security (MLS) protocol, standardized as RFC 9420 by the IETF.
Key properties:
- Native group key agreement. MLS was designed from the ground up for groups, not bolted onto a pairwise protocol. The ratchet tree structure provides O(log n) cost for group operations (add, remove, update), compared to O(n) or O(n^2) for pairwise-based schemes.
- Post-compromise security. Any group member can issue an Update proposal that replaces their leaf in the ratchet tree, generating a new group secret. This heals the tree: even if a member's key material was previously compromised, the new group secret is unknown to the attacker. This property is not available in Signal Sender Keys or Megolm.
- Forward secrecy. Each epoch (a new group state after a Commit) derives fresh keys. Past epoch keys are deleted and cannot decrypt old messages.
- Single Commit to update all members. A Commit message applies one or more proposals (Add, Remove, Update) atomically and is processed by all group members with a single message. No pairwise distribution is needed.
- Standardized. RFC 9420 was published by the IETF in July 2023 after years of design, analysis, and interoperability testing. Multiple independent implementations exist (openmls, mls-rs, Cisco's MLS, etc.).
Cost of group operations:
| Operation | Signal (Sender Keys) | Matrix (Megolm) | MLS (quicnprotochat) |
|---|---|---|---|
| Add member | O(n) Sender Key distributions | O(n) Megolm session shares | O(log n) tree update |
| Remove member | O(n) Sender Key rotations | O(n) new Megolm session | O(log n) tree update |
| Update (PCS heal) | Not supported | Not supported (session rotation is coarse) | O(log n) path update |
| Per-message encrypt | O(1) symmetric ratchet | O(1) symmetric ratchet | O(1) symmetric ratchet |
Transport comparison
The transport layer determines how encrypted payloads reach the server and how client-server authentication is performed.
| Property | Signal | Matrix | quicnprotochat |
|---|---|---|---|
| Transport protocol | TLS over TCP (HTTP/2) | HTTPS (TLS over TCP) | QUIC (UDP) + TLS 1.3 |
| Multiplexing | HTTP/2 stream multiplexing | HTTP/1.1 or HTTP/2 | Native QUIC stream multiplexing |
| Head-of-line blocking | Mitigated by HTTP/2 streams, but TCP HOL blocking remains | Same as Signal | Eliminated: QUIC streams are independent at the transport layer |
| Connection establishment | 1-RTT (TLS 1.3) or 0-RTT (TLS resumption) | 1-RTT (TLS 1.3) or 0-RTT | 0-RTT capable (QUIC resumption) or 1-RTT |
| Client authentication | Bearer tokens over TLS | Bearer tokens over TLS | TLS client certs (rustls/quinn) or bearer tokens via Auth struct |
| Fallback | TCP only | TCP only | None currently (QUIC only) |
Why QUIC?
QUIC eliminates TCP head-of-line blocking, which is particularly important for a messaging application where multiple independent conversations may be active simultaneously. A lost packet in one QUIC stream does not block delivery of packets in other streams. QUIC also provides built-in connection migration (useful for mobile clients changing networks) and 0-RTT resumption for reduced latency on reconnection.
Serialisation comparison
The serialisation format determines the overhead of encoding and decoding messages, the type safety of the wire format, and the feasibility of schema evolution.
| Property | Signal (Protobuf) | Matrix (JSON) | quicnprotochat (Cap'n Proto) |
|---|---|---|---|
| Format | Binary, schema-defined | Text, schema-optional (JSON Schema exists but is not enforced by the wire format) | Binary, schema-defined |
| Deserialization cost | Requires a decode pass (allocates and copies) | Requires a parse pass (allocates, copies, and handles UTF-8) | Zero-copy: the wire bytes are the in-memory representation. Readers traverse pointers in-place. |
| Schema enforcement | Compile-time via protoc codegen | Runtime only (if at all) | Compile-time via capnpc codegen |
| Schema evolution | Forward-compatible (unknown fields preserved) | Forward-compatible (unknown keys ignored) | Forward-compatible (unknown fields and methods ignored) |
| RPC support | Separate framework (gRPC) | REST/HTTP (no built-in RPC) | Built-in async RPC (capnp-rpc). Method dispatch, pipelining, and cancellation are part of the serialisation layer. |
| Canonical form | Not guaranteed (field ordering, default elision vary) | Not guaranteed (key ordering is implementation-dependent) | Canonical serialisation (deterministic byte output for identical messages). Suitable for signing. |
| Overhead | Low (varint encoding, no field names on wire) | High (field names as strings, quoting, escaping, UTF-8) | Very low (8-byte aligned, fixed-width fields, pointer-based data) |
Why Cap'n Proto over Protobuf?
While Protobuf is a reasonable choice (and Signal uses it successfully), Cap'n Proto provides two features that are particularly valuable for quicnprotochat:
- Zero-copy deserialization eliminates a class of allocation and performance overhead. In a messaging system that processes many small messages, avoiding deserialization copies adds up.
- Built-in RPC means that Cap'n Proto is both the serialisation format and the RPC framework. There is no need for a separate gRPC or HTTP layer. The same
.capnpschema file defines both the data structures and the service interface. - Canonical form means that two implementations producing the same logical message will generate identical bytes. This is important for signatures: the MLS layer signs over serialised data, and non-deterministic serialisation would make signature verification unreliable.
Summary comparison table
| Dimension | Signal | Matrix | quicnprotochat |
|---|---|---|---|
| 1:1 encryption | Double Ratchet (FS + PCS) | Olm / Double Ratchet (FS + PCS) | MLS (FS + PCS) |
| Group encryption | Sender Keys (FS only) | Megolm (FS only) | MLS (FS + PCS) |
| Group PCS | No | No | Yes (any member can heal the tree) |
| Group op cost | O(n) to O(n^2) | O(n) | O(log n) |
| Transport | TLS/TCP (HTTP/2) | TLS/TCP (HTTPS) | QUIC/UDP (0-RTT, no HOL blocking) |
| Serialisation | Protobuf | JSON | Cap'n Proto (zero-copy, canonical, built-in RPC) |
| Standardization | De facto standard | Matrix spec (open, community-governed) | IETF RFC 9420 (MLS) |
| Federation | No (centralized) | Yes (decentralized) | No (single server per deployment) |
| PQ readiness | PQXDH (X3DH + ML-KEM) in 1:1, not in groups | Not yet | Hybrid KEM (X25519 + ML-KEM-768) at envelope layer; MLS PQ integration planned (M5) |
| Maturity | 10+ years, billions of users | 7+ years, millions of users | Early development (M1-M3) |
What quicnprotochat gives up
No design is without trade-offs. Compared to Signal and Matrix, quicnprotochat:
- Has no federation. A single server per deployment means no decentralized architecture. This is a deliberate simplification -- federation adds significant complexity and metadata exposure.
- Is less mature. Signal and Matrix have years of production hardening, formal security audits, and battle-tested implementations. quicnprotochat is in early development.
- Has a smaller ecosystem. Signal and Matrix have extensive client libraries, bridges, and integrations. quicnprotochat is a standalone Rust implementation.
- Requires MLS client complexity. MLS clients must maintain a ratchet tree, process Commits, and handle epoch transitions. This is more complex than a simple symmetric ratchet (Sender Keys / Megolm), though the complexity buys post-compromise security.
Further reading
- Design Decisions Overview -- index of all ADRs
- ADR-002: Cap'n Proto over MessagePack -- serialisation format choice
- Protocol Layers Overview -- how quicnprotochat's layers compose
- MLS (RFC 9420) -- deep dive into the MLS protocol layer
- Architecture Overview -- system-level architecture