From 1781b9f0ee2419e77fdd37b7a060dfcc6353c208 Mon Sep 17 00:00:00 2001 From: maverick Date: Wed, 22 Jul 2026 02:06:59 +1000 Subject: [PATCH] Add README with architecture overview Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..f4e0463 --- /dev/null +++ b/README.md @@ -0,0 +1,69 @@ +# Cipher + +End-to-end encrypted messenger — a WhatsApp/Signal-style app running entirely on Cloudflare. + +**Live:** https://cipher.theradicalparty.com + +## Design + +The server is a **dumb key directory + encrypted relay**. It never sees message +plaintext or private keys — only public keys and ciphertext. Real-time delivery +plus offline store-and-forward, so messages arrive even when the recipient is away. + +| Concern | How | +|---|---| +| Encryption | **Signal Protocol** (X3DH + Double Ratchet) via libsignal, in the browser | +| Real-time + offline queue | Per-user **Mailbox Durable Object** (WebSocket + SQLite queue) | +| Key directory | **D1** — users, devices, prekey bundles (public keys only) | +| Media | Client-side AES-GCM, ciphertext stored in **R2**; key travels inside the E2E message | +| API | **Hono** on Workers | +| Client | Installable **PWA**, IndexedDB key store, Web Push wake-up | +| Identity | Username + password; QR device-linking planned | + +Private keys are generated on the device and stored only in IndexedDB. They are +never transmitted. See `docs/` notes inline in each source file. + +## Architecture + +``` + Alice (PWA) Cloudflare Worker Bob (PWA) + ┌─────────────┐ publish pubkeys ┌──────────────┐ + │ libsignal │ ──────────────────► │ D1 key dir │ + │ IndexedDB │ ◄── prekey bundle ─ │ │ + └─────┬───────┘ └──────────────┘ + │ encrypt (X3DH/ratchet) + │ POST ciphertext ┌──────────────┐ WS push ┌──────────┐ + └───────────────────────────► │ Mailbox DO │ ───────────► │ decrypt │ + │ (queue+WS) │ or queue │ locally │ + encrypt media (AES-GCM) ─► R2 └──────────────┘ └──────────┘ +``` + +## Develop + +```bash +npm install +npm run dev # local Worker + assets +npm run db:migrate:local # apply schema to local D1 +``` + +## Deploy + +Push to `main` → Forgejo post-receive hook runs `wrangler deploy`. + +```bash +git pushall main # pushes to Forgejo (origin) + GitHub (backup) +``` + +## Vendored crypto + +`public/js/vendor/libsignal.js` is a self-contained browser bundle of +`@privacyresearch/libsignal-protocol-typescript` (built with esbuild + a Buffer +shim). Rebuild with the esbuild command noted in the commit history if bumping +the library — loading crypto from a CDN at runtime is intentionally avoided. + +## Status + +Working: registration, login, key directory, E2E text + media, real-time and +offline delivery (both verified live). Planned: QR multi-device linking, group +chats (sender keys / MLS), WebRTC voice/video, Web Push fan-out, delivery/read +receipts, disappearing messages.