Sudo's groups are end-to-end encrypted. Every group. Every message. From a two-person DM up to a Stage room with two thousand connected wallets. None of those messages, including their metadata, ever exist in plaintext on a Sudo Labs server.
That sentence is easy to write and very hard to make true. The standard tool for E2EE — the Signal Double Ratchet — is excellent for one-to-one chats and acceptable for small groups, but it scales linearly with group size in a way that gets ugly fast. A 2,000-member room running pairwise Double Ratchet would need 2,000 individual key exchanges every time anyone joined, left or rotated their key. That is computationally and bandwidth-prohibitive on mobile.
So Sudo does not use Double Ratchet for groups. It uses MLS — the Messaging Layer Security protocol standardised in RFC 9420 — and this post is about why that mattered, what we learnt building on it, and the small number of trade-offs we accept in exchange for actually-scalable group encryption.
Why pairwise encryption breaks above 50 members
Imagine a 50-person group chat using pairwise Signal-style encryption. When you send a message, your client encrypts it 49 times — once for each recipient — and uploads 49 ciphertexts to the relay. Each recipient decrypts only their copy. Cross-message metadata (who is talking to whom, how often, in what order) is hidden, but bandwidth grows as O(n).
At 50 members this is annoying but workable. At 500 it is painful. At 2,000 — a normal Stage attendance for a Sudo AMA — the math falls apart. The sender ratchets 2,000 keys per message. The relay stores 2,000 ciphertexts. Mobile data plans melt.
The deeper problem is membership churn. In a pairwise scheme, every join and leave triggers a fresh key exchange between the joining party and every existing member. A 2,000-person room where one person joins per minute means 2,000 key exchanges per minute. The CPU and network cost is borne disproportionately by mobile clients.
Enter MLS
MLS solves the scaling problem with a clever data structure called a left-balanced binary tree, sometimes nicknamed TreeKEM in older drafts. Every member sits at a leaf of the tree, and the tree's internal nodes hold derived keys. The root key — derived from every leaf in turn — is what actually encrypts each message.
The trick is that key updates only need to touch the path from a single leaf to the root, which is O(log n) instead of O(n). Adding a new member to a 2,000-person tree requires updating around eleven internal nodes, not 1,999 individual key exchanges. Removing a member is the same. Rotating your own key — the operation Sudo runs every twelve hours, or earlier if your device looks compromised — is the same.
In other words: MLS is the protocol that makes "encrypted by default for everyone, even at scale" go from a marketing line to a thing you can actually ship.
What MLS gives us, in plain English
In Sudo, every group has a single live MLS state. When you join, your client downloads the state, applies the operations it has missed, and derives the current root key. That root key encrypts every new message in the room.
Forward secrecy is automatic. If your phone is compromised tomorrow, an attacker cannot decrypt yesterday's messages. Post-compromise security is also automatic. If your phone was compromised yesterday and you fix it today by rotating your keys, an attacker cannot decrypt tomorrow's messages either. Both properties hold even in a 2,000-person room, because every key rotation only needs to touch a logarithmic number of tree nodes.
When someone joins a Stage room, they cannot read messages sent before they joined. When someone leaves or is removed, they cannot read messages sent after they leave. These two properties — sometimes called "join confidentiality" and "remove confidentiality" — are the things that group chats running pairwise encryption struggle most to provide.
How Sudo implements it
The MLS spec is intentionally protocol-agnostic about transport, identity and storage. We had to make a few concrete choices.
For identity, we bind every leaf of the MLS tree to a Sudo wallet address — the same address your account is rooted in via SIWE. That means an MLS join is actually two operations: a SIWE signature proving you control the address, and an MLS welcome message proving you have been added to the group's tree. We can therefore reject welcome messages whose claimed identity does not hold a valid SIWE session, which closes a class of impersonation attacks.
For transport, we use a custom relay protocol over WebSocket that carries MLS handshake messages, application messages and welcome packages. The relay only ever sees ciphertext. Sender identity is derived from the handshake; the relay's view of the world is "ciphertext A from sender X went to room Y", nothing more.
For storage, we store the MLS state encrypted on each device, with encryption keys derived from your wallet signature. Multi-device sync uses the standard MLS commit/welcome flow — your laptop sends a welcome to your new phone, your phone joins as a new leaf, and the tree absorbs the change with a single commit.
What we don't encrypt
We have to be precise here, because no E2EE messenger encrypts everything and we would like users to know exactly where the line is.
We encrypt: message bodies, attachments, reactions, replies, edits, deletions, voice and video media payloads, presence within a room, and read receipts.
We do not encrypt: the existence of a room and its rough size; the wallet addresses of members (because membership has to be enforceable on chain for token-gated rooms); the timestamp of message arrival at the relay; and the size and frequency of each ciphertext. These metadata fields are necessary to deliver messages reliably, and we publish exactly which ones we keep.
If your threat model needs to defend against a sophisticated network adversary who sees these metadata fields, we recommend running a relay yourself or routing Sudo over Tor. Both are supported.
What we are still working on
MLS is a young standard in production terms. There are a handful of open issues we are tracking and contributing to upstream.
Federation across MLS deployments is not standardised yet. Today, a Sudo room only contains Sudo wallets — you cannot bring an MLS user from a different deployment into a Sudo room. There is active work in the IETF on a federation profile, and we plan to support it as soon as it stabilises.
Hybrid post-quantum ciphersuites are landing in MLS this year. Sudo's groups will adopt them as they become available, and we will publish a migration window in the Trust Center.
Audit transparency for tree state is an open research problem. We can prove cryptographically that the tree we present to a new joiner is consistent with the tree the rest of the room sees, but doing so without leaking who is in the room is nontrivial. We have a paper in progress; if you are an academic working on related problems, please reach out.
Why we put in the work
We could have shipped pairwise encryption that "scales" up to 30 or 50 members and called it good. Most messengers do. The reason we picked MLS instead is simple: in a Web3 messenger, communities are not just a feature — they are the product. Token-gated rooms, validator coordination, smart-contract groups, Stage AMAs, DAO governance threads. All of those workloads need group encryption that does not collapse at one or two thousand members.
MLS makes that math work. It is the unglamorous infrastructure decision behind the visible features, and we wanted to write it down.