Anzen

Security

What “sealed” means

Anzen is ciphertext-only for messages. The app calls this quantum-proof encryption (ML-KEM-1024). The server stores what it needs to deliver an envelope, and nothing it can read as a conversation.

The short version

Each account has one ML-KEM-1024 key pair. ML-KEM is a post-quantum key encapsulation method: a way to hand someone a secret so that even a quantum computer, of the kind that would break older public-key systems, is what the math is designed to resist. The message itself is locked with authenticated encryption (AES-256-GCM), a standard lock that also detects tampering.

When you send a message, the app:

  1. Makes a random key just for that message.
  2. Encrypts the message with authenticated encryption (AES-256-GCM), binding the conversation, the sender, and a sequence number into the lock.
  3. Wraps that message key to each member’s account public key with quantum-proof encryption (ML-KEM-1024). Members who do not have an account key yet get one wrap per device.
  4. Uploads the ciphertext, the nonce, and the envelopes. The scheme on the wire is ML-KEM-1024+AES-256-GCM.

People outside the conversation cannot list its messages or its keys. The same account key is what lets every device that holds your recovery secret open the same history. Messages sent before that account key existed stay tied to the devices they were encrypted for.

Keys you have to keep

The account private key is wrapped with a recovery secret the server never sees, then sealed again on the device with a PIN. The wrapped copy can sit on the server because the server cannot unwrap it. If the recovery key is lost, history sealed to that account key stays unreadable. Resetting the key from a signed-in device starts a new key, signs out every other session, and does not reopen the old history.

Copying the vault file is not enough to read it. The PIN is the barrier, so a longer PIN resists guessing better than six digits. On a phone, Face ID or a fingerprint can unlock instead of typing the PIN. That check releases the key from the device’s secure storage. The PIN itself is not stored, and it still works if the biometric check does not. The browser build does not offer this. The app locks the vault after five minutes in the background, unless a call is in progress.

What the server can and cannot see

Can see

  • Your email, username, and display name
  • Who belongs to a workspace or channel
  • Ciphertext, nonces, and recipient key envelopes
  • Public encryption keys, and a wrapped copy of the account private key that the server cannot unwrap
  • Who is typing, not the draft
  • Who is in a voice channel, plus the call-setup messages
  • Push: the sender’s name and the place, when notifications are enabled

Cannot see

  • Message text, replies, edits, and reactions
  • File names, types, and contents
  • Your PIN and your recovery key
  • Voice audio
  • Link addresses and preview titles
  • Decrypted pictures, which stay in memory until the vault locks

Voice

Voice is a direct WebRTC mesh. Each pair of people has one connection, and the call audio is encrypted (DTLS-SRTP), so the server cannot hear the call. The server does relay the setup: offers, answers, and network candidates. That signaling is not end-to-end encrypted, which means whoever runs the server could try to sit in the middle of a call.

To catch that, each pair sees a 30-digit voice privacy code, shown as six groups of five digits. It is a hash of both devices’ call certificates. If both people read the same code, nothing is between them. Only people who joined the channel can connect, and leaving a workspace ends the call there.

WebRTC normally shares device addresses with the other people in the call. “Always relay calls” restricts the connection to a TURN relay so peers see the relay’s address instead. If no relay is configured, the app refuses to join rather than fall back to a direct connection.

Files, pictures, and links

Attachments come from Photos, Camera, or Files. A file is encrypted with its own key. JPEG, PNG, and WebP pictures have location, camera, and editing details removed on the device before that happens. GIF metadata is not removed. The file’s name and type travel inside the encrypted message, not beside it.

Link previews are fetched by the reader’s device, only after that person allows the site or already trusts the host. The server never sees the address or the title. The site you preview sees your device’s IP address. The browser build does not show previews.

Sign-in

Accounts are passwordless. An email code comes first, then an authenticator app or a passkey. A new device always needs both. Trust lasts 14 days by default and can be set to 1, 7, 30, 90 days, or never. Inside that window the device still has to prove it holds its quantum-proof key (ML-KEM). A copied token is not enough. When the window has ended, device verification is authenticator-first: the app asks for the authenticator code if one is enrolled, and sends an email code only if you choose that instead. Change device PIN uses the same check.

Android backups and device transfers exclude the app’s data, and iOS excludes the vault from backup, so the PIN-sealed keys are not sitting in a cloud copy waiting to be guessed.

What this page is not

This is a description of the design in the current app, not an audit report. The shipping clients use a cross-platform ML-KEM implementation so phones and other builds can read the same envelopes. That is real encryption. It is not a substitute for an independent cryptography review, which the project still expects before a broad public launch.

Feature details · Privacy Policy · End User License Agreement