jiebi/CodeConvo huggingface dataset:
Change:
This PR moves the remark that there has to be validation of the attested identities upon a credential update to the KeyPackage validation subsection. It also changes the responsibility for the check to be that of the AS rather than that of the application. Note, that the boundaries are somewhat arbitrary at this point, since the application running on the local device may well implement parts of the AS. The reason for this change is to ensure any validation checks that pertain to authentication are part of the AS.
NAME Please make any required changes to the architecture document as well. Since I think that's where the AS is defined.
Right now it says in the Update proposal section: "Verify that the set of identities attested by the credential is acceptable to the application for the participant being updated." Firstly, I think this is a matter of authentication and thus the AS' job and secondly, it's a validation step that should probably go into the section.
Discussion on virtual interim: Depends on what the boundary of the AS is: Checking credential is valid Also checking (credential -> credential) transitions Moving this check to KP validation section would make it clearer NAME to make a PR
Fixed by

Discussion:
Verify that the credential in the KeyPackage 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 <del> protocol the KeyPackage is being verified. </del> <ins> protocol the KeyPackage is being verified with the following exception: If the KeyPackage is an update to another KeyPackage, the authentication service MUST additionally validate that the set of identities attested by the credential in the new KeyPackage is acceptable relative to the identities attested by the old credential. </ins> Verify that the signature on the KeyPackage is valid using the public key in the KeyPackage's credential

Verify that the "hpke_init_key" value is different from the corresponding field in the KeyPackage being replaced. <del> Verify that the set of identities attested by the credential is acceptable to the application for the participant being updated. </del> Replace the sender's leaf KeyPackage with the one contained in the Update proposal
Change:
The current description of external commits still leaves room for the committer to include various other proposals such as arbitrary proposals that are not Update or Remove proposals (e.g., Adds, RequiredCapability, PSK, etc.). I think we should narrow that down to a specific set of proposals (i.e. an allow list style) to keep the implementation and general protocol complexity low for external commits, both for creation and processing. The way I see it, the new joiner can always issue a follow-up commit for other proposals, but I might be missing important use-cases, so I'd be grateful for feedback on this.
I agree with the intent here. Looking through the list of proposal types, the only other one that seems like it might be useful is PSK -- I could see it being useful to prove that you have a PSK when joining from the outside. If we can add that as an option (probably in parallel to Remove), this seems good to go to me.
Would an External Commit adding yourself contain an Add or an Update Proposal?
It used to contain an proposal, but since that's pretty much redundant with the the commiter has to include, it got optimized away. So an external commit should be handled as if it contained an Add proposal, where the KeyPackage in the Add is instead in the .
Comment by NAME Why RECOMMENDED and not MUST ?

Discussion:
applications can choose to make it available to new members in order to allow External Commits. <del> External Commits work like regular Commits, with a few differences: </del> <ins> In principle, External Commits work like regular Commits.  However, their content has to meet a specific set of requirements: </ins> External Commits MUST contain a "path" field (and is therefore a "full" Commit).  The joiner is added at the leftmost free leaf

The proposals included by value in an External Commit MUST meet the following conditions: <del> There MUST be a single ExternalInit proposal </del> <ins> There MUST be a single ExternalInit proposal. </ins> <del> There MUST NOT be any Update proposals </del> <ins> There MAY be a single Remove proposal, where the LeafNode in the "path" field MUST meet the same criteria as the LeafNode in an Update for the removed leaf (see update).  In particular, the "credential" in the LeafNode MUST present a set of identifiers that is acceptable to the application for the removed participant. </ins> <del> If a Remove proposal is present, then the LeafNode in the "path" field MUST meet the same criteria as the LeafNode in an Update for the removed leaf (see update).  In particular, the "credential" in the LeafNode MUST present a set of identifiers that is acceptable to the application for the removed participant. </del> <ins> There MAY be one or more PreSharedKey proposals. There MUST NOT be any other proposals. </ins> External Commits MUST be signed by the new member.  In particular, the signature on the enclosing MLSPlaintext MUST verify using the
Change:
PublicGroupState was removed as an independent struct in . This PR fixes some dangling references to it.
cc NAME
Comment by NAME Hmmm :P
Cf. RFC 8446 We could provide some more citations to the analyses that are now in the literature if you think that would help.
CC NAME NAME NAME for citations
They are also in this architecture document PR: URL
Oh good, I'll just add a citation over to mls-architecture.
Also, update WireFormat: s/mlspublicgroupstate(4),/mlsgroup_info(4),/

Discussion:
In this process, the joiner sends a new "init_secret" value to the group using the HPKE export method.  The joiner then uses that <del> "init_secret" with information provided in the PublicGroupState and an external Commit to initialize their copy of the key schedule for the new epoch. </del> <ins> "init_secret" with information provided in the GroupInfo and an external Commit to initialize their copy of the key schedule for the new epoch. </ins> Members of the group receive the "kem_output" in an ExternalInit proposal and preform the corresponding calculation to retrieve the "init_secret" value. <del> In both cases, the "info" input to HPKE is set to the PublicGroupState for the previous epoch, encoded using the TLS serialization. </del> <ins> In both cases, the "info" input to HPKE is set to the GroupInfo for the previous epoch, encoded using the TLS serialization. </ins> 9.4.
Change:
The recently introduced variable size encoding allows for very large message sizes that are not practical in any realistic scenario. Since decoders will most likely not allow such large messages anyway, this PR limits the maximum size to 30-bit.
cc NAME who had some thoughts about limits on the last virtual interim.
My general points are: Code defensively Fail gracefully Use the lower level protocol carrying MLS Messages to send a clear and relevant error message if something is too big. Ex: HTTP/2.0 413 Commit.Proposals exceeds 2^16 bytes ex: HTTP/2.0 413 Too many proposals referenced in Commit (>9999)

Discussion:
min and max values, the vector description simply includes a "V". For example: <del> Such a vector can represent values with length from 0 bytes to 2^62 </del> <ins> Such a vector can represent values with length from 0 bytes to 2^30 </ins> bytes.  The variable-length integer encoding reserves the two most significant bits of the first byte to encode the base 2 logarithm of the integer encoding length in bytes.  The integer value is encoded

When decoding, values using more bits than necessary MUST be treated as malformed. <del> This means that integers are encoded on 1, 2, 4, or 8 bytes and can encode 6-, 14-, 30-, or 62-bit values respectively. </del> <ins> This means that integers are encoded on 1, 2, or 4 bytes and can encode 6-, 14-, or 30-bit values respectively. </ins> <del> For example, the eight-byte sequence c2 19 7c 5e ff 14 e8 8c (in hexadecimal) decodes to the decimal value 151288809941952652; the four byte sequence 9d 7f 3e 7d decodes to 494878333; the two byte sequence 7b bd decodes to 15293; and the single byte 25 decodes to 37 (as does the two byte sequence 40 25). </del> <ins> Vectors that start with "11" prefix are invalid and MUST be rejected. For example, the four byte sequence 0x9d7f3e7d decodes to 494878333; the two byte sequence 0x7bbd decodes to 15293; and the single byte 0x25 decodes to 37. </ins> The following figure adapts the pseudocode provided in RFC9000 to add a check for minimum-length encoding: The use of variable-size integers for vector lengths allows vectors <del> to grow very large, up to 2^62 bytes.  Implementations should take </del> <ins> to grow very large, up to 2^30 bytes.  Implementations should take </ins> care not to allow vectors to overflow available storage.  To facilitate debugging of potential interoperatbility problems, implementations should provide a clear error when such an overflow
Change:
The co-path is written both as 'co-path' and 'copath'. As a formality check, this should be unified.

Discussion:
The parent hash of P changes whenever an "UpdatePath" object is applied to the ratchet tree along a path from a leaf U traversing <del> node V (and hence also P).  The new "Parent Hash of P (with Co-Path Child S)" is obtained by hashing P's "ParentHashInput" struct. </del> <ins> node V (and hence also P).  The new "Parent hash of P (with copath child S)" is obtained by hashing P's "ParentHashInput" struct. </ins> The field "public_key" contains the HPKE public key of P.  If P is the root, then the "parent_hash" field is set to a zero-length octet

If, on the other hand, V is the leaf U and its LeafNode has "leaf_node_source" set to "commit", then the Parent Hash of P (with <del> V's sibling as co-path child) is stored in the "parent_hash" field. </del> <ins> V's sibling as copath child) is stored in the "parent_hash" field. </ins> This is true in particular of the LeafNode object sent in the "leaf_node" field of an UpdatePath.  The signature of such a LeafNode thus also attests to which keys the group member introduced into the
Change:
This PR adds two clarifications suggested by NAME Clarifying some antecedents in UpdatePath processing Explaining how the example trees can come about in practice

Discussion:
concatenating the resolution of its left child with the resolution of its right child, in that order <del> For example, consider the following tree, where the "_" character </del> <ins> For example, consider the following subtree, where the "_" character </ins> represents a blank node and unmerged leaves are indicated in square brackets:

The resolution of leaf 1 is the empty list [] <del> The resolution of root node is the list [A, Z, C] </del> <ins> The resolution of top node is the list [A, Z, C] </ins> Every node, regardless of whether the node is blank or populated, has a corresponding _hash_ that summarizes the contents of the subtree

to DeriveKeyPair. For example, suppose there is a group with four members, with C an <del> unmerged leaf at node 5: </del> <ins> unmerged leaf at Z: </ins> If member B subsequently generates an UpdatePath based on a secret "leaf_secret", then it would generate the following sequence of path

Compute the updated path secrets. <del> Identify a node in the filtered direct path for which the local member is in the subtree of the non-updated child. </del> <ins> Identify a node in the filtered direct path for which the recipient is in the subtree of the non-updated child. </ins> Identify a node in the resolution of the copath node for which <del> this node has a private key. </del> <ins> the recipient has a private key. </ins> Decrypt the path secret for the parent of the copath node using the private key from the resolution node.
Change:
A few changes to make code blocks a little more consistent / usable / pretty: Fence every code block with exactly three tildes Mark each code block with a type ( / / / / ) Marking with generates slightly prettier pictures for the ladder diagrams in the introduction. Marking with makes it easy to programmatically extract the TLS syntax definitions in case we want to produce a syntax summary appendix like , or in case implementers want to quickly get a listing of all the structs they need. The only substantive changes I made here were: Removing the lines from the branch and re-inject PSK illustrations Splitting pseudocode from TLS syntax in a few cases.
Yeah, I specifically had the idea because I wanted to pull out the TLS syntax blocks to update my implementation :)
Nice idea! It would also allow someone to compile the document with syntax coloration for TLS formats and Python code.

Discussion:
direct path, "path_secret[1]" to the second parent node, and so on. Compute the sequence of HPKE key pairs "(node_priv,node_pub)", one for each node on the leaf's direct path, as follows. The node secret is derived as a temporary intermediate secret so that each secret is only used with one algorithm: The path secret is used as an input to DeriveSecret and the node secret is used as an input

from the KDF for the group's ciphersuite, as well as the functions defined below: <ins> Where KDFLabel is specified as: </ins> The value "KDF.Nh" is the size of an output from "KDF.Extract", in bytes.  In the below diagram:
Change:
This matches the behavior in TLS, and saves space (due to not having to send the nonce).
Merging based on r+ from NAME out of band

Discussion:
Added an appendix with example code for tree math <ins> Changed the ECIES mechanism used by TreeKEM so that it uses nonces generated from the shared secret </ins> draft-00 Initial adoption of draft-barnes-mls-protocol-01 as a WG item.

path.  In both cases, the path is ordered from the leaf to the root; each node MUST be the parent of its predecessor. <ins> Note that in TreeKEM, the length of the "node_secrets" vector MUST be exactly one less than the length of the "nodes" vector, since the secret value for the leaf node is not encrypted.  For "i > 0", "node_secrets[i-1]" has the encrypted node secret corresponding to the public key in "nodes[i]". </ins> When using TreeKEM, the ECIESCiphertext values encoding the encrypted secret values are computed as follows:

Compute the shared secret Z with the node's other child <del> Generate a fresh nonce N </del> <ins> Derive a key and nonce as described below </ins> Encrypt the node's secret value using the AEAD algorithm specified by the ciphersuite in use, with the following inputs: <del> Key: A key derived from Z as specified by the ciphersuite </del> <ins> Key: The key derived from Z </ins> <del> Nonce: A random nonce N of the size required by the algorithm </del> <ins> Nonce: The nonce derived from Z </ins> Additional Authenticated Data: The empty octet string

ephemeral_key: The ephemeral public key x*G <del> nonce: The random nonce N </del> ciphertext: The AEAD output Decryption is performed in the corresponding way, using the private
Change:
the "MLS Proposal Types" section defines a table with columns Value Name Recommended Path Required Reference But the template directly above the table only mentions four of the five columns. It does not mention or describe what "Path Required" means. It should probably at least make clear that the field should be either or , and reference section "Commit" where the path requirement is discussed.

Discussion:
Standards Action RFC8126.  IESG Approval is REQUIRED for a Y->N transition. <ins> Path Required: Whether a Commit covering a proposal of this type is required to have its "path" field populated (see commit). </ins> Reference: The document where this extension is defined Initial contents:
Change:
The following statement is no longer up-to-date, given addition of P-384: "For ciphersuites using ECDSA with the NIST curves P-256 or P-521, the public key is..." To avoid tracking too many changes in the future for the document, I suggest the simple edit: "For ciphersuites using ECDSA with the NIST curves, the public key is..."

Discussion:
ciphersuite for a credential in a KeyPackage object.  For ciphersuites using Ed25519 or Ed448 signature schemes, the public key is in the format specified in RFC8032.  For ciphersuites using ECDSA <del> with the NIST curves P-256 or P-521, the public key is the output of the uncompressed Elliptic-Curve-Point-to-Octet-String conversion according to SECG. </del> <ins> with the NIST curves (P-256, P-384, or P-521), the public key is the output of the uncompressed Elliptic-Curve-Point-to-Octet-String conversion according to SECG. </ins> For an X.509 credential, each entry in the chain represents a single DER-encoded X.509 certificate.  The chain is ordered such that the
Change:
NAME Hi Brendan ! Would you mind please revert the last of the 3 changes. Even though the sentence is not amazing and your change correct, I find it better to keep explicit the fact that the root should not be included, instead of having to infer it from the fact it has no siblings :) Thanks !
You don't have to infer it -- direct paths are defined to never include the root node in the sentence just before.

Discussion:
To enforce forward secrecy and post-compromise security of messages, each participant periodically updates its leaf secret which represents its contribution to the group secret.  Any member of the <del> group can send an Update at any time by generating fresh leaf secret and keys and send an Update message that describes how to update the </del> <ins> group can send an Update at any time by generating a fresh leaf secret and sending an Update message that describes how to update the </ins> group secret with that new information.  Once all participants have processed this message, the group's secrets will be unknown to an attacker that had compromised the sender's prior leaf secret.

_siblings_ if they share the same parent. A _subtree_ of a tree is the tree given by the descendants of any <del> node, the _head_ of the subtree The _size_ of a tree or subtree is </del> <ins> node, the _head_ of the subtree.  The _size_ of a tree or subtree is </ins> the number of leaf nodes it contains.  For a given parent node, its _left subtree_ is the subtree with its left child as head (respectively _right subtree_).

The _direct path_ of a root is the empty list, and of any other node 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, excluding the root, which has no sibling.  The _frontier_ of a tree is the list of heads of the maximal full subtrees of the tree, ordered from left to right. </del> <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. </ins> For example, in the below tree:
Change:
This should have been done before publishing draft-14, but we can't fix that now. At least this will capture the history in draft-15.
Merging my own PR because this is strictly editorial.

Discussion:
RFC EDITOR PLEASE DELETE THIS SECTION. <ins> draft-14 Ensure that a signature public key is always intelligible (*) Clean up terminology of derived secrets/keys Fix parent hash (*) Specify compatibility behavior around new credentials Add Path Required to Proposal Type template Sub-group branching requires fresh key packages for each member Use "aasvg" and typed code blocks Require init key and leaf key to be different Preconfigured senders extension and removal of signature key indirection </ins> draft-13 TLS syntax updates (including variable-header-length vectors) (*)
Change:
In first paragraph, the "Ratchet Tree Evolution" Section states that whenever a member initiates an epoch change, they refresh the key pair in their leaves, etc. This is not the case for partial commits, where the epoch is advanced without a key update and without achieving PCS.

Discussion:
8.4. <del> In order to provide forward secrecy and post-compromise security, whenever a member initiates an epoch change (i.e., commits; see commit), they refresh the key pairs of their leaf and of all nodes on their leaf's direct path (all nodes for which they know the secret key). </del> <ins> Whenever a member initiates an epoch change (i.e., commits; see commit), they may need to refresh the key pairs of their leaf and of the nodes on their leaf's direct path in order to maintain forward secrecy and post-compromise security. </ins> The member initiating the epoch change generates the fresh key pairs using the following procedure.  The procedure is designed in a way

group are identified by a "external" or "new_member" SenderType in MLSPlaintext. <del> ReInit proposals can also be sent to the group by a "external" </del> <ins> ReInit proposals can also be sent to the group by an "external" </ins> sender, for example to enforce a changed policy regarding MLS version or ciphersuite.
Change:
The External Senders Extension allows clients to agree on the entities that are allowed to send external proposals, as well as the signature public keys required to verify them. It contains a list of credentials that is meant to achieve this goal. However, due to a recent change, Credentials don't necessarily contain signature public keys anymore. NAME suggested to have it contain a signature public key, as well as a corresponding Credential, which allows members to verify the binding between signature public key and the owning entity's identity, which I think would be a good solution.
Thanks NAME I like that this captures both the signature and authentication aspects. NAME wdyt?Looks good to me! NAME idea might be a good additional improvement.

Discussion:
13.1.8.1. The "external_senders" extension is a group context extension that <del> contains credentials of senders that are permitted to send external proposals to the group. </del> <ins> contains the credentials and signature keys of senders that are permitted to send external proposals to the group. </ins> 13.2.
Change:
There are several references to GroupContext in the first few sections. The details are fine where they are, but it would be good to introduce the notion that GroupContext summarizes the state of the group.

Discussion:
key that can be used to encrypt to that client, and which other clients can use to introduce the client to a new group. <ins> An object that summarizes the state of the group.  The group context is signed to bind a message to a particular group, and also provided to new members to help them join a group. </ins> A signing key pair used to authenticate the sender of a message. An MLSPlaintext or MLSCiphertext message carrying an MLS Proposal
Change:
In the "Restrictions" section, we say "During each epoch senders MUST NOT encrypt more data than permitted by the security bounds of the AEAD scheme used", without specifying the limits. We should cite something here, probably (cc NAME for visibility).

Discussion:
16.2. During each epoch senders MUST NOT encrypt more data than permitted <del> by the security bounds of the AEAD scheme used. </del> <ins> by the security bounds of the AEAD scheme used I-D.irtf-cfrg-aead- limits. </ins> Note that each change to the Group through a Handshake message will also set a new "encryption_secret".  Hence this change MUST be