Key MLS concepts
Group / Epoch
An MLS group is a set of members sharing a common cryptographic state. Each time the
group membership or keying material changes, the group advances to a new epoch.
Every epoch has a fresh symmetric encryption secret derived via the MLS key schedule.
Key Package
A
KeyPackage is a signed bundle containing a client’s identity credential and a
short-term HPKE public key. It is published to a key-distribution service and
consumed by a group member when adding the client to a group.Proposal
A proposal is a signed statement of intent: add a member, remove a member, or
update keying material. Proposals are queued and do not take effect until a commit
is created and merged. The bundle returned by proposal operations is
MlsProposalBundle.Commit
A commit finalises one or more pending proposals and advances the epoch. The committer
sends an
MlsCommitBundle to the delivery service, which fans it out to all current
members. New members receive a WelcomeBundle derived from the same commit.CoreCrypto’s MLS implementation
CoreCrypto’s MLS layer wraps OpenMLS — specifically a Wire-maintained fork that tracks upstream closely while incorporating Wire-specific patches. The fork is pulled in via theopenmls crate dependency and is not a hard fork in terms of
protocol compatibility.
Entry point: Session
Session (in crypto/src/mls/session/mod.rs) is the per-device MLS context. It maps to
the RFC 9420 concept of a Client but is named Session to avoid ambiguity with the word
“client” in product contexts.
Session exists per user device. It is created lazily via
TransactionContext::mls_init and stored inside CoreCrypto. A session can hold many
MLS conversations.
MlsConversation
MlsConversation wraps an OpenMLS MlsGroup and is the object on which all group
operations are performed. It holds:
id: ConversationId— an application-defined byte-slice identifierparent_id: Option<ConversationId>— for sub-conversationsgroup: MlsGroup— the underlying OpenMLS group stateconfiguration: MlsConversationConfiguration— ciphersuite, wire policy, custom extensions
| State | Encrypt | Handshake | Merge | Decrypt |
|---|---|---|---|---|
| 0 pending proposals, 0 pending commits | ✅ | ✅ | ❌ | ✅ |
| 1+ pending proposals, 0 pending commits | ❌ | ✅ | ❌ | ✅ |
| 0 pending proposals, 1 pending commit | ❌ | ❌ | ✅ | ✅ |
| 1+ pending proposals, 1 pending commit | ❌ | ❌ | ✅ | ✅ |
MlsCommitBundle
Every commit operation returns an MlsCommitBundle:
commit and welcome go to separate endpoints.
MlsTransport — the application callback
CoreCrypto does not send messages over the network itself. Instead, the application
must implement the MlsTransport trait and pass it to mls_init:
MlsTransportResponse::Success— message acceptedMlsTransportResponse::Retry— consume pending incoming messages and retryMlsTransportResponse::Abort { reason }— unrecoverable rejection
Retry, CoreCrypto automatically processes the queued messages and re-sends the
commit, so the application does not need to implement retry logic manually.
Group creation flow
Begin a transaction and initialise the MLS session
Session, which loads or creates the client’s identity keypair and
restores any previously persisted conversations.Add a credential and generate key packages
Invite other members
Welcome messages. CoreCrypto calls
MlsTransport::send_commit_bundle automatically.Supported ciphersuites
CoreCrypto delegates ciphersuite support entirely to OpenMLS. The default ciphersuite is:MlsConversationConfiguration. Hash algorithm selection (SHA-256, SHA-384,
SHA-512) is determined automatically by the chosen ciphersuite.