Encryption
Chatalot uses Signal Protocol-based end-to-end encryption to protect your messages.
Direct messages: the server never sees plaintext message content — only encrypted blobs pass through it. X3DH + Double Ratchet, keys generated and held on your device.
Group and community channels: this protection is weaker by default, and you should know how. Group messages are encrypted with a Sender Key. In the default configuration the sender uploads that key's chain key to the server as part of the key distribution, so the server holds the material from which group message keys are derived. A server operator, or anyone with database access, can therefore read group message content. This is a real limitation of the default setup, not a theoretical one.
A pairwise distribution mode (v2) removes this: each member's copy of the sender key is individually encrypted to them, and the server only ever stores ciphertext.
The default for sender_key_v2_enabled is false. A Chatalot instance ships with pairwise group-key distribution OFF; group message keys are handed to the server unless an operator has explicitly turned it on.
If you run a self-hosted instance and want group
confidentiality from the server, you must turn it on. If you use someone else's instance,
ask them whether it is on — there is currently no way to tell from the app.
Status. DM encryption is complete and in effect. Group encryption is in effect, but server-side confidentiality for group channels is NOT provided in the default configuration — see above. Per-message encryption indicators and fingerprint verification are available in the UI.
An earlier version of this page stated flatly that "the server never sees plaintext message content". That was true for direct messages and not true for group channels on the default configuration. It is corrected here rather than deleted, because a removed sentence reads as a property nobody ever claimed, and this one was relied upon.
Pages
| # | Page | Description |
|---|---|---|
| 1 | Overview | Why E2E encryption matters and what Signal Protocol provides |
| 2 | How It Works | High-level encryption flow for DMs and group channels |
| 3 | Key Management | Identity keys, prekeys, key generation, rotation, and storage |
| 4 | DM Encryption | X3DH key agreement and Double Ratchet for private messages |
| 5 | Group Encryption | Sender Keys for efficient group message encryption |
| 6 | Verification | Safety numbers, fingerprints, and trust-on-first-use |
| 7 | Limitations | What is not encrypted and other security boundaries |
| 8 | Technical Details | Cryptographic primitives, wire formats, and protocol specification |
Implementation Status
| Component | Status |
|---|---|
| ChaCha20-Poly1305 AEAD | Implemented and tested |
| Ed25519 identity keys | Implemented and tested |
| X3DH key agreement | Implemented and tested |
| Double Ratchet | Implemented and tested |
| Sender Keys (groups) | Implemented and tested — but see the confidentiality note above: the default mode gives the server the chain key |
| Pairwise sender-key distribution (v2) | Implemented — OFF by default, enabled per instance via sender_key_v2_enabled |
| Safety numbers | Implemented and tested |
| WASM bridge | Compiled and bundled |
| Web client integration | Complete |
| Per-message encryption indicators | Complete |
| Fingerprint verification modal | Complete |
| TOFU key change detection | Complete |
| Key storage (IndexedDB) | Complete |
| Key storage (desktop) | Planned (OS keychain) |
The crypto library includes 23 unit tests covering all protocols, including edge cases such as out-of-order messages, tampered ciphertext, invalid signatures, and session serialization round-trips.
Source Code
The encryption implementation lives in the following locations:
- Rust crypto crate:
crates/chatalot-crypto/src/-- X3DH, Double Ratchet, Sender Keys, AEAD, identity management - WASM bindings:
crates/chatalot-crypto-wasm/-- wasm-bindgen exports for browser use - Web client crypto:
clients/web/src/lib/crypto/-- KeyManager, SessionManager, CryptoStorage (IndexedDB) - Server key routes:
crates/chatalot-server/src/routes/keys.rs-- prekey bundle exchange - Server sender key routes:
crates/chatalot-server/src/routes/sender_keys.rs-- group sender key distribution