# 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: 1. **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. 2. **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 `.capnp` schema file defines both the data structures and the service interface. 3. **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](overview.md) -- index of all ADRs - [ADR-002: Cap'n Proto over MessagePack](adr-002-capnproto.md) -- serialisation format choice - [Protocol Layers Overview](../protocol-layers/overview.md) -- how quicnprotochat's layers compose - [MLS (RFC 9420)](../protocol-layers/mls.md) -- deep dive into the MLS protocol layer - [Architecture Overview](../architecture/overview.md) -- system-level architecture