Files
quicproquo/docs/src/introduction.md
Chris Nennemann 853ca4fec0 chore: rename project quicnprotochat -> quicproquo (binaries: qpq)
Rename the entire workspace:
- Crate packages: quicnprotochat-{core,proto,server,client,gui,p2p,mobile} -> quicproquo-*
- Binary names: quicnprotochat -> qpq, quicnprotochat-server -> qpq-server,
  quicnprotochat-gui -> qpq-gui
- Default files: *-state.bin -> qpq-state.bin, *-server.toml -> qpq-server.toml,
  *.db -> qpq.db
- Environment variable prefix: QUICNPROTOCHAT_* -> QPQ_*
- App identifier: chat.quicnproto.gui -> chat.quicproquo.gui
- Proto package: quicnprotochat.bench -> quicproquo.bench
- All documentation, Docker, CI, and script references updated

HKDF domain-separation strings and P2P ALPN remain unchanged for
backward compatibility with existing encrypted state and wire protocol.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 20:11:51 +01:00

6.9 KiB

Introduction

quicproquo is a research-oriented, end-to-end encrypted group messaging system written in Rust. It layers the Messaging Layer Security protocol (MLS, RFC 9420) on top of QUIC + TLS 1.3 transport (via quinn and rustls), with all service RPCs and wire messages framed using Cap'n Proto. The project exists to explore how modern transport encryption (QUIC), a formally specified group key agreement protocol (MLS), and a zero-copy serialisation format (Cap'n Proto) compose in practice -- and to provide a readable, auditable reference implementation for security researchers, protocol designers, and Rust developers who want to study or extend the design.


Protocol stack

┌─────────────────────────────────────────────┐
│          Application / MLS ciphertext        │  <- group key ratchet (RFC 9420)
├─────────────────────────────────────────────┤
│              Cap'n Proto RPC                │  <- typed, schema-versioned framing
├─────────────────────────────────────────────┤
│        QUIC + TLS 1.3 (quinn/rustls)        │  <- mutual auth + transport secrecy
└─────────────────────────────────────────────┘

Each layer addresses a distinct concern:

  1. QUIC + TLS 1.3 provides authenticated, confidential transport with 0-RTT connection establishment and multiplexed streams. The server presents a TLS 1.3 certificate (self-signed by default); the client verifies it against a local trust anchor. ALPN negotiation uses the token b"capnp".

  2. Cap'n Proto RPC defines the wire schema for all service operations (KeyPackage upload/fetch, message enqueue/fetch, health probes). Schemas live in schemas/*.capnp and are compiled to Rust at build time. Because Cap'n Proto uses a pointer-based layout, messages can be read without an unpacking step -- though quicproquo currently uses the unpacked wire format for simplicity.

  3. MLS (RFC 9420) provides the group key agreement layer. Each participant holds an Ed25519 identity keypair and generates single-use HPKE KeyPackages. The MLS epoch ratchet delivers forward secrecy and post-compromise security: compromising a member's state at epoch n does not reveal plaintext from epochs < n (forward secrecy) or > n+1 (post-compromise security, once the compromised member updates).


Security properties

Property Mechanism
Transport confidentiality TLS 1.3 over QUIC (rustls with TLS13 only)
Transport authentication TLS 1.3 server certificate (self-signed, SANs: localhost, 127.0.0.1, ::1)
Group key agreement MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519
Post-compromise security (PCS) MLS epoch ratchet -- each Commit advances the key schedule
Identity Ed25519 (ed25519-dalek); public key used as MLS BasicCredential
Framing Cap'n Proto (unpacked wire format, schema-versioned)

For a deeper discussion of the cryptographic guarantees, threat model, and known gaps, see:


Who is this for?

Security researchers studying how MLS composes with QUIC transport and Cap'n Proto framing. The codebase is intentionally small (four crates, ~2 500 lines of non-generated Rust) so that every cryptographic boundary is auditable.

Protocol designers evaluating MLS deployment patterns. quicproquo implements a concrete Authentication Service (AS) and Delivery Service (DS) pair, demonstrating single-use KeyPackage lifecycle, Welcome routing, and epoch advancement in a live system.

Rust developers looking for a working example of:

  • quinn + rustls server/client setup with self-signed certificates
  • capnp-rpc over QUIC bidirectional streams (including the !Send / LocalSet constraint)
  • openmls group creation, member addition, and application message encryption
  • zeroize-on-drop key material handling

Section What you will find
Comparison with Classical Protocols Why quicproquo? IRC+SSL, XMPP, Telegram vs. our design
Prerequisites Toolchain and system dependencies
Building from Source cargo build, Cap'n Proto codegen, troubleshooting
Running the Server Server startup, configuration, TLS cert generation
Running the Client All CLI subcommands with examples
Docker Deployment docker compose up, multi-stage build
Demo Walkthrough Step-by-step Alice-and-Bob narrative with sequence diagram
Architecture Overview Crate boundaries, service architecture, data flow
Protocol Layers Deep dives into QUIC/TLS, Cap'n Proto, MLS, Hybrid KEM
Wire Format Reference Cap'n Proto schema documentation
Cryptography Identity keys, key lifecycle, forward secrecy, PCS, threat model
Design Rationale ADRs and protocol design decisions
Roadmap Milestone tracker and future research directions

Current status

quicproquo is a proof of concept. It has not been audited by a third party.

Known limitations:

  • The server uses a self-signed TLS certificate by default. No certificate pinning or CA-based server identity is enforced.
  • MLS credentials use CredentialType::Basic (raw public key). A production system would bind credentials to a certificate authority or use X.509 certificates.
  • The Delivery Service performs no authentication of the recipientKey field -- anyone who knows a recipient's public key can enqueue messages for them. Access control is a future milestone.
  • The HPKE init private key generated during register-state is held in-process memory (or on-disk via the key store). If the process exits before the corresponding Welcome is consumed, join will fail because the private key is lost.

Multi-party groups (N > 2) are supported (milestone M5): Commit fan-out, send --all, and epoch sync work for all members.

For the full milestone tracker, see Milestones.


License

quicproquo is released under the MIT license. See LICENSE in the repository root.