jiebi/TextFlow huggingface dataset:
Original text:
Verify the signature on the GroupInfo object.  The signature input comprises all of the fields in the GroupInfo object except the signature field.  The public key and algorithm are taken from the <del> credential in the leaf node of the member with LeafNodeRef "signer".  If there is no matching leaf node, or if signature verification fails, return an error. </del>  Verify the integrity of the ratchet tree.

Reviewer comments:
This seems to be a layer of indirection that doesn't add any value to implementation.
The Credentials section claims there is an epoch id field in key packages. I don't think that actually exists. My apologies if this is a duplicate issue.
Addressed in but may need to be pulled out depending on the fate of that PR
contains all of the Proposals that were previously sent within the same epoch. This seems unnecessary, since all members should have them anyway. The list of in the actual message should be enough for members to parse and validate a message. We should discuss if we can de-duplicate this, since the list of Proposals might be quite long.
The current definition of is as follows; Maybe this issue is obsolete?
Seems it is now obsolete indeed.
I don't have a strong opinion on this question, but this change seems sensible to me. The use of LeafNodeRef requires either (a) a linear scan through the tree, which is time-expensive in large trees, or (b) keeping an index that maps LeafNodeRef values to indices, which is storage-intensive in large trees. IIRC, the change to LeafNodeRef was made in the context of NAME work to make the tree description less tied to the array representation. In general, that is the right thing to do, and it's good that we did it. But we still have leaf indices anyway, for . Since we still have the concept, we might as well use it where it makes sense. And it certainly seems to me like and make sense, since they are internal to the protocol. In case folks are worried about the application-facing API -- MLS stacks can certainly be more intelligent, e.g., exposing or or . But they can do that regardless of this PR.

Revised text:
Verify the signature on the GroupInfo object.  The signature input comprises all of the fields in the GroupInfo object except the signature field.  The public key and algorithm are taken from the  <ins> credential in the leaf node of the ratchet tree with leaf index "signer".  If the node is blank or if signature verification fails, return an error. </ins> Verify the integrity of the ratchet tree.
Original text:
If the "path_secret" value is set in the GroupSecrets object: Identify the lowest common ancestor of the leaf node "my_leaf" <del> and of the node of the member with LeafNodeRef </del>  "GroupInfo.signer".  Set the private key for this node to the private key derived from the "path_secret".

Reviewer comments:
This seems to be a layer of indirection that doesn't add any value to implementation.
The Credentials section claims there is an epoch id field in key packages. I don't think that actually exists. My apologies if this is a duplicate issue.
Addressed in but may need to be pulled out depending on the fate of that PR
contains all of the Proposals that were previously sent within the same epoch. This seems unnecessary, since all members should have them anyway. The list of in the actual message should be enough for members to parse and validate a message. We should discuss if we can de-duplicate this, since the list of Proposals might be quite long.
The current definition of is as follows; Maybe this issue is obsolete?
Seems it is now obsolete indeed.
I don't have a strong opinion on this question, but this change seems sensible to me. The use of LeafNodeRef requires either (a) a linear scan through the tree, which is time-expensive in large trees, or (b) keeping an index that maps LeafNodeRef values to indices, which is storage-intensive in large trees. IIRC, the change to LeafNodeRef was made in the context of NAME work to make the tree description less tied to the array representation. In general, that is the right thing to do, and it's good that we did it. But we still have leaf indices anyway, for . Since we still have the concept, we might as well use it where it makes sense. And it certainly seems to me like and make sense, since they are internal to the protocol. In case folks are worried about the application-facing API -- MLS stacks can certainly be more intelligent, e.g., exposing or or . But they can do that regardless of this PR.

Revised text:
If the "path_secret" value is set in the GroupSecrets object: Identify the lowest common ancestor of the leaf node "my_leaf"  <ins> and of the node of the member with leaf index </ins> "GroupInfo.signer".  Set the private key for this node to the private key derived from the "path_secret".
Original text:
Transmit the Welcome message to the other new members  The recipient of a Welcome message processes it as described in joining-via-welcome-message.  If application context informs the recipient that the Welcome should reflect the creation of a new group

Reviewer comments:
Brendan to revise based on Rohan suggestion.
Interim 2022-05-26: Concerns around making the group_id totally random Malicious group creator can choose it malicious Federated systems get worse randomness Using AEAD.Nk depends on ciphersuite, could be awkward NAME will revise to say: Here are the requirements that group ID must satisfy If you don’t have an alternative plan, do it randomly
Group ids are signed to bind certain information to specific groups. But I can imagine a case where a user mis-uses the group id to be something like a "room title" which lets an adversary control the group id and introduces potential problems. If we can prove that it's fine for a group id to be reused, then should we get rid of group ids? If not (as I expect), then group ids need to be guaranteed to be unique [globally per signing key] and we need to specify that.
Discussed at 19 May interim. NAME to generate PR documenting fresh random value approach.
Virtual interim 2022-05-19: Agreement that some sort of uniqueness requirement is worthwhile Main question is what scope of uniqueness should be Globally? Within scope of DS? Fresh random value? Simple, but precludes application usage of the field Also could help avoid metadata leakage Client / DS should probably still check for collisions NAME to write up a PR on the fresh random value idea
Group IDs must be generated randomly by creator Clients and DS must check that group ids are unique as far as they know

Revised text:
Transmit the Welcome message to the other new members <ins> Group IDs SHOULD be constructed in such a way that there's an overwhelmingly low probability of honest group creators generating the same group ID, even without assistance from the Delivery Service. For example, by making the group ID a freshly generated random value of size "KDF.Nh".  The Delivery Service MAY attempt to ensure that group IDs are globally unique by rejecting the creation of new groups with a previously used ID. </ins> The recipient of a Welcome message processes it as described in joining-via-welcome-message.  If application context informs the recipient that the Welcome should reflect the creation of a new group
Original text:
In both cases, the new members need information to bootstrap their local group state. <del> New members MUST verify the "signature" using the public key taken from the credential in the leaf node of the ratchet tree with leaf index "signer".  The signature covers the following structure, comprising all the fields in the GroupInfo above "signature": </del>  13.2.3.1.

Reviewer comments:
Brendan to revise based on Rohan suggestion.
Interim 2022-05-26: Concerns around making the group_id totally random Malicious group creator can choose it malicious Federated systems get worse randomness Using AEAD.Nk depends on ciphersuite, could be awkward NAME will revise to say: Here are the requirements that group ID must satisfy If you don’t have an alternative plan, do it randomly
Group ids are signed to bind certain information to specific groups. But I can imagine a case where a user mis-uses the group id to be something like a "room title" which lets an adversary control the group id and introduces potential problems. If we can prove that it's fine for a group id to be reused, then should we get rid of group ids? If not (as I expect), then group ids need to be guaranteed to be unique [globally per signing key] and we need to specify that.
Discussed at 19 May interim. NAME to generate PR documenting fresh random value approach.
Virtual interim 2022-05-19: Agreement that some sort of uniqueness requirement is worthwhile Main question is what scope of uniqueness should be Globally? Within scope of DS? Fresh random value? Simple, but precludes application usage of the field Also could help avoid metadata leakage Client / DS should probably still check for collisions NAME to write up a PR on the fresh random value idea
Group IDs must be generated randomly by creator Clients and DS must check that group ids are unique as far as they know

Revised text:
In both cases, the new members need information to bootstrap their local group state.  <ins> New members MUST verify that "group_id" is unique among the groups they're currently participating in. New members also MUST verify the "signature" using the public key taken from the leaf node of the ratchet tree with leaf index "signer".  The signature covers the following structure, comprising all the fields in the GroupInfo above "signature": </ins> 13.2.3.1.
Original text:
"signer".  If the node is blank or if signature verification fails, return an error.  Verify the integrity of the ratchet tree. Verify that the tree hash of the ratchet tree matches the

Reviewer comments:
Brendan to revise based on Rohan suggestion.
Interim 2022-05-26: Concerns around making the group_id totally random Malicious group creator can choose it malicious Federated systems get worse randomness Using AEAD.Nk depends on ciphersuite, could be awkward NAME will revise to say: Here are the requirements that group ID must satisfy If you don’t have an alternative plan, do it randomly
Group ids are signed to bind certain information to specific groups. But I can imagine a case where a user mis-uses the group id to be something like a "room title" which lets an adversary control the group id and introduces potential problems. If we can prove that it's fine for a group id to be reused, then should we get rid of group ids? If not (as I expect), then group ids need to be guaranteed to be unique [globally per signing key] and we need to specify that.
Discussed at 19 May interim. NAME to generate PR documenting fresh random value approach.
Virtual interim 2022-05-19: Agreement that some sort of uniqueness requirement is worthwhile Main question is what scope of uniqueness should be Globally? Within scope of DS? Fresh random value? Simple, but precludes application usage of the field Also could help avoid metadata leakage Client / DS should probably still check for collisions NAME to write up a PR on the fresh random value idea
Group IDs must be generated randomly by creator Clients and DS must check that group ids are unique as far as they know

Revised text:
"signer".  If the node is blank or if signature verification fails, return an error. <ins> Verify that the "group_id" is unique among the groups that the client is currently participating in. </ins> Verify the integrity of the ratchet tree. Verify that the tree hash of the ratchet tree matches the
Original text:
The client verifies the validity of a LeafNode using the following steps: <del> Verify that the credential in the LeafNode is valid according to the authentication service and the client's local policy.  These actions MUST be the same regardless of at what point in the protocol the LeafNode is being verified with the following exception: If the LeafNode is an update to another LeafNode, the authentication service MUST additionally validate that the set of identities attested by the credential in the new LeafNode is acceptable relative to the identities attested by the old credential.  For example: An Update proposal updates the sender's old LeafNode to a new one A "resync" external commit removes the joiner's old LeafNode via a Remove proposal and replaces it with a new one </del>  Verify that the signature on the LeafNode is valid using "signature_key".

Reviewer comments:
Replaces This PR attempts to add precision to the credential validation requirements in the document, along the lines NAME suggests in , in the spirit of what NAME wrote up in and drawing inspiration from what RFC 6125 does in the context of TLS. It seems like this gives a clearer definition of (a) what the AS's job is and (b) when it needs to be done.
While this is spread out throughout the document, it would be beneficial to spell out in which scenarios a Credential MUST be verified (with the AS): When fetching a KeyPackage to add a new member When discovering a KeyPackage in an AddProposal from another member When joining a new group (verify all other members' Credentials), both when receiving a Welcome message and when joining through an External Commit When a member updates its leaf ... anywhere else?
Thanks for picking it up!

Revised text:
The client verifies the validity of a LeafNode using the following steps:  <ins> Verify that the credential in the LeafNode is valid as described in credential-validation. </ins> Verify that the signature on the LeafNode is valid using "signature_key".
Original text:
17.6. This document registers the "message/mls" MIME media type in order to <del> allow other protocols (ex: HTTP RFC7540) to convey MLS messages. </del>  message

Reviewer comments:
As NAME pointed out on the mailing list, this reference does not need to be normative.

Revised text:
17.6. This document registers the "message/mls" MIME media type in order to  <ins> allow other protocols (e.g., HTTP RFC7540) to convey MLS messages. </ins> message
Original text:
for key exchange, AES-128-GCM for HPKE, HKDF over SHA2-256, and Ed25519 for signatures. <del> Values with the first byte 255 (decimal) are reserved for Private Use. </del> New ciphersuite values are assigned by IANA as described in iana- considerations.

Reviewer comments:
NAME thanks, good catch. should be fixed now.
Comment by NAME Algorithm entries use two octets (65535) but only allow 255 Private Use entries. I think that might be a little low. Maybe allow 0xf000 - 0xffff or something ?
I agree this should be changed. CCing NAME who I believe initially proposed this.

Revised text:
for key exchange, AES-128-GCM for HPKE, HKDF over SHA2-256, and Ed25519 for signatures.  New ciphersuite values are assigned by IANA as described in iana- considerations.
Original text:
is represented as an encoded UncompressedPointRepresentation struct, as defined in RFC8446.  The signatures used in this document are encoded as specified in RFC8446.  In particular, ECDSA signatures are DER-encoded and EdDSA signatures are defined as the concatenation of "r" and "s" as

Reviewer comments:
As discussed in the virtual interim 2022-12-16, it is possible that extensions might be tempted to re-use HPKE public keys created for MLS. Even within MLS, we have two different public-key encryption cases, Welcome and Commit (though these currently use different keys). Currently, for Commit encryption, the HPKE parameter is set to the group context. The content of is actually undefined for Welcome encryption (!) This PR makes the following changes: Define general and functions that populte the HPKE parameter with an encoded label and context Apply these to Commit and Welcome encryption: Commit: label="UpdatePathNode", context= Welcome: label="Welcome", context= Add an IANA registry of public-key encryption labels (as for signing) There is also a bit of reorganization of the Ciphersuites section to split it into three subsections.
Note that any previous analysis of MLS had to take this particular reuse into account. This can't be the case for any arbitrary extensions reusing the key. So if MLS uses an extension that reuses the key, none of the existing analysis applies, which is a much bigger issue. This said, this reuse did decrease security -- it weakened FS in that a joiner had to hold on to their HPKE leaf key, which also allowed to decrypt the init secret from the welcome message, long after joining.
I think this captures what we discussed during the interim. FWIW, I'm wondering if we didn't have a domain separation issue in the past when we only had one HPKE public key in KeyPackages and used it for both the Welcome subsequently for UpdatePath as well. Either way, I think this is a good defense-in-depth mechanism.

Revised text:
is represented as an encoded UncompressedPointRepresentation struct, as defined in RFC8446. <ins> 5.1.2. The signature algorithm specified in the ciphersuite is the mandatory algorithm to be used for signatures in FramedContentAuthData and the tree signatures.  It MUST be the same as the signature algorithm specified in the credentials in the leaves of the tree (including the leaf node information in KeyPackages used to add new members). </ins> The signatures used in this document are encoded as specified in RFC8446.  In particular, ECDSA signatures are DER-encoded and EdDSA signatures are defined as the concatenation of "r" and "s" as
Original text:
construction, using a distinct label.  To avoid collisions in these labels, an IANA registry is defined in mls-signature-labels. <del> The ciphersuites are defined in section mls-ciphersuites. </del>  5.2.

Reviewer comments:
As discussed in the virtual interim 2022-12-16, it is possible that extensions might be tempted to re-use HPKE public keys created for MLS. Even within MLS, we have two different public-key encryption cases, Welcome and Commit (though these currently use different keys). Currently, for Commit encryption, the HPKE parameter is set to the group context. The content of is actually undefined for Welcome encryption (!) This PR makes the following changes: Define general and functions that populte the HPKE parameter with an encoded label and context Apply these to Commit and Welcome encryption: Commit: label="UpdatePathNode", context= Welcome: label="Welcome", context= Add an IANA registry of public-key encryption labels (as for signing) There is also a bit of reorganization of the Ciphersuites section to split it into three subsections.
Note that any previous analysis of MLS had to take this particular reuse into account. This can't be the case for any arbitrary extensions reusing the key. So if MLS uses an extension that reuses the key, none of the existing analysis applies, which is a much bigger issue. This said, this reuse did decrease security -- it weakened FS in that a joiner had to hold on to their HPKE leaf key, which also allowed to decrypt the init secret from the welcome message, long after joining.
I think this captures what we discussed during the interim. FWIW, I'm wondering if we didn't have a domain separation issue in the past when we only had one HPKE public key in KeyPackages and used it for both the Welcome subsequently for UpdatePath as well. Either way, I think this is a good defense-in-depth mechanism.

Revised text:
construction, using a distinct label.  To avoid collisions in these labels, an IANA registry is defined in mls-signature-labels.  <ins> 5.1.3. As with signing, MLS includes a label and context in encryption operations to avoid confusion between ciphertexts produced for different purposes.  Encryption and decryption including this label and context are done as follows: Where EncryptContext is specified as: And its fields set to: Here, the functions "SealBase" and "OpenBase" are defined RFC9180, using the HPKE algorithms specified by the group's ciphersuite.  If MLS extensions require HPKE encryption operations, they should re-use the EncryptWithLabel construction, using a distinct label.  To avoid collisions in these labels, an IANA registry is defined in mls- public-key-encryption-labels. </ins> 5.2.
Original text:
new leaf nodes), with each ciphertext being the encryption to the respective resolution node. <del> The HPKECiphertext values are computed as where "node_public_key" is the public key of the node that the path secret is being encrypted for, group_context is the provisional GroupContext object for the group, and the functions "SetupBaseS" and "Seal" are defined according to RFC9180. </del>  <del> Decryption is performed in the corresponding way, using the private key of the resolution node. </del>  7.7.

Reviewer comments:
As discussed in the virtual interim 2022-12-16, it is possible that extensions might be tempted to re-use HPKE public keys created for MLS. Even within MLS, we have two different public-key encryption cases, Welcome and Commit (though these currently use different keys). Currently, for Commit encryption, the HPKE parameter is set to the group context. The content of is actually undefined for Welcome encryption (!) This PR makes the following changes: Define general and functions that populte the HPKE parameter with an encoded label and context Apply these to Commit and Welcome encryption: Commit: label="UpdatePathNode", context= Welcome: label="Welcome", context= Add an IANA registry of public-key encryption labels (as for signing) There is also a bit of reorganization of the Ciphersuites section to split it into three subsections.
Note that any previous analysis of MLS had to take this particular reuse into account. This can't be the case for any arbitrary extensions reusing the key. So if MLS uses an extension that reuses the key, none of the existing analysis applies, which is a much bigger issue. This said, this reuse did decrease security -- it weakened FS in that a joiner had to hold on to their HPKE leaf key, which also allowed to decrypt the init secret from the welcome message, long after joining.
I think this captures what we discussed during the interim. FWIW, I'm wondering if we didn't have a domain separation issue in the past when we only had one HPKE public key in KeyPackages and used it for both the Welcome subsequently for UpdatePath as well. Either way, I think this is a good defense-in-depth mechanism.

Revised text:
new leaf nodes), with each ciphertext being the encryption to the respective resolution node.  <ins> The HPKECiphertext values are encrypted and decrypted as follows: </ins>  <ins> Here "node_public_key" is the public key of the node for which the path secret is encrypted, "group_context" is the provisional GroupContext object for the group, and the "EncryptWithLabel" function is as defined in public-key-encryption. </ins> 7.7.