jiebi/TextFlow huggingface dataset:
Original text:
service, defines the types of credentials which may be used in a deployment and provides methods for: <del> Issuing new credentials, </del>  <del> Validating a credential against a reference identifier, and </del>  Validating whether or not two credentials represent the same <del> client. </del>  A *Delivery Service*, described fully in delivery-service, provides methods for:

Reviewer comments:
WGLC comments on Operation Requirements section. Added several overlooked requirements
Discussed on 12/8 interim, and folks seemed fine with this. I.e., it's ready to merge.

Revised text:
service, defines the types of credentials which may be used in a deployment and provides methods for:  <ins> Issuing new credentials with a relevant credential lifetime, </ins>  <ins> Validating a credential against a reference identifier, </ins> Validating whether or not two credentials represent the same  <ins> client, and Optionally revoking credentials which are no longer authorized. </ins> A *Delivery Service*, described fully in delivery-service, provides methods for:
Original text:
Delivering Welcome messages to new members of a group. <del> Downloading KeyPackages for specific clients, and uploading new KeyPackages for a user's own clients. </del>  Additional services may or may not be required depending on the application design:

Reviewer comments:
WGLC comments on Operation Requirements section. Added several overlooked requirements
Discussed on 12/8 interim, and folks seemed fine with this. I.e., it's ready to merge.

Revised text:
Delivering Welcome messages to new members of a group.  <ins> Uploading new KeyPackages for a user's own clients. Downloading KeyPackages for specific clients.  Typically, KeyPackages are used once and consumed. </ins> Additional services may or may not be required depending on the application design:
Original text:
set of acceptable behavior in a group.  These policies must be consistent between deployments for them to interoperate:  A policy on when to send proposals and commits in plaintext instead of encrypted.

Reviewer comments:
WGLC comments on Operation Requirements section. Added several overlooked requirements
Discussed on 12/8 interim, and folks seemed fine with this. I.e., it's ready to merge.

Revised text:
set of acceptable behavior in a group.  These policies must be consistent between deployments for them to interoperate: <ins> A policy on which ciphersuites are acceptable. A policy on any mandatory or forbidden MLS extensions. </ins> A policy on when to send proposals and commits in plaintext instead of encrypted.
Original text:
When, and under what circumstances, a reinitialization proposal is allowed. <del> When proposals from external senders are allowed. </del>  <del> When external joiners are allowed. </del>  A policy for when two credentials represent the same client.  Note that many credentials may be issued authenticating the same

Reviewer comments:
WGLC comments on Operation Requirements section. Added several overlooked requirements
Discussed on 12/8 interim, and folks seemed fine with this. I.e., it's ready to merge.

Revised text:
When, and under what circumstances, a reinitialization proposal is allowed.  <ins> When proposals from external senders are allowed and how to authorize those proposals. When external joiners are allowed and how to authorize those external commits. Which other proposal types are allowed. A policy of when members should commit pending proposals in a group. </ins>  <ins> A policy of how to protect and share the GroupInfo objects needed for external joins. </ins> A policy for when two credentials represent the same client.  Note that many credentials may be issued authenticating the same
Original text:
Finally, Clients should not be able to perform DoS attacks denial-of- service. 

Reviewer comments:
We need an IANA considerations section even if we make no requests of them. It's just part of the process and the section can be removed during the final publication phase.

Revised text:
Finally, Clients should not be able to perform DoS attacks denial-of- service. <ins> 5. This document makes no requests of IANA. </ins>
Original text:
setting, HSMs and secure enclaves can be used to protect signature keys.  7.  This document makes no requests of IANA.

Reviewer comments:
This PR adds a short paragraph referencing the various academic works that has gone into MLS. The references to the various works still need to be cleaned up, which I will do once the list is complete. In particular, each reference needs to be checked for correctness (eprint version vs. publicized version) and then included as informal reference in the yaml header of the document.
Is there another RFC you can point to that links academic papers on the protocol? I'd expect TLS 1.3 to be a good example of this, but I don't see them do this. The references should be cited properly if we do include it (ie, added as citations at the top of the file)
The references are in the appendices. For instance URL The reader should refer to the following references for analysis of the TLS handshake: [DFGS15], [CHSV16], [DFGS16], [KW16], [Kraw16], [FGSW16], [LXZFH16], [FG17], and [BBK17].
TLS 1.3 as cited by NAME was indeed the inspiration for this. The idea was to just have a small paragraph to point the reader in the right direction and then have the full bibliographic entry in the "Informal References" section. As noted above, I intend to properly format all the references once we agree on what references to include, as formatting them into the right yaml is a bit of a pain.
Thanks Konrad!

Revised text:
setting, HSMs and secure enclaves can be used to protect signature keys. <ins> 6.6. Various academic works have analyzed MLS and the different security guarantees it aims to provide.  The security of large parts of the protocol has been analyzed by [BBN19] (draft 7), [ACDT21] (draft 11) and [AJM20] (draft 12). Individual components of various drafts of the MLS protocol have been analyzed in isolation and with differing adversarial models, for example, [BBR18], [ACDT19], [ACCKKMPPWY19], [AJM20] and [ACJM20] analyze the ratcheting tree as the sub-protocol of MLS that facilitates key agreement, while [BCK21] analyzes the key derivation paths in the ratchet tree and key schedule.  Finally, [CHK19] analyzes the authentication and cross-group healing guarantees provided by MLS. </ins> 7. <ins> ACDT19: https://eprint.iacr.org/2019/1189 ACCKKMPPWY19: https://eprint.iacr.org/2019/1489 ACJM20: https://eprint.iacr.org/2020/752 AJM20: https://eprint.iacr.org/2020/1327 ACDT21: https://eprint.iacr.org/2021/1083 AHKM21: https://eprint.iacr.org/2021/1456 CHK19: https://eprint.iacr.org/2021/137 BCK21: https://eprint.iacr.org/2021/137 BBR18: https://hal.inria.fr/hal-02425247 BBN19: https://hal.laas.fr/INRIA/hal-02425229 8. </ins> This document makes no requests of IANA.
Original text:
node for which this node has a private key * Decrypt the secret value for the parent of the copath node using the private key from the resolution node * Derive secret values for ancestors of that <del> node using the KDF keyed with the decrypted secret </del>  Merge the updated secrets into the tree * Replace the public keys for nodes on the direct path with the received public keys * For

Reviewer comments:
Adding this check would be the first step in recognizing that an Update operation may have maliciously excluded a person from the group.
This would go better in the "Ratchet Tree Updates" section, right after "Derive secret values for ancestors of that node using the KDF keyed with the decrypted secret". That would align better with where in the code you want the checks to be. Other than that, LGTM.
Fixed
Thanks Michael !
Here's the Weekly Digest for : - - Last week 4 issues were created. Of these, 1 issues have been closed and 3 issues are still open. :greenheart: , by :greenheart: , by :greenheart: , by :heart: , by :speaker: , by It received 4 comments. - - Last week, 9 pull requests were created, updated or merged. Last week, 8 pull requests were updated. :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by Last week, 1 pull request was merged. :purpleheart: , by - - Last week there were 4 commits. :hammerandwrench: by :hammerandwrench: by :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 .

Revised text:
node for which this node has a private key * Decrypt the secret value for the parent of the copath node using the private key from the resolution node * Derive secret values for ancestors of that  <ins> node using the KDF keyed with the decrypted secret * The recipient SHOULD verify that the received public keys agree with the public keys derived from the new node_secret values </ins> Merge the updated secrets into the tree * Replace the public keys for nodes on the direct path with the received public keys * For
Original text:
The creator of the group constructs an Init message as follows: <del> Fetch a ClientInitKey for each member (including the creator) </del>  Identify a protocol version and cipher suite that is supported by all proposed members.

Reviewer comments:
Here's the Weekly Digest for : - - Last week 3 issues were created. Of these, 1 issues have been closed and 2 issues are still open. :greenheart: , by :greenheart: , by :heart: , by :speaker: , by It received 1 comments. - - Last week, 6 pull requests were created, updated or merged. Last week, 1 pull request was opened. :greenheart: , by Last week, 1 pull request was updated. :yellowheart: , by Last week, 4 pull requests were merged. :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by - - Last week there were 6 commits. :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :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 .
Here's the Weekly Digest for : - - Last week, no issues were created. - - Last week, 3 pull requests were created, updated or merged. Last week, 2 pull requests were updated. :yellowheart: , by :yellowheart: , by Last week, 1 pull request was merged. :purpleheart: , by - - Last week there was 1 commit. :hammerandwrench: by - - Last week there was 1 contributor. :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 .
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, 2 pull requests were created, updated or merged. Last week, 2 pull requests were opened. :greenheart: , by :greenheart: , by - - Last week there were no commits. - - Last week there were no contributors. - - Last week there were 2 stagazers. :star: :star: You all are the stars! :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 .

Revised text:
The creator of the group constructs an Init message as follows:  <ins> Fetch one or more ClientInitKeys for each member (including the creator) </ins> Identify a protocol version and cipher suite that is supported by all proposed members.
Original text:
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 ClientInitKey in the Add corresponding to the ciphersuite in use, as well as the credential under which the ClientInitKey was signed </del>  The "update_secret" resulting from this change is an all-zero octet string of length Hash.length.

Reviewer comments:
Here's the Weekly Digest for : - - Last week 3 issues were created. Of these, 1 issues have been closed and 2 issues are still open. :greenheart: , by :greenheart: , by :heart: , by :speaker: , by It received 1 comments. - - Last week, 6 pull requests were created, updated or merged. Last week, 1 pull request was opened. :greenheart: , by Last week, 1 pull request was updated. :yellowheart: , by Last week, 4 pull requests were merged. :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by - - Last week there were 6 commits. :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :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 .
Here's the Weekly Digest for : - - Last week, no issues were created. - - Last week, 3 pull requests were created, updated or merged. Last week, 2 pull requests were updated. :yellowheart: , by :yellowheart: , by Last week, 1 pull request was merged. :purpleheart: , by - - Last week there was 1 commit. :hammerandwrench: by - - Last week there was 1 contributor. :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 .
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, 2 pull requests were created, updated or merged. Last week, 2 pull requests were opened. :greenheart: , by :greenheart: , by - - Last week there were no commits. - - Last week there were no contributors. - - Last week there were 2 stagazers. :star: :star: You all are the stars! :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 .

Revised text:
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, as well as the credential under which the ClientInitKey was signed </ins> The "update_secret" resulting from this change is an all-zero octet string of length Hash.length.
Original text:
D.ietf-trans-rfc6962-bis.) The _direct path_ of a root is the empty list, and of any other node <del> is the concatenation of that node with the direct path of its parent. The _copath_ of a node is the list of siblings of nodes in its direct </del>  path.  The _frontier_ of a tree is the list of heads of the maximal full subtrees of the tree, ordered from left to right. For example, in the below tree: <del> The direct path of C is (C, CD, ABCD) </del>  The copath of C is (D, AB, EFG)

Reviewer comments:
You can also strike this sentence further down: " In particular, for the leaf node, there are no encrypted secrets, since a leaf node has no children."
Note that this severs the connection between the HPKE key in the leaf and the parent of the leaf. Whereas before, the leaf HPKE key was derived from a path secret, and the parent HPKE key was derived from the next path secret. Now the parent path secret is set directly, and the leaf HPKE key is set completely independently, with no dependency on a path secret. So we're losing a bit of internal structure in the tree. But this seems OK because that structure was never observable to the group -- only the holder of the leaf knows the leaf path secret, so nobody else could verify that the leaf was related to its parent.

Revised text:
D.ietf-trans-rfc6962-bis.) The _direct path_ of a root is the empty list, and of any other node  <ins> is the concatenation of that node's parent along with the parent's direct path.  The _copath_ of a node is the node's sibling concatenated with the list of siblings of all the nodes in its direct </ins> path.  The _frontier_ of a tree is the list of heads of the maximal full subtrees of the tree, ordered from left to right. For example, in the below tree:  <ins> The direct path of C is (CD, ABCD, ABCDEFG) </ins> The copath of C is (D, AB, EFG)
Original text:
The path secret value for a given node is encrypted for the subtree corresponding to the parent's non-updated child, that is, the child on the copath of the leaf node.  There is one encrypted path secret <del> for each public key in the resolution of the non-updated child.  In particular, for the leaf node, there are no encrypted secrets, since a leaf node has no children. </del>  The recipient of a path update processes it with the following steps:

Reviewer comments:
You can also strike this sentence further down: " In particular, for the leaf node, there are no encrypted secrets, since a leaf node has no children."
Note that this severs the connection between the HPKE key in the leaf and the parent of the leaf. Whereas before, the leaf HPKE key was derived from a path secret, and the parent HPKE key was derived from the next path secret. Now the parent path secret is set directly, and the leaf HPKE key is set completely independently, with no dependency on a path secret. So we're losing a bit of internal structure in the tree. But this seems OK because that structure was never observable to the group -- only the holder of the leaf knows the leaf path secret, so nobody else could verify that the leaf was related to its parent.

Revised text:
The path secret value for a given node is encrypted for the subtree corresponding to the parent's non-updated child, that is, the child on the copath of the leaf node.  There is one encrypted path secret  <ins> for each public key in the resolution of the non-updated child. </ins> The recipient of a path update processes it with the following steps:
Original text:
unoccupied leaf, or appended to the right edge of the tree if all leaves are occupied. <del> Create an initial, partial GroupInfo object reflecting the following values: Group ID: The group ID for the group Epoch: The epoch ID for the next epoch Tree: The group's ratchet tree after the commit has been applied Prior confirmed transcript hash: The confirmed transcript hash for the current state of the group (not the provisional state) </del> Create a DirectPath using the new tree (which includes any new members).  The GroupContext for this operation uses the "group_id", "epoch", "tree", and "prior_confirmed_transcript_hash"

Reviewer comments:
This PR adapts the Welcome logic so that the new joiners get their path secrets directly, rather than from a DirectPath. This cleans things up in a few ways. The new joiners no longer have to have the context for the previous epoch (which was used to encrypt the DirectPath). And we can get away with one HPKE operation per new joiner instead of two (one for the EncryptedKeyPackage and one for the DirectPath). The major cost is that there's a bit more complexity in the TreeKEM. Instead of just producing and consuming DirectPaths, you now need to know which path secrets go with which nodes. You also need tree math to identify the common ancestor of two leaves, but there's a simple closed-form formula for that, expressed in the Python code here.
NAME - Curious if this seems implementable to you. Clearly it's possible, since I did it in Go :) But it also needs to make sense to other people.

Revised text:
unoccupied leaf, or appended to the right edge of the tree if all leaves are occupied.  Create a DirectPath using the new tree (which includes any new members).  The GroupContext for this operation uses the "group_id", "epoch", "tree", and "prior_confirmed_transcript_hash"
Original text:
the "confirmation" value in the MLSPlaintext.  Sign the MLSPlaintext using the current epoch's GroupContext as context. <del> Complete the GroupInfo by populating the following fields: </del>  <del> Confirmed transcript hash: The confirmed transcript hash including the current Commit object </del>  <del> Interim transcript hash: The interim transcript hash including the current Commit object </del>  <del> Confirmation: The confirmation from the MLSPlaintext </del>  Sign the GroupInfo using the member's private signing key Encrypt the GroupInfo using the key and nonce derived from the <del> "init_secret" for the current epoch (see welcoming-new-members) </del>  <del> For each new member in the group, compute an EncryptedKeyPackage object that encapsulates the "init_secret" for the current epoch. </del> Construct a Welcome message from the encrypted GroupInfo object and the encrypted key packages.

Reviewer comments:
This PR adapts the Welcome logic so that the new joiners get their path secrets directly, rather than from a DirectPath. This cleans things up in a few ways. The new joiners no longer have to have the context for the previous epoch (which was used to encrypt the DirectPath). And we can get away with one HPKE operation per new joiner instead of two (one for the EncryptedKeyPackage and one for the DirectPath). The major cost is that there's a bit more complexity in the TreeKEM. Instead of just producing and consuming DirectPaths, you now need to know which path secrets go with which nodes. You also need tree math to identify the common ancestor of two leaves, but there's a simple closed-form formula for that, expressed in the Python code here.
NAME - Curious if this seems implementable to you. Clearly it's possible, since I did it in Go :) But it also needs to make sense to other people.

Revised text:
the "confirmation" value in the MLSPlaintext.  Sign the MLSPlaintext using the current epoch's GroupContext as context.  <ins> Update the tree in the provisional state by applying the direct path </ins>  <ins> Construct a GroupInfo reflecting the new state: </ins>  <ins> Group ID, epoch, tree, confirmed transcript hash, and interim transcript hash from the new state </ins>  <ins> The confirmation from the MLSPlaintext object </ins> Sign the GroupInfo using the member's private signing key Encrypt the GroupInfo using the key and nonce derived from the  <ins> "epoch_secret" for the new epoch (see welcoming-new-members) For each new member in the group: Identify the lowest common ancestor in the tree of the new member's leaf node and the member sending the Commit Compute the path secret corresponding to the commonn ancestor node Compute an EncryptedKeyPackage object that encapsulates the "init_secret" for the current epoch and the path secret for the common ancestor. </ins>  Construct a Welcome message from the encrypted GroupInfo object and the encrypted key packages.