relatively short period of time, clients have an indication that the credential might have been created without the user's knowledge.  Due to the asynchronous nature of MLS, however, there may be transient <del> inconsistencies in a user's device set, so correlating users' clients </del>  across groups is more of a detection mechanism than a prevention mechanism.

Particularly in multi-device scenarios (where a user has more than one device), we should recommend that clients correlate the set of devices of each user across groups. This would make it much harder for a malicious AS to issue fake device credentials for a particular user because clients would expect the credential to appear in all groups of which the user is a member. If a device credential does not appear in all groups after a while, clients have an indication that the credential might have been created without the user's knowledge. This should however only be a recommendation since it might not be a desirable property in all scenarios. In practical terms, users might also need some time to add their new device to all of the groups, therefore a grace period might be needed. Taking the latter into account, correlating users' devices across groups is more of a detection mechanism than a prevention mechanism.
"In many uses of MLS, there are multiple MLS clients which represent a single user (for example a human user with a mobile and desktop version of an application). Often the same set of clients is represented in exactly the same list groups. In applications where this is the case, clients can compare the set of devices of each user across groups. This would make it much harder for a malicious AS to issue fake device credentials for a particular user because clients would expect the credential to appear in all groups of which the user is a member. If a device credential does not appear in all groups after some relatively short period of time, clients have an indication that the credential might have been created without the user's knowledge. As this may take some time, correlating users' devices across groups is more of a detection mechanism than a prevention mechanism."
I lightly edited NAME prose and turned it into PR .
Made a quick pass. I think we should stick with "clients" rather than "devices".

relatively short period of time, clients have an indication that the credential might have been created without the user's knowledge.  Due to the asynchronous nature of MLS, however, there may be transient  <ins> inconsistencies in a user's client set, so correlating users' clients </ins> across groups is more of a detection mechanism than a prevention mechanism.


Various academic works have analyzed MLS and the different security guarantees it aims to provide.  The security of large parts of the <del> protocol has been analyzed by [BBN19] (draft 7), [ACDT21] (draft 11) and [AJM20] (draft 12). </del>  Individual components of various drafts of the MLS protocol have been analyzed in isolation and with differing adversarial models, for <del> example, [BBR18], [ACDT19], [ACCKKMPPWY19], [AJM20] and [ACJM20] </del>  analyze the ratcheting tree as the sub-protocol of MLS that <del> facilitates key agreement, while [BCK21] analyzes the key derivation paths in the ratchet tree and key schedule.  Finally, [CHK21] analyzes the authentication and cross-group healing guarantees provided by MLS. </del>  8. <del> ACCKKMPPWY19: https://eprint.iacr.org/2019/1489 ACDT19: https://eprint.iacr.org/2019/1189 ACDT21: https://eprint.iacr.org/2021/1083 ACJM20: https://eprint.iacr.org/2020/752 AHKM21: https://eprint.iacr.org/2021/1456 AJM20: https://eprint.iacr.org/2020/1327 BBN19: https://hal.laas.fr/INRIA/hal-02425229 BBR18: https://hal.inria.fr/hal-02425247 BCK21: https://eprint.iacr.org/2021/137 CHK21: https://www.usenix.org/system/files/sec21-cremers.pdf 9. </del> This document makes no requests of IANA.

The references at the end of the Security Considerations weren't in kramdown format. Fixed.

Various academic works have analyzed MLS and the different security guarantees it aims to provide.  The security of large parts of the  <ins> protocol has been analyzed by BBN19 (draft 7), ACDT21 (draft 11) and AJM20 (draft 12). </ins> Individual components of various drafts of the MLS protocol have been analyzed in isolation and with differing adversarial models, for  <ins> example, BBR18, ACDT19, ACCKKMPPWY19, AJM20, ACJM20, and AHKM21 </ins> analyze the ratcheting tree as the sub-protocol of MLS that  <ins> facilitates key agreement, while BCK21 analyzes the key derivation paths in the ratchet tree and key schedule.  Finally, CHK21 analyzes the authentication and cross-group healing guarantees provided by MLS. </ins> 8.  This document makes no requests of IANA.


KT log under a user's identity.  The verification function would correspond to verifying a key's inclusion in the log for a claimed identity, together with the KT log's mechanisms for a user to <del> monitor and control which keys are associated to their identity. </del>  By the nature of its roles in MLS authentication, the AS is invested with a large amount of trust and the compromise of one of its

For the authors' consideration: Section 3 A member with a valid credential authenticates its MLS messages by signing them with the s/its/it's/ mechanisms for a user to monitor and control which keys are associated to their identity. s/to their/with their/ Operational Requirements A extension can help maintain interoperability s/A extension/An extension/ Whether there should be a extension in groups. s/a extension/an extension/ Forward and Post-Compromise Security MLS partially defend against this problem by active member including freshness, however not s/defend/defends/ s/member/members/ Mandate a key updates from clients that are not otherwise sending messages s/a key/key/ Compromise of AEAD key material authentication is not affected in neither of these s/neither/either/ Compromise of the Group Secrets of a single group for one or more group epochs of the compromised party with no ability to an honest group to recover message secrecy. s/to an/for an/ Compromise by an active adversary with the ability to sign messages the attacker can perform all operations which are available to an legitimate client s/an legitmate/a legitimate/ Compromise of the authentication with access to a signature key Beware that in both oracle and private key access, an active adaptive attacker, can follow th s/attacker, can/attacker can/ Security consideration in the context of a full state compromise They also are providing the strong authentication guarantees to other clients s/providing the strong/providing strong/ hence we consider that their protection by additional security mechanism should be a priority. s/mechanism/mechanisms/ Overall there is no way to detect or prevent these compromise, as discussed s/compromise/compromises/ Privacy of delivery and push notifications For secure messaging systems, push notification are often sent real-time s/notification/notifications/ Authentication Service Compromise MLS client (which is under the control of the user) have often the ability s/have often/often have/
Approved with nits.These changes look good to me.

KT log under a user's identity.  The verification function would correspond to verifying a key's inclusion in the log for a claimed identity, together with the KT log's mechanisms for a user to  <ins> monitor and control which keys are associated with their identity. </ins> By the nature of its roles in MLS authentication, the AS is invested with a large amount of trust and the compromise of one of its


is persistently offline may still be holding old keying material and thus be a threat to both FS and PCS if it is later compromised. <del> MLS partially defend against this problem by active member including freshness, however not much can be done on the inactive side especially in the case where the client has not processed messages. </del>  <del> *RECOMMENDATION:* Mandate a key updates from clients that are not </del>  otherwise sending messages and evict clients which are idle for too long.

is persistently offline may still be holding old keying material and thus be a threat to both FS and PCS if it is later compromised.  <ins> MLS partially defends against this problem by active members including freshness, however not much can be done on the inactive side especially in the case where the client has not processed messages. </ins>  <ins> *RECOMMENDATION:* Mandate key updates from clients that are not </ins> otherwise sending messages and evict clients which are idle for too long.


the secrets themselves are protected by HPKE encryption. Note that under that compromise scenario, authentication is not <del> affected in neither of these cases.  As every member of the group can </del>  compute the AEAD keys for all the chains (they have access to the Group Secrets) in order to send and receive messages, the authentication provided by the AEAD encryption layer of the common

the secrets themselves are protected by HPKE encryption. Note that under that compromise scenario, authentication is not  <ins> affected in either of these cases.  As every member of the group can </ins> compute the AEAD keys for all the chains (they have access to the Group Secrets) in order to send and receive messages, the authentication provided by the AEAD encryption layer of the common


secrecy. If the adversary is active, the adversary can follow the protocol and <del> perform updates on behalf of the compromised party with no ability to an honest group to recover message secrecy.  However, MLS provides PCS against active adaptive attackers through its Remove group operation.  This means that, as long as other members of the group are honest, the protocol will guarantee message secrecy for all </del>  messages exchanged in the epochs after the compromised party has been removed.

secrecy. If the adversary is active, the adversary can follow the protocol and  <ins> perform updates on behalf of the compromised party with no ability for an honest group to recover message secrecy.  However, MLS provides PCS against active adaptive attackers through its Remove group operation.  This means that, as long as other members of the group are honest, the protocol will guarantee message secrecy for all </ins> messages exchanged in the epochs after the compromised party has been removed.


epochs until an honest update from the compromised client happens. Note that under this compromise scenario, the attacker can perform <del> all operations which are available to an legitimate client even </del>  without access to the actual value of the signature key. Without access to the group secrets, the adversary will not have the

epochs until an honest update from the compromised client happens. Note that under this compromise scenario, the attacker can perform  <ins> all operations which are available to a legitimate client even </ins> without access to the actual value of the signature key. Without access to the group secrets, the adversary will not have the


compromised parties refresh their credentials securely. Beware that in both oracle and private key access, an active adaptive <del> attacker, can follow the protocol and request to update its own </del>  credential.  This in turn induces a signature key rotation which could provide the attacker with part or the full value of the private key depending on the architecture of the service provider.

compromised parties refresh their credentials securely. Beware that in both oracle and private key access, an active adaptive  <ins> attacker can follow the protocol and request to update its own </ins> credential.  This in turn induces a signature key rotation which could provide the attacker with part or the full value of the private key depending on the architecture of the service provider.


and changed with each message received by a client. However, the signature private keys are mostly used by clients to <del> send a message.  They also are providing the strong authentication guarantees to other clients, hence we consider that their protection by additional security mechanism should be a priority. </del>  <del> Overall there is no way to detect or prevent these compromise, as </del>  discussed in the previous sections, performing separation of the application secret states can help recovery after compromise, this is the case for signature keys but similar concern exists for the

and changed with each message received by a client. However, the signature private keys are mostly used by clients to  <ins> send a message.  They also provide strong authentication guarantees to other clients, hence we consider that their protection by additional security mechanisms should be a priority. </ins>  <ins> Overall there is no way to detect or prevent these compromises, as </ins> discussed in the previous sections, performing separation of the application secret states can help recovery after compromise, this is the case for signature keys but similar concern exists for the


notification provider have to be trusted to avoid making correlation on which devices are recipients of the same message. <del> For secure messaging systems, push notification are often sent real- </del>  time as it is not acceptable to create artificial delays for message retrieval.

notification provider have to be trusted to avoid making correlation on which devices are recipients of the same message.  <ins> For secure messaging systems, push notifications are often sent real- </ins> time as it is not acceptable to create artificial delays for message retrieval.


The attacker can publish or distribute credentials Infrastructures that provide cryptographic material or credentials in <del> place of the MLS client (which is under the control of the user) have often the ability to use the associated secrets to perform operations on behalf of the user, which is unacceptable in many situations. Other mechanisms can be used to prevent this issue, such as the service blessing cryptographic material used by an MLS client. </del>  *RECOMMENDATION:* Make clients submit signature public keys to the AS, this is usually better than the AS generating public key pairs

The attacker can publish or distribute credentials Infrastructures that provide cryptographic material or credentials in  <ins> place of the MLS client (which is under the control of the user) often have the ability to use the associated secrets to perform operations on behalf of the user, which is unacceptable in many situations.  Other mechanisms can be used to prevent this issue, such as the service blessing cryptographic material used by an MLS client. </ins> *RECOMMENDATION:* Make clients submit signature public keys to the AS, this is usually better than the AS generating public key pairs


inside the group.  When members perform changes directly, this is clearly the case.  External joins are authorized indirectly, in the sense that a member publishing a GroupInfo object authorizes anyone <del> to join who has access to the GroupInfo object.  External joins do not allow for more granular authorization checks to be done before the new member is added to the group, so if an application wishes to both allow external joins and enforce such checks, then either all the members of the group must all have the ability to check and reject invalid External joins autonomously, or the application needs to do such checks when a member joins and remove them if those checks fail. </del>  Application setup may also determine other criteria for membership validity.  For example, per-device signature keys can be signed by an

I think the spirit of this change is good, but the last two sentences are confusing talking about the client trying to join and an existing member trying to prevent them from seeing anything confidential after joining. My initial reaction to this idea was always that post-hoc removing someone who should never have joined is a terrible architectural decision. Post-hoc removal either allows an undesirable member a window to see messages sent by some members, or it requires consistent policy across members. If there is consistent policy across members the members should simply treat the Commit from the undesirable client as invalid. Rather than further condone post-hoc removal (which doesn't require any normative change to the MLS protocol), why not just delete mentions of post-hoc removal?
Compromise - Deleted the sentence that talks about the security implications of post-hoc removal, left the mention of it simply being possible.
Following on from discussion in Even once a GroupInfo has been published to a prospective new joiner, there are still a few opportunities to apply authorization policy to the join: The DS can block the external Commit from reaching the group members (requires intelligent DS) The clients in the group can all refuse to apply the external Commit (requires consistent policy) Any client can remove the member after allowing them to join (might expose some group comms to the joiner)
Comment by NAME This seems rather risky? What could such a member do in the short time between getting added and getting kicked? Would they see message history? Group membership? How many devices a user has? When members were last online? Why support such a group type? Wouldn't it be better to not support this and have an automated "special member" being a bot that handles member addition?
Until someone else sends a message, a new joiner doesn't learn anything non-public. If you think about it, how would they? They're outside the group before they send an external join, and the external join just establishes a new shared secret with the group for future communications. More specifically: Message history - MLS's forward secrecy guarantees mean that new joiners don't get message history. Group membership - This is public anyway via the GroupInfo that an external joiner needs to join How many devices - To the degree this is exposed, it would be in the group membership Last online - MLS doesn't have any notion of this As for an "add me bot", it's a useful idea, but not applicable to a bunch of cases. The bot has to be a member of the group and has to be always-online. So now you have the group's secrets on a server somewhere, instead of just in the communicating endpoints, already an additional point of compromise. And it can't be the DS's server, since the whole point is to protect against the DS.
This statement in the draft is just plain wrong. In our implementation, we actually do validation of External joins at the application layer. I addressed this in (dating from WGLC) which says the following: "External joins do not allow for more granular authorization checks to be done before the new member is added to the group, so if an application wishes to both allow external joins and enforce such checks, then either all the members of the group must all have the ability to check and reject invalid External joins autonomously, or the application needs to do such checks when a member joins and remove them if those checks fail."

inside the group.  When members perform changes directly, this is clearly the case.  External joins are authorized indirectly, in the sense that a member publishing a GroupInfo object authorizes anyone  <ins> to join who has access to the GroupInfo object.  Both types of joins are done via a Commit message, which could be blocked by the DS or rejected by clients if the join is not authorized.  The former approach requires that Commits be visible to the DS; the latter approach requires that clients all share a consistent policy.  In the unfortunate event that an unauthorized member is able to join, MLS enables any member to remove them. </ins> Application setup may also determine other criteria for membership validity.  For example, per-device signature keys can be signed by an


5.5. <del> Within an MLS group, every member is authenticated to other member, by means of credentials issued and verified by the Authentication </del>  Service.  MLS does not prescribe what actions, if any, an application should take in the event that a group member presents an invalid credential.  For example, an application may require such a member to

NAME noted in URL that an important function of the AS is to ensure that clients come to consistent evaluations of credentials. We should make that recommendation in this document, including the fact that consistency is needed when validity can change over time.

5.5.  <ins> Within an MLS group, every member is authenticated to other member by means of credentials issued and verified by the Authentication </ins> Service.  MLS does not prescribe what actions, if any, an application should take in the event that a group member presents an invalid credential.  For example, an application may require such a member to


In some authentication systems, it is possible for a previously-valid credential to become invalid over time.  For example, in a system based on X.509 certificates, credentials can expire or be revoked. <del> Fortunately, the MLS update mechansisms allow a client to replace an old credential with a new one.  This is best done before the old credential becomes invalid. </del>  *RECOMMENDATION:* Proactively rotate credentials, especially if a credential is about to become invalid.

In some authentication systems, it is possible for a previously-valid credential to become invalid over time.  For example, in a system based on X.509 certificates, credentials can expire or be revoked.  <ins> The MLS update mechanisms allow a client to replace an old credential with a new one.  This is best done before the old credential becomes invalid. </ins> *RECOMMENDATION:* Proactively rotate credentials, especially if a credential is about to become invalid.


2.  MLS provides a way for _clients_ to form _groups_ within which they can communicate securely.  For example, a set of users might use clients on their phones or laptops to join a group and communicate with each other.  A group may be as small as two clients (e.g., for simple person to person messaging) or as large as tens of thousands. <del> A client that is part of a group is a _member_ of that group. </del>  In order to communicate securely, users initially interact with services at their disposal to establish the necessary values and

This replaced PR which has broken merge conflicts.
I've reverted this. It was prematurely merged. I'll open a new PR once I have had time to examine this.
This was discussed in the interim today and is the same as the content that was in . Thanks, -rohan Rohan Mahy l Vice President Engineering, Architecture Chat: NAME on Wire Wire - Secure team messaging. Zeta Project Germany GmbH l Rosenthaler Straße 40, 10178 Berlin, Germany Geschäftsführer/Managing Director: Alan Duric HRB 149847 beim Handelsregister Charlottenburg, Berlin VAT-ID DE288748675
That's fine, but I still want to go over it before it merges.

2. <ins> 2.1. </ins> MLS provides a way for _clients_ to form _groups_ within which they can communicate securely.  For example, a set of users might use clients on their phones or laptops to join a group and communicate with each other.  A group may be as small as two clients (e.g., for simple person to person messaging) or as large as tens of thousands.  <ins> A client that is part of a group is a _member_ of that group.  As groups change membership and group or member properties, they advance from one _epoch_ to another and the cryptographic state of the group evolves. The group is represented using a _ratchet tree_, which represents the members as the leaves of a tree.  It is used to efficiently encrypt to subsets of the members.  Each member has a _LeafNode_ object in the tree holding the client's identity, credentials, and capabilities. Various messages are used in the evolution from epoch to epoch.  A _Proposal_ message proposes a change to be made in the next epoch, such as adding or removing a member.  A _Commit_ message initiates a new epoch by instructing members of the group to implement a collection of proposals.  Proposals and Commits are collectively called _Handshake messages_.  A _KeyPackage_ provides keys that can be used to add the client to a group, including its LeafNode, and _Signature Key_.  A _Welcome_ message provides a new member to the group with the information to initialize their state for the epoch in which they were added. Of course most (but not all) applications use MLS to send encrypted group messages.  An _application message_ is an MLS message with an arbitrary application payload. Finally, a _PublicMessage_ contains an integrity-protected MLS Handshake message, while a _PrivateMessage_ contains a confidential, integrity-protected Handshake or Application message. For a more detailed explanation of these terms, please consult the MLS protocol specification. 2.2. </ins> In order to communicate securely, users initially interact with services at their disposal to establish the necessary values and


restricted to certain users, but we assume that those restrictions are enforced by the application layer. <del> 2.1. </del>  While informally, a group can be considered to be a set of users possibly using multiple endpoint devices to interact with the Service

restricted to certain users, but we assume that those restrictions are enforced by the application layer.  <ins> 2.3. </ins> While informally, a group can be considered to be a set of users possibly using multiple endpoint devices to interact with the Service


RFC EDITOR PLEASE DELETE THIS SECTION.  draft-03 Added ciphersuites and signature schemes (*)

This does not handle the removal of DH uses instead of KEM which will be done as part of Issue / PR ...
I would be happier if this PR were moving the draft to use draft-barnes-cfrg-hpke, which is one of the changes I had in mind for -04. Do you think that's premature?
This text is wrong:
This could also be addressed by using draft-barnes-cfrg-hpke.
This has been fixed by
Enable, e.g., P-256 with both AES-GCM and ChaChaPoly Re-use code points from TLS
We should discuss that today

RFC EDITOR PLEASE DELETE THIS SECTION. <ins> draft-04 ECIES is now renamed in favor of HPKE (*) </ins> draft-03 Added ciphersuites and signature schemes (*)


ciphertext in the list is the encryption to the corresponding node in the resolution. <del> The ECIESCiphertext values encoding the encrypted secret values are computed as follows: Generate an ephemeral DH key pair (x, x*G) in the DH group specified by the ciphersuite in use Compute the shared secret Z with the node's other child Derive a key and nonce as described below Encrypt the node's secret value using the AEAD algorithm specified by the ciphersuite in use, with the following inputs: Key: The key derived from Z Nonce: The nonce derived from Z Additional Authenticated Data: The empty octet string Plaintext: The secret value, without any further formatting Encode the ECIESCiphertext with the following values: ephemeral_key: The ephemeral public key x*G ciphertext: The AEAD output </del>  Decryption is performed in the corresponding way, using the private key of the resolution node and the ephemeral public key transmitted

ciphertext in the list is the encryption to the corresponding node in the resolution.  <ins> The HPKECiphertext values are computed according to the Encrypt function defined in HPKE. </ins> Decryption is performed in the corresponding way, using the private key of the resolution node and the ephemeral public key transmitted


The Welcome message contains the information that the new member needs to initialize a GroupState object that can be updated to the current state using the Add message.  This information is encrypted <del> for the new member using ECIES.  The recipient key pair for the ECIES </del>  encryption is the one included in the indicated UserInitKey, corresponding to the indicated ciphersuite.

The Welcome message contains the information that the new member needs to initialize a GroupState object that can be updated to the current state using the Add message.  This information is encrypted  <ins> for the new member using HPKE.  The recipient key pair for the HPKE </ins> encryption is the one included in the indicated UserInitKey, corresponding to the indicated ciphersuite.


simply copy all fields except the "leaf_secret" from its GroupState object. <del> [[ OPEN ISSUE: The Welcome message needs to be sent encrypted for the new member.  This should be done using the public key in the UserInitKey, either with ECIES or X3DH. ]] </del> [[ OPEN ISSUE: The Welcome message needs to be synchronized in the same way as the Add.  That is, the Welcome should be sent only if the Add succeeds, and is not in conflict with another, simultaneous Add.

simply copy all fields except the "leaf_secret" from its GroupState object.  [[ OPEN ISSUE: The Welcome message needs to be synchronized in the same way as the Add.  That is, the Welcome should be sent only if the Add succeeds, and is not in conflict with another, simultaneous Add.


each Participant creates an initial Participant Application Secret to be used for its own sending chain: <del> Note that [sender] represent the uint32 value encoding the index of the participant in the ratchet tree. </del>  Updating the Application secret and deriving the associated AEAD key and nonce can be summarized as the following Application key schedule

Fix for
NAME This might not be completely ideal, because of the group state but it currently does not change the key schedule, I am merging this because we need it for correct interop but feel free to get back to discuss a better way to do this in details.
There are at least two bugs in the message protection section that make it unimplementable: It calls for , but the third argument to as defined is a , not an octet string. It refers to a function , which is defined in TLS, but not here. ISTM the simplest way to fix these problems would to define and use it (1) as the basis for , (2) for deriving sender root secrets, and (3) for deriving keys and nonces.
Fixed by

each Participant creates an initial Participant Application Secret to be used for its own sending chain:  <ins> Note that [sender] represents the index of the member in the roster. </ins> Updating the Application secret and deriving the associated AEAD key and nonce can be summarized as the following Application key schedule


A Key Derivation Function (KDF) <del> A Derive-Public-Key function that produces a public key from a private key </del>  A ratchet tree is a left-balanced binary tree, in which each node contains up to three values:

Initial attempt to solve . This defines the KDF as discussed in and relocates the DH computation obligation and verification as part of the Derive-Key-Pair function definition.
Fixing my own review comments here, since NAME appears to be offline and we need to publish -04.
The PR from NAME introducing a KDF was merged before I had a chance to review it. There are a number of problems with it: Instead of calling for an abstract KDF, it should define one, as we have with the use of HKDF elsewhere We can't just say , since KDFs produce octet strings, not private keys. We need , not just . This doesn't match what I recall discussing on the list. I think what you want is actually as follows: Or in prose:
That was exactly the question I was asking on the list, i.e., if we need an explicit "derive-keypair" function. The idea with deriving the private key directly was to avoid a redundant derive-key operation. I'm totally fine re-doing the PR to represent either approach.
Merging that PR too quickly is on me. For the parent derivation, we can just use what the formal model for TreeKEM does, which is roughly the Richard points out. The part I don't like about this, is to define in the MLS specification as it depends on the HPKE internal algorithm. The TreeKEM formal specification, it is done the following way (because we know that the HPKE interface we use can take random bytes as a secret key): In the MLS specification, I suggest we avoid defining anything new but point to the HPKE spec instead. As it provides the KEM scheme, it should also provide ways to derive the from an octet string and the function that transform an to a . I suggest we define, in the HPKE document, something like that we already need anyway and eventually that maps the random bytes to an . For X25519 we don't even need the second function but generically we probably need it. That would lead to define the following in the MLS spec: NAME ?
I don't think we can delegate this to HPKE. HPKE doesn't have a need for anything like Derive-Key-Pair. We do, so it's on us to define it. The point NAME raises about avoiding unnecessary operations is relevant here: If we're forking the hashes like this, then we can remove the hashing part from Derive-Key-Pair, so that it's really just a definition of how you convert from an octet string to a private key (and thus its public key).
I disagree, it is not for MLS to define the and functions for all asymmetric schemes possibly used in HPKE. In MLS we should have to do only what TreeKEM does, aka, 2 KDFs, one outputing the parent's secret, one outputing the KEM encryption key, and that's it. I am willing to accept defining here but this is already odd.
If it's not our job, whose is it? It's not HPKE's job, because they don't have a need to convert byte strings to private keys. Some document needs to define this conversion in order for MLS to be implementable.
I agree we are in trouble here :) But I still wish that if we can avoid it, we should.
I agree that the KEM schemes themselves should define these things, like Curve25519 does. But it's like two lines of text. I'm not too bothered with it.
I think I'm a bit lost here. How do we go forward? Regarding the use of an abstract KDF: I was mostly just adapting the existing text, which used an abstract hash function if I recall correctly. I didn't touch the texts that got more concrete because they seemed to be a little outdated anyway. That shouldn't be a problem though.
NAME Ok, looking at this now, I am not sure what we decided in the end. I would be ok to define as you said but as it is KEM specific so there is no good solution for P256 or for whatever PQ KEM that would have a specific way of generating keys from pseudo random bytes...
NAME any suggestion here
Fixed by

A Key Derivation Function (KDF)  <ins> A Derive-Key-Pair function that produces an asymmetric keypair from a node secret </ins> A ratchet tree is a left-balanced binary tree, in which each node contains up to three values:


An asymmetric public key <del> The private key for a node is derived from its secret value using the KDF.  The public key is then derived from the private key using the Derive-Public-Key function. </del>  <del> The contents of a parent node are computed from one of its children as follows: </del>  <del> The contents of the parent are based on the latest-updated child. For example, if participants with leaf secrets A, B, C, and D join a group in that order, then the resulting tree will have the following structure: </del>  <del> If the first participant subsequently changes its leaf secret to be X, then the tree will have the following structure. </del>  5.3.

An asymmetric public key  <ins> The contents of the parent are based on the latest-updated child. Nodes in a tree are always updated along the "direct path" from a leaf to the root.  The generator of the update chooses a random secret value "path_secret[0]", and generates a sequence of "path secrets", one for each node from the leaf to the root.  That is, path_secret[0] is used for the leaf, path_secret[1] for its parent, and so on.  At each step, the path secret is used to derive a new secret value for the corresponding node, from which the node's key pair is derived. </ins>  <ins> For example, suppose there is a group with four participants: </ins>  <ins> If the first participant subsequently generates an update based on a secret X, then the sender would generate the following sequence of path secrets and node secrets: </ins>  <ins> After the update, the tree will have the following structure, where "ns[i]" represents the node_secret values generated as described above: </ins> 5.3.


curves, they SHOULD perform the additional checks specified in Section 7 of <del> Encryption keys are derived from shared secrets by taking the first 16 bytes of H(Z), where Z is the shared secret and H is SHA-256. </del> 5.5.2. This ciphersuite uses the following primitives:

curves, they SHOULD perform the additional checks specified in Section 7 of  5.5.2. This ciphersuite uses the following primitives:


elliptic curve equation.  For these curves, implementers do not need to verify membership in the correct subgroup. <del> Encryption keys are derived from shared secrets by taking the first 16 bytes of H(Z), where Z is the shared secret and H is SHA-256. </del> 5.6. A member of a group authenticates the identities of other

elliptic curve equation.  For these curves, implementers do not need to verify membership in the correct subgroup.  5.6. A member of a group authenticates the identities of other


Rename the GroupState structure to GroupContext (*)  draft-05 Common framing for handshake and application messages (*)

Overall, this seems OK. Just using "InitKey" would be clear and less wordy.
I tried this and that led people to confuse and
Here's the Weekly Digest for : - - Last week 5 issues were created. Of these, 1 issues have been closed and 4 issues are still open. :greenheart: , by :greenheart: , by :greenheart: , by :greenheart: , by :heart: , by - - Last week, 9 pull requests were created, updated or merged. Last week, 3 pull requests were opened. :greenheart: , by :greenheart: , by :greenheart: , by Last week, 1 pull request was updated. :yellowheart: , by Last week, 5 pull requests were merged. :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by - - Last week there were 8 commits. :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by - - Last week there were 2 contributors. :bustinsilhouette: :bustinsilhouette: - - Last week there was 1 stargazer. :star: You are the star! :star2: - - Last week there were no releases. - - That's all for last week, please :eyes: Watch and :star: Star the repository to receive next weekly updates. :smiley: You can also .
These keys are Client one-time use keys, so "UserInitKey" seems like a strange name.
I'm fine with ClientInitKey, as long as a client is not only a physical endpoint. Changes in the architecture doc should make this clear soon.

Rename the GroupState structure to GroupContext (*) <ins> Rename UserInitKey to ClientInitKey </ins> draft-05 Common framing for handshake and application messages (*)


A short-lived HPKE key pair used to introduce a new client to a group.  Initialization keys are published for each client <del> (UserInitKey). </del>  A secret that represent a member's contribution to the group secret (so called because the members' leaf keys are the leaves in

A short-lived HPKE key pair used to introduce a new client to a group.  Initialization keys are published for each client  <ins> (ClientInitKey). </ins> A secret that represent a member's contribution to the group secret (so called because the members' leaf keys are the leaves in


Removing a member. <del> Before the initialization of a group, clients publish UserInitKey </del>  objects to a directory provided to the Messaging Service. When a client A wants to establish a group with B and C, it first <del> downloads UserInitKeys for B and C.  It then initializes a group state containing only itself and uses the UserInitKeys to compute </del>  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

Removing a member.  <ins> Before the initialization of a group, clients publish ClientInitKey </ins> objects to a directory provided to the Messaging Service. When a client A wants to establish a group with B and C, it first  <ins> downloads ClientInitKeys for B and C.  It then initializes a group state containing only itself and uses the ClientInitKeys to compute </ins> 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


update its state to reflect their addition. Subsequent additions of group members proceed in the same way.  Any <del> member of the group can download an UserInitKey for a new client and broadcast an Add message that the current group can use to update </del>  their state and the new client can use to initialize its state. To enforce forward secrecy and post-compromise security of messages,

update its state to reflect their addition. Subsequent additions of group members proceed in the same way.  Any  <ins> member of the group can download an ClientInitKey for a new client and broadcast an Add message that the current group can use to update </ins> their state and the new client can use to initialize its state. To enforce forward secrecy and post-compromise security of messages,


In order to facilitate asynchronous addition of clients to a group, it is possible to pre-publish initialization keys that provide some <del> public information about a user.  UserInitKey messages provide </del>  information about a client that any existing member can use to add this client to the group asynchronously. <del> A UserInitKey object specifies what ciphersuites a client supports, </del>  as well as providing public keys that the client can use for key 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).  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. </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

In order to facilitate asynchronous addition of clients to a group, it is possible to pre-publish initialization keys that provide some  <ins> public information about a user.  ClientInitKey messages provide </ins> information about a client that any existing member can use to add this client to the group asynchronously.  <ins> A ClientInitKey object specifies what ciphersuites a client supports, </ins> as well as providing public keys that the client can use for key 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).  ClientInitKeys also contain an identifier chosen by the client, which the client MUST assure uniquely identifies a given ClientInitKey object among the set of ClientInitKeys 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


and used in the HPKE construction for TreeKEM. The whole structure is signed using the client's identity key.  A <del> UserInitKey object with an invalid signature field MUST be considered malformed.  The input to the signature computation comprises all of the fields except for the signature field. </del>  8.

and used in the HPKE construction for TreeKEM. The whole structure is signed using the client's identity key.  A  <ins> ClientInitKey object with an invalid signature field MUST be considered malformed.  The input to the signature computation comprises all of the fields except for the signature field. </ins> 8.


needs to initialize a GroupContext object that can be updated to the current state using the Add message.  This information is encrypted for the new member using HPKE.  The recipient key pair for the HPKE <del> encryption is the one included in the indicated UserInitKey, </del>  corresponding to the indicated ciphersuite. In the description of the tree as a list of nodes, the "credential"

needs to initialize a GroupContext object that can be updated to the current state using the Add message.  This information is encrypted for the new member using HPKE.  The recipient key pair for the HPKE  <ins> encryption is the one included in the indicated ClientInitKey, </ins> corresponding to the indicated ciphersuite. In the description of the tree as a list of nodes, the "credential"


The "welcome_info_hash" field contains a hash of the WelcomeInfo object sent in a Welcome message to the new member. <del> A group member generates this message by requesting a UserInitKey </del>  from the directory for the user to be added, and encoding it into an Add message.

The "welcome_info_hash" field contains a hash of the WelcomeInfo object sent in a Welcome message to the new member.  <ins> A group member generates this message by requesting a ClientInitKey </ins> from the directory for the user to be added, and encoding it into an Add message.


If the "index" value is equal to the size of the group, increment the size of the group, and extend the tree accordingly <del> Verify the signature on the included UserInitKey; if the signature verification fails, abort </del>  Generate a WelcomeInfo object describing the state prior to the add, and verify that its hash is the same as the value of the

If the "index" value is equal to the size of the group, increment the size of the group, and extend the tree accordingly  <ins> Verify the signature on the included ClientInitKey; if the signature verification fails, abort </ins> Generate a WelcomeInfo object describing the state prior to the add, and verify that its hash is the same as the value of the


direct path of the new node Set the leaf node in the tree at position "index" to a new node <del> containing the public key from the UserInitKey in the Add </del>  corresponding to the ciphersuite in use, as well as the credential <del> under which the UserInitKey was signed </del>  The "update_secret" resulting from this change is an all-zero octet string of length Hash.length.

direct path of the new node Set the leaf node in the tree at position "index" to a new node  <ins> containing the public key from the ClientInitKey in the Add </ins> corresponding to the ciphersuite in use, as well as the credential  <ins> under which the ClientInitKey was signed </ins> The "update_secret" resulting from this change is an all-zero octet string of length Hash.length.


RFC EDITOR PLEASE DELETE THIS SECTION.  draft-06 Reorder blanking and update in the Remove operation (*)

Update change log for draft-07 No conflicting PRs so I did break many lines that were too long. Fix a few minor editorial issues after merging the tree-based application key schedule.

RFC EDITOR PLEASE DELETE THIS SECTION. <ins> draft-07 Initial version of the Tree based Application Key Schedule (*) Initial definition of the Init message for group creation (*) Fix issue with the transcript used for newcomers (*) Clarifications on message framing and HPKE contexts (*) </ins> draft-06 Reorder blanking and update in the Remove operation (*)


For application messages, a chain of keys is derived for each sender in a similar fashion.  This allows forward secrecy at the level of application messages within and out of an epoch.  A step in this <del> chain (the second subscript) is called a "generation". As before the value [sender] represents the index of the member that will use this key to send, encoded as a uint32. [[ OPEN ISSUE: The HKDF context field is left empty for now.  A proper security study is needed to make sure that we do not need more information in the context to achieve the security goals.]] [[ OPEN ISSUE: At the moment there is no contributivity of Application secrets chained from the initial one to the next generation of Epoch secret.  While this seems safe because cryptographic operations using the application secrets can't affect the group init_secret, it remains to be proven correct. ]] The following rules apply to the usage of the secrets, keys, and nonces derived above: Senders MUST only use a given secret once and monotonically increment the generation of their secret.  This is important to provide Forward Secrecy at the level of Application messages.  An attacker getting hold of a member specific Application Secret at generation [N+1] will not be able to derive the member's Application Secret [N] nor the associated AEAD key and nonce. Receivers MUST delete an Application Secret once it has been used to derive the corresponding AEAD key and nonce as well as the next Application Secret.  Receivers MAY keep the AEAD key and nonce around for some reasonable period. Receivers MUST delete AEAD keys and nonces once they have been used to successfully decrypt a message. </del>  7.

For application messages, a chain of keys is derived for each sender in a similar fashion.  This allows forward secrecy at the level of application messages within and out of an epoch.  A step in this  <ins> chain (the second subscript) is called a "generation".  The details of application key derivation are described in the astree section below. </ins> 7.


tree of Application Secrets as well as one symmetric ratchet per group member. <del> Each client maintains their own local copy of (parts of) the Application Key Schedule for each epoch during which they are a group member.  They derive new keys, nonces and secrets as needed while deleting old ones as soon as they have been used. </del>  Application messages MUST be protected with the Authenticated- Encryption with Associated-Data (AEAD) encryption scheme associated <del> with the MLS ciphersuite.  Note that "Authenticated" in this context does not mean messages are known to be sent by a specific client but only from a legitimate member of the group.  To authenticate a message from a particular member, signatures are required.  Handshake messages MUST use asymmetric signatures to strongly authenticate the sender of a message. </del>  11.1. <del> The Application schedule begins with the Application secrets which are arranged in an "Application Secret Tree" or AS Tree for short; a left balanced binary tree with the same set of nodes and edges as the epoch's ratchet tree.  Each leaf in the AS Tree is associated with the same group member as the corresponding leaf in the ratchet tree. Nodes are also assigned an index according to their position in the array representation of the tree (described in tree-math).  If N is a node index in the AS Tree then left(N) and right(N) denote the children of N (if they exist). </del>  Each node in the tree is assigned a secret.  The root's secret is simply the application_secret of that epoch.  (See key-schedule for

tree of Application Secrets as well as one symmetric ratchet per group member.  <ins> Each client maintains their own local copy of the Application Key Schedule for each epoch during which they are a group member.  They derive new keys, nonces and secrets as needed while deleting old ones as soon as they have been used. </ins> Application messages MUST be protected with the Authenticated- Encryption with Associated-Data (AEAD) encryption scheme associated  <ins> with the MLS ciphersuite using the common framing mechanism.  Note that "Authenticated" in this context does not mean messages are known to be sent by a specific client but only from a legitimate member of the group.  To authenticate a message from a particular member, signatures are required.  Handshake messages MUST use asymmetric signatures to strongly authenticate the sender of a message. </ins> 11.1.  <ins> The application key schedule begins with the application secrets which are arranged in an "Application Secret Tree" or AS Tree for short; a left balanced binary tree with the same set of nodes and edges as the epoch's ratchet tree.  Each leaf in the AS Tree is associated with the same group member as the corresponding leaf in the ratchet tree.  Nodes are also assigned an index according to their position in the array representation of the tree (described in tree-math).  If N is a node index in the AS Tree then left(N) and right(N) denote the children of N (if they exist). </ins> Each node in the tree is assigned a secret.  The root's secret is simply the application_secret of that epoch.  (See key-schedule for


The secret of any other node in the tree is derived from its parent's secret using a call to Derive-App-Secret. <del> If N is a node index in the ASTree then the secrets of the children </del>  of N are defined to be: <del> Note that fixing concrete values for GroupState_[n] and </del>  application_secret completely defines all secrets in the AS Tree. 11.2.

The secret of any other node in the tree is derived from its parent's secret using a call to Derive-App-Secret.  <ins> If N is a node index in the AS Tree then the secrets of the children </ins> of N are defined to be:  <ins> Note that fixing concrete values for GroupContext_[n] and </ins> application_secret completely defines all secrets in the AS Tree. 11.2.


11.3. <del> It is important to delete all security sensitive values as soon as </del>  they, or another value derived from them, is used for encryption or decryption.

11.3.  <ins> It is important to delete all security sensitive values S as soon as </ins> they, or another value derived from them, is used for encryption or decryption.


encrypt or (successfully) decrypt a message or <del> if a key, nonce or secret derived from S has been consumed.  (This goes both for values derived via Derive-Secret and HKDF-Expand- Label). </del>  Here, S may be the init_secret, update_secret, epoch_secret, application_secret as well as any secret in the AS Tree or one of the

encrypt or (successfully) decrypt a message or  <ins> if a key, nonce or secret derived from S has been consumed. (This goes both for values derived via Derive-Secret and HKDF-Expand- Label.) </ins> Here, S may be the init_secret, update_secret, epoch_secret, application_secret as well as any secret in the AS Tree or one of the


11.4. <del> During each epoch senders MUST NOT encrypt more messages than permitted by the security bounds of the AEAD scheme used. </del>  Note that each change to the Group through a Handshake message will also set a new application_secret.  Hence this change MUST be applied

11.4.  <ins> During each epoch senders MUST NOT encrypt more data than permitted by the security bounds of the AEAD scheme used. </ins> Note that each change to the Group through a Handshake message will also set a new application_secret.  Hence this change MUST be applied


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 mechanism presented here use a </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.

Here's the Weekly Digest for : - - Last week 2 issues were created. Of these, 0 issues have been closed and 2 issues are still open. :greenheart: , by :greenheart: , by - - Last week, 8 pull requests were created, updated or merged. Last week, 1 pull request was opened. :greenheart: , by Last week, 5 pull requests were updated. :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by Last week, 2 pull requests were merged. :purpleheart: , by :purpleheart: , by - - Last week there were 2 commits. :hammerandwrench: by :hammerandwrench: by - - Last week there was 1 contributor. :bustinsilhouette: - - Last week there was 1 stargazer. :star: You are the star! :star2: - - Last week there were no releases. - - That's all for last week, please :eyes: Watch and :star: Star the repository to receive next weekly updates. :smiley: You can also .

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.


group.  Initialization keys are published for each client (ClientInitKey). <del> A secret that represent a member's contribution to the group </del>  secret (so called because the members' leaf keys are the leaves in the group's ratchet tree).

group.  Initialization keys are published for each client (ClientInitKey).  <ins> A secret that represents a member's contribution to the group </ins> secret (so called because the members' leaf keys are the leaves in the group's ratchet tree).


The recipient of an update processes it with the following steps: <del> Compute the updated path secrets * Identify a node in the direct path for which the local member is in the subtree of the non- updated child * Identify a node in the resolution of the copath node for which this node has a private key * Decrypt the path secret for the parent of the copath node using the private key from the resolution node * Derive path secrets for ancestors of that node using the algorithm described above * The recipient SHOULD verify that the received public keys agree with the public keys derived from the new node_secret values Merge the updated path secrets into the tree * Replace the public keys for nodes on the direct path with the received public keys * For nodes where an updated path secret was computed in step 1, compute the corresponding node secret and node key pair and replace the values stored at the node with the computed values. </del>  For example, in order to communicate the example update described in the previous section, the sender would transmit the following values: <del> In this table, the value pk(X) represents the public key corresponding derived from the node secret X.  The value E(K, S) represents the public-key encryption of the path secret S to the public key K. </del>  6.

The recipient of an update processes it with the following steps:  <ins> Compute the updated path secrets. Identify a node in the direct path for which the local member is in the subtree of the non-updated child. Identify a node in the resolution of the copath node for which this node has a private key. Decrypt the path secret for the parent of the copath node using the private key from the resolution node. Derive path secrets for ancestors of that node using the algorithm described above. The recipient SHOULD verify that the received public keys agree with the public keys derived from the new node_secret values. Merge the updated path secrets into the tree. Replace the public keys for nodes on the direct path with the received public keys. For nodes where an updated path secret was computed in step 1, compute the corresponding node secret and node key pair and replace the values stored at the node with the computed values. </ins> For example, in order to communicate the example update described in the previous section, the sender would transmit the following values:  <ins> In this table, the value pk(X) represents the public key derived from the node secret X.  The value E(K, S) represents the public-key encryption of the path secret S to the public key K. </ins> 6.


6.1.  This ciphersuite uses the following primitives: Hash function: SHA-256

6.1. <ins> 6.1.1. </ins> This ciphersuite uses the following primitives: Hash function: SHA-256


curves, they SHOULD perform the additional checks specified in Section 7 of <del> 6.1.1. </del>  This ciphersuite uses the following primitives:

curves, they SHOULD perform the additional checks specified in Section 7 of  <ins> 6.1.2. </ins> This ciphersuite uses the following primitives:


The creator of the group constructs an Init message as follows: <del> Fetch a UserInitKey for each member (including the creator) </del>  Identify a protocol version and cipher suite that is supported by all proposed members. Construct a ratchet tree with its leaves populated with the public <del> keys and credentials from the UserInitKeys of the members, and all other nodes blank. </del>  Generate a fresh leaf key pair for the first leaf

The creator of the group constructs an Init message as follows:  <ins> Fetch a ClientInitKey for each member (including the creator) </ins> Identify a protocol version and cipher suite that is supported by all proposed members. Construct a ratchet tree with its leaves populated with the public  <ins> keys and credentials from the ClientInitKeys of the members, and all other nodes blank. </ins> Generate a fresh leaf key pair for the first leaf


Decompose group operations into Proposals and Commits (*)  draft-07 Initial version of the Tree based Application Key Schedule (*)

Depends on
Here's the Weekly Digest for : - - Last week 9 issues were created. Of these, 6 issues have been closed and 3 issues are still open. :greenheart: , by :greenheart: , by :greenheart: , by :heart: , by :heart: , by :heart: , by :heart: , by :heart: , by :heart: , by :speaker: , by It received 2 comments. - - Last week, 13 pull requests were created, updated or merged. Last week, 3 pull requests were updated. :yellowheart: , by :yellowheart: , by :yellowheart: , by Last week, 10 pull requests were merged. :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by - - Last week there were 38 commits. :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by - - Last week there were 2 contributors. :bustinsilhouette: :bustin_silhouette: - - Last week there was 1 stargazer. :star: You are the star! :star2: - - Last week there were no releases. - - That's all for last week, please :eyes: Watch and :star: Star the repository to receive next weekly updates. :smiley: You can also .*
Long-term inactive users undermine the FS and PCS properties of the protocol. Obviously, users can remove each other if they notice that a participant is inactive. We should consider whether we want to allow the server to do such a removal.
Discussion at interim 2019-01: Could do this as "server-instructed" vs. "server done" i.e., server instructs a client to do a remove But this causes some ambiguity w.r.t. the rest of the group The only difference between Remove and a server-initiated variant would be signature Other use cases: User deletes account User is no longer authorized to be in group Application would need to set policy about whether / when server-initiated actions would be allowed
I'm assigning this to draft-04 under the theory that the signature changes that will come about as a result of will make it straightforward to have an additional key for the server that can be used to sign Adds / Removes. If that doesn't turn out to be the case, this might get deferred.
After discussion with NAME and NAME There will be a need to signal that a non-member key is being used, e.g., with some reserved values Do the participants in the group need to agree the set of allowed non-member signers? If some members accept a signer, others don't, then you can get partition -04 will focus on Remove, not Add, and punt on the agreement question; we assume the application maintains consistency of the view of authorized signers.
We should push some of this to the application layer in order to not introduce a new handshake message with problematic authenticity (agreement on the list of non-members who can sign handshake messages). The server could publish an "intent to remove" that will be honored by the first client to come online. The actual Remove HS message will be issued by a member of the group. It can additionally be attached to the server intent to remove, so that clients can convey more contextual information to users. Example: Server issues the intent to remove Alice from the group. Bob comes online first after that and send a regular Remove HS message to remove Alice and links it to the sever intent. Other members of the group can now display "Alice was removed" instead of "Bob removed Alice" to the user. In this example Bob is the first member to come online, but it could really be any other member. This has the advantage that the protocol remains unaffected as such, while the desired behavior is still achieved.
Currently, in order for a new member to join a group, an existing member needs to add them to the group. Certain use cases work more naturally if a new joiner can initiate the add process. I think that broadly speaking we want a process here where someone outside the group can (1) request to be added and (2) send to the group, but cannot receive from the group until added. Some things to consider here: Anything that is revealed to a joiner that joins this way is effectively public. Should they be able to see, e.g., the roster? How should these interactions relate to the key schedule? Assuming there's some message, should it be included into the transcript at Add time? What happens if there are multiple parallel requests?
At the 2019-01 interim, we discussed a "reversed Add" flow, where: Group publishes an InitKey The new joiner sends a UIK to the group and establishes a shared secret with the group This initiates a period where the new joiner can send, but nobody in the group can Before anyone in the group can send, they have to send a Welcome for the new joiner ... which initiates an epoch where they are fully joined
In certain use cases, such as enterprise messaging there may/could/might be a problem if "Any member of the group can download an ClientInitKey for a new client and broadcast an Add message". An enterprise may wish to enforce access restrictions for certain information such as ClientInitKey. Just thinking about security related issues that may be most easily noticed by corp IT types. On the other hand this may be best dealt with outside the protocol scope.
NAME I think this is fixed by correct? A user can propose to Add herself.
Partly addressed by . To complete the story, we need a "send-to-group-from-outside" mechanism. Leaving this open until we have that.
I don't think a "send-to-group-from-outside" mechanism will be possible, given that we try quite hard to prevent any key material from inside the group from ever being published.
The signing key of external actors will be contained in the leaf in the case it is a CIK.

Decompose group operations into Proposals and Commits (*) <ins> Enable Add and Remove proposals from outside the group (*) </ins> draft-07 Initial version of the Tree based Application Key Schedule (*)


Blank the intermediate nodes along the path from the removed leaf to the root  10.2. A Commit message initiates a new epoch for the group, based on a

Blank the intermediate nodes along the path from the removed leaf to the root <ins> 10.1.4. Add and Remove proposals can be constructed and sent to the group by a party that is outside the group.  For example, a Delivery Service might propose to remove a member of a group has been inactive for a long time, or propose adding a newly-hired staff member to a group representing a real-world team.  Proposals originating outside the group are identified by having a "sender" value in the range 0xFFFFFF00 - 0xFFFFFFFF. The specific value 0xFFFFFFFF is reserved for clients proposing that they themselves be added.  Proposals with types other than Add MUST NOT be sent with this sender index.  In such cases, the MLSPlaintext MUST be signed with the private key corresponding to the ClientInitKey in the Add message.  Recipients MUST verify that the MLSPlaintext carrying the Proposal message is validly signed with this key. The remaining values 0xFFFFFF00 - 0xFFFFFFFE are reserved for signer that are pre-provisioned to the clients within a group.  If proposals with these sender IDs are to be accepted within a group, the members of the group MUST be provisioned by the application with a mapping between sender indices in this range and authorized signing keys.  To ensure consistent handling of external proposals, the application MUST ensure that the members of a group have the same mapping and apply the same policies to external proposals. An external proposal MUST be sent as an MLSPlaintext object, since the sender will not have the keys necessary to construct an MLSCiphertext object. [[ TODO: Should recognized external signers be added to some object that the group explicitly agrees on, e.g., as an extension to the GroupContext? ]] </ins> 10.2. A Commit message initiates a new epoch for the group, based on a


A hash function <del> A Diffie-Hellman finite-field group or elliptic curve </del>  An AEAD encryption algorithm

This PR begins filling in the IANA Considerations section, starting with a Ciphersuites registry. This addresses the concerns in as discussed at the interim (2019-10), namely by reserving for vendor use chunk of the code points space large enough to be selected at random without huge risk of collision (2^12 values). Depends on
Here's the Weekly Digest for : - - Last week 9 issues were created. Of these, 6 issues have been closed and 3 issues are still open. :greenheart: , by :greenheart: , by :greenheart: , by :heart: , by :heart: , by :heart: , by :heart: , by :heart: , by :heart: , by :speaker: , by It received 2 comments. - - Last week, 13 pull requests were created, updated or merged. Last week, 3 pull requests were updated. :yellowheart: , by :yellowheart: , by :yellowheart: , by Last week, 10 pull requests were merged. :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by - - Last week there were 38 commits. :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by - - Last week there were 2 contributors. :bustinsilhouette: :bustin_silhouette: - - Last week there was 1 stargazer. :star: You are the star! :star2: - - Last week there were no releases. - - That's all for last week, please :eyes: Watch and :star: Star the repository to receive next weekly updates. :smiley: You can also .*
Enable, e.g., P-256 with both AES-GCM and ChaChaPoly Re-use code points from TLS
We should discuss that today

A hash function  <ins> A Diffie-Hellman finite-field group or elliptic curve group </ins> An AEAD encryption algorithm


14. <del> TODO: Registries for protocol parameters, e.g., ciphersuites </del>

14.  <ins> This document requests the creation of the following new IANA registries: MLS Ciphersuites All of these registries should be under a heading of "Message Layer Security", and administered under a Specification Required policy RFC8126. 14.1. The "MLS Ciphersuites" registry lists identifiers for suites of cryptographic algorithms defined for use with MLS.  These are two- byte values, so the maximum possible value is 0xFFFF = 65535.  Values in the range 0xF000 - 0xFFFF are reserved for vendor-internal usage. Template: Value: The two-byte identifier for the ciphersuite Name: The name of the ciphersuite Reference: Where this algorithm is defined The initial contents for this registry are as follows: [[ Note to RFC Editor: Please replace "XXXX" above with the number assigned to this RFC. ]] </ins>


where "node_public_key" is the public key of the node that the path secret is being encrypted for, group_context is the current <del> GroupContext object for the group, and the functions "SetupBaseI" and </del>  "Seal" are defined according to I-D.irtf-cfrg-hpke. Decryption is performed in the corresponding way, using the private

In the latest HPKE draft (draft-irtf-cfrg-hpke-04), "Initiator (I)" was renamed to "Sender (S)".

where "node_public_key" is the public key of the node that the path secret is being encrypted for, group_context is the current  <ins> GroupContext object for the group, and the functions "SetupBaseS" and </ins> "Seal" are defined according to I-D.irtf-cfrg-hpke. Decryption is performed in the corresponding way, using the private


left and right children, respectively.  When computing the hash of a leaf node, the hash of a "LeafNodeHashInput" object is used:  7.6. Each member of the group maintains a GroupContext object that

NAME - I seem to recall you had some opinions on node hashing?
Right now the LeafNodeHashInput struct uses the index of the node among the leaves, while the ParentNodeHashInput struct uses the index of the node among all nodes. This means that, for example, the index value will be the same for the second leaf and its parent ( in both cases). We should probably just use the node index in both cases.
URL is a better solution

left and right children, respectively.  When computing the hash of a leaf node, the hash of a "LeafNodeHashInput" object is used: <ins> Note that the "node_index" field contains the index of the leaf among the nodes in the tree, not its index among the leaves; "node_index = 2 * leaf_index". </ins> 7.6. Each member of the group maintains a GroupContext object that


An AEAD encryption algorithm  A signature algorithm The HPKE parameters are used to instantiate HPKE I-D.irtf-cfrg-hpke

Just to recap the options as I understand them: a) Today: encryptedsenderdata = AEAD(senderdatakey, senderdatanonce, (groupID, epoch), senderdata) encryptedcontent = AEAD(appkey[i][j], appkey[i][j], (groupID, epoch, encryptedsenderdata), content) b) Sample sender data nonce from ciphertext (saves explicit nonce) encryptedcontent = AEAD(appkey[i][j], appnonce[i][j], (groupID, epoch), content) encryptedsenderdata = AEAD(senderdatakey, sample(encryptedcontent), (groupID, epoch, encryptedcontent), senderdata) c) Drop auth tag from content encryption (saves explicit nonce and content auth tag) encryptedcontent = Enc(appkey[i][j], appnonce[i][j], content) encryptedsenderdata = AEAD(senderdatakey, sample(encryptedcontent), (groupID, epoch, encryptedcontent), senderdata)
Earlier, we had considered a "masking" approach for sender data, much like QUIC does for . This approach would save 28 bytes of overhead (nonce + tag), but was abandoned because of uncertainty around the security of the masking approach. Since then, Bellare et al. published , which includes what is effectively a proof of the security properties of the QUIC scheme. The QUIC scheme is essentially scheme HN1 of the paper, the main difference being that QUIC encrypt not the nonce directly, but a packet number which is used to compute the nonce. Our application would be similar, since we would encrypt metadata used to encrypt the key and the nonce. Given this new analysis, is it time to bring back masking?
Fixed by

An AEAD encryption algorithm <ins> A hash algorithm </ins> A signature algorithm The HPKE parameters are used to instantiate HPKE I-D.irtf-cfrg-hpke


Application messages <del> The sender information used to look up the key for the content encryption is encrypted under AEAD using a random nonce and the "sender_data_key" which is derived from the "sender_data_secret" as follows: </del>  For handshake and application messages, a sequence of keys is derived via a "sender ratchet".  Each sender has their own sender ratchet,

Application messages  <ins> The sender information used to look up the key for content encryption is encrypted with an AEAD where the key and nonce are derived from both "sender_data_secret" and a sample of the encrypted message content. </ins> For handshake and application messages, a sequence of keys is derived via a "sender ratchet".  Each sender has their own sender ratchet,


each key/nonce pair MUST NOT be used to encrypt more than one message. <del> Keys, nonces and secrets of ratchets are derived using </del>  DeriveAppSecret.  The context in a given call consists of the index of the sender's leaf in the ratchet tree and the current position in the ratchet.  In particular, the index of the sender's leaf in the

each key/nonce pair MUST NOT be used to encrypt more than one message.  <ins> Keys, nonces, and the secrets in ratchets are derived using </ins> DeriveAppSecret.  The context in a given call consists of the index of the sender's leaf in the ratchet tree and the current position in the ratchet.  In particular, the index of the sender's leaf in the


Set group_id, epoch, content_type and authenticated_data fields from the MLSPlaintext object directly <del> Randomly generate the sender_data_nonce field </del> Identify the key and key generation depending on the content type <del> Encrypt an MLSSenderData object for the encrypted_sender_data field from MLSPlaintext and the key generation Generate and sign an MLSPlaintextTBS object from the MLSPlaintext object </del> Encrypt an MLSCiphertextContent for the ciphertext field using the <del> key identified, the signature, and MLSPlaintext object </del>  <del> Decryption is done by decrypting the metadata, then the message, and then verifying the content signature. </del>  The following sections describe the encryption and signing processes in detail. 8.1. <del> The "sender data" used to look up the key for the content encryption is encrypted under AEAD using the MLSCiphertext sender_data_nonce and the sender_data_key from the keyschedule.  It is encoded as an object of the following form: MLSSenderData.sender is assumed to be a "member" sender type.  When constructing an MLSSenderData from a Sender object, the sender MUST verify Sender.sender_type is "member" and use Sender.sender for MLSSenderData.sender. The "reuse_guard" field contains a fresh random value used to avoid nonce reuse in the case of state loss or corruption, as described in content-signing-and-encryption. The Additional Authenticated Data (AAD) for the SenderData ciphertext computation is its prefix in the MLSCiphertext, namely: When parsing a SenderData struct as part of message decryption, the recipient MUST verify that the sender field represents an occupied leaf in the ratchet tree.  In particular, the sender index value MUST be less than the number of leaves in the tree. 8.2. The signature field in an MLSPlaintext object is computed using the </del>  signing private key corresponding to the credential at the leaf in the tree indicated by the sender field.  The signature covers the plaintext metadata and message content, which is all of MLSPlaintext

Set group_id, epoch, content_type and authenticated_data fields from the MLSPlaintext object directly  Identify the key and key generation depending on the content type  Encrypt an MLSCiphertextContent for the ciphertext field using the  <ins> key identified and MLSPlaintext object Encrypt the sender data using a key and nonce derived from the "sender_data_secret" for the epoch and a sample of the encrypted MLSCiphertextContent. </ins>  <ins> Decryption is done by decrypting the sender data, then the message, and then verifying the content signature. </ins> The following sections describe the encryption and signing processes in detail. 8.1.  <ins> The "signature" field in an MLSPlaintext object is computed using the </ins> signing private key corresponding to the credential at the leaf in the tree indicated by the sender field.  The signature covers the plaintext metadata and message content, which is all of MLSPlaintext


GroupContext for the current epoch, so that signatures are specific to a given group and epoch. <del> The ciphertext field of the MLSCiphertext object is produced by </del>  supplying the inputs described below to the AEAD function specified by the ciphersuite in use.  The plaintext input contains content and signature of the MLSPlaintext, plus optional padding.  These values

GroupContext for the current epoch, so that signatures are specific to a given group and epoch.  <ins> 8.2. The "ciphertext" field of the MLSCiphertext object is produced by </ins> supplying the inputs described below to the AEAD function specified by the ciphersuite in use.  The plaintext input contains content and signature of the MLSPlaintext, plus optional padding.  These values


contains an object of the following form, with the values used to identify the key and nonce: <del> The ciphertext field of the MLSCiphertext object is produced by supplying these inputs to the AEAD function specified by the ciphersuite in use. </del>  9.

contains an object of the following form, with the values used to identify the key and nonce:  <ins> 8.3. The "sender data" used to look up the key for the content encryption is encrypted with the ciphersuite's AEAD with a key and nonce derived from both the "sender_data_secret" and a sample of the encrypted content.  Before being encrypted, the sender data is encoded as an object of the following form: MLSSenderData.sender is assumed to be a "member" sender type.  When constructing an MLSSenderData from a Sender object, the sender MUST verify Sender.sender_type is "member" and use Sender.sender for MLSSenderData.sender. The "reuse_guard" field contains a fresh random value used to avoid nonce reuse in the case of state loss or corruption, as described in content-encryption. The key and nonce provided to the AEAD are computed as the KDF of the first "KDF.Nh" bytes of the ciphertext generated in the previous section.  If the length of the ciphertext is less than "KDF.Nh", the whole ciphertext is used without padding.  In pseudocode, the key and nonce are derived as: ``` ciphertext_sample = ciphertext[0..KDF.Nh-1] sender_data_key = ExpandWithLabel(sender_data_secret, "key", ciphertext_sample, AEAD.Nk) sender_data_nonce = ExpandWithLabel(sender_data_secret, "nonce", ciphertext_sample, AEAD.Nn) ``` The Additional Authenticated Data (AAD) for the SenderData ciphertext is all the fields of MLSCiphertext excluding "encrypted_sender_data": When parsing a SenderData struct as part of message decryption, the recipient MUST verify that the sender field represents an occupied leaf in the ratchet tree.  In particular, the sender index value MUST be less than the number of leaves in the tree. </ins> 9.


The mandatory-to-implement ciphersuite for MLS 1.0 is "MLS10_128_HPKE25519_AES128GCM_SHA256_Ed25519" which uses <del> Curve25519, HKDF over SHA2-256 and AES-128-GCM for HPKE, and AES- 128-GCM with Ed25519 for symmetric encryption and signatures. </del>  Values with the first byte 255 (decimal) are reserved for Private Use.

The mandatory-to-implement ciphersuite for MLS 1.0 is "MLS10_128_HPKE25519_AES128GCM_SHA256_Ed25519" which uses  <ins> Curve25519 for key exchange, AES-128-GCM for HPKE, HKDF over SHA2-256, AES for metadata masking, and Ed25519 for signatures. </ins> Values with the first byte 255 (decimal) are reserved for Private Use.


Provider (SP) as described in I-D.ietf-mls-architecture.  In particular, we assume the SP provides the following services: <del> A long-term identity key provider which allows clients to </del>  authenticate protocol messages in a group. A broadcast channel, for each group, which will relay a message to

The credentials we have defined at the moment only contain a single public key and no information regarding what signature scheme that keypair works with (even though the Spec actually says it should include the signature scheme as well). It would be nice, however, to support potential CredentialTypes that, similar to KeyPackages, include multiple supported signature schemes, each accompanied by a corresponding public key. The Key that should be used in any given group is then determined by the CipherSuite of the group (which includes a Signature Scheme). When choosing a KeyPackage of a new member, it has to be one that contains a Credential which supports that Signature Scheme. Note, that I'm not suggesting that this be the case in all Credentials, or even that we change the BasicCredential. I understand that it's possible to have multiple credentials per identity, but in some authentication settings it can be beneficial to have a 1-to-1 mapping between Credential and identity.
KeyPackages don't support multiple signature schemes? In what scenario is it beneficial?
Ah, right. I think that was the case in the past, but you're right, they don't. Of course it's always possible to just bundle a bunch of certificates, each supporting a different signature scheme and then treat that as your "Multi-Scheme Credential" in the grand scheme of things. However, if you end up rotating them a lot, where you have to sign them and potentially store the whole chain for a longer period of time, being able to support multiple signature schemes in only one credential means less overhead.
Credentials are stored in each group's ratchet tree though, so you're keeping a bunch of unnecessary key material in the group's tree which everyone has to store
That's fair. And it's not something you have to do if you don't want to. I'm just proposing for MLS to support that type of Credential in general.
To support hybrid PQ/standard schemes at any point in the future, allowing for multiple schemes is reasonable (in addition to the above arguments for it). Most applications probably will not use the feature, especially to start with, but providing support for just the option is not going to cause any of the problems noted.
PQ schemes can be used by switching the entire group to a new ciphersuite using those schemes. Requiring everybody in the group to store a bunch of unused key material isn't reasonable
The statement was not about PQ, but hybrid PQ/standard schemes. Those require use to two signature schemes, for which both types of keying material are used.
Then you need a ciphersuite that specifies a hybrid scheme.
It would be ideal to have a ciphersuite specifying a single hybrid scheme, but even that does not imply use of a single credential, unfortunately. In fact, hybrid schemes may rely on two separate credentials, with the ciphersuite specifying the hybrid algorithm for combining them. Since the "main" method of building a solo hybrid credential is under patent, there is also additional motivation for applications to use two.
I concur with Brendan here. To be consistent with our earlier decisions to (a) keep KeyPackages to one ciphersuite and (b) include the signature algorithm in the ciphersuite, we should keep credentials to one signature algorithm as well. Propose closing this PR without merging.
Discussed at 2020-10-06 interim, TODO: Re-add SignatureScheme enum, re-using the TLS signature schemes Clarify that the main job of a Credential is to provide a public key for verifying messages How it provides the credential might be different per credential type e.g., in BasicCredential, it's provided directly, X509Credential, have to parse the leaf certificate
LGTM with a couple nits.

Provider (SP) as described in I-D.ietf-mls-architecture.  In particular, we assume the SP provides the following services:  <ins> A long-term signature key provider which allows clients to </ins> authenticate protocol messages in a group. A broadcast channel, for each group, which will relay a message to


A member of a group authenticates the identities of other participants by means of credentials issued by some authentication system, like a PKI.  Each type of credential MUST express the <del> following data: </del>  <del> The public key of a signature key pair </del>  <del> The identity of the holder of the private key The signature scheme that the holder will use to sign MLS messages </del>  Credentials MAY also include information that allows a relying party to verify the identity / signing key binding.  A BasicCredential is a raw, unauthenticated assertion of an identity/ key binding.  The format of the key in the "public_key" field is defined by the relevant ciphersuite: the group ciphersuite for a

A member of a group authenticates the identities of other participants by means of credentials issued by some authentication system, like a PKI.  Each type of credential MUST express the  <ins> following data in the context of the group it is used with: </ins>  <ins> The public key of a signature key pair matching the SignatureScheme specified by the CipherSuite of the group </ins>  <ins> The identity of the holder of the private keys </ins> Credentials MAY also include information that allows a relying party to verify the identity / signing key binding. <ins> Additionally, Credentials SHOULD specify the signature scheme corresponding to each contained public key. </ins> A BasicCredential is a raw, unauthenticated assertion of an identity/ key binding.  The format of the key in the "public_key" field is defined by the relevant ciphersuite: the group ciphersuite for a


A KeyPackage object specifies a ciphersuite that the client supports, as well as providing a public key that others can use for key <del> agreement.  The client's identity key can be updated throughout the </del>  lifetime of the group by sending a new KeyPackage with a new <del> identity; the new identity MUST be validated by the authentication service. </del>  When used as InitKeys, KeyPackages are intended to be used only once and SHOULD NOT be reused except in case of last resort.  (See

A KeyPackage object specifies a ciphersuite that the client supports, as well as providing a public key that others can use for key  <ins> agreement.  The client's signature key can be updated throughout the </ins> lifetime of the group by sending a new KeyPackage with a new  <ins> signature key; the new signature key MUST be validated by the authentication service. </ins> When used as InitKeys, KeyPackages are intended to be used only once and SHOULD NOT be reused except in case of last resort.  (See


The value for hpke_init_key MUST be a public key for the asymmetric encryption scheme defined by cipher_suite.  The whole structure is <del> signed using the client's identity key.  A KeyPackage object with an </del>  invalid signature field MUST be considered malformed.  The input to the signature computation comprises all of the fields except for the signature field.

The value for hpke_init_key MUST be a public key for the asymmetric encryption scheme defined by cipher_suite.  The whole structure is  <ins> signed using the client's signature key.  A KeyPackage object with an </ins> invalid signature field MUST be considered malformed.  The input to the signature computation comprises all of the fields except for the signature field.


creator, because they are derived from an authenticated key exchange protocol.  Subsequent leaf keys are known only by their owner. <del> Note that the long-term identity keys used by the protocol MUST be </del>  distributed by an "honest" authentication service for clients to authenticate their legitimate peers.

creator, because they are derived from an authenticated key exchange protocol.  Subsequent leaf keys are known only by their owner.  <ins> Note that the long-term signature keys used by the protocol MUST be </ins> distributed by an "honest" authentication service for clients to authenticate their legitimate peers.


The second form considers authentication with respect to the sender, meaning the group members can verify that a message originated from a particular member of the group.  This property is provided by digital <del> signatures on the messages under identity keys. </del>  14.3.

The second form considers authentication with respect to the sender, meaning the group members can verify that a message originated from a particular member of the group.  This property is provided by digital  <ins> signatures on the messages under signature keys. </ins> 14.3.


reveal previous message or root keys.  Post-compromise security is provided by Commit operations, in which a new root key is generated from the latest ratcheting tree.  If the adversary cannot derive the <del> updated root key after an Commit operation, it cannot compute any </del>  derived secrets. In the case where the client could have been compromised (device

reveal previous message or root keys.  Post-compromise security is provided by Commit operations, in which a new root key is generated from the latest ratcheting tree.  If the adversary cannot derive the  <ins> updated root key after a Commit operation, it cannot compute any </ins> derived secrets. In the case where the client could have been compromised (device


A signed object describing a client's identity and capabilities, and including a hybrid public-key encryption (HPKE I-D.irtf-cfrg- <del> hpke ) public key that can be used to encrypt to that client. </del>  A key package that is prepublished by a client, which other clients can use to introduce the client to a new group.

cc NAME
NAME is the build expected to fail?
No, but the problem seem unrelated to your change, so we are all good.
Looks like it was a transient failure. Re-running resulted in success.
NAME points out that the HPKE version is not pinned. This is probably needed for interop. Version -07 should come sometime this week, so that seems like a perfectly fine version to use. I can send a PR when that version is cut.
Fixed by

A signed object describing a client's identity and capabilities, and including a hybrid public-key encryption (HPKE I-D.irtf-cfrg-  <ins> hpke) public key that can be used to encrypt to that client. </ins> A key package that is prepublished by a client, which other clients can use to introduce the client to a new group.


A signature algorithm <del> The HPKE parameters are used to instantiate HPKE I-D.irtf-cfrg-hpke for the purpose of public-key encryption.  The "DeriveKeyPair" function associated to the KEM for the ciphersuite maps octet strings to HPKE key pairs. </del>  Ciphersuites are represented with the CipherSuite type.  HPKE public keys are opaque values in a format defined by the underlying protocol

A signature algorithm  <ins> MLS uses draft-07 of HPKE I-D.irtf-cfrg-hpke for public-key encryption.  The "DeriveKeyPair" function associated to the KEM for the ciphersuite maps octet strings to HPKE key pairs. </ins> Ciphersuites are represented with the CipherSuite type.  HPKE public keys are opaque values in a format defined by the underlying protocol


Name: The name of the ciphersuite <del> Recommended: Whether support for this extension 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. </del>  Reference: The document where this ciphersuite is defined

I noticed a bunch of typos in the "IANA Considerations" section: the "ciphersuites" and "credentials" were probably copy-pasted from the "extension" one, and some parts were not changed correctly. This PR fixes these typos.
Discussed 20210526 Interim: editorial will be taken up by editors.
Thanks!

Name: The name of the ciphersuite  <ins> Recommended: Whether support for this ciphersuite 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. </ins> Reference: The document where this ciphersuite is defined


16.3. This registry lists identifiers for types of credentials that can be <del> used for authentication in the MLS protocol.  The extension type field is two bytes wide, so valid extension type values are in the </del>  range 0x0000 to 0xffff. Template:

16.3. This registry lists identifiers for types of credentials that can be  <ins> used for authentication in the MLS protocol.  The credential type field is two bytes wide, so valid credential type values are in the </ins> range 0x0000 to 0xffff. Template:


Name: The name of the credential type <del> Recommended: Whether support for this extension is recommended by </del>  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 extension is defined </del>  Initial contents:

Name: The name of the credential type  <ins> Recommended: Whether support for this credential is recommended by </ins> 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.  <ins> Reference: The document where this credential is defined </ins> Initial contents: