Sprint plan for cycles 12-19. Pick 8 of 12 features: A) Federation wiring, B) Contacts/blocking, C) Voice/video signaling, D) Encrypted backup, E) Group roles, F) KT audit client, G) Message search, H) Server clustering, I) Protocol compliance, J) User profiles, K) Notification framework, L) Mobile app shell.
QPQ — quicproquo
End-to-end encrypted messaging over QUIC + TLS 1.3 + MLS (RFC 9420), written in Rust.
The server never sees plaintext. Every byte on the wire is protected by a QUIC
transport secured with TLS 1.3 (quinn + rustls). The inner MLS layer
provides forward secrecy, post-compromise security, and ratcheted group key
agreement across any number of participants. Messages are framed with
Cap'n Proto for zero-copy, schema-versioned serialisation.
┌─────────────────────────────────────────────┐
│ 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
└─────────────────────────────────────────────┘
| Property | Mechanism |
|---|---|
| Transport confidentiality | TLS 1.3 over QUIC (rustls) |
| Transport authentication | TLS 1.3 server cert (self-signed or CA) |
| Group key agreement | MLS MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 |
| Post-compromise security | MLS epoch ratchet |
| Forward secrecy | Per-epoch key schedule |
| Identity | Ed25519 (MLS credential + leaf node signature) |
| Password auth | OPAQUE (password never sent to server) |
| Post-quantum readiness | X25519 + ML-KEM-768 hybrid KEM envelope |
| Local storage encryption | SQLCipher + Argon2id + ChaCha20-Poly1305 |
| Message framing | Cap'n Proto (unpacked wire format) |
Features
Core
- Interactive REPL — multi-conversation chat with auto-register, auto-login, slash commands, background polling, and message history
- 1:1 DMs — dedicated channels with server-enforced membership authorization
- Multi-party groups — N-member MLS groups with Commit fan-out and epoch sync
- OPAQUE authentication — password-authenticated key exchange (password never leaves the client)
- Encrypted local storage — SQLCipher database + encrypted session tokens (Argon2id + ChaCha20-Poly1305)
- Persistent state — server and client survive restarts; SQLite/SQLCipher or file-backed storage
- Self-DM notepad — send messages to yourself (local-only, no server round-trip)
- Certificate pinning — pass the server cert as
--ca-certto trust only that server - Federation — server-to-server message relay via Cap'n Proto RPC over QUIC with mTLS
- mDNS discovery — servers announce
_quicproquo._udp.local.; clients auto-discover nearby nodes - Sealed sender mode — optional anonymous enqueue (sender identity inside MLS ciphertext only)
- Prometheus metrics —
--metrics-listenexposes/metricsendpoint for monitoring - Dynamic plugin system — load
.so/.dylibplugins at runtime via--plugin-dir - Safety numbers —
/verify <username>for out-of-band key verification (60-digit numeric code) - Transcript export — encrypted, tamper-evident message archives with hash-chain integrity verification
- 20 CLI subcommands —
register-user,login,create-group,invite,join,send,recv,chat,repl,export,export-verify, and more
REPL slash commands
| Command | Description |
|---|---|
/dm <username> |
Start a 1:1 DM with a peer |
/create-group <name> (or /cg) |
Create a new group |
/invite <username> |
Add a member to the current group |
/remove <username> |
Remove a member from the current group |
/join |
Join a pending group invitation |
/leave |
Leave the current group |
/switch @user or /switch #group |
Switch active conversation |
/list or /ls |
List all conversations |
/members |
Show group members |
/history [count] (or /hist) |
Show message history (default 20) |
/verify <username> |
Compare safety numbers with a peer |
/update-key (or /rotate-key) |
Rotate your MLS key material |
/mesh peers |
Scan for nearby qpq nodes via mDNS |
/mesh server <host:port> |
Note a discovered server address |
/whoami |
Show identity and group status |
/help |
Command reference |
/quit |
Exit |
Experimental / proof-of-concept
- Tauri 2 GUI (
quicproquo-gui) — foundational desktop app shell; not feature-complete - Mobile FFI (
quicproquo-mobile) — C API for QUIC connection migration (wifi to cellular) - P2P transport (
quicproquo-p2p) — iroh-based direct peer-to-peer messaging with NAT traversal (feature-gated behind--features mesh) - Bot framework (
quicproquo-bot) — programmable bot client
Quick start
# Prerequisites: Rust 1.77+, capnp CLI
brew install capnp # macOS
# apt-get install capnproto # Debian/Ubuntu
# Build (excludes GUI — requires GTK system libs)
cargo build --bin qpq-server --bin qpq
# Run tests
cargo test --workspace --exclude quicproquo-gui
# Start the server (port 7000 by default, auto-generates self-signed cert)
cargo run --bin qpq-server -- --allow-insecure-auth
# Interactive REPL (auto-registers and logs in)
cargo run --bin qpq -- repl --username alice --password mypass
REPL quickstart (two terminals)
# Terminal 1
qpq repl --username alice --password secretA
# Terminal 2
qpq repl --username bob --password secretB
# In Alice's REPL:
/dm bob
Hello from Alice!
# Bob sees: [alice] Hello from Alice!
Server configuration (TOML)
cat > qpq-server.toml <<'EOF'
listen = "0.0.0.0:7000"
data_dir = "data"
tls_cert = "data/server-cert.der"
tls_key = "data/server-key.der"
auth_token = "your-strong-token-here"
store_backend = "sql" # or "file"
db_path = "data/qpq.db"
db_key = "your-db-encryption-key"
metrics_listen = "0.0.0.0:9090"
metrics_enabled = true
# Federation (optional)
# federation_enabled = true
# federation_domain = "chat.example.com"
# federation_listen = "0.0.0.0:7001"
# Plugin loading (optional)
# plugin_dir = "/etc/qpq/plugins"
EOF
cargo run --bin qpq-server -- --config qpq-server.toml
Production: use a strong
QPQ_AUTH_TOKEN, setQPQ_DB_KEYwhen usingstore_backend = "sql", and provide real TLS certificates (the server refuses to auto-generate certs in production mode).
See the full demo walkthrough for a step-by-step guide.
Crate layout
| Crate | Purpose |
|---|---|
quicproquo-core |
MLS group operations, hybrid KEM, OPAQUE auth, crypto primitives |
quicproquo-proto |
Cap'n Proto schemas and generated RPC code |
quicproquo-server |
QUIC server, NodeService RPC, storage backends, federation, plugins |
quicproquo-client |
CLI + REPL, session management, conversation store |
quicproquo-plugin-api |
C-compatible plugin hook API (HookVTable) |
quicproquo-kt |
Key transparency / Merkle-log identity bindings |
quicproquo-bot |
Programmable bot client framework |
quicproquo-gen |
Code generation utilities |
quicproquo-gui |
Tauri 2 desktop app (experimental, requires GTK) |
quicproquo-mobile |
C FFI for mobile connection migration (experimental) |
quicproquo-p2p |
iroh-based P2P transport (feature-gated, --features mesh) |
CI pipeline
GitHub Actions runs on every push and PR:
cargo fmt --check— formattingcargo build --workspace— full buildcargo test --workspace— 103+ tests (core, server, client, E2E, doctests)cargo clippy --workspace— lintcargo deny check— license and advisory auditcargo audit— vulnerability scancargo tarpaulin— code coverage (uploaded as artifact)docker build— container image validation
Milestones
| # | Name | Status | What it adds |
|---|---|---|---|
| M1 | QUIC/TLS transport | Done | QUIC + TLS 1.3 endpoint, length-prefixed framing, Ping/Pong |
| M2 | Authentication Service | Done | Ed25519 identity, KeyPackage generation, AS upload/fetch |
| M3 | Delivery Service + MLS groups | Done | DS relay, GroupMember create/join/add/send/recv |
| M4 | Group CLI subcommands | Done | Persistent CLI, OPAQUE login, 20 subcommands |
| M5 | Multi-party groups | Done | N > 2 members, Commit fan-out, send --all, epoch sync |
| M6 | Persistence + REPL | Done | SQLite/SQLCipher, interactive REPL, DM channels, encrypted local storage |
| M7 | Post-quantum MLS | Planned | Hybrid X25519 + ML-KEM-768 integrated into MLS ciphersuite |
M7 note: the hybrid KEM envelope is already implemented and tested (10 tests passing). What remains is integrating it into the OpenMLS CryptoProvider so all MLS key material gets post-quantum confidentiality.
Roadmap
See ROADMAP.md for the full phased plan. Summary:
| Phase | Focus | Status |
|---|---|---|
| 1 | Production hardening (unwrap removal, secure defaults, Docker) | In progress |
| 2 | Test and CI maturity | Partially done |
| 3 | Client SDKs (Go, Python, WASM, FFI, WebTransport) | Planned |
| 4 | Trust and security (audit, key transparency, PQ MLS) | Planned |
| 5 | Features and UX (multi-device, offline queue, file transfer) | Planned |
| 6 | Scale and operations (horizontal scaling, observability) | Planned |
| 7 | Platform expansion (mobile, web, federation, sealed sender) | Planned |
| 8 | Freifunk / community mesh networking | F0-F2 done |
| 9 | Developer experience and community growth | Planned |
Recently completed
- Federation routing — server-to-server message relay with mTLS
- mDNS discovery — servers advertise on local network, clients discover peers
- P2P transport — iroh-based direct messaging re-included in workspace (
--features mesh) - CI pipeline — fmt, build, test, clippy, deny, audit, coverage, Docker build
- Plugin system — dynamic
.so/.dylibloading with C-compatible hook API - Safety numbers — Signal-style 60-digit verification codes
- Transcript export — encrypted, hash-chained message archives
Building without the GUI
The GUI crate requires GTK system libraries. To build just the server and client:
cargo build --bin qpq-server --bin qpq
To build the client with mesh/P2P support:
cargo build -p quicproquo-client --features mesh
Documentation
Full documentation is available as an mdBook in docs/:
cargo install mdbook # once
mdbook serve docs # http://localhost:3000
- Architecture Overview — two-service model, dual-key design, crate layout
- Protocol Deep Dives — QUIC/TLS 1.3, Cap'n Proto, MLS, Hybrid KEM
- Cryptographic Properties — forward secrecy, post-compromise security, PQ readiness, threat model
- Design Rationale — why MLS over Signal/Matrix, ADRs for key decisions
- Wire Format Reference — annotated Cap'n Proto schemas
- Getting Started — build, run, demo walkthrough
- Roadmap — milestones, production readiness, future research
- Future Improvements — prioritised list of security, ops, and feature improvements
Security
This is a research project and has not undergone a formal third-party audit. See the threat model and security audit for details.
- The server only routes opaque ciphertexts by recipient key — it never sees plaintext.
- OPAQUE ensures passwords never leave the client.
- Local databases are encrypted with SQLCipher when a password is provided.
- Session tokens are encrypted at rest (Argon2id key derivation + ChaCha20-Poly1305).
- Certificate pinning: pass the server cert as
--ca-certso the client trusts only that server. - Sealed sender: optional mode where the server cannot see who sent a message.
- Dependency checks: CI runs
cargo deny checkandcargo auditon every PR.
License
MIT
