(see external-senders-extension).  The "content_type" of the message MUST be "proposal". <del> "new_member": The signature key in the LeafNode in the Commit's path (see joining-via-external-commits).  The "content_type" of the message MUST be "commit". </del>  Recipients of an MLSMessage MUST verify the signature with the key depending on the "sender_type" of the sender as described above. 13.1.8. Add and Remove proposals can be constructed and sent to the group by <del> a party that is outside the group, indicated by an "external" SenderType.  This is useful in cases where, for example, an automated service might propose to remove a member of a group who has been inactive for a long time, or propose adding a newly-hired staff </del>  member to a group representing a real-world team. ReInit proposals can also be sent to the group by an "external" to the clients within a group and can only be used if the "external_senders" extension is present in the group's GroupContext.  An external proposal MUST be sent as an MLSPlaintext object, since the sender will not have the keys necessary to construct an MLSCiphertext object. the external init secret as described in external-initialization. The sender type for the MLSPlaintext encapsulating the External <del> Commit MUST be "new_member" </del>  External Commits come in two "flavors" - a "join" commit that adds the sender to the group or a "resync" commit that replaces a member's

Add new newproposalmember SenderType and rename newmember to newcommit_member. This restores the External Proposal Add functionality which was present in the protocol for some years but clarifies how the authorization and signing takes place in this case.
Interim 2022-06-02: Could punt to extensions, but this is partly just because we moved a little too fast on the removal No objections to reverting Once conflicts and comments resolved, good to merge
LGTM, though would still prefer etc. One minor suggestion to lock down the content.

(see external-senders-extension).  The "content_type" of the message MUST be "proposal".  <ins> "new_member_commit": The signature key in the LeafNode in the Commit's path (see joining-via-external-commits).  The "content_type" of the message MUST be "commit". "new_member_proposal": The signature key in the LeafNode in the KeyPackage embedded in an External Add Proposal.  The "content_type" of the message MUST be "proposal"and the "proposal_type" of the Proposal MUST be "add". </ins> Recipients of an MLSMessage MUST verify the signature with the key depending on the "sender_type" of the sender as described above. 13.1.8. Add and Remove proposals can be constructed and sent to the group by  <ins> a party that is outside the group in two cases.  One case, indicated by an "external" SenderType is useful in cases where, for example, an automated service might propose to remove a member of a group who has been inactive for a long time, or propose adding a newly-hired staff </ins> member to a group representing a real-world team. ReInit proposals can also be sent to the group by an "external" to the clients within a group and can only be used if the "external_senders" extension is present in the group's GroupContext. <ins> The other case, indicated by a "new_member_proposal" SenderType is useful when existing members of the group can independently authorize the addition of an MLS client proposing it be added to the group. External proposals which are not authorized are considered invalid. </ins> An external proposal MUST be sent as an MLSPlaintext object, since the sender will not have the keys necessary to construct an MLSCiphertext object. the external init secret as described in external-initialization. The sender type for the MLSPlaintext encapsulating the External  <ins> Commit MUST be "new_member_commit" </ins> External Commits come in two "flavors" - a "join" commit that adds the sender to the group or a "resync" commit that replaces a member's


In this tree, we can see all of the above rules in play: <del> The resolution of node Z is the list [Z, C] </del>  <del> The resolution of leaf 1 is the empty list [] </del>  <del> The resolution of top node is the list [A, Z, C] </del>  5.1.2.

The current resolution example tree can't be created by the protocol. If C were not blank, then D would not populate Z in its filtered direct path. (Note that this implies that there are never unmerged leaves at the first level of the tree.) This PR expands the example tree so that it can have unmerged leaves while still having a blank top node. This makes the example a little more complicated (you have to follow the recursion down two levels), but it doesn't seem too bad.
cc NAME
Good catch! It's kind of subtle in this case.
NAME - I think I have this patched up, would appreciate a quick re-review.
I walked through the example tree on a whiteboard with different colored markers and it looks correct to me.

In this tree, we can see all of the above rules in play:  <ins> The resolution of node X is the list [X, B] </ins>  <ins> The resolution of leaf 2 or leaf 6 is the empty list [] </ins>  <ins> The resolution of top node is the list [X, B, Y, H] </ins> 5.1.2.


The fields in this state have the following semantics:  The "group_id" field is an application-defined identifier for the group. steps: Verify that the ciphersuite and protocol version of the KeyPackage <del> match those in use in the group. </del>  Verify that the "leaf_node" of the KeyPackage is valid for a KeyPackage according to leaf-node-validation. the external init secret as described in external-initialization. The sender type for the MLSAuthenticatedContent encapsulating the <del> External Commit MUST be "new_member_commit " </del>  External Commits come in two "flavors" - a "join" commit that adds the sender to the group or a "resync" commit that replaces a member's Verify that the "group_id" is unique among the groups that the client is currently participating in.  Verify the integrity of the ratchet tree. Verify that the tree hash of the ratchet tree matches the

This will guarantee that all group members agree on the ciphersuite used. It gives more meaning to statements like "Each MLS session uses a single ciphersuite". Also, it prevents the following attack: the adversary (a malicious insider) invites someone and convinces them that the group uses a ciphersuite with say a signature scheme that is weaker but still compatible with the one actually used. Now the new member uses a weaker scheme and the adversary can impersonate them.
Interim 2022-06-02: Agreement that more binding is better

The fields in this state have the following semantics: <ins> The "cipher_suite" is the cipher suite used by the group. </ins> The "group_id" field is an application-defined identifier for the group. steps: Verify that the ciphersuite and protocol version of the KeyPackage  <ins> match those in the "GroupContext". </ins> Verify that the "leaf_node" of the KeyPackage is valid for a KeyPackage according to leaf-node-validation. the external init secret as described in external-initialization. The sender type for the MLSAuthenticatedContent encapsulating the  <ins> External Commit MUST be "new_member_commit". </ins> External Commits come in two "flavors" - a "join" commit that adds the sender to the group or a "resync" commit that replaces a member's Verify that the "group_id" is unique among the groups that the client is currently participating in. <ins> Verify that the "cipher_suite" in the GroupInfo matches the "cipher_suite" in the KeyPackage. </ins> Verify the integrity of the ratchet tree. Verify that the tree hash of the ratchet tree matches the


RFC EDITOR PLEASE DELETE THIS SECTION.  draft-14 Ensure that a signature public key is always intelligible (*)

Constructed from the highlights of PR titles, with breaking changes indicated with as usual.
Just filing this so that I don't forget it before posting the draft.
Fixed by

RFC EDITOR PLEASE DELETE THIS SECTION. <ins> draft-15 Include ciphersuite in group context (*) Add new new_proposal_member SenderType (*) Always use a full tree (*) Change KeyPackage identifier extension to be LeafNode identifier (*) Use new tree for context in path secret encryption (*) Use a hash function for hash identifiers (*) Add a marker byte to tree hash input structs (*) Recommend that group ids are generated randomly (*) Update external senders extension to have SignaturePublicKey and Credential (*) Replace LeafNodeRef with leaf index (*) Remove AppAck proposal (*) Make padding arbitrary-size and all-zero (*) Require that unmerged_leaves be ordered Derive the commit secret from the end of the UpdatePath, not the root Specify the precise points in the protocol where credential validation must be done Make PSK provisions more uniform, e.g., always generating a fresh random nonce Improve parent hash guarantees with stricter checks on tree correctness Streamline some structs, e.g., folding GroupContext into GroupInfo Provide clearer rules for validating and applying commits Clarify tree hash and parent hash, and correct examples Clean up struct names and references to outdated structs Cite AEAD limits draft </ins> draft-14 Ensure that a signature public key is always intelligible (*)


The "epoch" field increments by one for each GroupOperation that is processed <del> The "transcript" is updated by a GroupOperation message "operation" by appending "operation" to "transcript" </del>  5.6.

There is no reason for the members of a conversation to keep the whole history of group operations, but they should agree on it.

The "epoch" field increments by one for each GroupOperation that is processed  <ins> The "transcript_hash" is updated by a GroupOperation message "operation" in the following way: When a new one-member group is created (which requires no GroupOperation), the "transcript_hash" field is set to an all-zero vector of length Hash.length. </ins> 5.6.


over arbitrary lower layer protocols.  The security considerations in this document (RFC XXXX) also apply.  18.  References 18.1.  URIs [1] mailto:mls-reg-review@ietf.org [2] mailto:iesg@ietf.org

Early review from IANA indicated that we had not completed the . This PR adds the missing fields.

over arbitrary lower layer protocols.  The security considerations in this document (RFC XXXX) also apply. <ins> N/A RFC XXXX MLS-based messaging applications N/A Additional information: Deprecated alias names for this type: N/A Magic number(s): N/A File extension(s): N/A Macintosh file type code(s): N/A IETF MLS Working Group mls@ietf.org [3] COMMON N/A IETF MLS Working Group IESG No </ins> 18.  References 18.1.  URIs [1] mailto:mls-reg-review@ietf.org [2] mailto:iesg@ietf.org <ins> [3] mailto:mls@ietf.org </ins>


Welcome message from the committer meeting the requirements of reinitialization.  13.4.3. New members can join the group in two ways.  Either by being added by node in the tree is known only to members of the group that are assigned a leaf in the node's subtree.  This is called the _ratchet tree invariant_ and it makes it possible to encrypt to all group <del> members except one, with a number of ciphertexts that's logarithmic </del>  in the number of group members. The ability to efficiently encrypt to all members except one allows an impersonation attack, the attacker would need to compromise the relevant PSK as well as the victim's signature key.  The cost of this mitigation is that the application needs some external arrangement <del> that ensures that the legitimate members of the group to have the </del>  required PSKs. 16.3.

Clarify what client should do when receiving a Commit removing itself update Remove example to show removed client receiving the Commit fix typos in Security Considerations
While implementing removals, I came to the conclusion that clients would Currently in the MLS Protocol, when a Commit containing a Remove Proposal is sent to a group, the specification does not provide enough implementation guidance to insure that the removed member is notified of its removal. I can think of three ways a member can determine it has been removed: Require the DS to forward the Commit message containing the removal to all removed members. Require an out-of-band protocol convey this information Create a new MLS message type (ex: Goodbye) specifically to convey removal. Forwarding the Commit message would require only one new normative statement in the MLS protocol document, some similar additional text in the MLS architecture document, and a minor change to the remove example flow diagram in the MLS protocol document. This would be a straightforward clarification. The disadvantage is that forwarding the commit to a removed member can leak other membership changes (ex: the credentials of newly added members, and the potential knowledge of which other members were removed at the same time). Requiring an out-of-band protocol to convey removal information, while possible, leaves a privacy sensitive decision out of scope, while the analogous action is a first-class part of the MLS protocol (Welcomes). Using a new message type (ex: Goodbye) requires new specification work, but allows a message analogous to a Welcome which can inform clients individually they were removed without leaking potentially sensitive information about the new membership of the group they just departed. Note that the architecture document could require that the DS either implement 1 or 2, but leaving too many choices makes interoperability more complicated.
The Commit is the goodbye message. Clients are able to parse it and conclude that they have been removed. I thought that 1. was always implied, what makes you think otherwise?
I assumed this as well, but it is only implied in the spec, and the example flow showing a remove doesn't have an arrow going to the removed client (which would clearly be wrong if it is required). (For good or bad, a lot of implementers code from examples and then go back and check their assumptions in the body of a spec. That is why it is so important to get examples correct.) If we decide that it's an implementation choice (and say that it is also ok to do it out of band for example) then we need to explain that in the architecture document. So, we can 1) Decide that a client MUST always get the Commit removing them; make that explicit in the protocol; fix the example; explain the privacy leak in the Security Considerations; possibly summarize this in the architecture document. 2) Say that a client MUST be informed about their removal in the protocol spec and leave how to convey removals as one of these policy choices for the DS (you could even make sending the Commit a SHOULD); explain more extensively in the architecture document. 3) Address the privacy issue directly by making an explicit Goodbye message.
You introduce the notion of a 'privacy leak' and a 'privacy issue' in your last message, what exactly are you referring to? I think 1. is currently implied and examples should be adjusted if they don't reflect that.
I think the privacy issue NAME is concerned about is something like: If other changes are made in the same Commit that removes a participant, then the removed participant can see those changes. For example, the identities of people added to the group in that commit. It's not totally clear to me what the security objective here is. It seems like the point of informing a member they have been removed via a group message (Commit or Goodbye) would be to prevent the DS from lying to the member about whether they have been removed -- telling them they'd been removed when they hadn't, or vice versa. This honestly isn't something I'm all that worried about, because (a) none of this affects the security of those who remain in the group, and (b) even if you had a message, the DS could suppress it (and thus lie in at least one direction). The best argument that occurs to me is that being removed might (might!) trigger deletion of old keys, thus providing better FS for any outstanding messages in prior epochs in the event the removed member was compromised. (This is unlike the add situation, where we need a protocol message to provide the new joiner with the cryptographic material they need to participate in the group. That cannot be delegated to the DS.) If we had an explicit Goodbye message, we would have a malicious insider risk, in that a group member could generate a Goodbye for someone that was not actually removed. Net of all that, I think something like Rohan's option (2) would be my preference. Mostly punt it to OOB, but note that the Commit COULD be used.
I suspect as much. I'd say that this is only a potential privacy issue because the committer can simply avoid it by issuing two commits. The leaked information about other proposals is also not necessarily sensitive. That being said, I think it would be worth mentioning this in the architecture doc. I think either (1) or (2). would work, where (2) has the added benefit of more flexibility. (3) would indeed be problematic for the reasons you mention.
It sounds like there is weak consensus that a client should be informed either by a Commit or out-of-band. I submitted PR which shows a Commit going to the removed user in the example flow, and provides some guidance to a client about processing a Commit that removes itself. I'll submit a separate PR for the architecture spec that adds this to the list of things you need for a concrete DS / client implementation.
Resolved with

Welcome message from the committer meeting the requirements of reinitialization. <ins> Note that clients need to be prepared to receive a valid Commit message which removes them from the group.  In this case, the client cannot send any more messages in the group and SHOULD promptly delete its group state and secret tree.  (A client might keep the secret tree for a short time to decrypt late messages in the previous epoch.) </ins> 13.4.3. New members can join the group in two ways.  Either by being added by node in the tree is known only to members of the group that are assigned a leaf in the node's subtree.  This is called the _ratchet tree invariant_ and it makes it possible to encrypt to all group  <ins> members except one, with a number of ciphertexts that is logarithmic </ins> in the number of group members. The ability to efficiently encrypt to all members except one allows an impersonation attack, the attacker would need to compromise the relevant PSK as well as the victim's signature key.  The cost of this mitigation is that the application needs some external arrangement  <ins> that ensures that the legitimate members of the group have the </ins> required PSKs. 16.3.


A member of the group applies a Remove message by taking the following steps: <del> Identify a leaf node matching "removed".  This lookup MUST be done on the tree before any non-Remove proposals have been applied (the "old" tree in the terminology of commit), since proposals such as Update can change the LeafNode stored at a leaf.  Let L be this leaf node. </del>  Replace the leaf node L with a blank node

The part about doing the lookup in the old tree was added in , it was relevant here because of the hash references. This is not a problem anymore since we came back to referencing with leaf index.

A member of the group applies a Remove message by taking the following steps:  <ins> Identify the leaf node matching "removed".  Let L be this leaf node. </ins> Replace the leaf node L with a blank node


external public key In other words, to join a group via an External Commit, a new member <del> needs a GroupInfo with an "ExternalPub" extension present in its </del>  "extensions" field. Thus, a member of the group can enable new clients to join by making

For consistency with references to other extensions (and with the IANA registry), refer to the extension as "external_pub".

external public key In other words, to join a group via an External Commit, a new member  <ins> needs a GroupInfo with an "external_pub" extension present in its </ins> "extensions" field. Thus, a member of the group can enable new clients to join by making


Name: The name of the ciphersuite  Recommended: Whether support for this ciphersuite is recommended <del> by the IETF MLS WG.  Valid values are "Y" and "N".  The "Recommended" column is assigned a value of "N" unless explicitly requested, and adding a value with a "Recommended" value of "Y" requires Standards Action RFC8126.  IESG Approval is REQUIRED for a Y->N transition. </del>  Reference: The document where this ciphersuite is defined

... by just importing the . NAME lmk if you think we should reference instead.
The consensus in saag was to expand Recommended to include "D" to RFC 8447bis. Should probablly do the same here.

Name: The name of the ciphersuite <ins> [[ RFC EDITOR: This section should be the same as the corresponding text in draft-ietf-tls-rfc8447bis.  Please align the two documents if they have diverged in the approval process. ]] </ins> Recommended: Whether support for this ciphersuite is recommended  <ins> by the IETF MLS WG.  Valid values are "Y", "N", and "D", as described below.  The default value of the "Recommended" column is "N".  Setting the Recommended item to "Y" or "D", or changing a item whose current value is "Y" or "D", requires Standards Action RFC8126. Y: Indicates that the IETF has consensus that the item is RECOMMENDED.  This only means that the associated mechanism is fit for the purpose for which it was defined.  Careful reading of the documentation for the mechanism is necessary to understand the applicability of that mechanism.  The IETF could recommend mechanisms that have limited applicability, but will provide applicability statements that describe any limitations of the mechanism or necessary constraints on its use. N: Indicates that the item has not been evaluated by the IETF and that the IETF has made no statement about the suitability of the associated mechanism.  This does not necessarily mean that the mechanism is flawed, only that no consensus exists. The IETF might have consensus to leave an items marked as "N" on the basis of it having limited applicability or usage constraints. D: Indicates that the item is discouraged and SHOULD NOT or MUST NOT be used.  This marking could be used to identify mechanisms that might result in problems if they are used, such as a weak cryptographic algorithm or a mechanism that might cause interoperability problems in deployment. </ins> Reference: The document where this ciphersuite is defined


1. <del> DISCLAIMER: This is a work-in-progress draft of MLS and has not yet seen significant security analysis.  It should not be used as a basis for building production systems. </del> RFC EDITOR: PLEASE REMOVE THE FOLLOWING PARAGRAPH The source for this draft is maintained in GitHub.  Suggested changes should be submitted as pull requests at https://github.com/mlswg/mls-protocol. Update messages SHOULD be sent at regular intervals of time as long as the group is active, and members that don't update SHOULD eventually be removed from the group.  It's left to the application <del> to determine an appropriate amount of time between Updates. </del>  Members are removed from the group in a similar way.  Any member of the group can send a Remove proposal followed by a Commit message. MUST be filled with all zero bytes.  A receiver MUST verify that there are no non-zero bytes in the "padding" field, and if this check fails, the enclosing MLSCiphertext MUST be rejected as malformed.  In the MLS key schedule, the sender creates two distinct key ratchets for handshake and application messages for each member of the group. The length of the "padding" field in "MLSCiphertextContent" can be chosen at the time of message encryption by the sender.  Senders may use padding to reduce the ability of attackers outside the group to <del> infer the size of the encrypted content. </del>  15.2.

Thanks to Gorry Fairhurst: URL Reviewer: Gorry Fairhurst Review result: On the Right Track This is an early review of draft-ietf-mls-protocol-16, which seeks to specify a key establishment protocol to provide scalable efficient asynchronous group key establishment. This document seems to define a component that could be used to build or operate over an Internet transport. The focus is on security algorithms and procedures. There are some issues that Major Issue: This would have been easier to understand if there was a section that described the transport requirements of the messages. This makes me wonder what transport service is actually needed? - Can the underlying transport reorder messages? Is loss tolerated or reliability required? Are there any requirements on message size? etc. A brief paragraph explicitly explaining the requirements would help. A later statement says, which appears to suggest any service can be used: "MLS is an encrypted messaging layer designed to be transmitted over arbitrary lower layer protocols....." I note draft-ietf-mls-architecture states: "MLS is not intended as a full instant messaging protocol but rather is intended to be embedded in concrete protocols, such as XMPP [RFC6120]." This could form a part of such an explanation, if it applies to this ID also? Major Issue: The document targets PS, but the version I reviewed added a "DISCLAIMER: This is a work-in-progress draft of MLS and has not yet seen significant security analysis. It should not be used as a basis for building production systems." - Why is the final document proposed as a PS rather than EXP, if this is not for general deployment? Or is this clause to be removed by RFC-Ed? Major Issue: From a transport perspective, there are issues in the statement providing insufficient guidance on selecting a rate: "Update messages SHOULD be sent at regular intervals of time as long as the group is active, and members that don't update SHOULD eventually be removed from the group. It's left to the application to determine an appropriate amount of time between Updates." One possible way to address this is to state that the messages are either sent over a congestion-controlled transport or the maximum aggregate rate of messages falls within a specific guideline as defined in RFC8085, or some other BCP with similar advice on rate selection. Minor: " Application messages MAY be padded to provide some resistance against traffic analysis techniques over encrypted traffic [CLINIC] [HCJ16]." - Padding is a well known technique - it can have benefits and also have drawbacks, e.g. in efficiency of transmission and for message-based transfers in reducing robustness to paths that have limited PMTU, where larger messages can be dropped. Minor: " A receiver MUST verify that there are no non-zero bytes in the padding field, and if this check fails, the enclosing MLSCiphertext MUST be rejected as malformed." - I don't doubt that this is useful, but it would be helpful to add a sentence to explain why these are required to be encoded as zero.

1.  RFC EDITOR: PLEASE REMOVE THE FOLLOWING PARAGRAPH The source for this draft is maintained in GitHub.  Suggested changes should be submitted as pull requests at https://github.com/mlswg/mls-protocol. Update messages SHOULD be sent at regular intervals of time as long as the group is active, and members that don't update SHOULD eventually be removed from the group.  It's left to the application  <ins> to determine an appropriate amount of time between Updates.  In general, however, applications should take care that they do not send MLS messages at a rate that overwhelms the transport over which messages are being sent. </ins> Members are removed from the group in a similar way.  Any member of the group can send a Remove proposal followed by a Commit message. MUST be filled with all zero bytes.  A receiver MUST verify that there are no non-zero bytes in the "padding" field, and if this check fails, the enclosing MLSCiphertext MUST be rejected as malformed. <ins> This check ensures that the padding process is deterministic, so that, for example, padding cannot be used as a covert channel. </ins> In the MLS key schedule, the sender creates two distinct key ratchets for handshake and application messages for each member of the group. The length of the "padding" field in "MLSCiphertextContent" can be chosen at the time of message encryption by the sender.  Senders may use padding to reduce the ability of attackers outside the group to  <ins> infer the size of the encrypted content.  Note, however, that the transports used to carry MLS messages may have maximum message sizes, so padding schemes SHOULD avoid increasing message size beyond any such limits that exist in a given deployment scenario. </ins> 15.2.


A group of users who want to send each other encrypted messages needs a way to derive shared symmetric encryption keys.  For two parties, this problem has been studied thoroughly, with the Double Ratchet <del> emerging as a common solution doubleratchet signal.  Channels </del>  implementing the Double Ratchet enjoy fine-grained forward secrecy as well as post-compromise security, but are nonetheless efficient enough for heavy use over low-bandwidth networks. For a group of size greater than two, a common strategy is to unilaterally broadcast symmetric "sender" keys over existing shared symmetric channels, and then for each member to send messages to the <del> group encrypted with their own sender key.  Unfortunately, while this improves efficiency over pairwise broadcast of individual messages and provides forward secrecy (with the addition of a hash ratchet), it is difficult to achieve post-compromise security with sender keys. </del>  An adversary who learns a sender key can often indefinitely and passively eavesdrop on that member's messages.  Generating and distributing a new sender key provides a form of post-compromise In this document, we describe a protocol based on tree structures that enable asynchronous group keying with forward secrecy and post- compromise security.  Based on earlier work on "asynchronous <del> ratcheting trees" art, the protocol presented here uses an </del>  asynchronous key-encapsulation mechanism for tree structures.  This mechanism allows the members of the group to derive and update shared keys with costs that scale as the log of the group size. further secret values, and "key" to refer to a value that is used with an algorithm such as HMAC or an AEAD algorithm.  2.1. We use the TLS presentation language RFC8446 to describe the In MLS, there are several vectors whose sizes vary over significant ranges.  So instead of using a fixed-size length field, we use a variable-size length using a variable-length integer encoding based <del> on the one in Section 16 of RFC9000.  (They differ only in that the one here requires a minimum-size encoding.)  Instead of presenting min and max values, the vector description simply includes a "V". For example: </del>  Such a vector can represent values with length from 0 bytes to 2^30 bytes.  The variable-length integer encoding reserves the two most Vectors that start with "11" prefix are invalid and MUST be rejected. <del> For example, the four byte sequence 0x9d7f3e7d decodes to 494878333; the two byte sequence 0x7bbd decodes to 15293; and the single byte 0x25 decodes to 37. </del>  The following figure adapts the pseudocode provided in RFC9000 to add a check for minimum-length encoding: secrets: After applying the UpdatePath, the tree will have the following <del> structure, where "lp" and "np[i]" represent the leaf_priv and node_priv values generated as described above: </del>  8.5. 16.3.  Post-compromise security is provided between epochs by members regularly updating their leaf key in the ratchet tree.  Updating their leaf key prevents group secrets from continuing to be encrypted to previously compromised public keys. <del> Forward-secrecy between epochs is provided by deleting private keys </del>  from past versions of the ratchet tree, as this prevents old group secrets from being re-derived.  Forward secrecy _within_ an epoch is provided by deleting message encryption keys once they've been used

URL Reviewer: Rich Salz Review result: Ready with Nits I reviewed this draft for ART. I did not review the cryptography as I am unqualified, compared with the draft authors (and other participants). Overall: I think references should be uppercase, as "[art]" should be "[ART]" Abstract: Nicely describes the problem. Is 'forward secrecy and post-compromise security' redundant? If not, there should be definitions in the draft for both terms and perhaps a forward link toe the terminology section. Introduction. "pairwise broadcast of individual messages" seems to go to far for terseness to make the sentence grammatical. The section on common strategy should have a reference or two to implementations. And do you mean "unilaterally broadcast Asymmetric keys" Or is the common technique to allow everyone to impersonate anyone? Sec 2, Terminology. Alphabetical order please. Maybe mention that MSLPlaintext, MLSCiphertext are message formats described in section 4.1; I wondered why they didn't appear in the terminology. And when I searched forward to find where they are defined, I noticed that elsewhere they are rendered as for example, and here the underscores aren't present. Consistency is a virtue. The last paragraph starts by saying "keys and secrets are used interchangeably" which is contradicted by the last sentence. Sec 2.1.2 I was consistently confused by the term "variable-size vector headers" Suggest replacing "Headers" with "Sizes" The parenthetical should not be parenthesized, the difference is important and not an aside. The example vector should be "StructWithVector" not plural, right? The examples are useful, but should be more clear that they are sample encodings of the length bytes and mark the length of the following vector in bytes. Sec 3. Short and understandable. Sec 4. Not short :) but understandable. Sec 4.2 is very useful and have a nice use of the railroad diagrams. The section title should be plural tho. "Executions" Is there any guidance to be offered on access control policies? How does A know whether or not Z can remove B? Are messages NAK'd or ignored or something else? I guess a forward link to 6.3 makes sense. Sec 5 The worked examples are very useful. I like figure 9 Sec 6.2, nit no underscores around first use of I skimmed sec 7 and 8. The end of 8.4 'where lp and np[i] represent" confused me as I don't see those notations in the diagram that follows. Doing a spot-check of these sections it seems that overall the text is clear. Sorry, I ran out of time do finish the document. Holy cow, this is a large document with a great deal of technical detail. I'll be surprised if you got much early feedback. More time, next time, please. Table 5 says "LVL the security level" Should mention "strengh in bits" maybe.

A group of users who want to send each other encrypted messages needs a way to derive shared symmetric encryption keys.  For two parties, this problem has been studied thoroughly, with the Double Ratchet  <ins> emerging as a common solution DoubleRatchet Signal.  Channels </ins> implementing the Double Ratchet enjoy fine-grained forward secrecy as well as post-compromise security, but are nonetheless efficient enough for heavy use over low-bandwidth networks. For a group of size greater than two, a common strategy is to unilaterally broadcast symmetric "sender" keys over existing shared symmetric channels, and then for each member to send messages to the  <ins> group encrypted with their own sender key.  On the one hand, using sender keys improves efficiency relative to pairwise broadcast of individual messages, and it provides forward secrecy (with the addition of a hash ratchet).  On the other hand, it is difficult to achieve post-compromise security with sender keys, requiring a number of key update messages that scales as the square of the group size. </ins> An adversary who learns a sender key can often indefinitely and passively eavesdrop on that member's messages.  Generating and distributing a new sender key provides a form of post-compromise In this document, we describe a protocol based on tree structures that enable asynchronous group keying with forward secrecy and post- compromise security.  Based on earlier work on "asynchronous  <ins> ratcheting trees" ART, the protocol presented here uses an </ins> asynchronous key-encapsulation mechanism for tree structures.  This mechanism allows the members of the group to derive and update shared keys with costs that scale as the log of the group size. further secret values, and "key" to refer to a value that is used with an algorithm such as HMAC or an AEAD algorithm. <ins> The MLSPlaintext and MLSCiphertext formats are defined in message- framing; they represent integrity-protected and confidentiality- protected messages, respectively.  Security notions such as forward secrecy and post-compromise security are defined in security- considerations. </ins> 2.1. We use the TLS presentation language RFC8446 to describe the In MLS, there are several vectors whose sizes vary over significant ranges.  So instead of using a fixed-size length field, we use a variable-size length using a variable-length integer encoding based  <ins> on the one in Section 16 of RFC9000.  They differ only in that the one here requires a minimum-size encoding.  Instead of presenting min and max values, the vector description simply includes a "V".  For example: </ins> Such a vector can represent values with length from 0 bytes to 2^30 bytes.  The variable-length integer encoding reserves the two most Vectors that start with "11" prefix are invalid and MUST be rejected.  <ins> For example: The four byte length value 0x9d7f3e7d decodes to 494878333. The two byte length value 0x7bbd decodes to 15293. The single byte length value 0x25 decodes to 37. </ins> The following figure adapts the pseudocode provided in RFC9000 to add a check for minimum-length encoding: secrets: After applying the UpdatePath, the tree will have the following  <ins> structure: </ins> 8.5. 16.3. <ins> Forward secrecy and post-compromise security are important security notions for long-lived MLS groups.  Forward secrecy means that messages sent at a certain point in time are secure in the face of later compromise of a group member.  Post-compromise security means that messages are secure even if a group member was compromised at some point in the past. </ins> Post-compromise security is provided between epochs by members regularly updating their leaf key in the ratchet tree.  Updating their leaf key prevents group secrets from continuing to be encrypted to previously compromised public keys.  <ins> Forward secrecy between epochs is provided by deleting private keys </ins> from past versions of the ratchet tree, as this prevents old group secrets from being re-derived.  Forward secrecy _within_ an epoch is provided by deleting message encryption keys once they've been used


"init_secret" for the current epoch and the path secret (if present). <del> Construct a Welcome message from the encrypted GroupInfo object, the encrypted key packages, and any PSKs for which a proposal was included in the Commit.  The order of the "psks" MUST be the same as the order of PreSharedKey proposals in the "proposals" vector. </del>  If a ReInit proposal was part of the Commit, the committer MUST create a new group with the parameters specified in the ReInit 12.4.3.1. <del> The sender of a Commit message is responsible for sending a single Welcome message to all the new members added via Add proposals.  The Welcome message provides the new members with the current state of the group after the application of the Commit message.  The new </del>  members will not be able to decrypt or verify the Commit message, but will have the secrets they need to participate in the epoch initiated by the Commit message. <del> In order to allow the same Welcome message to be sent to all new </del>  members, information describing the group is encrypted with a symmetric key and nonce derived from the "joiner_secret" for the new epoch.  The "joiner_secret" is then encrypted to each new member

This initial effort tweaks the sections that talk about generating and processing Welcome messages. There might be other references to a single Welcome per Commit that should be amended for clarity. Someone should audit for those before we merge this PR.
From my reading, it looks like the creator of an epoch must send the exact same message to each new user. However, in some systems, it is more efficient to send a different message to each user, only containing the intended for them, rather than the for all new members. As far as I can tell, no changes are required on the recipient side. I'm running some performance testing, trying to add thousands of members at a time, and the messages are hundreds of kilobytes large. In a federated environment, this could be copied to multiple servers, with the vast majority of that being unnecessary data.
Good point NAME I filed . In the case, you would do something like send a Welcome per home server?
Thanks. With the way that Matrix currently works, it would probably be best to send a separate message per user, since the current endpoint for sending messages directly to devices requires specifying the message separately for each recipient, and implementations (AFAIK) currently don't do deduplication. In the future, it might be possible to do it differently.
NAME shouldn't ResumptionPSKUsage include (255)? enum { reserved(0), application(1), reinit(2), branch(3), (255) } ResumptionPSKUsage;
Fixed in

"init_secret" for the current epoch and the path secret (if present).  <ins> Construct one or more Welcome messages from the encrypted GroupInfo object, the encrypted key packages, and any PSKs for which a proposal was included in the Commit.  The order of the "psks" MUST be the same as the order of PreSharedKey proposals in the "proposals" vector.  As discussed on joining-via-welcome- message, the committer is free to choose how many Welcome messages to construct.  However, the set of Welcome messages produced in this step MUST cover every new member added in the Commit. </ins> If a ReInit proposal was part of the Commit, the committer MUST create a new group with the parameters specified in the ReInit 12.4.3.1.  <ins> The sender of a Commit message is responsible for sending a Welcome message to each new member added via Add proposals.  The format of the Welcome message allows a single Welcome message to be encrypted for multiple new members.  It is up to the committer to decide how many Welcome messages to create for a given Commit.  The committer could create one Welcome that is encrypted for all new members, a different Welcome for each new member, or Welcome messages for batches of new members (according to some batching scheme that works well for the application).  The processes for creating and processing the Welcome are the same in all cases, aside from the set of new members for whom a given Welcome is encrypted. The Welcome message provides the new members with the current state of the group after the application of the Commit message.  The new </ins> members will not be able to decrypt or verify the Commit message, but will have the secrets they need to participate in the epoch initiated by the Commit message.  <ins> In order to allow the same Welcome message to be sent to multiple new </ins> members, information describing the group is encrypted with a symmetric key and nonce derived from the "joiner_secret" for the new epoch.  The "joiner_secret" is then encrypted to each new member


application to supply a "reference identifier" for the authenticated client, if any. <del> A BasicCredential is a bare assertion of an identity, without any </del>  additional information.  The format of the encoded identity is defined by the application.

made me realize that BasicCredential actually doesn't exist anymore!
Well, "basic" is listed as a credential type in the IANA registry defined in . That said, your proposed text seems perfectly consistent with the registry and the rest of the document.

application to supply a "reference identifier" for the authenticated client, if any.  <ins> A "basic" credential is a bare assertion of an identity, without any </ins> additional information.  The format of the encoded identity is defined by the application.


Public keys used in the protocol are opaque values in a format defined by the ciphersuite, using the following types:  5.5.1. This ciphersuite uses the following primitives:

Need some actual values here for interop. Signature scheme values are a subset of those in RFC 8446. NAME - Do you think we should go ahead and define the higher-security-level ciphersuites as well as signature algorithms?
Looks good to me! We can always re-introduce Ed448 with X448 later.

Public keys used in the protocol are opaque values in a format defined by the ciphersuite, using the following types: <ins> Cryptographic algorithms are indicated using the following types: </ins> 5.5.1. This ciphersuite uses the following primitives:


When a participant A wants to establish a group with B and C, it first downloads InitKeys for B and C.  It then initializes a group <del> state containing only itself and uses the InitKeys to compute Add messages to add B and C, in a sequence chosen by A.  These messages are broadcasted to the Group, and processed in sequence by B and C. Messages received before a participant has joined the group are ignored.  Only after A has received its Add messages back from the server does it update its state to reflect their addition. </del>  Subsequent additions of group members proceed in the same way.  Any member of the group can download an InitKey for a new participant and derivation and signing.  The client's identity key is intended to be stable throughout the lifetime of the group; there is no mechanism to change it.  Init keys are intended to be used a very limited number <del> of times, potentially once. (see init-key-reuse). </del>  The init_keys array MUST have the same length as the cipher_suites array, and each entry in the init_keys array MUST be a public key for The Welcome message contains the information that the new member needs to initialize a GroupState object that can be updated to the <del> current state using the Add message: </del>  Note that the "init_secret" in the Welcome message is the "init_secret" at the output of the key schedule diagram in key-

This PR addresses two outstanding issues with Welcome messages: Welcome messages were not encrypted for the new member, so that the information in them (in particular, init secrets) were not appropriately protected. The protocol overview had not been updated to include the Welcome-based add flow.
This was resolved in , but recording it in this issue for posterity. A Welcome message carries the value for the group, and so it needs to be encrypted for the new joiner. The struct proposed in the revised draft wraps the information in the Welcome in an ECIES ciphertext, and adds enough information to enable the joiner to identify the private key it needs to decrypt the Welcome message.

When a participant A wants to establish a group with B and C, it first downloads InitKeys for B and C.  It then initializes a group  <ins> state containing only itself and uses the InitKeys to compute Welcome and Add messages to add B and C, in a sequence chosen by A.  The Welcome messages are sent directly to the new members (there is no need to send them to the group).  The Add messages are broadcasted to the Group, and processed in sequence by B and C.  Messages received before a participant has joined the group are ignored.  Only after A has received its Add messages back from the server does it update its state to reflect their addition. </ins> Subsequent additions of group members proceed in the same way.  Any member of the group can download an InitKey for a new participant and derivation and signing.  The client's identity key is intended to be stable throughout the lifetime of the group; there is no mechanism to change it.  Init keys are intended to be used a very limited number  <ins> of times, potentially once. (see init-key-reuse).  UserInitKeys also contain an identifier chosen by the client, which the client MUST assure uniquely identifies a given UserInitKey object among the set of UserInitKeys created by this client. </ins> The init_keys array MUST have the same length as the cipher_suites array, and each entry in the init_keys array MUST be a public key for The Welcome message contains the information that the new member needs to initialize a GroupState object that can be updated to the  <ins> current state using the Add message.  This information is encrypted for the new member using ECIES.  The recipient key pair for the ECIES encryption is the one included in the indicated UserInitKey, corresponding to the indicated ciphersuite. </ins> Note that the "init_secret" in the Welcome message is the "init_secret" at the output of the key schedule diagram in key-


A member of a group authenticates the identities of other participants by means of credentials issued by some authentication system, e.g., a PKI.  Each type of credential MUST express the <del> holder's identity as well as the public key of a signature key pair that the holder of the credential will use to sign MLS messages. </del>  Credentials MAY also include information that allows a relying party to verify the identity / signing key binding.

This PR fixes several small issues I encountered while bringing my implementation more up to date. When I changed to allow blanks in the tree, I failed to update accordingly Credentials should dictate what signature scheme they will be used with, and once that's the case, we no longer need to indicate what algorithm is in use in cases where the signer's credential is known should come with a credential, not just a public key The confirmation value is easier to parse as an opaque vector value than as an array whose size depends on the ciphersuite in use

A member of a group authenticates the identities of other participants by means of credentials issued by some authentication system, e.g., a PKI.  Each type of credential MUST express the  <ins> following data: The public key of a signature key pair The identity of the holder of the private key The signature scheme that the holder will use to sign MLS messages </ins> Credentials MAY also include information that allows a relying party to verify the identity / signing key binding.


If the the above checks are successful, consider the updated GroupState object as the current state of the group. <del> The "finished_mac" value is computed over the provisional group state and the current handshake message (with the confirmation value set to zero): </del>  HMAC RFC2104 uses the Hash algorithm for the ciphersuite in use.  [[ OPEN ISSUE: The Add and Remove operations create a "double-join" situation, where a participants leaf key is also known to another

Looking at the signature and confirmation calculations in the current draft and comparing them to TLS, things seemed a bit complicated. In TLS, we have the following: This PR implements an analogous computation for MLS, where the signature in a message covers the transcript hash in the latest group state (which includes any changes to the roster ~ Certificate), and the confirmation MAC covers the transcript hash, plus the signature (i.e., the contents of CertificateVerify).
Merging this despite CI failures because they seem to be spurious.

If the the above checks are successful, consider the updated GroupState object as the current state of the group.  <ins> The "signature" and "confirmation" values are computed over the transcript of group operations, using the transcript hash from the provisional GroupState object: </ins> HMAC RFC2104 uses the Hash algorithm for the ciphersuite in use. <ins> Sign uses the signature algorithm indicated by the signer's credential in the roster. </ins> [[ OPEN ISSUE: The Add and Remove operations create a "double-join" situation, where a participants leaf key is also known to another


For ciphersuites using Ed25519 or Ed448 signature schemes, the public key is in the format specified in RFC8032.  For ciphersuites using ECDSA with the NIST curves (P-256, P-384, or P-521), the public key <del> is the output of the uncompressed Elliptic-Curve-Point-to-Octet- String conversion according to SECG. </del>  The signatures used in this document are encoded as specified in RFC8446.  In particular, ECDSA signatures are DER-encoded and EdDSA "new_member_proposal": The signature key in the LeafNode in the KeyPackage embedded in an External Add Proposal.  The <del> "content_type" of the message MUST be "proposal"and the </del>  "proposal_type" of the Proposal MUST be "add". Recipients of an MLSMessage MUST verify the signature with the key 7.8. MLS hashes the contents of the tree in two ways to authenticate <del> different properties of the tree.  This section defines _tree hashes_, and _parent hashes_ are defined in parent-hashes. </del>  Each node in a ratchet tree has a tree hash that summarizes the subtree below that node.  The tree hash of the root is used in the perform an excessive number of key derivations.  For example, a malicious group member could send a message with "generation = 0xffffffff" at the beginning of a new epoch, forcing recipients to <del> perform billions of key derivations. </del>  15. Post-compromise security is provided between epochs by members regularly updating their leaf key in the ratchet tree.  Updating their leaf key prevents group secrets from continuing to be encrypted <del> to previously compromised public keys. </del>  Forward secrecy between epochs is provided by deleting private keys from past versions of the ratchet tree, as this prevents old group provided by deleting message encryption keys once they've been used to encrypt or decrypt a message. <del> Post-compromise security is also provided for new groups by members regularly generating new KeyPackages and uploading them to the Delivery Service, such that compromised key material won't be used when the member is added to a new group. </del>  15.4.

Comment by NAME I personally don't like the underscored words in the html rendering of the document It "blank" the new American spelling of "blanc" ? I find "summarizes" a strange word here. It is not the hash contains a summary one can read. [SECG] has no IETF equivalent? Should it? proposaland -> proposal and I would say "after removing member C" (avoid ambiguity about "every third") I read this wrong the first way, the "," vanishes due to the unscores. Maybe: This section defines tree hashes, the next section defines parent hashes. Or alternatively, leave onlthe the first sentence in 8.8, then put the remainder and next section in two subsections (so 8.8.1 and 8.8.2) Maybe: For example, a malicious group member could otherwise send Maybe: to public keys whose private key was previously compromised. This reads a little odd as "new groups" would have no history and thus no previous compromise.
Filed I think it's important to emphasize the terms being defined, and this seems more readable than a definition list. Note that a hash function is often called a "message digest", in the same sense as the "Weekly github digest" that goes to the mailing list. I think referring to SECG is still pretty state-of-the-art. But apparently RFC 8446 moved on from that, so I updated to use that representation.

For ciphersuites using Ed25519 or Ed448 signature schemes, the public key is in the format specified in RFC8032.  For ciphersuites using ECDSA with the NIST curves (P-256, P-384, or P-521), the public key  <ins> is represented as an encoded UncompressedPointRepresentation struct, as defined in RFC8446. </ins> The signatures used in this document are encoded as specified in RFC8446.  In particular, ECDSA signatures are DER-encoded and EdDSA "new_member_proposal": The signature key in the LeafNode in the KeyPackage embedded in an External Add Proposal.  The  <ins> "content_type" of the message MUST be "proposal" and the </ins> "proposal_type" of the Proposal MUST be "add". Recipients of an MLSMessage MUST verify the signature with the key 7.8. MLS hashes the contents of the tree in two ways to authenticate  <ins> different properties of the tree.  _Tree hashes_ are defined in this section, and _parent hashes_ are defined in parent-hashes. </ins> Each node in a ratchet tree has a tree hash that summarizes the subtree below that node.  The tree hash of the root is used in the perform an excessive number of key derivations.  For example, a malicious group member could send a message with "generation = 0xffffffff" at the beginning of a new epoch, forcing recipients to  <ins> perform billions of key derivations unless they apply limits of the type discussed above. </ins> 15. Post-compromise security is provided between epochs by members regularly updating their leaf key in the ratchet tree.  Updating their leaf key prevents group secrets from continuing to be encrypted  <ins> to public keys whose private keys had previously been compromised. </ins> Forward secrecy between epochs is provided by deleting private keys from past versions of the ratchet tree, as this prevents old group provided by deleting message encryption keys once they've been used to encrypt or decrypt a message.  <ins> New groups are also at risk of using previously compromised keys (as with post-compromise security), if a member is added to a new group via an old KeyPackage whose corresponding private key has been compromised.  This risk can be mitigated by having clients regularly generate new KeyPackages and upload them to the Delivery Service. This way, the key material used to add a member to a new group is more likely to be fresh and less likely to be compromised. </ins> 15.4.


MLS Ciphersuites (mls-ciphersuites)  MLS Extension Types (mls-extension-types) MLS Proposal Types (mls-proposal-types) 16.2.  This registry lists identifiers for extensions to the MLS protocol. The extension type field is two bytes wide, so valid extension type values are in the range 0x0000 to 0xffff. Initial contents: <del> 16.3. </del>  This registry lists identifiers for types of proposals that can be made for changes to an MLS group.  The extension type field is two Initial contents: <del> 16.4. </del>  This registry lists identifiers for types of credentials that can be used for authentication in the MLS protocol.  The credential type Initial contents: <del> 16.5. </del>  Specification Required RFC8126 registry requests are registered after a three-week review period on the MLS DEs' mailing list: mls-reg- be perceived as creating a conflict of interest for a particular MLS DE, that MLS DE SHOULD defer to the judgment of the other MLS DEs. <del> 16.6. </del>  This document registers the "message/mls" MIME media type in order to allow other protocols (e.g., HTTP RFC7540) to convey MLS messages.

I think this is unnecessary and capricious.
Interim 2022-12-08: Make ProtocolVersion and WireFormat two bytes Leave other enums as-is Define an IANA registry for WireFormat
Fixed by
Comment by NAME Would it really do harm to turn this into two octets? I don't think message size is a real concern here. Same for ContentType and SenderType. Note: thank you for skipping 0 as a valid entry!! Implementers applaud you :)
Yep, we have tried to reserve 0 in all the enums, precisely because I was a grumpy implementor!
On the one hand, yes, one octet is not that much more, and it saves worrying about space. On the other hand, in its long life, TLS has only exhausted 4 of its 65k versions, and its HandshakeType and ContentType enums are both still comfortable at 1 byte (the analogous to the other ProposalType and ContentType here). Among the identifiers we have, we should be most worried about the intended extension points, namely ExtensionType and ProposalType. Both of those are already. There's no mechanism for adding new values to ContentType and SenderType, so I would leave them at . (Technically they could be updated by an extension -- but an extension could also make them 16 bits!) I can live with expanding ProtocolVersion, in case we decide to do some of the GREASE-like stuff that QUIC is doing.
I don't have a strong opinion about this either, but if we make this 16-bit wide, we should do the same for consistency for ContentType, SenderType & WireFormat (the MLS extension document does introduce a new WireFormat for example).
Hi, I don't think there is any expectation that we are going to exhaust the version space (and we could do an extension later to fix that in the event we are wildly successful). As for the idea that implementations will be easier if things are aligned on 16-bit or 32-bit boundaries, that doesn't help us because the Vector lengths are variable. I would leave this as is.
I can agree with the reasoning here
We talked about quite a number of different ways to do deletion in *ART groups. Give at least a high-level overview of the main ones, and mention their pros and cons. These include: just rebuild the tree Pros: simple, easy, no extra operations Cons: inefficient, puts the deleter in a trusted position in the group until every remaining member has updated update deletee's key to blank Pros: fairly simple, no extra operations Cons: puts the deleter in a trusted position until the sibling or cousin of the deletee has updated send a delete secret over pairwise channels Pros: no trusted positions Cons: O(N), leaves a potentially-compromised leaf node in the tree send a delete secret by KEMing to everyone else Pros: no trusted positions, efficient Cons: leaves a potentially-compromised leaf node in the tree, multiple deletes interact in a complex way
I don't quite follow the deletion algorithm that's in there at the moment. Does it require double-join bookkeeping, NAME If so I can add a note about that.
I'm going to look at clarifying deletion in the doc; but essentially we're going for replace-then-blank in this initial draft. Keeping punctured trees is an option we should discuss once it's out there.
NAME I think the algorithm in is explicitly double-joined. When I get time, I'll file another PR to move to the delete-without-double-join algorithm I posted to the list (i.e., puncture the tree).
Since we're no longer using ART, I think this issue is no longer relevant.

MLS Ciphersuites (mls-ciphersuites) <ins> MLS Wire Formats (mls-wire-formats) </ins> MLS Extension Types (mls-extension-types) MLS Proposal Types (mls-proposal-types) 16.2. <ins> This registry lists identifiers for the types of messages that can be sent in MLS.  The wire format field is two bytes wide, so the valid wire format values are in the range 0x0000 to 0xffff. Template: Value: The numeric value of the wire format Name: The name of the wire format Recommended: Whether support for this wire format is recommended by the IETF MLS WG.  Valid values are "Y" and "N".  The "Recommended" column is assigned a value of "N" unless explicitly requested, and adding a value with a "Recommended" value of "Y" requires Standards Action RFC8126.  IESG Approval is REQUIRED for a Y->N transition. Reference: The document where this wire format is defined Initial contents: 16.3. </ins> This registry lists identifiers for extensions to the MLS protocol. The extension type field is two bytes wide, so valid extension type values are in the range 0x0000 to 0xffff. Initial contents:  <ins> 16.4. </ins> This registry lists identifiers for types of proposals that can be made for changes to an MLS group.  The extension type field is two Initial contents:  <ins> 16.5. </ins> This registry lists identifiers for types of credentials that can be used for authentication in the MLS protocol.  The credential type Initial contents:  <ins> 16.6. </ins> Specification Required RFC8126 registry requests are registered after a three-week review period on the MLS DEs' mailing list: mls-reg- be perceived as creating a conflict of interest for a particular MLS DE, that MLS DE SHOULD defer to the judgment of the other MLS DEs.  <ins> 16.7. </ins> This document registers the "message/mls" MIME media type in order to allow other protocols (e.g., HTTP RFC7540) to convey MLS messages.


Add and Commit message adding that member, and broadcasts them to the group.  It also generates a Welcome message and sends this directly to the new member (there's no need to send it to the group).  Only <del> after A has received its Commit message back from the server does it update its state to reflect the new member's addition. Upon receiving the Welcome message, the new member will be able to read and send new messages to the group.  However, messages sent before they were added to the group will not be accessible. </del>  Subsequent additions of group members proceed in the same way.  Any member of the group can download a KeyPackage for a new client and used.  array-based-trees and link-based-trees provide some details on how to implement the tree operations required for MLS in these representations.  MLS places no requirements on implementations' <del> internal representations of ratchet trees.  An implementation MAY use </del>  any tree representation and associated algorithms, as long as they produce correct protocol messages. When decoding an MLSCiphertextContent, the application MUST check that the MLSContentAuthData is valid.  6.3.2. The "sender data" used to look up the key for content encryption is Concrete algorithms for these operations on array-based and link- based trees are provided in array-based-trees and link-based-trees. <del> The concrete algorithms are non-normative.  An implementation MAY use </del>  any algorithm that produces the correct tree in its internal representation. Applications SHOULD define a policy on how long to keep unused nonce and key pairs for a sender, and the maximum number to keep.  This is <del> in addition to ensuring that these nonce and key pairs are promptly deleted when the epoch ends.  Applications SHOULD also define a policy limiting the maximum number of steps that clients will move the ratchet forward in response to a new message.  Messages received with a generation counter that's too much higher than the last message received would then be rejected.  This avoids causing a denial-of-service attack by requiring the recipient to perform an excessive number of key derivations.  For example, a malicious group member could send a message with "generation = 0xffffffff" at the beginning of a new epoch, forcing recipients to perform billions of key derivations. </del>  15. between two security levels (roughly 128-bit and 256-bit).  Within the security levels clients can choose between faster X25519/X448 curves and FIPS 140-2 compliant curves for Diffie-Hellman key <del> negotiations.  Additionally clients that run predominantly on mobile processors can choose ChaCha20Poly1305 over AES-GCM for performance reasons.  Since ChaCha20Poly1305 is not listed by FIPS 140-2 it is not paired with FIPS 140-2 compliant curves.  The security level of symmetric encryption algorithms and hash functions is paired with the security level of the curves. </del>  The mandatory-to-implement ciphersuite for MLS 1.0 is "MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519" which uses Curve25519

Comment by NAME Citation needed? I think most phones have AES(_GCM) in hardware too ? Also compared to HPKE operations and the times for epoch/group reinit, does this performance really matter? (eg waking up from sleep to increment the epoch would make the symmetric encryption cost pretty irrelevant. I would remove this sentence.
I'll remove the "mobile processors" bit and phrase it a little more evenhandedly ("can choose ChaCha or GCM"), but I think it's fair to say that there might be environments where ChaCha/Poly is more performant than AES-GCM.
Thanks. I do think you might be right that "there are", but I also do not think "mobile" is that :)
Comment by NAME This sentence with a hidden MUST is stuck between a sentence with MAY and a sentence with SHOULD. Perhaps make the MUST explicit ?
This is already well covered in the discussion, but I can add a cross-reference.
I meant just rephase the sentence so it contains "MUST delete when the epoch ends"
Comment by NAME That is quite some information that must be publicly available to allow external Add requests. This leaks information, eg same epoch means the group membership did not change, etc etc. I hope this will appear in the Security Considerations later :)
I suppose between this and , we should add a subsection to the Security Considerations on metadata privacy.
I'm not sure actually resolves this?
Oops, that's correct NAME Had it in my notes among the others.
Comment by NAME Isn't there technically also limits to how much one AEAD key and one nonce can be used to encrypt a (very very) large message? I guess this could not happen, but is there some formal message size limit in MLS ? (looking at the vectors at the start, limits could be higher than 2^64 ?)
Comment by NAME Another weird MAY here. Again, I would just lowercase it as this is just a pointer to a human decision, not a 2119 based protocol enforcement.
Comment by NAME Figure 10 claims to have seven members, but I count 8, namely Y,T,X,A,B,E,F and G (not counting W, the root)
Actually, it only has five! A, B, E, F, and G. Recall that members are at the leaves of the tree.
Ah right :)
Comment by NAME This MAY is super weird. Is it allowed to implement in such a way that they to NOT produce correct protocol messages? :-) Remove the entire sentence or lowercase the MAY?
Comment by NAME What server? The Delivery Service ?
Comment by NAME Should this be "prospective member" or "invitee" ? They haven't joined yet, have they?
From the perspective of the group, they are joined. Once the Commit adding the new member is processed and the new epoch starts, that member is able to access the group's secrets. The only thing "provisional" about the membership is that the new member hasn't initialized their local state. We use "new member" consistently to mean the subject of an Add proposal, and I don't think this is a big enough distinction to merit more terminology.
Another way to look at it is that keying information from the new member is already incorporated into the group, therefore they are a member and not a provisional member.
Ah yes. Perhaps a single line explaining this at the quoted location could be useful, but is not required

Add and Commit message adding that member, and broadcasts them to the group.  It also generates a Welcome message and sends this directly to the new member (there's no need to send it to the group).  Only  <ins> after A has received its Commit message back from the Delivery Service does it update its state to reflect the new member's addition. Once A has updated its state, the new member has processed the Welcome, and any other group members have processed the Commit, they will all have consistent representations of the group state, including a group secret that is known only to the members the group. The new member will be able to read and send new messages to the group, but messages sent before they were added to the group will not be accessible. </ins> Subsequent additions of group members proceed in the same way.  Any member of the group can download a KeyPackage for a new client and used.  array-based-trees and link-based-trees provide some details on how to implement the tree operations required for MLS in these representations.  MLS places no requirements on implementations'  <ins> internal representations of ratchet trees.  An implementation may use </ins> any tree representation and associated algorithms, as long as they produce correct protocol messages. When decoding an MLSCiphertextContent, the application MUST check that the MLSContentAuthData is valid. <ins> It is up to the application to decide what "authenticated_data" to provide and how much padding to add to a given message (if any).  The overall size of the AAD and ciphertext MUST fit within the limits established for the group's AEAD algorithm in [!I-D.irtf-cfrg-aead- limits]. </ins> 6.3.2. The "sender data" used to look up the key for content encryption is Concrete algorithms for these operations on array-based and link- based trees are provided in array-based-trees and link-based-trees.  <ins> The concrete algorithms are non-normative.  An implementation may use </ins> any algorithm that produces the correct tree in its internal representation. Applications SHOULD define a policy on how long to keep unused nonce and key pairs for a sender, and the maximum number to keep.  This is  <ins> in addition to ensuring that these secrets are deleted according to the deletion schedule defined in deletion-schedule.  Applications SHOULD also define a policy limiting the maximum number of steps that clients will move the ratchet forward in response to a new message. Messages received with a generation counter that's too much higher than the last message received would then be rejected.  This avoids causing a denial-of-service attack by requiring the recipient to perform an excessive number of key derivations.  For example, a malicious group member could send a message with "generation = 0xffffffff" at the beginning of a new epoch, forcing recipients to perform billions of key derivations. </ins> 15. between two security levels (roughly 128-bit and 256-bit).  Within the security levels clients can choose between faster X25519/X448 curves and FIPS 140-2 compliant curves for Diffie-Hellman key  <ins> negotiations.  Clients may also choose ChaCha20Poly1305 or AES-GCM, e.g., for performance reasons.  Since ChaCha20Poly1305 is not listed by FIPS 140-2 it is not paired with FIPS 140-2 compliant curves.  The security level of symmetric encryption algorithms and hash functions is paired with the security level of the curves. </ins> The mandatory-to-implement ciphersuite for MLS 1.0 is "MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519" which uses Curve25519


The former is used to update the confirmed transcript hash and the latter to update the interim transcript hash.  8.3. In addition to initializing a new epoch via KDF invocations as 11. <del> A group is always created with a single member, the "creator".  The other members are added when the creator effectively sends itself Add proposals, commits them, and then sends the corresponding Welcome message to the new participants.  These processes are described in detail in add, commit, and joining-via-welcome-message. </del>  The creator of a group MUST take the following steps to initialize the group: <del> Fetch KeyPackages for the members to be added, and select a version and ciphersuite according to the capabilities of the members.  To protect against downgrade attacks, the creator MUST use the "capabilities" information in these KeyPackages to verify that the chosen version and ciphersuite is the best option supported by all members. </del> Initialize a one-member group with the following initial values: Ratchet tree: A tree with a single node, a leaf containing an Confirmed transcript hash: The zero-length octet string <del> Interim transcript hash: The zero-length octet string Init secret: A fresh random value of size "KDF.Nh" </del>  Extensions: Any values of the creator's choosing <del> For each member, construct an Add proposal from the KeyPackage for that member (see add) </del>  <del> Construct a Commit message that commits all of the Add proposals, in any order chosen by the creator (see commit) </del>  <del> Process the Commit message to obtain a new group state (for the epoch in which the new members are added) and a Welcome message </del>  <del> Transmit the Welcome message to the other new members </del>  <del> Group IDs SHOULD be constructed in such a way that there's an overwhelmingly low probability of honest group creators generating the same group ID, even without assistance from the Delivery Service. For example, by making the group ID a freshly generated random value of size "KDF.Nh".  The Delivery Service MAY attempt to ensure that group IDs are globally unique by rejecting the creation of new groups with a previously used ID. </del>  <del> The recipient of a Welcome message processes it as described in joining-via-welcome-message. </del>  In principle, the above process could be streamlined by having the creator directly create a tree and choose a random value for first In both cases, the new members need information to bootstrap their local group state.  New members MUST verify that "group_id" is unique among the groups they're currently participating in.

This PR is an alternative to . This PR updates the group creation process so that epoch 0 is a "full-fledged" epoch, with an epoch secret (and all the derivatives) instead of just an init secret. One implication of that is that the interim transcript hash can now be computed in the usual way, by extending the confirmed transcript hash with a confirmation tag: This has the nice side effect of immediately mixing the epoch secret into the transcript hash, helping the group diverge (a concern NAME raised on the call today). While I was editing the group creation section, I also rationalized the requirements a bit. One reason that came up is that the group creation section currently assumes you're always starting with multiple members. So the MUST-level requirement to fetch key packages has been downgraded to a SHOULD. Finally, I updated the specification of GroupInfo to explain the fields, in particular explaining how you get the confirmation tag in epoch 0 or later epochs.
Since this PR clarifies more than and the solution is equally good, I'd suggest closing and merging this one.

The former is used to update the confirmed transcript hash and the latter to update the interim transcript hash. <ins> In this notation, "InterimTranscriptHashInput_[epoch]" and "ConfirmedTranscriptHashInput_[epoch+1]" are based on the Commit that initiated the epoch with epoch number "epoch".  (Note that the "epoch" field in this Commit will be set to "epoch - 1", since it is sent within the previous epoch.) </ins> 8.3. In addition to initializing a new epoch via KDF invocations as 11.  <ins> A group is always created with a single member, the "creator".  Other members are then added to the group using the usual Add/Commit mechanism. The creator of a group is responsible for setting the group ID, ciphersuite, and initial extensions for the group.  If the creator intends to add other members at the time of creation, then it SHOULD Fetch KeyPackages for the members to be added, and select a ciphersuite and extensions according to the capabilities of the members.  To protect against downgrade attacks, the creator MUST use the "capabilities" information in these KeyPackages to verify that the chosen version and ciphersuite is the best option supported by all members. Group IDs SHOULD be constructed in such a way that there's an overwhelmingly low probability of honest group creators generating the same group ID, even without assistance from the Delivery Service. For example, by making the group ID a freshly generated random value of size "KDF.Nh".  The Delivery Service MAY attempt to ensure that group IDs are globally unique by rejecting the creation of new groups with a previously used ID. </ins> The creator of a group MUST take the following steps to initialize the group:  Initialize a one-member group with the following initial values: Ratchet tree: A tree with a single node, a leaf containing an Confirmed transcript hash: The zero-length octet string  <ins> Epoch secret: A fresh random value of size "KDF.Nh" </ins> Extensions: Any values of the creator's choosing  <ins> Calculate the interim transcript hash: </ins>  <ins> Derive the "confirmation_key" for the epoch as described in key-schedule. </ins>  <ins> Compute a "confirmation_tag" over the empty "confirmed_transcript_hash" using the "confirmation_key" as described in content-authentication. </ins>  <ins> Compute the updated "interim_transcript_hash" from the "confirmed_transcript_hash" and the "confirmation_tag" as described in </ins>  <ins> At this point, the creator's state represents a one-member group with a fully initialized key schedule, transcript hashes, etc.  Proposals and Commits can be generated for this group state just like any other state of the group, such as Add proposals and Commits to add other members to the group.  A GroupInfo object for this group state can also be published to facilitate external joins. </ins>  <ins> Members other than the creator join either by being sent a Welcome message (as described in joining-via-welcome-message) or by sending an external Commit (see joining-via-external-commits). </ins> In principle, the above process could be streamlined by having the creator directly create a tree and choose a random value for first In both cases, the new members need information to bootstrap their local group state. <ins> The "group_context" field represents the current state of the group. The "extensions" field allows the sender to provide additional data that might be useful to new joiners.  The "confirmation_tag" represents the confirmation tag from the Commit that initiated the current epoch, or for epoch 0, the confirmation tag computed in the creation of the group (see group-creation).  (In either case, the creator of a GroupInfo may recompute the confirmation tag as "MAC(confirmation_key, confirmed_transcript_hash)".) </ins> New members MUST verify that "group_id" is unique among the groups they're currently participating in.


architecture.  In particular, we assume that the following services are provided: <del> A Delivery Service that routes MLS messages among the participants in the protocol.  The following types of delivery are typically required: </del>  Pre-publication of KeyPackage objects for clients Unicast delivery of Welcome messages to new members of a group <del> An Authentication Service that enables group members to </del>  authenticate the credentials presented by other group members.  1.2. RFC EDITOR PLEASE DELETE THIS SECTION. The security goals of MLS are described in I-D.ietf-mls-architecture. We describe here how the protocol achieves its goals at a high level, though a complete security analysis is outside of the scope of this <del> document. </del>  15.1. 15.2.  The first form of authentication we provide is that group members can verify a message originated from one of the members of the group. For encrypted messages, this is guaranteed because messages are that ensures that the legitimate members of the group have the required PSKs. <del> 15.3. </del>  Forward secrecy and post-compromise security are important security notions for long-lived MLS groups.  Forward secrecy means that This way, the key material used to add a member to a new group is more likely to be fresh and less likely to be compromised. <del> 15.4. </del>  KeyPackages are intended to be used only once.  That is, once a KeyPackage has been used to introduce the corresponding client to a KeyPackage publication system SHOULD rate-limit KeyPackage requests, especially if not authenticated. <del> 15.5. </del>  It is possible for a malicious member of a group to "fragment" the group by crafting an invalid UpdatePath.  Recall that an UpdatePath

Add a paragraph to Operational Context describing additional security services that the DS can provide Add a citation to security analyses via the MLS Architecture Add a section discussing metadata protection
It also feels like the text assumes that the DS is a server as opposed to the abstract layer that we define it as in the architecture document. Maybe we should qualify the considerations accordingly?
NAME NAME - Thanks for sending . I didn't merge it directly, but rewrote the metadata section trying to hit the key points from your proposal. LMK what you think.
Comment by NAME Hmmm :P
Cf. RFC 8446 We could provide some more citations to the analyses that are now in the literature if you think that would help.
CC NAME NAME NAME for citations
They are also in this architecture document PR: URL
Oh good, I'll just add a citation over to mls-architecture.
Comment by NAME That is quite some information that must be publicly available to allow external Add requests. This leaks information, eg same epoch means the group membership did not change, etc etc. I hope this will appear in the Security Considerations later :)
I suppose between this and , we should add a subsection to the Security Considerations on metadata privacy.
I'm not sure actually resolves this?
Oops, that's correct NAME Had it in my notes among the others.
Comment by NAME There seems to be no group "owner", so inviting one member X, could that member than delete members from the group until the group is empty? Apparently, there is ACLs for this, but the document doesn't describe how ACLS would work or how these would be implemented.
You are correct that MLS is "egalitarian" by default, in that any member can perform any action. This capability can be limited by policy, enforced either at the endpoints or at the DS (the latter requiring handshake messages to be unencrypted). This is discussed in the MLS architecture document, e.g., in the section. I would be open to adding some security considerations noting this. But seeing as it's already in the architecture, I would be inclined to close this issue with no action.
Comment by NAME I find the interaction with the application layer not clear. Not much is mentioned in this document. How can a group have an administrator? How is that enforced at the MLS layer? How do ACLs interact with MLS? (How are DoS attacks mitigated (eg spam attempts to join any group). What hooks would be in the authentication service and/or delivery server? How would clients know the properties of these two services? This includes how it is not clear to me how race conditions are handled. What if two members try to expel each other at the same time? What if the group is so large, members always get their epoch wrong for things like Commit messages?
I think the intent was to have these issues mostly dealt with in the architecture document. Broadly speaking, it is the DS's job to solve these problems. For example, the DS we use in Webex chooses which member makes which commit. This is why we have Section 3, . There are also some brief notes in Section 14, ". Unless we need to make this division of labor clearer, I'm inclined to close this issue with no action.
While instant messaging was one of the big motivators for MLS, it is not the only one to be implemented in the same timeframe. In MIMI for example we are planning to have a whole work item that specifies many more constraints on how the DS would be expected to work in an instant messaging context. Whereas we have implementors of MLS who are planning to do things very differently for an IoT communication application.
I'll reread the architecture bit again about the DS, but it still feels to me it could be made more clear.

architecture.  In particular, we assume that the following services are provided:  <ins> A Delivery Service (DS) that routes MLS messages among the participants in the protocol.  The following types of delivery are typically required: </ins> Pre-publication of KeyPackage objects for clients Unicast delivery of Welcome messages to new members of a group  <ins> Sequencing of Commit messages (see sequencing) An Authentication Service (AS) that enables group members to </ins> authenticate the credentials presented by other group members. <ins> The DS and AS may also apply additional policies to MLS operations to obtain additional security properties.  For example, MLS enables any participant to add or remove members of a group; a DS could enforce a policy that only certain members are allowed to perform these operations.  MLS authenticates all members of a group; a DS could help ensure that only clients with certain types of credential are admitted.  MLS provides no inherent protection against denial of service; A DS could also enforce rate limits in order to mitigate these risks. </ins> 1.2. RFC EDITOR PLEASE DELETE THIS SECTION. The security goals of MLS are described in I-D.ietf-mls-architecture. We describe here how the protocol achieves its goals at a high level, though a complete security analysis is outside of the scope of this  <ins> document.  The Security Considerations section of I-D.ietf-mls- architecture provides some citations to detailed security analyses. </ins> 15.1. 15.2. <ins> MLS does not provide confidentiality protection to some messages and fields within messages: KeyPackage messages GroupInfo messages The unencrypted portion of a Welcome message Any Proposal or Commit messages sent as MLSPlaintext messages The unencrypted header fields in MLSCiphertext messages The lengths of encrypted Welcome and MLSCiphertext messages The only mechanism MLS provides for confidentially distributing a group's ratchet tree to new members is to send it in a Welcome message as a "ratchet_tree" extension.  If an application distributes the tree in some other way, its security will depend on that application mechanism. A party observing these fields might be able to infer certain properties of the group: Group ID Current epoch and frequency of epoch changes Frequency of messages within an epoch Group extensions Group membership The amount of metadata exposed to parties outside the group, and thus the ability of these parties to infer the group's properties, depends on several aspects of the DS design, such as: How KeyPackages are distributed How the ratchet tree is distributed How prospective external joiners get a GroupInfo object for the group Whether MLSPlaintext or MLSCiphertext messages are used for Proposal and Commit messages In the remainder of this section, we note the ways that the above properties of the group are reflected in unprotected group messages, as a guide to understanding how they might be exposed or protected in a given application. 15.2.1. MLS provides no mechanism to protect the group ID and epoch of a message from the DS, so the group ID and the frequency of messages and epoch changes are not protected against inspection by the DS. 15.2.2. A group's extensions are first set by the group's creator and then updated by GroupContextExtensions proposals.  A GroupContextExtension proposal sent as MLSPlaintext leaks the groups' extensions. A new member learns the group's extensions via a GroupInfo object. When the new member joins via a Welcome message, the Welcome message's encryption protects the GroupInfo message.  When the new member joins via an external join, they must be provided with a GroupInfo object.  Protection of this GroupInfo object is up to the application - if it is transmitted over a channel that is not confidential to the group and the new joiner, then it will leak the group's extensions. 15.2.3. The group's membership is represented directly by its ratchet tree, since each member's LeafNode contains members' cryptographic keys, a credential that contains information about the member's identity, and possibly other identifiers.  Applications that expose the group's ratchet tree outside the group also leak the group's membership. Changes to the group's membership are made by means of Add and Remove proposals.  If these proposals are sent as MLSPlaintext, then information will be leaked about the corresponding changes to the group's membership.  A party that sees all of these changes can reconstruct the group membership. Welcome messages contain a hash of each KeyPackage for which the Welcome message is encrypted.  If a party has access to a pool of KeyPackages and observes a Welcome message, then they can identify the KeyPackage representing the new member.  If the party can also associate the Welcome with a group, then the party can infer that the identified new member was added to that group. Note that these information leaks reveal the group's membership only to the degree that that membership is revealed by the contents of a member's LeafNode in the ratchet tree.  In some cases, this may be quite direct, e.g., due to credentials attesting to identifiers such as email addresses.  An application could construct a member's leaf node to be less identifying, e.g., by using a pseudonymous credential and frequently rotating encryption and signature keys. 15.3. </ins> The first form of authentication we provide is that group members can verify a message originated from one of the members of the group. For encrypted messages, this is guaranteed because messages are that ensures that the legitimate members of the group have the required PSKs.  <ins> 15.4. </ins> Forward secrecy and post-compromise security are important security notions for long-lived MLS groups.  Forward secrecy means that This way, the key material used to add a member to a new group is more likely to be fresh and less likely to be compromised.  <ins> 15.5. </ins> KeyPackages are intended to be used only once.  That is, once a KeyPackage has been used to introduce the corresponding client to a KeyPackage publication system SHOULD rate-limit KeyPackage requests, especially if not authenticated.  <ins> 15.6. </ins> It is possible for a malicious member of a group to "fragment" the group by crafting an invalid UpdatePath.  Recall that an UpdatePath


To disambiguate different signatures used in MLS, each signed value is prefixed by a label as shown below:  Here, the functions "Signature.Sign" and "Signature.Verify" are defined by the signature algorithm. and Commits refer to Proposals they cover.  These identifiers are computed as follows:  For a KeyPackageRef, the "value" input is the encoded KeyPackage, and the ciphersuite specified in the KeyPackage determines the KDF used. For a ProposalRef, the "value" input is the MLSAuthenticatedContent

This PR fixes some minor issues with the presentation language. Moving and to their own block is required so that the can now detect them.

To disambiguate different signatures used in MLS, each signed value is prefixed by a label as shown below: <ins> Where SignContent is specified as: And its fields set to: </ins> Here, the functions "Signature.Sign" and "Signature.Verify" are defined by the signature algorithm. and Commits refer to Proposals they cover.  These identifiers are computed as follows: <ins> Where RefHashInput is defined as: And its fields set to: </ins> For a KeyPackageRef, the "value" input is the encoded KeyPackage, and the ciphersuite specified in the KeyPackage determines the KDF used. For a ProposalRef, the "value" input is the MLSAuthenticatedContent