- Remove `|| true` from cursor positioning condition in v2_tui.rs - Replace .lock().unwrap() with .expect() in P2P routing tests - Remove assert!(true) placeholder in WebTransport test
quicprochat
End-to-end encrypted group messaging over QUIC, powered by MLS and post-quantum cryptography.
Roadmap · SDK Docs · Operations · Quick Start
quicprochat is a production-grade messenger where the server never sees plaintext. All traffic flows over QUIC/TLS 1.3, group keys are negotiated with the MLS protocol (RFC 9420), and a hybrid X25519 + ML-KEM-768 KEM provides post-quantum confidentiality. Written in Rust. 45,000 lines of code. 301 tests.
┌─────────────────────────────────────────────────┐
│ Application / MLS ciphertext │ ← group key ratchet (RFC 9420)
├─────────────────────────────────────────────────┤
│ Protobuf RPC / Cap'n Proto (legacy) │ ← typed, schema-versioned framing
├─────────────────────────────────────────────────┤
│ QUIC + TLS 1.3 (quinn/rustls) │ ← mutual auth + transport secrecy
└─────────────────────────────────────────────────┘
Highlights
| Zero-knowledge server | Routes opaque MLS ciphertexts by recipient key — never decrypts |
| Post-quantum ready | Hybrid X25519 + ML-KEM-768 KEM on both MLS and Noise layers |
| Password auth | OPAQUE — password never leaves the client, not even as a hash |
| Forward secrecy | MLS epoch ratchet: compromise today can't decrypt yesterday |
| Multi-device | Per-device keys, delivery fan-out, up to 5 devices per account |
| Federation | Server-to-server relay over QUIC with mTLS |
| Offline-first | Client-side outbox with idempotent retry and gap detection |
| Sealed sender | Optional anonymous enqueue — server can't see who sent a message |
| 7 SDKs | Rust, Go, Python, TypeScript, Swift, Kotlin/Java, Ruby |
Quick Start
# Build (no system dependencies — protoc is vendored)
cargo build --workspace
# Run tests
cargo test --workspace
# Start the server (auto-generates self-signed TLS cert)
cargo run --bin qpc-server -- --allow-insecure-auth
# Interactive REPL (registers + logs in automatically)
cargo run --bin qpc -- repl --username alice --password secret
Two-terminal demo:
# Terminal 1 # Terminal 2
qpc repl -u alice -p secretA qpc repl -u bob -p secretB
# Alice: # Bob sees:
/dm bob [alice] Hello, Bob!
Hello, Bob!
Architecture
quicprochat/
├── crates/
│ ├── quicprochat-core # MLS, hybrid KEM, PQ Noise, OPAQUE, recovery, padding
│ ├── quicprochat-proto # Protobuf (prost) + Cap'n Proto generated types
│ ├── quicprochat-rpc # QUIC RPC framework (framing, dispatch, middleware)
│ ├── quicprochat-sdk # Client SDK (QpqClient, conversation store, outbox)
│ ├── quicprochat-server # QUIC server, 33 RPC methods, domain services, plugins
│ ├── quicprochat-client # CLI + REPL + TUI (Ratatui)
│ ├── quicprochat-kt # Key transparency (Merkle-log, revocation)
│ ├── quicprochat-p2p # iroh P2P, mesh identity, store-and-forward
│ ├── quicprochat-ffi # C FFI (libquicprochat_ffi.so)
│ └── quicprochat-plugin-api # Dynamic plugin hooks (C ABI)
├── proto/qpc/v1/ # 15 .proto schema files
├── sdks/ # Go, Python, TypeScript, Swift, Kotlin, Java, Ruby
├── docs/ # mdBook docs, SDK guides, operational runbooks
└── packaging/ # OpenWrt, Docker, cross-compilation
Security Properties
| Property | Mechanism |
|---|---|
| Transport confidentiality | TLS 1.3 over QUIC (rustls) |
| Group key agreement | MLS MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 |
| Post-quantum confidentiality | X25519 + ML-KEM-768 hybrid KEM (MLS + Noise layers) |
| Forward secrecy | MLS epoch ratchet + per-epoch key schedule |
| Post-compromise security | MLS Update proposals rotate leaf material |
| Identity | Ed25519 long-term keys (MLS credential + leaf signature) |
| Password authentication | OPAQUE-ke (augmented PAKE, no password on wire) |
| Local storage | SQLCipher + Argon2id + ChaCha20-Poly1305 |
| Key transparency | Append-only Merkle log with inclusion proofs + revocation |
| Traffic analysis resistance | Uniform padding + configurable decoy traffic |
Features
Messaging
- 1:1 DMs and N-party groups with full MLS lifecycle (add, remove, key rotation)
- Rich messaging — reactions, read receipts, typing indicators, edit, delete
- File transfer — chunked upload/download, SHA-256 content addressing, 50 MB limit
- Disappearing messages — per-conversation TTL with server-side GC
- Offline queue — messages queued locally when disconnected, flushed on reconnect
- Delivery proofs — server-signed Ed25519 receipts for cryptographic send confirmation
- Transcript export — encrypted, tamper-evident archives with Merkle chain verification
Infrastructure
- Multi-device — per-device keys and delivery fan-out (up to 5 devices)
- Account recovery — 8 recovery codes, encrypted bundles, zero-knowledge server
- Federation — server-to-server relay with mTLS and cross-server user resolution
- Abuse prevention — user blocking, message reporting, ban enforcement, admin tools
- Graceful shutdown — SIGTERM drain with configurable timeout, health endpoint awareness
- Rate limiting — sliding window algorithm, trait-based for Redis swap
- Observability — request correlation IDs, per-endpoint latency histograms, structured audit log
- Dynamic plugins — load
.so/.dylibat runtime via--plugin-dir(6 hook points) - Mesh networking — iroh P2P, mDNS discovery, store-and-forward, broadcast channels
Client SDKs
| Language | Location | Transport | Notes |
|---|---|---|---|
| Rust | crates/quicprochat-sdk |
QUIC (quinn) | Reference implementation |
| Go | sdks/go/ |
QUIC (quic-go) | Cap'n Proto RPC, full API |
| Python | sdks/python/ |
QUIC (aioquic) + FFI | Async client, PyPI-ready |
| TypeScript | sdks/typescript/ |
WebSocket + WASM crypto | 175 KB WASM bundle, browser demo |
| Swift | sdks/swift/ |
C FFI wrapper | iOS 15+ / macOS 13+ |
| Kotlin/Java | sdks/kotlin/, sdks/java/ |
JNI + C FFI | Android + JVM |
| Ruby | sdks/ruby/ |
C FFI gem | Block-form auto-disconnect |
REPL Commands
40+ slash commands including:
/dm <user> Start a 1:1 DM
/create-group <name> Create a group
/invite <user> Add member to group
/remove <user> Remove member
/send-file <path> Upload and send a file
/verify <user> Compare safety numbers
/rotate-keys Rotate MLS key material
/disappear <duration> Set message TTL
/export <path> Export encrypted transcript
/devices list|add|rm Manage devices
/block <user> Block a user
/recovery setup Generate recovery codes
/help Full command reference
Deployment
Docker
docker build -t quicprochat -f docker/Dockerfile .
docker run -p 7000:7000 -v qpc-data:/data quicprochat
Production (Docker Compose)
# Includes server + Prometheus + Grafana with pre-configured dashboards
docker compose -f docker-compose.prod.yml up -d
OpenWrt
Cross-compiled static binaries for mesh/embedded deployments:
./scripts/cross-compile.sh # builds for x86_64, armv7, aarch64 (musl)
See docs/openwrt.md for opkg packaging and procd init scripts.
Configuration
# Environment variables (see .env.example for full list)
QPC_LISTEN=0.0.0.0:7000
QPC_AUTH_TOKEN=your-strong-token
QPC_DB_KEY=your-db-encryption-key
QPC_STORE_BACKEND=sql
QPC_METRICS_LISTEN=0.0.0.0:9090
QPC_DRAIN_TIMEOUT=30
QPC_RPC_TIMEOUT=30
Documentation
mdbook serve docs # http://localhost:3000
- SDK Integration Guide — wire format, per-language guides, "build your own SDK"
- Operational Runbook — backup/restore, key rotation, incident response
- Scaling Guide — resource sizing, horizontal scaling, capacity planning
- Monitoring — Prometheus metrics, Grafana dashboards, alert rules
Security Status
This software has not undergone an independent security audit. While it implements cryptographic best practices (MLS RFC 9420, OPAQUE, zeroization, constant-time comparisons), no third-party firm has reviewed the implementation. Do not rely on it for high-risk communications until an audit is completed. See SECURITY.md for our vulnerability disclosure policy.
License
MIT
