jiebi/CodeConvo huggingface dataset:
Code change:
object must be a randomly sampled nonce of length "KDF.Nh" to avoid key re-use. <del> 10.1.1. </del> <ins> 10.2.1. </ins> If a client wants to create a subgroup of an existing group, they MAY choose to include a "PreSharedKeyID" in the "GroupSecrets" object of

Related discussion:
text: This PR adds a RequiredCapabilities extension that allows the members of a group to impose a requirement that new joiners support certain capabilities. The extension is carried in the GroupContext and verified at Add time (including on external commits). In the interim 2021-10-04, we briefly discussed whether this mechanism needed to be included in the core protocol. Because of its interactions with Add and GroupContextExtensions proposals, it seems worth having in the main protocol.
s currently have two usages in the spec: Pre-published key packages that you can download and put in a leaf when adding a new member leaf node content that you update when doing a full Currently, things have been designed to use only one structure for both uses, leading to some weirdness such as: and are useful in the usage 1, but are parameters of the group in usage 2. is a good name in usage 1, but would better be named in usage 2. some data is important in usage 2 and have no meaning in usage 1, hence they were designed as "mandatory-when-updating extensions" (such as , and we were also discussing about adding the in to help prevent cross-group attacks) How about using different structures for these? // Essentially identical to KeyPackage struct { ProtocolVersion version; CipherSuite ciphersuite; HPKEPublicKey hpkeinitkey; opaque endpointid; Credential credential; Extension extensions; opaque signature; } PrePublishedKeyPackage; struct { HPKEPublicKey hpkekey; opaque endpointid; Credential credential; opaque parenthash; opaque groupid; Extension extensions; opaque signature; } LeafNodeContent; enum { reserved(0), prepublishedkeypackage(1), leafnodecontent(2), (255) } LeafNodeType; struct LeafNode { // This is not included in the signature, but with the "unambiguous signature" PR that's not a problem LeafNodeType type; select(URL) { case prepublishedkeypackage: PrePublishedKeyPackage data; case leafnode_content: LeafNodeContent data; } } What would you think about refactoring like this?
If we're doing this, I'd suggest including a dedicated public key to encrypt Welcome messages to for the . NAME suggested this at some point.
Code change:
object must be a randomly sampled nonce of length "KDF.Nh" to avoid key re-use. <del> 10.1.1. </del> <ins> 10.2.1. </ins> If a client wants to create a subgroup of an existing group, they MAY choose to include a "PreSharedKeyID" in the "GroupSecrets" object of

Related discussion:
text: It gives us better FS guarantees, because the receiver of the can delete the corresponding private key immediately after decryption, while they might have to keep the other key around for a bit until they can actually issue an update. This might also help clarify .
Ties into as well because is an example of an extension that is required and should be a field instead
NAME one concern I have is how is that field in created?
When sending a full , the participant includes a new in the (it replaces the field). It computes the signature with where: corresponds to all the fields of except (the usual thing) comes from
What about the scenario where Alice pulls down Bob's key package to add him to the group? In that case Alice can't do the conversion between formats on Bob's behalf.
Alice don't have to do the conversion, this is why either contain a (when adding someone to the group) or a (when updating your own key package).
Ah somehow I missed that part in your original post. Makes sense
I like this general direction. It solves a few things. Instead of having leaf nodes contain either a prepublished thing or a normal leaf node, how about having the prepublished thing wrap the leaf node thing? As a bonus, we get separation between the key pair used for Welcome encryption and the key pair that goes in the leaf for TreeKEM. Then when Alice adds Bob, she extracts his LeafNodeContent and sends that in the Add. That doesn't let the other members of the group verify that Alice did the right thing w.r.t. expiry, but I'm not heartbroken about that. We might also be able to remove the extensions field from the outer (KeyPackage) wrapping if we turn the extension into KeyPackage field. I expect we probably need leaf extensions, but would be open to making into a field.
Why not keep sending the KeyPackage in the Add? That wouldn't cost much and would allow everyone to validate the lifetime. Note, that the lifetime is crucial in achieving PCS for pre-published key material. If I compromise Bob and get hold of the private key material of a bunch of his KeyPackages, I can add "Bob" to any group I want as long as the Credential inside the LeafNodeContent remains valid and Bob doesn't revoke the LeafNodeContent somehow.
Code change:
object must be a randomly sampled nonce of length "KDF.Nh" to avoid key re-use. <del> 10.1.1. </del> <ins> 10.2.1. </ins> If a client wants to create a subgroup of an existing group, they MAY choose to include a "PreSharedKeyID" in the "GroupSecrets" object of

Related discussion:
text: Also, we'll have to do this if we want to enable any member to send the Welcome message as you proposed here: URL
I agree that including inside is quite clean, but something is bothering me with this approach: I'd like that the is signed by the participant occupying that leaf, to protect against cross-group attacks. In the first message of this issue I did this by including in , but in fact we don't need to store it in the leaf, we just need to include it in the . In any case, if we want to include in the signature, we need a way to differentiate between leaves that triggered a commit and the ones that are "fresh". And for that I think using a tagged-union struct is the cleanest way to do it.
It always feels a bit lazy to use an extension (and implementations have to be careful to check for their presence), but we could use a extension in the same way that we use a extension. You will find both of them only on LeafContents that were updated at least once. Another result of including GroupId in the KeyPackage is that the signature will explicitly sign the and I'm not sure if that doesn't completely destroy any deniability guarantees we can still get from MLS.
I don't think there's really a good way to get the into the leaf. Because of prepublication, it would have to be optional, but in order to prevent attacks, you need rules to decide whether it's required in a given situation. It seems like the best you can do is basically TOFU: When you first get the tree, you can't validate whether the groupid should be in a given leaf or not Once you're a member, you require that groupid is sent in Update and UpdatePath.leafkey_package I could live with a solution of that character, but given it's a bit complex, might prefer to leave it out unless we get a useful property from it. NAME - Re: Sending KeyPackage in Add - Yep, that makes sense. So you would send KeyPackage in Add, and LeafNode in Update.
I tried to worked through what would be necessary to implement this. It looks like it would require some fairly invasive changes to be made to rationalize the document's structure before making this change. But those changes should probably be made anyway.
Code change:
object must be a randomly sampled nonce of length "KDF.Nh" to avoid key re-use. <del> 10.1.1. </del> <ins> 10.2.1. </ins> If a client wants to create a subgroup of an existing group, they MAY choose to include a "PreSharedKeyID" in the "GroupSecrets" object of

Related discussion:
text: Proposal: Preparatory PR: Rationalize layout Move "Cryptograhic Objects" to before "Ratchet Trees" Update "Ratchet Tree Nodes" to define ParentNode and LeafNode structs, with LeafNode initially just equal to KeyPackage Move subsections of "Key Packages" to under "Ratchet Trees" Parent Hash Tree Hashes Update Paths Move Group State to its own top-level section Main PR: Change LeafNode to have the required content: HPKE key for TreeKEM Credential Parent hash Capabilities Extensions Signature Change KeyPackage to refer to LeafNode for internals, plus: HPKE key for Welcome Lifetime Extensions Signature Add continues to send KeyPackage Update and Commit send LeafNode instead of KeyPackage Remove and Sender refer to LeafNodeRef instead of KeyPackageRef We should probably do the preparatory PR regardless of this issue.
Discussion on working call: General agreement on the approach Should sign group_id when possible Include in TBS if we at least have a flag for pre-published / in-group Or we can store it Or we could have independent structs for pre-published / in-group leaves Do we need extensions at both levels? Capabilities / lifetime should probably be promoted to fields
Many protocols which have an extensibility mechanism have a way to indicate that understanding an extension is mandatory for certain behaviors. For MLS, this would mean having a way to require a member understand an MLS extension before it can join a group. The three extension types defined currently are: MLS ciphersuites, MLS extension types, and MLS credential types. One logical way to add mandatory extensions would be to pick one of these types (the MLS extensions type) and use the high order bit or a specific range to indicate that a member must understand and implement the extension to join a group which uses that extension. The IANA values could be changed as follows: Values from 0x8000-0xffff indicate understanding the extension is required 0x7f00 - 0x7fff Reserved for Private Use (not required) 0xff00 - 0xfff Reserved for Private Use (required) If a required ciphersuite or credential becomes necessary, a new extension type could be created to add an extension in the KeyPackage or GroupInfo which would be required and would indicate support for the mandatory ciphersuites or credentials.
Code change:
object must be a randomly sampled nonce of length "KDF.Nh" to avoid key re-use. <del> 10.1.1. </del> <ins> 10.2.1. </ins> If a client wants to create a subgroup of an existing group, they MAY choose to include a "PreSharedKeyID" in the "GroupSecrets" object of

Related discussion:
text: In order to prevent some other entity from adding an MLS client that does not support a mandatory extension, we already have the KeyPackage Client Capabilities, which lists which extensions are supported by the client.
Note that though this might seem "now or never", I don't think it really is. Consider TLS by way of analogy -- it has no mechanism for specifying that extensions are required. But if a server gets a ClientHello that is missing some extension that it requires, it can just abort the handshake. Likewise in MLS, the member adding a new joiner to the group can examine that joiner's KeyPackage to see if they support the extensions needed for the group. So I think you could implement this as a non-mandatory GroupContext extension, which would state the extensions required by the group so that all members apply the same requirements for new joiners.
While you can implement this "out-of-band", that makes it implicit rather than explicit behavior.
Discussed at 20211004 interim, liked this functionality. But, instead of IANA registry use field (or extension) in group context to indicate which extensions are required. NAME to generate PR.
Discussed with NAME and incorporated this functionality into PR
Code change:
groups marked "No" range from "good" to "bad" from a cryptographic standpoint. <ins> If an item is not marked as recommended it does not necessarily mean that it is flawed; rather, it indicates that either the item has not been through the IETF consensus process, has limited applicability, or is intended only for specific use cases. </ins> The designated expert RFC8126 only ensures that the specification is publicly available.  An Internet Draft that is posted and never published or a standard in another standards body, industry

Related discussion:
text: NAME PTAL
LGTM - ‘twas just a comment anyway. W I don't think the execution is relevant when it was obviously a bad idea in the first place. This is like putting rabid weasels in your pants, and later expressing regret at having chosen those particular rabid weasels and that pair of pants. ---maf
Code change:
6.2. Message Framers generate an event whenever a Connection sends a new <del> Message. </del> <ins> Message.  The parameters to the event align with the Send call in the API (Section 9.2 of I-D.ietf-taps-interface). </ins> Upon receiving this event, a framer implementation is responsible for performing any necessary transformations and sending the resulting

Related discussion:
text: Capitalization seems to be a problem for us. We need to make things uniform. At first, I reacted to seeing "connection" as parameters in this PR, because we use the term "Connection" to refer to a TAPS-provided connection (as opposed to a connection of the underlying system), and so, de-capitalizing the term here may look better, but it is also somewhat imprecise. This said, we do the same with other capitalized terms too, here and in the API draft - e.g., "messageContext". Should we generally agree to begin terms with a lowercase letter when they are used as parameters in code examples? I think we have this in most places, though at least the API draft has several counterexamples... e.g., the server example code: Preconnection := NewPreconnection(LocalSpecifier, TransportProperties, SecurityParameters) (..) Listener -> ConnectionReceived
From discussion on
This was a mistake. As I wanted to do this now, I noticed that all occurrences of capitalized terms as parameters are objects that are defined and used elsewhere in the code examples. For example: Preconnection := NewPreconnection(RemoteSpecifier, TransportProperties, SecurityParameters) refers to RemoteSpecifier etc., being objects that are initialized some lines above. Making them appear in lower case everywhere would be awkward, this is then a much more drastic change to our pseudocode. As a result, I think it's fine to leave things as they are, and I suggest to close this issue with no action.
Framers: What is the difference between the Final message property and the separate IsEndOfMessage event argument?
Also there, the term MessageContext could use a definition
and searching "isEndOfMessage" tells me that there is no text describing this parameter. Regarding the question, the difference should be clear: seems self-explanatory, whereas indicates that the Message carrying it is the last one of the Connection. So, this is End of the Message vs. End of the Connection.
Sounds like this needs a reference to the API doc, and change IsEndOfMessage to endOfMessage to match the API.
Probably fix with
I think this looks ok (and thanks for doing this!), but see also my comment about making things uniform wrt.
Code change:
6.2. Message Framers generate an event whenever a Connection sends a new <del> Message. </del> <ins> Message.  The parameters to the event align with the Send call in the API (Section 9.2 of I-D.ietf-taps-interface). </ins> Upon receiving this event, a framer implementation is responsible for performing any necessary transformations and sending the resulting

Related discussion:
text: capitalization: if we merge this PR, we should also do one that does the same with the API draft.Thanks LGTM! Although I noticed another nit that can perhaps be fixed in the same PR even if not directly related to the parameter names. Regarding the capitalization I think we can merge this PR and then have a separate issue for the capitalization as we will need to fix this either way.
Code change:
13. <del> QUIC provides integrity protection for its version negotiation process.  This process assumes that the set of versions that a server supports is fixed.  This complicates the process for deploying new QUIC versions or disabling old versions when servers operate in </del> <ins> QUIC version 1 does not specify a version negotation mechanism in the base spec but I-D.draft-ietf-quic-version-negotiation proposes an extension.  This process assumes that the set of versions that a server supports is fixed.  This complicates the process for deploying new QUIC versions or disabling old versions when servers operate in </ins> clusters. A server that rolls out a new version of QUIC can do so in three

Related discussion:
text: process assumes that the set of versions that a server supports is fixed. This complicates the process for deploying new QUIC versions or disabling old versions when servers operate in clusters. This functionality was removed from -transport, and appears to refer to text in draft-ietf-quic-version-negotiation, but that draft isn't referenced at all.
I can add a reference to draft-ietf-quic-version-negotiation and make clear that this is an extension and not part of the base spec.
Code change:
be sent in multiple parts. Protocols that provide the framing (such as length-value protocols, <del> or protocols that use delimiters) provide data boundaries that may be longer than the typical datagram.  Each Message for framing protocols </del> <ins> or protocols that use delimiters) may support Message sizes that do not fit within a single datagram.  Each Message for framing protocols </ins> corresponds to a single frame, which may be sent either as a complete <del> Message, or in multiple parts. </del> <ins> Message in the underlying protocol, or in multiple parts. </ins> 5.1.

Related discussion:
text: Now I feel like I'm shaving the yak. This is more than what we talked about in the interim, but it felt like the following sentence required additional clarity. Let me know if I misunderstood the intended meaning, in which case I will rephrase.
Code change:
acknowledgment (see sending-acknowledgements). A packet that does not increase the largest received packet number <del> for its packet number space by exactly one.  A packet can arrive out of order if it is delayed or if earlier packets are lost or delayed. </del> <ins> for its packet number space (packet-numbers) by exactly one.  A packet can arrive out of order if it is delayed or if earlier packets are lost or delayed. </ins> An entity that can participate in a QUIC connection by generating, receiving, and processing QUIC packets.  There are only two types

Related discussion:
text: Fixes issue
Sect. 7 in transport refers to packer number spaces without any reference to what that might mean. These are only introduced later in sect. 12.3. Also the text talks about crypto sequence numbers and the text is not very clear about these being different from packet numbers if you haven't been through TLS text.
This is still an issue. I think adding references to where packet number spaces are mentioned (List of Common Terms and Section 7) would be sufficient.
Sounds great, would you be willing to write a PR NAME
Fixed in .
Code change:
RFC7657 apply. The Capacity Profile for a selected protocol stack may be modified on <del> a per-Message basis using the Transmission Profile Message Context Property; see send-profile. </del> <ins> a per-Message basis using the Transmission Profile Message Property; see send-profile. </ins> 9.2.

Related discussion:
text: Message Context Parameters/Properties are now Message Properties, and associated terminology cleanup. Addresses part of the resolution to .
Looks good, thanks for the cleanup!LGTM
Code change:
The comparison "a <= b" yields true if and only if "a < b" yields true or "a == b" yields true. <del> The comparison "a >= b" yields true if and only if "a > b" yields </del> <ins> The comparison "a > b" yields true if and only if "b < a" yields true. The comparison "a >= b" yields true if and only if "b < a" yields </ins> true or "a == b" yields true. 3.5.5.2.3.

Related discussion:
text: Fixes URL
Thanks for your comments NAME and NAME I feel I should explain. The current draft defines the orderings and using the same text. For strings, the text talks about "less than" but not "greater than". So the current text implicitly assumes that for strings and , if and only if . Non-mathematicians would tend to say this is patently obvious. But this PR avoids that assumption by only defining using the same text and then defining in terms of . However, I take the point about the standalone definitions and the arbitrariness of defining one in terms of the other. So my question is: is the current draft text sufficiently precise? If not, I'll rework this PR to make it more precise. (When I started out doing that, it began to get quite wordy, so I changed tack.)
Despite the fact, that Glyn's approach is mathematically clean, I would favour the symmetric approach by defining , ,. I am quite sure, that nobody will cry "redundancy" then.
Yes. Is that a problem? comes before ...
Actually, on the symmetry point, we were comfortable defining in terms of and that was asymmetric.
In what system of mathematics are operations ordered? This is completely arbitrary. I'm not convinced this needs to change. I prefer defining both and . And for symmetry, I'd change strings to match.
Applying editorial discretion here. Merging.
The current spec defines string comparison using one of the operators , , , or in terms of when one string is less than another. That's fine for , but: for it effectively assumes is fixed (i.e. that for strings and if or ) for and it leaves quite a lot to the reader's imagination. Once we've settled on , the above should be addressed. ~We should also adopt a similar approach for ordered comparisons () of arrays if is adopted.~ (It wasn't.) (I labelled this issue as because I don't believe it will change the intended semantics in either case.)
I propose to let URL land before addressing this issue.
I personally prefer the previous version, with standalone definitions, but think this is a matter of editorial discretion.I agree with Tim. It's fine and correct to define in terms of other operators, but I feel and should both be equally defined.
Code change:
The comparison "a <= b" yields true if and only if "a < b" yields true or "a == b" yields true. <del> The comparison "a >= b" yields true if and only if "a > b" yields </del> <ins> The comparison "a > b" yields true if and only if "b < a" yields true. The comparison "a >= b" yields true if and only if "b < a" yields </ins> true or "a == b" yields true. 3.5.5.2.3.

Related discussion:
text: Defining one in terms of the other means you have to make an arbitrary choice of which is directly defined and which is indirectly defined.This PR is exactly the right way to do this.