# Chat control vs. this project — an honest threat-model mapping *Legal facts below are as of **2026-07-14** and will drift; the architecture conclusions won't. This is engineering documentation, not legal advice.* ## What actually passed in July 2026 On 9–10 July 2026 the European Parliament adopted the revival of **"Chat Control 1.0"** — an extension of the 2021 ePrivacy derogation that had expired in April 2026. Precisely: - It **permits** (does not mandate) providers to scan content they can read — the legal cover for what large US providers already do voluntarily on Gmail, Instagram/Facebook DMs, Discord, Snapchat, Skype, Xbox, iCloud mail. - The adopted text **excludes end-to-end encrypted communications** from its scope ("communications to which end-to-end encryption is, has been, or will be applied") — encrypted messengers like Signal are not scanned under it. - It passed "through the back door": **314 MEPs voted to reject vs. 276 to keep**, but rejecting at second reading needs an absolute majority of 361, so the measure survived a plurality against it. It now goes to the Council and runs until **3 April 2028** or until a permanent framework replaces it. - The real fight is **"Chat Control 2.0"** (the permanent CSA Regulation): mandatory **detection orders** that could compel providers — including E2EE providers — to detect content, which in practice means **client-side scanning**: code inside the provider's app that inspects messages *before* encryption. Negotiations resume **September 2026**. The German federal data-protection authority (BfDI) notes detection technologies with error rates up to 12% and calls the approach the entry into indiscriminate mass surveillance of private communication. ## Where scanning technically happens Chat control is **not a wiretap on the network**. Scanning happens where plaintext exists: 1. **At the provider**, for services that can read your content (hosted mail, platform DMs, cloud storage). This is what CC 1.0 legalizes today. 2. **Inside the client**, if a provider is ever compelled to ship scanning code in its app or web page (the CC 2.0 endgame for E2EE services). 3. **Around the content**: metadata (who talks to whom, when, how much, from which IP) is visible to whoever operates the service regardless of encryption. Those are the three trust points any countermeasure has to address: the **service**, the **client code**, and the **metadata**. ## What defends against what | Surveillance vector | Defence | Status in this project | |---|---|---| | Provider scans content it can read (CC 1.0, live today) | Genuine E2EE — no provider ever holds plaintext | ✅ Built: all crypto runs in the endpoints; the relay forwards only ciphertext ([web/README.md](../web/README.md)) | | Provider compelled by a detection order (CC 2.0 risk) | **Be your own provider.** A self-hosted relay has no third party to compel — and holds nothing useful even if seized (no keys, no plaintext, no storage, rooms in memory only) | ✅ Built: one static ~16 MB relay binary with the whole site embedded (or one `docker compose up`) | | Scanning code delivered *into the client* — for a web app, a compelled/compromised origin can serve modified JS/WASM per visit, per target | **Install once, verify, run locally.** The offline app is one self-contained HTML file: download once, check its SHA-256 (or rebuild from source — the build is byte-reproducible), open from disk. Code can no longer be swapped remotely; every inline block is pinned by CSP hash inside the file | ✅ Built: `ragnarok.html` via `web/tools/gen-offline` | | Record ciphertext now, decrypt with a quantum computer later | Hybrid post-quantum key exchange | ✅ Built: X25519 + ML-KEM-1024 (FIPS 203), PQ in confidentiality **and** authentication (KEMTLS-style static ML-KEM identities) | | A stolen key unlocking past traffic | Per-message key ratchet (forward secrecy) — keys rotate on **every message** | ✅ Built: symmetric hash ratchet ([securechannel/channel.go](../securechannel/channel.go)) | | Message-size profiling on the wire | Padding to fixed-size buckets | ✅ Built (coarsens, does not hide — see limits) | | An impostor relay inserting itself | Mutual identity authentication + out-of-band fingerprint verification; the relay *cannot* MITM without failing the handshake | ✅ Built: TOFU pinning + expected-fingerprint mode | | Who-talks-to-whom, timing, IP addresses | **Not solvable by encryption.** Reduce it: run the relay yourself (the observer is you), put it behind Tor as an onion service, keep rooms as random codes | ⚠️ Partial — see below | | Malware / a compelled OS or browser on the endpoint | Nothing a messenger can do | ❌ Out of scope for any tool, including Signal | Two properties often asked of "surveillance-resistant" designs map onto this table: *dynamic key rotation* is the per-message ratchet plus the fresh hybrid handshake per session (built), and *decentralized multi-node communication* is the untrusted-relay design — the important property is not *many* nodes but that **no node needs to be trusted**; anyone can run one anywhere, and the offline app lets you point at any relay and switch at will. ## What this does NOT give you - **The cipher is an unaudited research artifact.** No third-party cryptanalysis. The standing recommendation in this repo does not change: for communication that matters, **use Signal** — which is exactly the kind of E2EE service the adopted CC 1.0 text excludes, is audited, and ships post-quantum key exchange too. This project demonstrates that the architecture (E2EE + untrusted self-hosted relay + verifiable local client) is buildable with ~zero dependencies, and serves as a personal hedge and a learning vehicle — not a Signal replacement. See [SECURITY-ANALYSIS.md](SECURITY-ANALYSIS.md). - **Metadata still exists.** The relay operator sees connecting IPs, room codes, timing and padded sizes. Self-hosting moves that knowledge to yourself; Tor can hide it from the network; nothing eliminates it. - **No post-compromise secrecy yet.** The ratchet heals nothing after a full state compromise; reconnect periodically (fresh hybrid handshake). A KEM-based re-handshake ratchet is the documented next protocol step. - **Legal posture is yours to check.** Obligations in these regulations attach to *providers offering communication services to the public*. Running a relay for yourself, your family, or internally for your company is a materially different position from operating a public service — if you plan the latter, read the final text and the analyses by [GFF](https://freiheitsrechte.org/en/themen/freiheit-im-digitalen-zeitalter/chatkontrolle) and the [BfDI](https://www.bfdi.bund.de/DE/Fachthemen/Inhalte/Telemedien/CSA_Verordnung.html) before relying on anything here. ## Practical setups **A citizen (no server, minimal effort):** 1. Get `ragnarok.html` — download it from an instance you trust (the landing page's "download the app" button) or build it yourself: `make web` prints the SHA-256, and the build is **reproducible**, so your rebuild must match a published hash byte for byte. Verify a downloaded copy with `shasum -a 256 -c ragnarok.html.sha256`. 2. Open the file locally (double-click; it needs no server for the UI), enter any relay address, and share the conversation code **plus your fingerprint** with your peer over a channel you already trust. 3. Your peer does the same with their own copy. Verify fingerprints out loud once; after that, a changed fingerprint means interception. **A small business (own infrastructure, ~15 minutes):** ```console $ docker compose up -d --build # relay on 127.0.0.1:8080, no state, no keys ``` — or skip Docker entirely: download a self-contained relay binary from a hosted instance's landing page (or build with `make release`), verify it against `SHA256SUMS.txt`, and run it; the landing page, app, docs and offline bundle are embedded in the binary. Put it behind the reverse proxy you already run (or use `deploy/` for turnkey Caddy + Let's Encrypt), or keep it VPN/intranet-only so it is never exposed publicly at all. Distribute the offline bundle and its hash on the intranet. The relay can be wiped and redeployed freely — it stores nothing. **Metadata-reduced deployment (Tor onion service):** ``` # /etc/tor/torrc on the relay host HiddenServiceDir /var/lib/tor/ragnarok/ HiddenServicePort 80 127.0.0.1:8080 ``` Peers using Tor Browser reach the relay without revealing their IP to it (or the relay's location to the network). The hosted page works over the onion address directly; the offline bundle can point its relay field at `ws:///ws`. Expect higher latency; the securechannel handshake and ratchet are unaffected. ## If the law changes underneath this The design goal is that **no plausible variant of chat control has a lever here**: there is no provider to order (you host), no app store to filter (a file, sideloaded), no code-update channel to compel (the bundle is static and hash-verified), and no plaintext or key material at the only third party involved (the relay). What remains reachable is what remains reachable for every tool — the endpoints and the law's treatment of individuals themselves. Watch the CC 2.0 negotiations from September 2026; if detection duties ever extend beyond providers, revisit this document. ## Sources (2026-07-14) - [Euronews — Chat Control 1.0 passed the European Parliament through the back door](https://www.euronews.com/next/2026/07/10/chat-control-10-passed-the-european-parliament-through-the-back-door) - [The Record — Europe revives law allowing big tech to scan for CSAM](https://therecord.media/chat-control-2-csam-scans-european-parliament-passage) - [Patrick Breyer — EU Parliament greenlights Chat Control 1.0](https://www.patrick-breyer.de/en/eu-parliament-greenlights-chat-control-1-0-breyer-our-children-lose-out/) - [fightchatcontrol.eu — status and September 2026 outlook](https://fightchatcontrol.eu/) - [GFF — Chatkontrolle analysis](https://freiheitsrechte.org/en/themen/freiheit-im-digitalen-zeitalter/chatkontrolle) - [BfDI — CSA-Verordnung](https://www.bfdi.bund.de/DE/Fachthemen/Inhalte/Telemedien/CSA_Verordnung.html)