0bdc222724f3a7d3c83000a6221bd7448d7db8e4
Phase 1 — Foundation: - Constant-time token comparison via subtle::ConstantTimeEq (Fix 11) - Structured error codes E001–E020 in new error_codes.rs (Fix 15) - Remove dead envelope.capnp code and related types (Fix 16) Phase 2 — Auth Hardening: - Registration collision check via has_user_record() (Fix 5) - Auth required on uploadHybridKey/fetchHybridKey RPCs (Fix 1) - Identity-token binding at registration and login (Fix 2) - Session token expiry with 24h TTL and background reaper (Fix 3) - Bounded pending logins with 5-minute timeout (Fix 4) Phase 3 — Resource Limits: - Rate limiting: 100 enqueues/60s per token (Fix 6) - Queue depth cap at 1000 + 7-day message TTL/GC (Fix 7) - Partial queue drain via limit param on fetch/fetchWait (Fix 8) Phase 4 — Crypto Fixes: - OPAQUE KSF switched from Identity to Argon2id (Fix 10) - Random AEAD nonce in hybrid KEM instead of HKDF-derived (Fix 12) - Zeroize secret fields in HybridKeypairBytes (Fix 13) - Encrypted client state files via QPCE format (Fix 9) Phase 5 — Protocol: - Commit fan-out to all existing members on invite (Fix 14) - Add member_identities() to GroupMember Breaking: existing OPAQUE registrations invalidated (Argon2 KSF). Schema: added auth to hybrid key ops, identityKey to OPAQUE finish RPCs, limit to fetch/fetchWait. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
quicnprotochat
End-to-end encrypted group messaging over QUIC + TLS 1.3 + MLS (RFC 9420), written in Rust.
Every byte on the wire is protected by a QUIC transport secured with TLS 1.3
(quinn + rustls). The inner MLS layer provides post-compromise security
and ratcheted group key agreement across any number of participants. Messages
are framed with Cap'n Proto, keeping serialisation zero-copy and
schema-versioned.
┌─────────────────────────────────────────────┐
│ 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 by default) |
| Group key agreement | MLS MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 |
| Post-compromise security | MLS epoch ratchet |
| Identity | Ed25519 (MLS credential + leaf node signature) |
| Message framing | Cap'n Proto (unpacked wire format) |
Documentation
Full documentation is available as an mdBook wiki in docs/:
# Install mdBook (once)
cargo install mdbook
# Build and serve locally
mdbook serve docs
# Open http://localhost:3000
Highlights
- Architecture Overview — Two-service model, dual-key design, crate layout
- Protocol Deep Dives — QUIC/TLS, Noise_XX, 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 all key decisions
- Wire Format Reference — Annotated Cap'n Proto schemas
- Getting Started — Build, run, demo walkthrough
- Roadmap — Milestones, production readiness, future research
Quick start
# Prerequisites: Rust 1.77+, capnp CLI
brew install capnp # macOS
# apt-get install capnproto # Debian/Ubuntu
# Build and test
cargo build --workspace
cargo test --workspace
# Start the server (port 7000 by default)
cargo run -p quicnprotochat-server
# Or via a config file (TOML)
cat > quicnprotochat-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 = "devtoken"
store_backend = "file" # or "sql"
db_path = "data/quicnprotochat.db"
db_key = ""
EOF
cargo run -p quicnprotochat-server -- --config quicnprotochat-server.toml
# Run the Alice/Bob demo
cargo run -p quicnprotochat-client -- demo-group \
--server 127.0.0.1:7000 --ds-server 127.0.0.1:7000
See the full demo walkthrough for a step-by-step guide.
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 | Next | Persistent CLI (create-group, invite, join, send, recv) |
| M5 | Multi-party groups | Planned | N > 2 members, Commit fan-out, Proposal handling |
| M6 | Persistence | Planned | SQLite key store, durable group state |
| M7 | Post-quantum | Planned | PQ hybrid for MLS/HPKE (X25519 + ML-KEM-768) |
Security notes
This is a proof-of-concept research project. It has not been audited. See the threat model for a detailed analysis of what is and isn't protected.
License
MIT
Description
End-to-end encrypted messaging over QUIC + TLS 1.3 + MLS (RFC 9420), written in Rust.
Languages
Rust
86.4%
HTML
3.6%
Python
2.1%
TeX
1.9%
Shell
1.6%
Other
4.2%