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

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

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

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

Revised text:
application to supply a "reference identifier" for the authenticated client, if any.  <ins> A "basic" credential is a bare assertion of an identity, without any </ins> additional information.  The format of the encoded identity is defined by the application.
Original text:
Public keys used in the protocol are opaque values in a format defined by the ciphersuite, using the following types:  5.5.1. This ciphersuite uses the following primitives:

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

Revised text:
Public keys used in the protocol are opaque values in a format defined by the ciphersuite, using the following types: <ins> Cryptographic algorithms are indicated using the following types: </ins> 5.5.1. This ciphersuite uses the following primitives:
Original text:
A member of a group authenticates the identities of other participants by means of credentials issued by some authentication system, e.g., a PKI.  Each type of credential MUST express the <del> holder's identity as well as the public key of a signature key pair that the holder of the credential will use to sign MLS messages. </del>  Credentials MAY also include information that allows a relying party to verify the identity / signing key binding.

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

Revised text:
A member of a group authenticates the identities of other participants by means of credentials issued by some authentication system, e.g., a PKI.  Each type of credential MUST express the  <ins> following data: The public key of a signature key pair The identity of the holder of the private key The signature scheme that the holder will use to sign MLS messages </ins> Credentials MAY also include information that allows a relying party to verify the identity / signing key binding.
Original text:
If the the above checks are successful, consider the updated GroupState object as the current state of the group. <del> The "finished_mac" value is computed over the provisional group state and the current handshake message (with the confirmation value set to zero): </del>  HMAC RFC2104 uses the Hash algorithm for the ciphersuite in use.  [[ OPEN ISSUE: The Add and Remove operations create a "double-join" situation, where a participants leaf key is also known to another

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

Revised text:
If the the above checks are successful, consider the updated GroupState object as the current state of the group.  <ins> The "signature" and "confirmation" values are computed over the transcript of group operations, using the transcript hash from the provisional GroupState object: </ins> HMAC RFC2104 uses the Hash algorithm for the ciphersuite in use. <ins> Sign uses the signature algorithm indicated by the signer's credential in the roster. </ins> [[ OPEN ISSUE: The Add and Remove operations create a "double-join" situation, where a participants leaf key is also known to another
Original text:
To disambiguate different signatures used in MLS, each signed value is prefixed by a label as shown below:  Here, the functions "Signature.Sign" and "Signature.Verify" are defined by the signature algorithm. and Commits refer to Proposals they cover.  These identifiers are computed as follows:  For a KeyPackageRef, the "value" input is the encoded KeyPackage, and the ciphersuite specified in the KeyPackage determines the KDF used. For a ProposalRef, the "value" input is the MLSAuthenticatedContent

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

Revised text:
To disambiguate different signatures used in MLS, each signed value is prefixed by a label as shown below: <ins> Where SignContent is specified as: And its fields set to: </ins> Here, the functions "Signature.Sign" and "Signature.Verify" are defined by the signature algorithm. and Commits refer to Proposals they cover.  These identifiers are computed as follows: <ins> Where RefHashInput is defined as: And its fields set to: </ins> For a KeyPackageRef, the "value" input is the encoded KeyPackage, and the ciphersuite specified in the KeyPackage determines the KDF used. For a ProposalRef, the "value" input is the MLSAuthenticatedContent
Original text:
RFC EDITOR PLEASE DELETE THIS SECTION.  draft-02 Removed ART (*)

Reviewer comments:
I forgot to update the changelog before I published -03. We should add that to the review criteria. This will at least fix it for -04.

Revised text:
RFC EDITOR PLEASE DELETE THIS SECTION. <ins> draft-03 Added ciphersuites and signature schemes (*) Re-ordered fields in UserInitKey to make parsing easier (*) Fixed inconsistencies between Welcome and GroupState (*) Added encryption of the Welcome message (*) </ins> draft-02 Removed ART (*)
Original text:
Update messages SHOULD be sent at regular intervals of time as long as the group is active, and members that don't update SHOULD eventually be removed from the group.  It's left to the application <del> to determine an appropriate amount of time between Updates.  In general, however, applications should take care that they do not send MLS messages at a rate that overwhelms the transport over which messages are being sent. </del>  Members are removed from the group in a similar way, as shown in remove-flow.  Any member of the group can send a Remove proposal

Reviewer comments:
URL Thanks for working on this interesting topic. Thanks for Gorry fairhost for this TSVART review. I have few comments, which I believe if addressed will improve the document. - There is a mismatch between intended status of this spec (PS) and what in the doc header (Informational). I see Lars already have a discuss on it, so supporting it. - The specification says the UPDATE messages SHOULD be periodically sent and expects the applications to decided on the period between UPDATE messages. As I can see there are multiple implementations, can't we also recommend some guidelines and considerations on how to select the period? In some discussions I saw we were talking about hours and months.. - it says - "In general, however, applications should take care that they do not send MLS messages at a rate that overwhelms the transport over which messages are being sent." I am not sure I understand what "overwhelms the transport" means. Are we talking about the congestion control or bandwidth estimation part of transport protocols? Usually the application have no or very vague information about the internal protocol states, in that case how the applications are expected to take care of this? are we suggesting some interaction application rate control?

Revised text:
Update messages SHOULD be sent at regular intervals of time as long as the group is active, and members that don't update SHOULD eventually be removed from the group.  It's left to the application  <ins> to determine an appropriate amount of time between Updates.  Since the purpose of sending an Update is to proactively constrain a compromise window, the right frequency is usually on the order of hours or days, not milliseconds. The MLS architecture recommends that MLS be operated over a secure transport (see Section 7.1 of I-D.ietf-mls-architecture).  Such transport protocols will typically provide functions such as congestion control that manage the impact of an MLS-using application on other applications sharing the same network.  Applications should take care that they do not send MLS messages at a rate that will cause problems such as network congestion, especially if they are not following the above recommendation (e.g., sending MLS directly over UDP instead). </ins> Members are removed from the group in a similar way, as shown in remove-flow.  Any member of the group can send a Remove proposal
Original text:
RFC EDITOR PLEASE DELETE THIS SECTION.  draft-15 Include ciphersuite in group context (*)

Reviewer comments:
Also adds a draft-18 section to cover any edits between now and the next I-D.

Revised text:
RFC EDITOR PLEASE DELETE THIS SECTION. <ins> draft-18 Make the document standards track Make the ratchet tree non-malleable (*) Use ExpandWithLabel to derive welcome key (*) Change MLS-Exporter label from "exporter" to "exported" (*) Loosen chain requirements (*) Clarify transcript hash initialization GREASE for MLS registries Move pseudocode out of KDFLabel definition. Rename PrivateContentTBE to PrivateMessageContent Fix DecryptWithLabel argument order for Welcome Responses to IESG reviews Describe varint length check more clearly draft-17 Rename MLSCiphertext and MLSPlaintext to PrivateMessage and PublicMesssage respectively (*) Add label and context to public-key encryption (*) Include leaf index in LeafNodeTBS for better parent-hash guarantees (*) Make ProtocolVersion two bytes (*) Clarify group creation (*) Validate additional properties of unmerged leaves (*) Clarify that the AS needs to vet the signature key Remove "MLS" prefix on structs Credentials should be replaced before expiring Add a section discussing the security of the sender data protection Minor fixes in presentation language. Allow multiple welcomes per commit Remove reference to BasicCredential. Client aware of its own removal in group Create IANA registries for signature and export labels Complete IANA media type registration Make more vendor code points available Update Recommended column definition to match 8447bis Responses to early ARTART review Responses to early OPSDIR review Responses to early TSV-ART review draft-16 Fix GroupInfoTBS (*) Make reference to h2 informative </ins> draft-15 Include ciphersuite in group context (*)
Original text:
former is used to update the confirmed transcript hash and the latter to update the interim transcript hash. <del> In this notation, "InterimTranscriptHashInput_[epoch]" and "ConfirmedTranscriptHashInput_[epoch+1]" are based on the Commit that initiated the epoch with epoch number "epoch".  (Note that the "epoch" field in this Commit will be set to "epoch - 1", since it is </del>  sent within the previous epoch.)  8.3. In addition to initializing a new epoch via KDF invocations as

Reviewer comments:
The current text on initializing the transcript hash is ambiguous. In particular, it never tells you how to compute the first . This PR provides clearer initialization instructions, and a figure that summarizes the transcript hash evolution [2]. [1] To be clear, I think the intent is clear and all current implementations are consistent. The text is just bad. [2] The diagram is a little over-the-top elaborate. I would be OK removing it :)
I generally like the diagram, but the intersection between , and is not clear to me. What is going where? Also shouldn't and also get numbers? And what's the different between the and suffix?
OK, I rotated the diagram 90 degrees and rejiggered things to hopefully be clearer. It now should just barely fit in the .TXT format. What do folks think?
Beautiful!

Revised text:
former is used to update the confirmed transcript hash and the latter to update the interim transcript hash.  <ins> In this notation, "ConfirmedTranscriptHashInput_[epoch]" and "InterimTranscriptHashInput_[epoch]" are based on the Commit that initiated the epoch with epoch number "epoch.  (Note that the "epoch"field in this Commit will be set to "epoch - 1`, since it is </ins> sent within the previous epoch.) <ins> The transcript hash "ConfirmedTranscriptHashInput_[epoch]" is used as the "confirmed_transcript_hash" input to the "confirmation_tag" field for this Commit.  Each Commit thus confirms the whole transcript of Commits up to that point, except for the latest Commit's confirmation tag. </ins> 8.3. In addition to initializing a new epoch via KDF invocations as
Original text:
If the tree has "2^d" leaves, then it has "2^(d+1) - 1" nodes.  The "ratchet_tree" vector logically has this number of entries, but the <del> sender SHOULD NOT include blank nodes after the last non-blank node. If a receiver encounters a vector whose length "L" is not of the form "2^(d+1) - 1", then the receiver MUST extend it to the right with blank values until it has such a length, adding the minimum number of blank values possible.  (Obviously, this may be done "virtually", by synthesizing blank nodes when required, as opposed to actually changing the structure in memory.) </del>  The leaves of the tree are stored in even-numbered entries in the array (the leaf with index "L" in array position "2*L").  The root

Reviewer comments:
As discussed in mlswg/mls-implementations . Currently, there are several valid for one tree: the sender can choose ("SHOULD") to omit some (but not all) blank nodes at the right of the tree. This PR changes this: the sender MUST omit all the blank nodes at the right of the tree, and the receiver MUST check that it was done correctly (i.e., the last node of is non-blank).
Right now, the signature on an MLSPlaintext includes the GroupContext for the group. If we are going to allow Add proposals signed by the new member, then this will need to change, because the new member doesn't know the GroupContext. My preference would be to simply remove the GroupContext from the plaintext. The Group ID is already included, so copy/paste protection can be added that way. The other elements of the GroupContext effectively overlap with the Epoch that is already signed.
Haven't thought about this too deeply, but having the full GroupContext in MLSPlaintextTBS means that we know all the members agree on the state of the ratchet tree, the transcript, the extensions. Removing it means we would no longer have agreement on those, right?
We won't have confirmation of agreement as a result of signature verification. The question is whether that is necessary. If the MLSPlaintext was decrypted from an MLSCiphertext, for example, then the successful decryption of the MLSCiphertext implies agreement on all those things. I suppose you could also switch the signature input based on SenderType, but that seems messier.
I'm not so sure that decrypting an MLSCiphertext implies agreement, because the crypto is symmetric. A man-in-the-middle can re-encrypt but not re-sign.

Revised text:
If the tree has "2^d" leaves, then it has "2^(d+1) - 1" nodes.  The "ratchet_tree" vector logically has this number of entries, but the  <ins> sender MUST NOT include blank nodes after the last non-blank node. The receiver MUST check that the last node in "ratchet_tree" is non- blank, and extend it to the right until it has a length of the form "2^(d+1) - 1", adding the minimum number of blank values possible. (Obviously, this may be done "virtually", by synthesizing blank nodes when required, as opposed to actually changing the structure in memory.) </ins> The leaves of the tree are stored in even-numbered entries in the array (the leaf with index "L" in array position "2*L").  The root
Original text:
"leaf_node_source" is set to "key_package". If the LeafNode appears in an Update proposal, verify that <del> "leaf_node_source" is set to "update". </del>  If the LeafNode appears in the "leaf_node" value of the UpdatePath in a Commit, verify that "leaf_node_source" is set Identify the leaf L for the new member: if there are empty leaves in the tree, L is the leftmost empty leaf.  Otherwise, the tree is <del> extended to the right by one leaf node and L is the new leaf. </del>  For each non-blank intermediate node along the path from the leaf L to the root, add L's leaf index to the "unmerged_leaves" list If this is an external commit, assign the sender the leftmost blank leaf node in the new ratchet tree.  If there are no blank <del> leaf nodes in the new ratchet tree, add a blank leaf to the right side of the new ratchet tree and assign it to the sender. </del>  Update the sender's direct path in the ratchet tree as described in synchronizing-views-of-the-tree.  Define

Reviewer comments:
This PR fixes small issues that I noticed while implementing proposal validation and fixing some external join bugs: The pseudocode for determining whether a path is required assumes that all proposals are by-reference. The PR updates the pseudocode to be more general, and also account for proposals by value. There were two references to adding a single leaf to the tree, which are updated to make clear that the tree grows by doubling, not by single leaves. There was no current requirement that an Update proposal have a distinct , so one is added.

Revised text:
"leaf_node_source" is set to "key_package". If the LeafNode appears in an Update proposal, verify that  <ins> "leaf_node_source" is set to "update" and that "encryption_key" represents a different public key than the "encryption_key" in the leaf node being replaced by the Update proposal. </ins> If the LeafNode appears in the "leaf_node" value of the UpdatePath in a Commit, verify that "leaf_node_source" is set Identify the leaf L for the new member: if there are empty leaves in the tree, L is the leftmost empty leaf.  Otherwise, the tree is  <ins> extended to the right as described in adding-and-removing-leaves and L is assigned the leftmost new blank leaf. </ins> For each non-blank intermediate node along the path from the leaf L to the root, add L's leaf index to the "unmerged_leaves" list If this is an external commit, assign the sender the leftmost blank leaf node in the new ratchet tree.  If there are no blank  <ins> leaf nodes in the new ratchet tree, expand the tree to the right as defined in adding-and-removing-leaves and assign the leftmost new blank leaf to the sender. </ins> Update the sender's direct path in the ratchet tree as described in synchronizing-views-of-the-tree.  Define
Original text:
Name: mqtt-topic-filter <del> Description/Specification: Topic Filter as defined in mqtt-defs. </del>  Reference: [[This document]] (scope) Name: mqtt-permissions <del> Description/Specification: Permissions for MQTT client.  Tperm is a string with a value either "pub" or "sub". </del>  <del> Reference: [[This document]] (scope ) </del>  8.

Reviewer comments:
Thanks Carsten! I'll go clear my DISCUSS :)
I see. These didn't cause a problem on my side.

Revised text:
Name: mqtt-topic-filter  <ins> Description/Specification: Topic Filter as defined in scope. </ins> Reference: [[This document]] (scope) Name: mqtt-permissions  <ins> Description/Specification: Permissions for MQTT client as defined in scope.  Tperm is an array of one or more text strings that each have a value of either "pub" or "sub". </ins>  <ins> Reference: [[This document]] (scope) </ins> 8.
Original text:
of-Possession (PoP) token by default. This document follows RFC7800 for PoP semantics for JWTs (CWTs MAY <del> also be used).  The AS includes a "cnf" (confirmation) parameter to </del>  the PoP token, to declare that the Client possesses a particular key and RS can cryptographically confirm that the Client has possession <del> of that key.  The "cnf" parameter is REQUIRED if a symmetric key is used, and MAY be present for asymmetric PoP keys, as described in I- D.ietf-ace-oauth-params. </del>  Note that the contents of the web tokens (including the "cnf" parameter) are to be consumed by the RS and not the Client (the

Reviewer comments:
Let's assume we're talking about what the AS puts in the token (not the token response). That means that "cnf" always has to be present. The flow where "cnf" is only required in the symmetric case and is optional for the asymmetric case is the use of the "cnf" parameter in the token response, from AS to client.

Revised text:
of-Possession (PoP) token by default. This document follows RFC7800 for PoP semantics for JWTs (CWTs MAY  <ins> also be used).  The AS includes a "cnf" (confirmation) parameter in </ins> the PoP token, to declare that the Client possesses a particular key and RS can cryptographically confirm that the Client has possession  <ins> of that key, as described in I-D.ietf-ace-oauth-params. </ins> Note that the contents of the web tokens (including the "cnf" parameter) are to be consumed by the RS and not the Client (the