| Internet-Draft | MLS Hybrid KEM | October 2026 |
| Maia, et al. | Expires 29 April 2027 | [Page] |
This document specifies a hybrid classical/post-quantum Key Encapsulation Mechanism (KEM) for use in the ratchet trees of the Messaging Layer Security (MLS) protocol. Each parent node of the ratchet tree carries both a classical and a post-quantum public key, and a direct path update encapsulates to both. The combiner binds both ciphertexts and both public keys, so that the derived node secret is pseudorandom if at least one of the two KEMs remains IND-CCA secure, including against an adversary that controls the keys and ciphertexts of the broken KEM.¶
This document also specifies an optional asynchronous mode, in which fresh post-quantum output is produced only on designated rotation commits rather than on every commit. Asynchronous mode trades a bounded delay in post-quantum post-compromise recovery for a reduction in post-quantum bandwidth proportional to the rotation interval. Forward secrecy within the rotation window is retained by a one-way ratchet.¶
This document is independent of the MLS Combiner draft, which achieves hybrid security by a different mechanism: running a pure post-quantum and a traditional MLS session in parallel and injecting a secret exported from the former into the latter as a pre-shared key.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 29 April 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
The Messaging Layer Security (MLS) protocol [RFC9420] provides continuous group key agreement with cost logarithmic in the group size, by arranging members as the leaves of a ratchet tree. An adversary who records MLS ciphertext today may be able to decrypt it once a cryptographically relevant quantum computer exists. Migrating MLS to post-quantum key agreement therefore has value independent of when such a computer arrives.¶
A hybrid construction runs a classical and a post-quantum primitive together, so that confidentiality survives the failure of either. This document specifies such a construction for the MLS ratchet tree. Each parent node carries a classical and a post-quantum public key; a direct path update encapsulates to both and derives the node secret using the combiner of Section 3.¶
The objective is that the robustness property, namely that the node secret is pseudorandom if at least one of the two KEMs is IND-CCA secure, holds under a precise and implementable construction, and holds against an adversary that controls the broken KEM's keys and ciphertexts.¶
Section 7 defines an optional asynchronous mode in which fresh post-quantum output is produced only on designated rotation commits. Post-quantum bandwidth is reduced by a factor equal to the rotation interval, at the cost of a bounded delay in post-quantum post-compromise recovery.¶
This document is not an update to [I-D.ietf-mls-combiner]. That document specifies a different mechanism: two complete MLS sessions are run in parallel over the same membership, and hybrid security is obtained by exporting a secret from the post-quantum session and importing it into the traditional session as a Pre-Shared Key, carried by an ordinary PreSharedKey proposal. It contains no per-commit key mixing step, no classical and post-quantum shared secret pair, and no combiner context string. The requirements in this document therefore have no counterpart in its text.¶
The two approaches are alternatives rather than revisions of one another. The parallel session approach requires no new cryptographic primitive and runs on unmodified MLS implementations, at the cost of duplicated group state, KeyPackages and commit traffic. The approach specified here requires a new ciphersuite and changes to the tree KEM, and keeps a single group state and a single commit stream.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
This document uses the following notation.¶
The operator || denotes concatenation. HKDF-Extract and HKDF-Expand are as defined in [RFC5869].¶
Implementations MUST compute the node secret as follows.¶
ctx_enc = lv("MLS-Hybrid-KEM-Combiner")
|| combiner_version
|| lv(CTX)
|| lv(ALG_C)
|| lv(ALG_P)
IKM = lv(K_C) || lv(K_P)
|| lv(ct_C) || lv(ct_P)
|| lv(pk_C) || lv(pk_P)
PRK = HKDF-Extract(salt = ctx_enc, IKM = IKM)
KEY = HKDF-Expand(PRK, info = ctx_enc, L)
¶
The ciphertext and public key fields in IKM MUST NOT be omitted. Without them the construction is not robust against an adversary that controls the broken KEM, because distinct ciphertexts that decapsulate to the same shared secret would yield the same node secret. See Section 8.¶
All secret material MUST be supplied in IKM and MUST NOT be supplied in the salt argument, so that the construction remains within the extract-then-expand model without assuming that HMAC is a dual-PRF.¶
The info argument MUST be ctx_enc verbatim. It MUST NOT be an independent re-concatenation of the same fields, so that the expand stage cannot be made ambiguous independently of the extract stage.¶
The hash function MUST be SHA-256 for L = 32 and SHA-512 for L = 64, and MUST match the hash of the negotiated MLS ciphersuite. K_C, K_P, IKM, PRK and all intermediate buffers MUST be zeroized immediately after use.¶
For n > 2 inputs, callers MUST sort the algorithm identifiers lexicographically, append lv(ALG_i) to ctx_enc in that order, and append lv(K_i) || lv(ct_i) || lv(pk_i) to IKM in the same order.¶
The number of fields is determined by the algorithm list carried in ctx_enc. Together with universal length prefixing, this keeps the encoding injective for every n.¶
CTX MUST be computed as follows.¶
CTX = lv(group_id)
|| epoch
|| lv(confirmed_transcript_hash)
|| node_index
¶
Here epoch is an 8-byte big-endian unsigned integer and node_index is a 4-byte big-endian unsigned integer, both as defined by [RFC9420].¶
The node index MUST be included so that two nodes on the same direct path cannot derive the same secret. The epoch and confirmed transcript hash MUST be included so that the derivation cannot be replayed into another commit.¶
A HybridKEMParameters structure MUST be carried in MLS Commit and Welcome messages.¶
struct {
uint8 combiner_version;
opaque algorithms<V>; /* ordered list of ALG ids */
uint16 desired_key_length; /* L in bytes */
} HybridKEMParameters;
¶
Recipients MUST verify that the listed algorithms match those they support, and that combiner_version is recognised. On mismatch they MUST reject the commit. Silent fallback to a non-hybrid mode MUST NOT be permitted.¶
Each input K_i supplied to IKM MUST be the full, untruncated shared secret output of a registered classical or post-quantum primitive, and MUST be at least 256 bits in length.¶
Pre-hashing or compression of K_i prior to combiner invocation MUST preserve the source min-entropy. Lossy transformations MUST NOT be applied.¶
Ciphersuite registrations whose shared secret output does not meet this floor MUST NOT be listed in HybridKEMParameters.algorithms.¶
If decapsulation of any listed input fails, the recipient MUST abort processing of the Commit, MUST NOT advance the group epoch, and MUST emit an MLS-level error indicating the failing algorithm identifier.¶
Implementations MUST NOT substitute zero, constant or fallback values for a failed input, and MUST NOT derive KEY from a strict subset of the listed inputs.¶
ML-KEM [FIPS203] uses implicit rejection and returns a pseudorandom value rather than an error when decapsulation fails. This output MAY be supplied to the combiner only if no out-of-band signal indicates failure. An example of such a signal is a subsequent MAC verification on a key derived from KEY. On such a signal the recipient MUST treat the commit as failed and trigger a rekey through the standard MLS Update and Commit flow.¶
An implementation MAY operate the hybrid KEM specified above in asynchronous mode, in which fresh post-quantum output is produced only on designated rotation commits. The preceding sections remain normative for rotation commits themselves.¶
Asynchronous mode reduces post-quantum bandwidth by a factor equal to the rotation interval k. It provides a strictly weaker post-quantum guarantee than synchronous operation, as described in Section 8.2.¶
Each member MUST maintain the following additional state.¶
The counter and the rotation context MUST be carried in a GroupContext extension, so that every member derives them identically.¶
A commit MUST be a rotation if pq_rotation_counter has reached k, or if the commit contains an Add, Remove or ReInit proposal, or if the commit is an external commit. The counter MUST be reset to zero on every rotation, from either cause, so that the window is at most k commits.¶
The rotation interval k MUST be fixed by the ciphersuite. It MUST NOT be negotiable, carried in any message field, or otherwise influenced by group members. A negotiable window would be an attacker-influenceable parameter whose only useful direction of attack is to widen it, lengthening exposure and delaying recovery.¶
Ciphersuites defined by this document use k = 32. The reasoning behind that value is given in Section 7.7. Ciphersuites defined elsewhere MUST state their own value of k, and SHOULD justify it against the same considerations.¶
The requirement to rotate on membership change is load bearing. A removed member holds S_t at the moment of its removal, and the ratchet step of Section 7.4 is a public function of S_t and public context. Absent a rotation, a removed member could compute all successor values indefinitely and would retain the post-quantum half of the group's protection after removal.¶
Recipients MUST independently compute whether the current commit is required to be a rotation, and MUST reject any commit that fails to carry a post-quantum direct path update when one is required, or whose pq_rotation_counter does not match their own computation.¶
Implementations MUST NOT accept a commit on the grounds that the committer asserted no rotation was due. Without this check, a malicious committer could decline to rotate indefinitely, reducing the construction to classical MLS with a stale secret mixed in.¶
On a rotation at epoch r with post-quantum root secret P_r, the ratchet is initialised as follows.¶
S_r = HKDF-Expand(
HKDF-Extract(mix_ctx_r, lv(P_r)),
"pq-ratchet-init", L)
¶
On every other epoch, the ratchet is advanced as follows.¶
S_t+1 = HKDF-Expand(
HKDF-Extract(mix_ctx_t+1, lv(S_t)),
"pq-ratchet-step", L)
¶
S_t MUST be zeroized immediately after S_t+1 is derived.¶
Implementations MUST NOT retain P_r beyond the derivation of S_r, and MUST NOT carry P_r forward in place of the ratcheted value. Carrying a constant value forfeits forward secrecy across the entire rotation window on a single compromise.¶
The ratchet step and the mixing step of Section 7.5 share mix_ctx_t, which is available only once the confirmed transcript hash for epoch t has been computed. Implementations MUST sequence the epoch as follows: compute confirmed_transcript_hash_t, derive S_t from S_t-1, zeroize S_t-1, then derive hybrid_commit_secret_t. The two formulae are not circular, but the ordering is normative rather than an implementation detail.¶
The epoch's classical commit_secret, as defined in [RFC9420], and the ratchet secret MUST be combined as follows.¶
mix_ctx_t = lv("MLS-Async-Hybrid-Mixer")
|| version
|| lv(group_id)
|| epoch_t
|| lv(confirmed_transcript_hash_t)
|| lv(ALG_C)
|| lv(ALG_P)
|| lv(pq_rotation_ctx)
hybrid_commit_secret_t =
HKDF-Extract(salt = mix_ctx_t,
IKM = lv(commit_secret_t) || lv(S_t))
¶
hybrid_commit_secret_t MUST be used wherever MLS uses commit_secret.¶
pq_rotation_ctx MUST be included. It binds the ratchet state to the rotation that produced it, and prevents substitution of a state descended from a different rotation. On a non-rotation commit there is no post-quantum ciphertext to bind, so this field takes the place of the per-node ciphertext binding required by Section 3.¶
On rotation commits, Section 6 applies unchanged.¶
On non-rotation commits there is no post-quantum decapsulation and therefore no decapsulation failure. However, if a member's S_t is absent, corrupt, or inconsistent with pq_rotation_ctx, the member MUST abort processing and re-synchronise. It MUST NOT derive hybrid_commit_secret from commit_secret alone, which would be a silent downgrade to classical-only operation.¶
This subsection is non-normative. It records why k = 32 was selected, so that the choice can be revisited on the same basis if ML-KEM parameters, MLS framing, or deployment evidence change.¶
k sets the average post-quantum cost of a commit and not the peak. A rotation commit carries the full post-quantum direct path whatever k is. Deployments whose binding constraint is maximum message size or fragmentation gain nothing from raising k, and should use synchronous operation instead.¶
The trigger counts commits rather than elapsed time because Section 7.3 requires every recipient to compute independently whether a rotation is due. That is possible only when the trigger is a deterministic function of shared group state. MLS carries no clock in the GroupContext, so a time bound would leave members with skewed clocks rejecting each other's honest commits, or would reduce to the committer asserting that the deadline had not passed, which is what Section 7.3 exists to prevent.¶
Post-quantum cost falls as 1/k and saturates quickly, while the exposure window grows linearly in k and does not saturate. Beyond a certain point each doubling of k buys a fraction of a percent of bandwidth in exchange for twice the worst-case recovery delay.¶
The value was therefore chosen as the smallest k at which post-quantum material ceases to dominate the commit. For a group of 1000 members (h = 10) using ML-KEM-768, a rotation commit carries 2272 bytes per node, being one 1088-byte ciphertext and one 1184-byte public key, or about 22.2 KiB in total. Against a classical direct path of roughly 1.3 KiB for the same tree, k = 32 reduces the overhead of a commit from about 18 times the classical baseline to about 1.5 times, capturing roughly 97 percent of the available reduction. k = 64 recovers a further 1.5 percentage points for twice the window, and k = 16 leaves the post-quantum contribution roughly equal to the entire classical commit.¶
k bounds commits and not elapsed time, and the two are related by a commit rate that varies by orders of magnitude between deployments. No fixed constant can bound both, which argues for choosing conservatively. Two effects limit the consequences: membership changes force a rotation, so k binds only in membership-stable groups, and the window is exploitable only by an adversary that has both compromised ratchet state and broken the classical KEM.¶
Making k a function of group size was considered. It would satisfy Section 7.3, since the tree is shared state, and would let one ciphersuite serve a wide range of group sizes. It is not adopted here because it would weaken the property that the worst-case window is known from the ciphersuite alone, group size being something participants can influence, and because the case for it rests on commit-rate measurements that are not yet available. A clamped form, with a coefficient, a floor and a ceiling all registered alongside the ciphersuite, would bound the worst case and remains the natural candidate if evidence later shows that a single constant serves the extremes of the size range badly.¶
Under the HKDF extract-then-expand model, if at least one component of IKM has computational min-entropy t from the adversary's view, with t at least 256 as required by Section 5, then KEY is indistinguishable from random with bounds derived from the randomness-extractor security of HKDF-Extract.¶
The guarantee is stated against a strong adversary. One of the two KEMs may be entirely broken, with the adversary choosing its public key, ciphertext and shared secret adaptively. Robustness in that setting depends on two properties of Section 3 that are easily lost in implementation.¶
First, IKM is an injective encoding of its six fields, so that no two distinct input tuples collide. This is why every field is length prefixed, and why no delimiter characters appear anywhere, including in fields such as group_id whose byte content is unconstrained by [RFC9420].¶
Second, both ciphertexts and both public keys are bound into the extract step, so that a broken KEM admitting two ciphertexts that decapsulate to the same shared secret still yields two distinct node secrets. A construction that mixes only K_C and K_P satisfies neither property and MUST NOT be used.¶
This requirement is not specific to MLS. The same binding appears in [I-D.connolly-cfrg-xwing-kem], which hashes the X25519 ciphertext and public key alongside the ML-KEM shared secret for the same reason.¶
Implementations SHOULD provide constant-time KDF code paths and platform-level zeroization.¶
PRK is a per-invocation secret. Implementations MUST NOT cache PRK across invocations, MUST NOT write PRK to persistent storage, and MUST NOT reuse PRK across distinct combinations of CTX, algorithms and combiner_version, even when one or more K_i are unchanged between invocations.¶
This requirement is generic KDF hygiene in synchronous operation, but it is load bearing in asynchronous mode. Because one input is unchanged between rotations, a PRK object held across epochs is an obvious implementation shortcut. mix_ctx_t includes the epoch and the confirmed transcript hash, so the extract input does differ at every epoch and a correct implementation has no reusable value; the risk is that a long-lived PRK object in an HKDF or HPKE wrapper keeps material alive that the ratchet of Section 7.4 is required to have destroyed.¶
PRK, IKM, every K_i, and any platform scratch buffers used by the KDF MUST be zeroized before the combiner returns. KEY itself MUST NOT be reused across commits.¶
Let R be the set of rotation epochs, and for an epoch t let r(t) be the greatest element of R that is less than or equal to t. The epoch secret at epoch t is pseudorandom if either of the following holds.¶
The second condition is weaker than its synchronous counterpart, which reads simply that the post-quantum KEM is secure at epoch t. The one-way ratchet of Section 7.4 sharpens it: a compromise at epoch u exposes only the epochs from u up to the next rotation, and not those preceding u.¶
Forward secrecy therefore holds within the rotation window. Post-quantum post-compromise security does not hold within the window, and is restored only at the next rotation: within k commits, and immediately on any membership change.¶
Because S_t is mixed into the key schedule of every epoch, and not only into rotation epochs, there is no epoch whose secret depends on the classical primitive alone. An adversary that has broken the classical KEM entirely still cannot derive any epoch secret without the post-quantum material.¶
Implementations MUST document the rotation interval k of each ciphersuite they support, so that deployments can evaluate the worst-case post-compromise recovery delay.¶
This document requests that IANA establish two new registries in the "Messaging Layer Security (MLS)" group of registries, and requests allocations in an existing registry as described below.¶
The registration policy for this registry is Specification Required. Each entry contains a version value (an 8-bit unsigned integer), a name, a reference, and a change controller. The initial contents are as follows.¶
| Value | Name | Reference |
|---|---|---|
| 0x00 | Reserved | This document |
| 0x01 | MLS-Hybrid-KEM-Combiner-v1 | This document |
| 0x02-0xFF | Unassigned |
The registration policy for this registry is Specification Required. Each entry contains an identifier, the name of the KEM, the length in bytes of its shared secret output, whether the KEM is classical or post-quantum, a reference, and a change controller.¶
A registration whose shared secret output is shorter than 256 bits MUST NOT be accepted, as required by Section 5. The initial contents are as follows.¶
| Identifier | KEM | Secret bytes | Class | Reference |
|---|---|---|---|---|
| DHKEM-X25519 | DHKEM(X25519, HKDF-SHA256) | 32 | Classical | RFC 9180 |
| DHKEM-P256 | DHKEM(P-256, HKDF-SHA256) | 32 | Classical | RFC 9180 |
| ML-KEM-768 | ML-KEM-768 | 32 | Post-quantum | FIPS 203 |
| ML-KEM-1024 | ML-KEM-1024 | 32 | Post-quantum | FIPS 203 |
This document requests allocation of MLS ciphersuite code points pairing each registered classical KEM with each registered post-quantum KEM. A ciphersuite that supports asynchronous mode (Section 7) MUST register its rotation interval k as part of the ciphersuite definition, because k is not negotiable. The ciphersuites requested by this document register k = 32, for the reasons given in Section 7.7.¶
This non-normative section collects the requirements most likely to be missed in implementation, in approximate order of consequence. It introduces no new requirements.¶
The analysis that led to this document benefited from a detailed review that identified a mischaracterisation of [I-D.ietf-mls-combiner] in an earlier draft, and from the observation that a combiner over shared secrets alone is not robust against an adversary controlling the broken half of the hybrid.¶