Threat model
We assume the network and our own server are hostile: they can record, delay, replay and modify traffic, and they serve the key directory. We also assume a future adversary with a large quantum computer who has recorded today’s traffic (“harvest now, decrypt later”).
Goals: confidentiality and integrity of content; forward secrecy and post-compromise security in one-to-one chats; sender anonymity towards the server; no silent key substitution; post-quantum confidentiality for every layer that carries content keys.
Out of scope: a compromised device, and traffic analysis by a global passive observer beyond what padding, randomised group delivery and Tor reduce.
Primitives and standards
Only standardised primitives from established, reviewed libraries; no home-made cryptography. One shared core produces identical results on Android, iPhone and computers.
Identity, safety number and key transparency
Every account has a hybrid signing identity and a hybrid encryption identity. The public address is derived from the post-quantum signing key. The safety number is the same on both sides. Version 2 covers all four identity keys — secp256k1, X25519, ML-DSA-65 and ML-KEM-1024 — and is used when both sides have announced it inside their encrypted messages; with an older version the pair falls back to version 1, which covers the classical keys, and the post-quantum keys are then covered by the transparency log. Once announced, version 2 is pinned: if it disappears, the app warns that the key has changed instead of falling back silently.
The server keeps an append-only Merkle log of identity keys. The app checks the tree head, signed with Ed25519 and ML-DSA-65, and an inclusion proof, so the directory can’t serve a key it didn’t log — including the post-quantum key and the protocol version, which prevents a silent downgrade.
Sealed envelope
Each one-to-one envelope is sealed to the recipient with a classical exchange and a post-quantum encapsulation. The key derivation is bound to a hash of the transcript — the ephemeral key, the ML-KEM ciphertext and the recipient’s keys — as X-Wing does. A full envelope carries a fresh capsule; in between, short envelopes take their keys from a pair secret that both sides have confirmed, moved forward through a one-way chain, so the capsule isn’t repeated in every message. The sender’s identity travels inside, so the server sees neither who wrote nor, from the address, who receives. Envelopes are padded to size classes.
Double Ratchet with a post-quantum step
Inside the envelope, a Double Ratchet session changes keys with every message. A post-quantum secret is periodically mixed into the root key, so a conversation recorded today stays closed even if the classical part is broken later, and the session heals after a key compromise.
Hybrid signatures
Messages, key bundles and device certificates carry two signatures — secp256k1 and ML-DSA-65. A signature is accepted only if both verify, so a forgery requires breaking both schemes.
Files
Every file is encrypted with its own random key after padding, so its stored size reveals little. The file key reaches the recipient wrapped with the same hybrid as messages, independently of the channel that carries the file description. The server deletes the file after delivery.
Groups (MLS)
Groups use the MLS standard with the X-Wing post-quantum suite. Post-quantum protection covers every operation that distributes keys — invitations, adding and removing members and every epoch change — not only the first key exchange. Existing groups are migrated in place with their history.
MLS member signatures are Ed25519, as the standard defines today. On top of them, every Commit, Proposal and Welcome carries an ML-DSA-65 signature over the MLS frame and the member list, and each sender’s ordinary messages form a hash chain closed by regular ML-DSA-65 checkpoints. Once a member has announced post-quantum signatures, a change in their name without one is rejected. A phone signs with the account key; a linked computer with its own device key, certified by the account.
Every member also refreshes its own leaf regularly with an UpdatePath commit, so the group heals after a key compromise even when nobody joins or leaves. Members on old versions don’t add the ML-DSA-65 signature; their changes are accepted with Ed25519 alone.
Calls and screen sharing
Media is encrypted with DTLS-SRTP between devices, and the relay only forwards ciphertext. Because DTLS key agreement is classical, every audio, video and screen frame is encrypted a second time with keys from a hybrid exchange carried inside the end-to-end encrypted call setup. One-to-one calls, transfers between devices and every pair in a conference get their own keys.
Linking a computer
The computer shows a short-lived QR code; the phone runs a hybrid key exchange bound to the transcript, both screens show the same 6-digit code, and keys are confirmed in both directions. The phone then certifies the computer’s own long-term keys. The account’s private keys are never transferred, and an unlinked computer erases its data.
Communities
Every channel has its own pseudonym with its own keys, so channels can’t be linked to each other or to your account. All asymmetric operations are hybrid — Ed25519 + ML-DSA-65 for signatures, X25519 + ML-KEM-1024 for encryption — and private channels encrypt posts, files and metadata end to end.
Delivery and metadata
Envelopes go to delivery addresses that only the two parties can compute; they aren’t tied to an account, and once both sides run the new version they are derived from the post-quantum envelope secret as well. From the next release the address of a pair also changes every week; the boundary is the same for everyone, so a change doesn’t single out a conversation. The switch is negotiated inside the encrypted conversation, and the app keeps listening on the neighbouring weeks, so nothing is lost at the boundary or while a device is offline. With a contact on an older version, and for linked computers, the address doesn’t change yet. An app checks all its mailboxes over one connection, so a server watching live can group the addresses of one device. Push wake-ups go to a per-device wake handle that isn’t linked to any mailbox address; the handle is shared with contacts only inside end-to-end encrypted messages. Anonymous endpoints carry no account token. Sizes are padded, and a group message leaves as separate envelopes in random order with small random delays. The connection to the server uses TLS 1.3, and with Tor turned on the server doesn’t see the IP address; without Tor it does.
On the device
Local databases are encrypted, and their keys are held by the system keystore of each platform. Key backups and chat exports are encrypted with a key derived from your password by Argon2id.
Why it holds
Every layer that protects content keys combines a classical and a post-quantum secret, so it stays secure as long as at least one of them does. Signatures are a conjunction: a forgery needs both schemes broken.
There is no independent audit yet. We have applied for one and will publish the report in full. If you find a problem, write to the contacts in SECURITY.md — we fix it, ship the fix and say what was wrong.
Check it yourself
The cryptographic core and its tests are open source under Apache-2.0. Reference vectors pin every primitive byte for byte. On the Proof page you can watch the tests run and see what the relay records in Wireshark.