This page is informational. You do not need this knowledge to build (the Chat XDK performs every operation here for you).
The big picture
Let’s look at the entire flow from account creation up to sending / receiving messages.1
Account creation
Here the Chat XDK generates two keypairs on your device:
- an identity keypair, for receiving secrets
- a signing keypair, for proving authorship
2
Conversation creation
To message you, a sender generates a fresh conversation key, a symmetric key that will encrypt the messages.They fetch your public key from the X backend, verify the signature on it, and encrypt the conversation key to your identity key.This is a crucial property of public key cryptography, anyone can encrypt to your public key; only your private key can decrypt, and only you hold it. So X can store and deliver the encrypted copy, but never open it. (For the exact schemes used, see the glossary.)Why don’t we just encrypt the messages directly to your public key? Speed: public key encryption is much more expensive than symmetric key encryption, so exchanging a key enables better efficiency for subsequent messages.
3
Messaging
When someone messages you, you will receive the conversation key, encrypted with your identity public key, and the messages encrypted with the conversation key.You use your identity private key to decrypt the conversation key (again, only you hold this key) and then use the resulting conversation key to decrypt the messages.Every so often, keys in a conversation rotate (a new symmetric key is shared), for different reasons. Therefore, each conversation key has a version so participants can always know they are using the right key.
4
Signing
Encryption lets anyone send you a message, which only you can decrypt. Signing is, in some sense, the opposite, it lets you (and only you) sign a message, and anyone verify the signature. Practically, the private key is necessary for signing, and the public key can be used for verifying.In X Chat, every sender signs their message. Signatures prove both who signed the message and the exact bytes signed, so all recipients can verify that this exact message was what the sender typed. Again, the XDK handles this for you; we cover the details in Signatures explained.
Putting it together
X Chat composes three standard cryptographic tools, each doing the one job it is good at:- A conversation key encrypts messages: symmetric, fast enough for all message and media traffic.
- An identity keypair delivers conversation keys to each participant without anyone else (including X) seeing them.
- A signing keypair proves authorship: every message carries a signature recipients verify.
A worked example
Let’s walk through what actually happens when you create a group with Bob and Carol.1
Generate the conversation key
The XDK generates a fresh random conversation key. So far it exists only in memory on your device.
2
Fetch and verify participant keys
Your app fetches Bob’s and Carol’s public keys from the X backend and verifies the signature on each. If a signature doesn’t check out, you stop; never encrypt to a key you couldn’t verify.
3
Wrap the key to each participant
The XDK wraps the conversation key three times: to Bob’s identity public key, to Carol’s, and to your own (so your other devices can read it too).
4
Sign the change
The XDK signs a payload describing exactly this change: the group, its members, the wrapped keys. Creating a group needs two action signatures; the XDK produces both for you.
5
Publish
Your app POSTs the wrapped copies and signatures to X. The server stores three encrypted blobs it cannot open. At no point did the raw conversation key leave your device!
6
Bob reads
Bob’s XDK unwraps his copy with his identity private key, verifies the key change came from you, and holds the raw conversation key.
Secure key backup: distributed key storage
Earlier we said your private keys are saved to secure key backup, recoverable only with your passcode. Let’s look at how that works, because it is the part people are most skeptical about: how can keys be backed up without X being able to read them?The problem with traditional key storage
How secure key backup solves it
X Chat uses the open-source Juicebox protocol, which combines threshold secret sharing with passcode protection. The full protocol is specified there; the short version: Storing (once, at account creation). The XDK splits your private keys into shares and distributes them to three realms, separate services isolated from one another. All three are operated by X, so isolation alone would not mean much. That is where hardware comes in: two of the realms live inside hardware security modules (HSMs), tamper-resistant hardware that will not give up its share to anyone, not even an X administrator with full server access. A share on its own reveals nothing, and recovery requires shares from two of the three realms, so every possible recovery goes through at least one HSM: there is no software-only path to your keys. The HSM software and the key ceremony that provisioned it are publicly documented. Recovering (new device). You enter your passcode, and the XDK proves to each realm that you know it. The Juicebox protocol makes this possible without the passcode ever leaving your device. Each realm that verifies you releases its share of your keys, and once two of the three respond, the XDK puts your keys back together on your device. Guess limits. Each realm allows at most 20 wrong passcode attempts. On the 20th wrong attempt, your key share is deleted from the realm. This is hardware-enforced by the HSMs and protects against any brute-force attack. The result: you can recover your keys on a new device with just your passcode, no single realm ever holds the whole secret, and the hardware-backed realms enforce their limits even against X itself.You do not configure any of this by hand. The Chat XDK includes the backup client, and realm configuration arrives from the X backend with your public-key record. Passcode storage and unlock are Chat XDK calls; see initialize with existing keys and create and register keys. Servers and bots often skip backup and use an exported key blob instead; protect it like a password.
Signatures explained
Every message’s signature gives recipients two guarantees:- Authenticity: produced by the holder of the sender’s signing private key
- Integrity: the encrypted content was not modified after signing
reply_preview_validation (Valid / Invalid). An Invalid outcome means the quote does not match the signed original—treat the quoted material as untrusted, even though the reply itself is verified separately—so no participant can attribute fabricated words to another.
Signed state changes (action signatures)
Messages are not the only thing signed. Every change to a conversation (creating a group, adding members, rotating a key) must also carry action signatures: the sender signs a payload describing exactly what the change does, and the API rejects requests where these are missing or malformed. The XDK produces them for you. Why the server cannot fully verify a key change. The server never holds the raw conversation key (that is the point), so it cannot check a signature over material it cannot see. It checks what it can, that the signed description matches the request, and recipients do the real cryptographic check when they unwrap the key change. Events are immutable: one that fails verification is permanently invalid. See Troubleshooting.Security properties
Here is what X Chat protects against, and just as important, what it does not.What X Chat protects against
What X Chat does not protect against, and why
Glossary
Next steps
Getting Started
Implement keys, send, and receive step by step
Chat XDK Reference
Encryption SDK methods and types
Introduction
Product overview and architecture
Real-time events
How encrypted events are delivered