jiebi/TextFlow huggingface dataset:
Original text:
GroupContext for the current epoch, so that signatures are specific to a given group and epoch.  The ciphertext field of the MLSCiphertext object is produced by supplying the inputs described below to the AEAD function specified by the ciphersuite in use.  The plaintext input contains content and 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 <del> group are identified by an "preconfigured" or "new_member" SenderType </del>  in MLSPlaintext. The "new_member" SenderType is used for clients proposing that they

Reviewer comments:
by special-casing external senders. Removing the GroupContext would allow me to take messages that user A sent in one instance of a group, and make it look like they're speaking in another group by re-encrypting the ciphertext.
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:
GroupContext for the current epoch, so that signatures are specific to a given group and epoch. <ins> [[OPEN ISSUE: group_id and epoch are duplicated in the TBS and in GroupContext.  Think about how to de-duplicate.]] </ins> The ciphertext field of the MLSCiphertext object is produced by supplying the inputs described below to the AEAD function specified by the ciphersuite in use.  The plaintext input contains content and 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  <ins> group are identified by a "preconfigured" or "new_member" SenderType </ins> in MLSPlaintext. The "new_member" SenderType is used for clients proposing that they
Original text:
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 <del> these IDs 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. </del>  An external proposal MUST be sent as an MLSPlaintext object, since the sender will not have the keys necessary to construct an

Reviewer comments:
This stuck out to me while reading because verification is explicitly specified for the 'newmember' sender type in the paragraph above this and not for the 'preconfigured' sender type. I think it would be better to specify this as the verification flow is different for these external proposals i.e. the KeyPackage in the proposal is used for newmember sender types, and the key corresponding to an authorized sender is used for preconfigured senders.

Revised text:
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  <ins> these IDs and authorized signing keys.  Recipients MUST verify that the MLSPlaintext carrying the Proposal message is validly signed with the corresponding key.  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. </ins> An external proposal MUST be sent as an MLSPlaintext object, since the sender will not have the keys necessary to construct an
Original text:
5.4. <del> When performing a Commit, the leaf KeyPackage of the committer and its direct path to the root are updated with new secret values.  The HPKE leaf public key within the KeyPackage MUST be a freshly generated value to provide post-compromise security. The generator of the Commit starts by using the HPKE secret key "leaf_hpke_secret" associated with the new leaf KeyPackage (see key- packages) to compute "path_secret[0]" and generate a sequence of "path secrets", one for each ancestor of its leaf.  That is, path_secret[0] is used for the node directly above the leaf, </del>  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. For example, suppose there is a group with four members: If member B subsequently generates a Commit based on a secret <del> "leaf_hpke_secret", then it would generate the following sequence of path secrets: </del>  After the Commit, the tree will have the following structure, where "np[i]" represents the node_priv values generated as described above:  5.5. The members of the group need to keep their views of the tree in sync

Reviewer comments:
This PR tries to clarify these paragraphs by the following: Differentiating between HPKE public/private keys when describing how these keys are rotated for a commit Clarifying who does the actions associated with a commit Adding consistency fixes between the two paragraphs Let me know if these fixes are not quite right, as this PR tries to clarify where I had questions when reading.

Revised text:
5.4.  <ins> When performing a Commit, the generator of the Commit updates its leaf KeyPackage and its direct path to the root with new secret values.  The HPKE leaf public key within the KeyPackage MUST be derived from a freshly generated HPKE secret key to provide post- compromise security. The generator of the Commit starts by sampling a fresh random value called "leaf_secret", and uses the leaf_secret to generate their leaf HPKE key pair (see key-packages) and to seed a sequence of "path secrets", one for each ancestor of its leaf.  In this setting, path_secret[0] refers to the node directly above the leaf, </ins> 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. For example, suppose there is a group with four members: If member B subsequently generates a Commit based on a secret  <ins> "leaf_secret", then it would generate the following sequence of path secrets: </ins> After the Commit, the tree will have the following structure, where "np[i]" represents the node_priv values generated as described above: <ins> After performing these operations, the generator of the Commit MUST delete the leaf_secret. </ins> 5.5. The members of the group need to keep their views of the tree in sync
Original text:
of the group, who apply it to keep their local views of the tree in sync with the sender's.  When a client commits a change to the tree (e.g., to add or remove a member), it transmits a handshake message <del> containing a set of public values for intermediate nodes in the direct path of a leaf.  The other members of the group can use these public values to update their view of the tree, aligning their copy of the tree to the sender's. </del>  To perform an update for a path (a Commit), the sender broadcasts to the group the following information for each node in the direct path

Reviewer comments:
This PR adds a fix mentioned in but was not included in the PR that was eventually merged. Specifically, both public and encrypted private values are sent in a message containing key material to ratchet the tree forward.

Revised text:
of the group, who apply it to keep their local views of the tree in sync with the sender's.  When a client commits a change to the tree (e.g., to add or remove a member), it transmits a handshake message  <ins> containing a set of public and encrypted private values for intermediate nodes in the direct path of a leaf.  The other members of the group can use these values to update their view of the tree, aligning their copy of the tree to the sender's. </ins> To perform an update for a path (a Commit), the sender broadcasts to the group the following information for each node in the direct path
Original text:
Interim transcript hash: 0 <del> Init secret: 0 </del>  For each member, construct an Add proposal from the KeyPackage for that member (see add)

Reviewer comments:
This suggestion is based on a discussion in the MLS mailing list . It prevents issues that currently arrise when the very first commit of a group is an "add-only" commit because both the and would be 0. Let me know if the wording or anything else should be changed. /cc NAME URL
I believe this change invalidates the last paragraph of the , as it is impossible to verify the group creation process for the joiner without knowing the random that the group creator used.
maybe one alternative is to keep the zero , but make it compulsory to populate the path for this group creation welcome/commit (so that isn't zero)?
That would also work NAME (I also suggested that as an alternative in my original report in the mailing list), to me it is a little bit less elegant though. Personally, I also wonder why it is necessary to verify that group creation just happened. (Moreover, this way of recognizing group creation would prevent any group from which all but one person left from continuing, which my be confusing to end-users)
lgtm with one minor thing fixed Hi Eric, Thanks for the analysis, and the detailed, clear writeup. I agree that there are some real issues here, and with the solution approach. Just to align on a couple of details: is clearly a problem. Good catch. is less clear to me. You lose me when you say ""add-only" commits allow new group members (ONLY) to learn the value at the root of the TreeKEM tree". How do you think this happens? As I understand the spec, this is not the case. New members are added to the "unmergedleaves" array at the root, but they are not told the root secret or root private key. In any case, I agree that we should change the initial initsecret from being zero to being random. I think I had set it to zero out of a general caution against requiring fresh entropy, and likely under the theory that the first commit would change it (before was optional). But it is clearly necessary now. If you would like to send a PR, I would be happy to review. Thanks, --Richard >

Revised text:
Interim transcript hash: 0  <ins> Init secret: a fresh random value of size "KDF.Nh" </ins> For each member, construct an Add proposal from the KeyPackage for that member (see add)
Original text:
members to incorporate a Commit message into the transcript without having to store the whole MLSPlaintextCommitAuthData structure. <del> When a new group is created, the "interim_transcript_hash" field is set to the zero-length octet string. </del>  7.7. These ciphersuites map to HPKE primitives and TLS signature schemes as follows I-D.irtf-cfrg-hpke RFC8446:  It is advisable to keep the number of ciphersuites low to increase the chances clients can interoperate in a federated environment, therefore the ciphersuites only inlcude modern, yet well-established

Reviewer comments:
Addresses ambiguity pointed out on the mailing list by NAME
In , we changed from using HKDF to using the KDF from HPKE, which I thought removed the need for the ciphersuite to specify a hash function. As a result, ciphersuites no longer needed to specify a hash. However, the transcript computations still have a raw invocation, not a KDF invocation. So we need to either: Change the transcript hash computations to use the KDF, or Clarify that ciphersuites still specify a hash function (as before)
What about the call in the and the "hashes" for ?

Revised text:
members to incorporate a Commit message into the transcript without having to store the whole MLSPlaintextCommitAuthData structure.  <ins> As shown above, when a new group is created, the "interim_transcript_hash" field is set to the zero-length octet string. </ins> 7.7. These ciphersuites map to HPKE primitives and TLS signature schemes as follows I-D.irtf-cfrg-hpke RFC8446: <ins> The hash used for the MLS transcript hash is the one referenced in the ciphersuite name.  In the ciphersuites defined above, "SHA256" and "SHA512" refer to the SHA-256 and SHA-512 functions defined in SHS. </ins> It is advisable to keep the number of ciphersuites low to increase the chances clients can interoperate in a federated environment, therefore the ciphersuites only inlcude modern, yet well-established
Original text:
KeyPackage, the leaf secret from which the Commit is built, and the intermediate key pairs along the direct path to the root. <del> A new member receiving a Welcome message can recognize group creation if the number of entries in the "members" array is equal to the number of leaves in the tree minus one.  A client receiving a Welcome message SHOULD verify whether it is a newly created group, and if so, SHOULD verify that the above process was followed by reconstructing the Add and Commit messages and verifying that the resulting transcript hashes and epoch secret match those found in the Welcome message. </del> 10. Over the lifetime of a group, its membership can change, and existing

Reviewer comments:
As discussed on this removes the paragraph in the Group Creation section specifying that joiners SHOULD verify group creation if it is detected. A recent change to group creation - namely a random initial - makes it impossible to verify group creation.
URL Hi Eric, I agree with (2). I think the stuff that's in the spec right now about verifying group creation is mainly just a legacy of the fact that we used to have separate Init and Add operations. When those got coalesced into Welcome, it must have seemed appealing to enable recipients to continue to distinguish the cases. But as you point out, that's not really tenable. So please feel free to send a PR! Thanks, --Richard Cornelissen Eric wrote:

Revised text:
KeyPackage, the leaf secret from which the Commit is built, and the intermediate key pairs along the direct path to the root.  10. Over the lifetime of a group, its membership can change, and existing
Original text:
credential in a ratchet tree, the KeyPackage ciphersuite for a credential in a KeyPackage object.  For ciphersuites using Ed25519 or Ed448 signature schemes, the public key is in the format specified RFC8032.  For ciphersuites using ECDSA with the NIST curves P-256 or P-521, the public key is the output of

Reviewer comments:
This PR adds clarification around X509 cert structure, the chain and its encoding X509.
NAME thanks for the suggestions. updated PR to reflect the changes . pls let me know ..
NAME i have pushed another commit .. can you please check. thanks

Revised text:
credential in a ratchet tree, the KeyPackage ciphersuite for a credential in a KeyPackage object. <ins> For X509Credential, each entry in the chain represents a single DER- encoded X509 certificate.  The chain is ordered such that the first entry (chain[0]) is the end-entity certificate and each subsequent certificate in the chain MUST be the issuer of the previous certificate.  The algorithm for the "public_key" in the end-entity certificate MUST match the relevant ciphersuite. </ins> For ciphersuites using Ed25519 or Ed448 signature schemes, the public key is in the format specified RFC8032.  For ciphersuites using ECDSA with the NIST curves P-256 or P-521, the public key is the output of
Original text:
The public key of a signature key pair matching the SignatureScheme specified by the CipherSuite of the group <del> The identity of the holder of the private keys </del>  Credentials MAY also include information that allows a relying party to verify the identity / signing key binding.

Reviewer comments:
Thanks NAME pointing out the imprecision. Is this what you were looking for? Thanks NAME for the pointer to the correct registry.
This doesn't make sense because we don't actually use this registry. The signature scheme is defined by the ciphersuite, and the ciphersuite registry doesn't map to this unrelated registry
The is not authoritative in the group context and will always correspond with the one in the group (as is required by the generic description of the functionalities that Credentials have to provide). The SignatureScheme is there for when the Credential is handled in a context where there is no surrounding group. For example, when it's handled by the AS. There is a mapping from ciphersuit to SignatureScheme in Table 5, the entries of which correspond to the entries in the referenced registry. Is that what you meant?

Revised text:
The public key of a signature key pair matching the SignatureScheme specified by the CipherSuite of the group  <ins> The identity of the holder of the private key </ins> Credentials MAY also include information that allows a relying party to verify the identity / signing key binding.
Original text:
supported by all members. Initialize a one-member group with the following initial values <del> (where "0" represents an all-zero vector of size Hash.length): </del>  Ratchet tree: A tree with a single node, a leaf containing an HPKE public key and credential for the creator

Reviewer comments:
For the record: I asked NAME whether we could just update DeriveTreeSecret so that it always produces octets. But he pointed out that DeriveTreeSecret is also used to produce keys and nonces. Might be something to clean up later.

Revised text:
supported by all members. Initialize a one-member group with the following initial values  <ins> (where "0" represents an all-zero vector of size KDF.Nh): </ins> Ratchet tree: A tree with a single node, a leaf containing an HPKE public key and credential for the creator
Original text:
from the closest node to the leaf to the root; each node MUST be the parent of its predecessor. <del> The number of ciphertexts in the "encrypted_path_secret" vector MUST be equal to the length of the resolution of the corresponding copath node.  Each ciphertext in the list is the encryption to the corresponding node in the resolution. </del>  The HPKECiphertext values are computed as the "path" field at its discretion. If populating the "path" field: Create a UpdatePath using the new <del> tree (which includes any new members).  The GroupContext for this operation uses the "group_id", "epoch", "tree_hash", and "confirmed_transcript_hash" values in the initial GroupContext object. </del>  Assign this UpdatePath to the "path" field in the Commit.

Reviewer comments:
As briefly explained in the mailing list, commit messages currently contain encryptions for newly added group members that never even receive this commit message. This PR explicitely exlcudes them during the preparation of the UpdatePath.
I think this is a good point that wasn't really specified so far. The wording sounds a bit convoluted, maybe there is an easier way to describe it, like saying that the final resolution list should be filtered and all new leaf nodes should be removed from it.

Revised text:
from the closest node to the leaf to the root; each node MUST be the parent of its predecessor.  <ins> For each "UpdatePathNode", the resolution of the corresponding copath node MUST be filtered by removing all new leaf nodes added as part of this MLS Commit message.  The number of ciphertexts in the "encrypted_path_secret" vector MUST be equal to the length of the filtered resolution, with each ciphertext being the encryption to the respective resolution node. </ins> The HPKECiphertext values are computed as the "path" field at its discretion. If populating the "path" field: Create a UpdatePath using the new  <ins> tree.  Any new member (from an add proposal) MUST be exluded from the resolution during the computation of the UpdatePath.  The GroupContext for this operation uses the "group_id", "epoch", "tree_hash", and "confirmed_transcript_hash" values in the initial GroupContext object. </ins> Assign this UpdatePath to the "path" field in the Commit.
Original text:
confirmation key and the "confirmed_transcript_hash" from the GroupInfo.  11.3. By default, a GroupInfo message only provides the joiner with a

Reviewer comments:
As discussed on 2020-10-20, this field is not needed now that moved the signature under the confirmation tag.
We have a long-standing OPEN ISSUE on creating a group with a single Init message instead of N Add messages, which would change the work of initialization from O(N log N) to O(N). I would propose roughly the following: Then the processing would be: Find the welcome that's for you Initialize a one-member tree from the Welcome Use the UserInitKeys to populate the leaves of the tree Use the DirectPath to populate the creator's direct path (as in Update)
Fixed by URL
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.

Revised text:
confirmation key and the "confirmed_transcript_hash" from the GroupInfo. <ins> Use the confirmed transcript hash and confirmation tag to compute the interim transcript hash in the new state. </ins> 11.3. By default, a GroupInfo message only provides the joiner with a
Original text:
draft-10  Re-enable constant-time Add (*)  draft-09 Remove blanking of nodes on Add (*)

Reviewer comments:
We have a changelog for the document by I-D release, but haven't been updating it as we go. This PR updates the changelog based on merged PRs and the few we expect to close before releasing draft-10. Marking this as draft right now, until the other PRs have merged.

Revised text:
draft-10 <ins> Allow new members to join via an external Commit (*) Enable proposals to be sent inline in a Commit (*) </ins> Re-enable constant-time Add (*) <ins> Change expiration extension to lifetime extension (*) Make the tree in the Welcome optional (*) PSK injection, re-init, sub-group branching (*) Require the initial init_secret to be a random value (*) Remove explicit sender data nonce (*) Do not encrypt to joiners in UpdatePath generation (*) Move MLSPlaintext signature under the confirmation tag (*) Explicitly authenticate group membership with MLSPLaintext (*) Clarify X509Credential structure (*) Remove uneeded interim transcript hash from GroupInfo (*) IANA considerations Derive an authentication secret Use Extract/Expand from HPKE KDF Clarify that application messages MUST be encrypted </ins> draft-09 Remove blanking of nodes on Add (*)