XChaCha20-Poly1305 — and nothing else
One mandated cipher for all confidentiality. No negotiation, no downgrade path. Symmetric crypto faces only Grover, not Shor — 128-bit effective strength that quantum computers do not break.
Quantum-resistant · metadata-blind · self-hosted
Cutout’s server is a dumb mailbox. It is architecturally incapable of learning who its users are, who talks to whom, when anything is sent — or whether a given blob is a message at all. Not restricted by policy — denied by construction.
Built for a threat model of “aliens with infinite resources” — quantum computers, full server compromise, global passive network observation.
Message, vouch, or decoy? From whom, to whom? A message at all? The server has no way to know.
The boundary
A compromised server, a malicious operator, or a state adversary holding the database learns almost nothing. Here is the complete list — both sides of it.
A message is never addressed “to Bob.” It lands in a bucket only the sender and the intended reader can derive from a shared secret. The server sees “a blob with tag X in bucket 42, tick 12345” — and cannot tell that it is a message, let alone that Bob exists.
Why now
The EU’s chat-control push — and every law like it — works by compelling providers to scan or weaken end-to-end encrypted services. Once that is the game, the real question is no longer “is the crypto sound?” It’s “who can be forced, and would you ever find out?”
You cannot know what WhatsApp, Telegram or even Signal were quietly ordered to add. You can know nobody backdoored the server your own crew runs — because you deployed it, from source you can read.
How it works
The trust anchor is a face-to-face QR scan: those secrets never travel over the network — no key exchange to intercept, no MITM window, nothing on the wire to harvest now and decrypt later. Friends can also introduce friends without a meeting: the new channel's secrets cross the wire exactly once, sealed to the recipient with post-quantum ML-KEM-768 — the introducer relays but can never read them — and the contact is colour-marked until you verify in person, which rotates the secrets back off the wire entirely.
Sender and reader derive the bucket and tag for each 30-second tick from their shared secret, using keyed hashes. The server stores what arrives but lacks the secret to verify, correlate, or even recognise any of it. Next tick, everything rotates.
There is no “give me my messages” request — that would reveal which messages are yours. Clients blind-fetch the entire tick and match tags locally. The server never learns which blobs anyone actually wanted.
Every client emits a fixed number of packets per tick, whether or not you’re talking. Real messages silently displace decoys inside that fixed schedule — and since real and decoy are byte-identical, an observer watching your line sees a flat, unchanging rate. Silence looks like conversation. Conversation looks like silence.
Cryptography
Most “post-quantum messengers” bolt new math onto an old design. Cutout removes the vulnerable step from conversations entirely — no network key agreement to attack — and the one place keys do cross the wire (introductions) is wrapped in NIST post-quantum crypto.
One mandated cipher for all confidentiality. No negotiation, no downgrade path. Symmetric crypto faces only Grover, not Shor — 128-bit effective strength that quantum computers do not break.
Every message gets a fresh random nonce wide enough that collisions are infeasible — no counters to corrupt. Restore a backup, reinstall the app, roll back the clock: nonce reuse stays impossible by design.
Two NIST-standardized primitives, each with one job: ML-DSA-44 (Dilithium) signs —
group authorship, vouches, name changes — via Cloudflare’s independently audited circl,
the same code on server and client. ML-KEM-768 (Kyber) wraps keys for one thing only:
introductions, inside end-to-end payloads the server never even recognises.
No RSA, no elliptic curves, nowhere.
Message keys are re-derived every UTC day from the pair root via HKDF-SHA-256, and old daily keys are deleted after seven days. A leaked daily key exposes at most ~24 hours; your history stays dark — the server deleted its copy within a day anyway.
Identity & trust
Every contact carries a trust color derived only from local evidence — QR scans you performed and signed vouches from people you verified. Nothing a server says can change it.
You scanned this person’s QR code in person. Their keys are pinned on your device. This is the strongest identity claim that exists in Cutout.
Someone you verified in person has cryptographically vouched for this person’s key with a post-quantum signature. One hop, no further — a blue contact’s vouch promotes no one.
Neither of the above. You can still message them, but the app tells you plainly: this identity is unproven. No false comfort, no hidden defaults.
Lose trust in a green contact? Every contact who was blue solely on their word is instantly recolored red — stale trust never lingers.
A contact can connect two people who never met: fresh channel secrets are sealed with post-quantum ML-KEM-768 so only the recipient can open them — the introducer relays a package it cannot read. In a group, the offer is even blind to everyone else: no recipient is named; only the addressee’s device can unwrap it. Colours tell the truth about what happened — an introduced contact is never green until you scan their QR, and if the QR doesn’t match the identity you were introduced to, the app says so loudly.
Every contact carries a local, hash-chained audit log: how they reached your device, every name they have presented, every vouch, every verification. Renames they announce are post-quantum-signed and recorded — your own label always wins — and any local tampering with the log breaks its chain visibly. Stored on your device, never synced.
Nothing to leak
Every “modern” messenger convenience below leaks exactly the metadata Cutout exists to remove. They aren’t off by default. They don’t exist.
One rule decided all of it: if a feature feels modern by moving your activity, timing, content, or contacts off your device — it’s forbidden. Polish comes from craft, not leaky conveniences.
The last residue
The one thing the server still sees is the sender’s IP. A built-in, app-scoped outbound tunnel removes it — and if the tunnel drops, the app fails closed and sends nothing. Never a silent fallback to your real connection.
Straight to your server over TLS. The default: simple, fast, and honest about what it shows — the server sees your IP, your ISP sees a generic HTTPS connection.
An embedded, userspace WireGuard tunnel — bring any provider or your own endpoint. Routes only this app’s traffic, needs no OS VPN profile, and leaves every other app untouched. Even DNS resolves inside the tunnel.
Route through a local Tor client for the no-trust path: no single relay sees both ends. Slower — and Cutout’s tick-based design is built to tolerate exactly that.
Honest limits
A security tool that oversells is a security hole. These limits are documented in the spec, surfaced in the app, and stated here — plainly.
If a device’s master secret leaks, daily rotation protects your past — but the system cannot cryptographically recover on its own. Recovery means meeting again and re-scanning QR codes. There is no asymmetric ratchet, because conversations involve no network key agreement — that trade is deliberate.
A channel you got through an introduction had its secrets cross the wire one time, sealed with post-quantum ML-KEM-768. If that cipher ever falls decades from now, a recording of that one message could expose that channel — QR-scanned channels have no such recording, anywhere. Verifying an introduced contact in person rotates their secrets back into the QR class. The trust colours double as exactly this hierarchy.
In WireGuard mode, the tunnel provider sees your real IP and that you reach a Cutout server. That helps only if you trust the provider more than the server’s network path. For no-trust routing, use Tor.
The server knows some traffic exists and how much per 30-second tick. Constant-rate cover traffic flattens what that reveals about you; it cannot make the server unaware traffic exists.
iOS suspends backgrounded apps, so the fixed emission rate can’t be guaranteed while suspended. An adversary watching both your link and the server could infer activity from those gaps. The browser client is weaker still: its protections run only while the tab is open, and it tells you so with a persistent, non-dismissible notice.
A photo or shoulder-surf of a displayed QR compromises what it carries, until rotated. The exchange is physical precisely so that you control the room it happens in — the app warns you at every display.
The complete adversary’s manual: every known way to break, degrade, or fool Cutout — so you can judge your own exposure.
Clients
Self-host
A single static Go binary with an embedded SQLite store. Point a domain at a fresh VPS and it obtains and renews its own TLS certificates — or slot it behind the reverse proxy you already run.
Full source of server and clients is on GitHub — auditable by anyone. Free for individuals and any organization under $10M revenue.
# 0 — get the code
$ git clone https://github.com/etragardh/cutout
$ cd cutout/deploy
# 1 — say who you are
$ cp cutout.env.example .env
$ $EDITOR .env # SERVER_URL=https://chat.example.com
# 2 — bring it up (TLS is automatic)
$ docker compose up -d
✓ cutout listening — cert obtained via Let’s Encrypt
# 3 — invite people, in person
$ cutout --qr
rendering server QR… hand your phone to a friend, not the network
No accounts. No recipients. No metadata. A server that couldn’t betray you if it tried.