Rename all project references from quicproquo/qpq to quicprochat/qpc across documentation, Docker configuration, CI workflows, packaging scripts, operational configs, and build tooling. - Docker: crate paths, binary names, user/group, data dirs, env vars - CI: workflow crate references, binary names, artifact names - Docs: all markdown files under docs/, SDK READMEs, book.toml - Packaging: OpenWrt Makefile, init script, UCI config (file renames) - Scripts: justfile, dev-shell, screenshot, cross-compile, ai_team - Operations: Prometheus config, alert rules, Grafana dashboard - Config: .env.example (QPQ_* → QPC_*), CODEOWNERS paths - Top-level: README, CONTRIBUTING, ROADMAP, CLAUDE.md
8.6 KiB
Architecture Overview
quicprochat is an end-to-end encrypted group messaging system built in Rust. This page describes the high-level architecture: the services that compose the system, the dual-key cryptographic model, and how the pieces fit together.
Two-Service Model
The server exposes two logical services through a unified RPC endpoint bound to port 5001 over QUIC + TLS 1.3:
| Logical Service | Responsibility |
|---|---|
| Authentication Service (AS) | Stores and distributes single-use MLS KeyPackages. Clients upload KeyPackages after identity generation; peers fetch them to add new members to a group. Also manages hybrid PQ public keys and identity resolution. |
| Delivery Service (DS) | Store-and-forward relay for opaque payloads. The DS never inspects MLS ciphertext -- it routes solely by recipient Ed25519 public key (and optional channel ID). |
Both services are accessed through a single QUIC connection using the v2 Protobuf framing protocol. Each RPC call gets a dedicated QUIC bidirectional stream to prevent head-of-line blocking.
See Service Architecture for per-method details, connection lifecycle, and push event delivery.
Identity Key Model
Each quicprochat client holds a single Ed25519 signing keypair that serves as its long-term identity:
quicprochat Key Model
+--------------------------------------------------+
| |
| Ed25519 signing keypair (MLS identity) |
| ------------------------------------------ |
| - Generated once per user/device |
| - Embedded in MLS BasicCredential |
| - Signs KeyPackages, Commits, and group ops |
| - Raw 32-byte public key is the AS index |
| - Managed by IdentityKeypair, zeroize-on-drop |
| |
+--------------------------------------------------+
| Property | Ed25519 (MLS) |
|---|---|
| Curve | Ed25519 (Twisted Edwards) |
| Purpose | Identity binding, signing, MLS credentials |
| Crate | ed25519-dalek |
| Zeroize on drop | Yes (Zeroizing<[u8; 32]>) |
| PQ protection | MLS key schedule uses DHKEM(X25519); hybrid X25519+ML-KEM-768 KEM available at envelope level |
For details on the cryptographic properties, see Ed25519 Identity Keys.
System Diagram
+-----------------+ +-----------------+
| Alice Client | | Bob Client |
| | | |
| IdentityKeypair | | IdentityKeypair |
| (Ed25519) | | (Ed25519) |
| | | |
| QpqClient | | QpqClient |
| (SDK) | | (SDK) |
+--------+---------+ +--------+---------+
| |
| QUIC + TLS 1.3 (quinn/rustls) ALPN: "qpc" |
| |
v v
+------------------------------------------------------------------------+
| quicprochat-server (port 5001) |
| |
| +---------------------------+ +--------------------------------+ |
| | Authentication Service | | Delivery Service | |
| | | | | |
| | OpaqueRegisterStart(100) | | Enqueue(200) | |
| | OpaqueRegisterFinish(101)| | Fetch(201) | |
| | OpaqueLoginStart(102) | | FetchWait(202) | |
| | OpaqueLoginFinish(103) | | Peek(203) | |
| | | | Ack(204) | |
| | UploadKeyPackage(300) | | BatchEnqueue(205) | |
| | FetchKeyPackage(301) | | | |
| | UploadHybridKey(302) | | Store: SQLCipher | |
| | FetchHybridKey(303) | | DashMap waiters | |
| | FetchHybridKeys(304) | +--------------------------------+ |
| +---------------------------+ |
| |
| + 34 more methods: Keys, Channel, Group, User, KT, Blob, Device, |
| P2P, Federation, Moderation, Recovery, Account (see method_ids) |
| |
+------------------------------------------------------------------------+
Key observations:
-
The server never sees plaintext message content. MLS ciphertext is opaque to the DS -- it merely routes by
recipientKey. -
KeyPackages are single-use (RFC 9420 requirement). The AS atomically removes a KeyPackage on fetch to enforce this invariant.
-
QUIC + TLS 1.3 is the sole transport layer. The ALPN identifier is
qpc. -
Push events (new messages, typing, presence, membership changes) are delivered server-to-client on QUIC uni-streams using a separate push frame format.
Protocol Layering
The system stacks three protocol layers:
-
Transport -- QUIC + TLS 1.3. Provides confidentiality, integrity, and server authentication. See Protocol Stack.
-
Framing / RPC -- Custom binary header + Protobuf serialisation. Each request frame is
[method_id: u16][request_id: u32][payload_len: u32][protobuf]. Responses are[status: u8][request_id: u32][payload_len: u32][protobuf]. See Protobuf Framing. -
End-to-End Encryption -- MLS (RFC 9420). Provides group key agreement, forward secrecy, and post-compromise security. The server never holds group keys. See MLS (RFC 9420).
An optional fourth layer -- the hybrid KEM envelope (X25519 + ML-KEM-768) -- wraps MLS payloads for post-quantum confidentiality at the per-message level. See Hybrid KEM.
Crate Map
The implementation is split across nine workspace crates:
| Crate | Role |
|---|---|
quicprochat-core |
Crypto primitives, MLS state machine, hybrid KEM |
quicprochat-proto |
Cap'n Proto legacy types + Protobuf (prost) v2 generated types |
quicprochat-kt |
Key transparency (append-only log, revocation) |
quicprochat-plugin-api |
#![no_std] C-ABI plugin interface |
quicprochat-rpc |
QUIC RPC framework: framing, server dispatch, client, middleware |
quicprochat-sdk |
Client SDK: QpqClient, event broadcast, ConversationStore |
quicprochat-server |
RPC server + domain services |
quicprochat-client |
CLI/TUI client binary |
quicprochat-p2p |
iroh P2P endpoint publish/resolve (feature-flagged) |
See Crate Responsibilities for a full breakdown and dependency diagram.
Further Reading
- Protocol Stack -- layered protocol stack description
- Service Architecture -- 44 RPC methods, connection lifecycle, push events
- End-to-End Data Flow -- registration, group creation, and message exchange sequence diagrams
- Wire Format Reference -- Protobuf schema reference and method ID table
- Cryptography Overview -- detailed cryptographic properties and threat model