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>
5.1 KiB
5.1 KiB
Protocol Stack
quicproquo layers three protocol stages to move a plaintext message from sender to recipient with end-to-end encryption, typed RPC framing, and authenticated transport. This page describes each layer and provides a comparison table.
Transport: QUIC + TLS 1.3
The transport layer is QUIC over UDP with TLS 1.3 negotiated by quinn and
rustls. Cap'n Proto RPC rides on a bidirectional QUIC stream.
┌─────────────────────────────────────────────┐
│ 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
└─────────────────────────────────────────────┘
What each layer provides
QUIC + TLS 1.3 (quinn, rustls)
- Encrypted, authenticated transport with 0-RTT connection establishment (where resumed).
- TLS 1.3 provides perfect forward secrecy per connection via ephemeral ECDHE.
- The server presents a self-signed certificate by default; the client pins
the server certificate via
--ca-cert. - ALPN protocol identifier:
capnp. - Multiplexed streams over a single UDP socket -- one bidirectional stream per RPC session.
Cap'n Proto RPC (capnp, capnp-rpc)
- Zero-copy, schema-versioned serialisation.
- Asynchronous RPC with promise pipelining (multiple in-flight calls).
- The
NodeServiceinterface (defined inschemas/node.capnp) multiplexes Authentication and Delivery operations on a single connection. - The two-party VatNetwork runs over
tokio::io::compatadapters wrapping QUIC send/recv streams.
MLS (RFC 9420) (openmls, openmls_rust_crypto)
- Group key agreement with ratchet-tree-based key schedule.
- Forward secrecy: past messages remain confidential if a member's key is compromised.
- Post-compromise security (PCS): the group heals after a compromise once an honest update occurs.
- Identity binding: each member's Ed25519 public key is embedded in the MLS
BasicCredential. - Ciphersuite:
MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519.
Comparison Table
| Layer | Provides | Crate(s) |
|---|---|---|
| Transport: QUIC + TLS 1.3 | Confidentiality, server authentication, forward secrecy, multiplexed streams, congestion control | quinn, rustls |
| Framing: Cap'n Proto | Zero-copy typed serialisation, schema versioning, async RPC with promise pipelining | capnp, capnp-rpc |
| Encryption: MLS | Group key agreement, forward secrecy, post-compromise security, identity binding | openmls, openmls_rust_crypto |
| Encryption: Hybrid KEM (optional) | Post-quantum confidentiality for individual payloads (X25519 + ML-KEM-768) | ml-kem, x25519-dalek, chacha20poly1305, hkdf |
Data Path Summary
A plaintext message traverses the stack as follows:
Sender Recipient
────── ─────────
plaintext bytes
│
▼
MLS create_message()
│ ── encrypts with group AEAD key (AES-128-GCM) ──
▼
TLS-encoded MlsMessageOut (opaque ciphertext blob)
│
▼
Cap'n Proto: enqueue(recipientKey, payload)
│ ── serialised into NodeService RPC call ──
▼
QUIC stream (TLS 1.3 encrypted)
│
▼
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ network ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
│
▼
Server: NodeService.enqueue() stores payload in FIFO queue
│
▼
Cap'n Proto: fetch() / fetchWait() returns payload
│
▼
MLS process_message()
│ ── decrypts with group AEAD key ──
▼
plaintext bytes
The server never holds the MLS group key. It sees only the encrypted
MlsMessageOut blob.
Further Reading
- Architecture Overview -- high-level system diagram and identity key model
- QUIC + TLS 1.3 -- QUIC configuration, ALPN, and certificate handling
- Cap'n Proto Serialisation and RPC -- schema design and VatNetwork wiring
- MLS (RFC 9420) -- ciphersuite selection, key schedule, and ratchet tree
- Hybrid KEM: X25519 + ML-KEM-768 -- post-quantum envelope encryption