Files
quicproquo/docs/src/design-rationale/why-not-signal.md
Christian Nennemann 9fdb37876a Remove Noise protocol references from wiki docs and tests
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>
2026-02-22 08:25:23 +01:00

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:

  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