Draft: draft-ietf-mls-protocol

Commentary: With regard to : I searched for references to MLSPlaintext and Credential that were obsolete in light of the change to the MLSMessage framework . ( In particular , we used to have the idea that you would encode things as MLSPlaintext , then tranform them to MLSCiphertext if needed ; now you encode to AuthenticatedContent and then convert that to MLSPlaintext / MLSCiphertext before sending . ) There were a few fixes for MLSPlaintext ; I did n't find anything that needed fixing for Credentia , largely thanks to some PRs that have landed since I did the review that resulted in . 
 Does anyone know why the MLS draft uses the " MLS " prefix for some structs , e.g. , and not just ? Is there ( still ) some logic behind this ? None of the explanations I could come up with hold for all structs . Maybe this is something that just evolved over the years ? If so , I would be happy to make an editorial PR to remove all of those :-) 
 Historic ... , and from RFC 8446 This also helps disambiguating between message formats 
 Can you say more ? One of my theories was that it was used to avoid naming collisions with other possibly " imported " structs from other RFCs . But its and not , so ... :-) 
 Eg . A " plaintext " can be pretty much anything like a containing an while an MLSPlaintext has a specific format content . Structures which have more internal constraints on their values have less chances to be confused with each other . 
 First of all , sorry if I widen the scope of this issue a bit . But when you said that the terminology comes from TLS , it clicked . When I started to work with MLS a few weeks ago , I got confused by the term MLSPlaintext . In TLS , a TLSPlaintext is not protected and only used as a stepping stone . This is different in MLS because an MLSPlaintext is always signed and not " converted " into an MLSCiphertext afterwards.¹ It seems close to TLS but is n't . Which brings me back to the " MLS " prefix thing . Not sure how peoples ' heads work , but mine tries to get rid of not useful information such as an " MLS " prefix . And when we remove all " MLS " prefixes , it becomes more clear that  is probably not the right term to describe a signed message . The prefix " MLS " in MLSPlaintext blurries that because now we have something " MLS - specific " . But still , it has " plaintext " in its name . Also , I thought that -- similar to the fact that " ... TBS " is " never send over the wire " -- the " MLS " prefix denotes things that are send over the wire -- which is not true , e.g. , in the case of MLSContentTBS . Furthermore , the MLS prefix makes MLSCiphertext and MLSPlaintext stand out in ... What makes these variants different ? What would have made more sense to me is something like ... However , I have no good idea what a much better name would be . and is a bit better IMO but clunky . ¹ This was the case in the past , see 
 For correctness , this was done in . Before this PR , the procedure was to generate an MLSPlaintext and convert it to an MLSCiphertext . I this this is an heritage of TLS 1.3 which does the same thing ( ) . After this PR , the procedure is to generate a MLSContent and convert it to MLSPlaintext or MLSCiphertext . Otherwise I agree , it would be nice to have consistent names in the document ! 
 I agree that the current use of " MLS " in struct names is inconsistent , and MLSPlaintext / MLSCiphertext are n't accurate for what those messages do now . This will be a large - ish change , but probably worth doing to increase clarity . I did an audit of struct names in the document and tried to think through what else they could be called . Here 's a proposal : The latter two are the most challenging . It 's difficult to get across precisely what they 're about without getting super verbose . Another route would be to use something like SignedMessage and EncryptedMessage . 
 Thanks for bringing this up and thanks for the proposal I like the proposed changes , although might I suggest the prefix " Message " instead of " Group " for -Content -ContentTBS and -ContentAuthData ? It is targeted to a group , but it 's really the core content of a message . 
 Thanks , This looks really promising ! and are the best terms I heard so far . While we 're at it , should we add a " ... TBE " ( To - Be - Encrypted ) to the ( possibly new ) ? While the , and appendices may seem intimidating at first , they provide a very good idea where to expect ( and how to use ) them . 
 There are still several references to in the old sense . These should pretty much all be changed to . should be in some places ( e.g. , ) 
 The collection of structs could be less chatty . Suggest PreSharedKeys is only used once , can be inlined in GroupSecrets Use GroupContext for the internals of GroupInfo 
 Note : was fixed in In , we did : So only the following remain : Use GroupContext for the internals of GroupInfo 
 Here 's the Weekly Digest for : - - Last week 8 issues were created . Of these , 0 issues have been closed and 8 issues are still open . : greenheart : , by : greenheart : , by : greenheart : , by : greenheart : , by : greenheart : , by : greenheart : , by : greenheart : , by : greenheart : , by : speaker : , by It received 1 comments . - - Last week , 6 pull requests were created , updated or merged . Last week , 1 pull request was opened . : greenheart : , by Last week , 3 pull requests were updated . : yellowheart : , by : yellowheart : , by : yellowheart : , by Last week , 2 pull requests were merged . : purpleheart : , by : purpleheart : , by - - Last week there were 10 commits . : hammerandwrench : by : hammerandwrench : by : hammerandwrench : by : hammerandwrench : by : hammerandwrench : by : hammerandwrench : by : hammerandwrench : by : hammerandwrench : by : hammerandwrench : by : hammerandwrench : by - - Last week there were 2 contributors . : bustinsilhouette : : bustin_silhouette : - - Last week there was 1 stargazer . : star : You are the star ! : star2 : - - Last week there were no releases . - - That 's all for last week , please < kbd : eyes : Watch</kbdand < kbd : star : Star</kbdthe repository to receive next weekly updates . : smiley : You can also .
Paragraph (version A):
The signature algorithm specified in the ciphersuite is the mandatory
algorithm to be used for signatures in MLSMessageAuth and the tree
signatures.  It MUST be the same as the signature algorithm specified
in the credentials in the leaves of the tree (including the leaf node
information in KeyPackages used to add new members).
Paragraph (version B):
The signature algorithm specified in the ciphersuite is the mandatory
algorithm to be used for signatures in MLSContentAuthData and the
tree signatures.  It MUST be the same as the signature algorithm
specified in the credentials in the leaves of the tree (including the
leaf node information in KeyPackages used to add new members).
Paragraph (version A):
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 MLSMessageContentAuth
carrying the proposal.  In the latter two cases, the KDF is
determined by the group's ciphersuite.
Paragraph (version B):
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
carrying the proposal.  In the latter two cases, the KDF is
determined by the group's ciphersuite.
Paragraph (version A):
The main structure is MLSMessageContent, which contains the content
of the message.  This structure is authenticated using MLSMessageAuth
(see content-authentication).  The two structures are combined in
MLSMessageContentAuth, which can then be encoded/decoded from/to
MLSPlaintext or MLSCiphertext, which are then included in the
MLSMessage structure.
Paragraph (version B):
In most of the protocol, messages are handled in the form of
MLSAuthenticatedContent objects.  These structures contain the
content of the message itself as well as information to authenticate
the sender (see content-authentication).  The additional protections
required to transmit these messages over an untrusted channel (group
membership authentication or AEAD encryption) are added by encoding
the MLSAuthenticatedContent as an MLSPlaintext or MLSCiphertext
message, which can then be sent as an MLSMessage.  Likewise, these
protections are enforced (via membership verification or AEAD
decryption) when decoding an MLSPlaintext or MLSCiphertext into an
MLSAuthenticatedContent object.
Paragraph (version A):
External sender types are sent as MLSPlaintext, see external-
proposals for their use.
Paragraph (version B):
Messages from senders that aren't in the group are sent as
MLSPlaintext.  See external-proposals and joining-via-external-
commits for more details.
Paragraph (version A):
MLSMessageContent is authenticated using the MLSMessageAuth
structure.
Paragraph (version A):
The signature is computed using "SignWithLabel" with label
""MLSMessageContentTBS"" and with a content that covers the message
content and the wire format that will be used for this message.  If
the sender's "sender_type" is "member", the content also covers the
GroupContext for the current epoch so that signatures are specific to
a given group and epoch.
Paragraph (version B):
MLSContent is authenticated using the MLSContentAuthData structure.
Paragraph (version B):
The signature is computed using "SignWithLabel" with label
""MLSContentTBS"" and with a content that covers the message content
and the wire format that will be used for this message.  If the
sender's "sender_type" is "member", the content also covers the
GroupContext for the current epoch so that signatures are specific to
a given group and epoch.
Paragraph (version A):
The confirmation tag value confirms that the members of the group
have arrived at the same state of the group.  An MLSMessageAuth is
said to be valid when both the "signature" and "confirmation_tag"
fields are valid.
Paragraph (version B):
The confirmation tag value confirms that the members of the group
have arrived at the same state of the group.  A MLSContentAuthData is
said to be valid when both the "signature" and "confirmation_tag"
fields are valid.
Paragraph (version A):
When decoding an MLSPlaintext into an MLSMessageContentAuth, the
application MUST check "membership_tag" and MUST check that the
MLSMessageAuth is valid.
Paragraph (version B):
When decoding an MLSPlaintext into an MLSAuthenticatedContent, the
application MUST check "membership_tag" and MUST check that the
MLSContentAuthData is valid.
Paragraph (version A):
When decoding an MLSCiphertextContent, the application MUST check
that the MLSMessageAuth is valid.
Paragraph (version B):
When decoding an MLSCiphertextContent, the application MUST check
that the MLSContentAuthData is valid.
Paragraph (version A):
The "confirmed_transcript_hash" field is updated with the data for
an MLSPlaintext message encoding a Commit message as described
below.
Paragraph (version B):
The "confirmed_transcript_hash" field is updated with the data for
an MLSAuthenticatedContent encoding a Commit message as described
below.
Paragraph (version A):
The transcript hashes computed in MLS represent a running hash over
all Proposal and Commit messages that have ever been sent in a group.
Commit messages are included directly.  Proposal messages are
indirectly included via the Commit that applied them.  Both types of
message are included by hashing the MLSPlaintext in which they were
sent.
Paragraph (version B):
The transcript hashes computed in MLS represent a running hash over
all Proposal and Commit messages that have ever been sent in a group.
Commit messages are included directly.  Proposal messages are
indirectly included via the Commit that applied them.  Both types of
message are included by hashing the MLSAuthenticatedContent object in
which they were sent.
Paragraph (version A):
Each Commit message updates these hashes by way of its enclosing
MLSMessageContentAuth.  The MLSMessageContentAuth struct is split
into ConfirmedTranscriptHashInput and InterimTranscriptHashInput.
The former is used to update the confirmed transcript hash and the
latter to update the interim transcript hash.
Paragraph (version B):
Each Commit message updates these hashes by way of its enclosing
MLSAuthenticatedContent.  The MLSAuthenticatedContent struct is split
into ConfirmedTranscriptHashInput and InterimTranscriptHashInput.
The former is used to update the confirmed transcript hash and the
latter to update the interim transcript hash.
Paragraph (version A):
On receiving an MLSMessageContent containing a Proposal, a client
MUST verify the signature inside MLSMessageAuth and that the "epoch"
field of the enclosing MLSMessageContent is equal to the "epoch"
field of the current GroupContext object.  If the verification is
successful, then the Proposal should be cached in such a way that it
can be retrieved by hash (as a ProposalOrRef object) in a later
Commit message.
Paragraph (version B):
On receiving an MLSContent containing a Proposal, a client MUST
verify the signature inside MLSContentAuthData and that the "epoch"
field of the enclosing MLSContent is equal to the "epoch" field of
the current GroupContext object.  If the verification is successful,
then the Proposal should be cached in such a way that it can be
retrieved by hash (as a ProposalOrRef object) in a later Commit
message.
Paragraph (version A):
Each proposal covered by the Commit is included by a ProposalOrRef
value, which identifies the proposal to be applied by value or by
reference.  Commits that refer to new Proposals from the committer
can be included by value.  Commits for previously sent proposals from
anyone (including the committer) can be sent by reference.  Proposals
sent by reference are specified by including the hash of the
MLSPlaintext in which the proposal was sent (see hash-based-
identifiers).
Paragraph (version B):
Each proposal covered by the Commit is included by a ProposalOrRef
value, which identifies the proposal to be applied by value or by
reference.  Commits that refer to new Proposals from the committer
can be included by value.  Commits for previously sent proposals from
anyone (including the committer) can be sent by reference.  Proposals
sent by reference are specified by including the hash of the
MLSAuthenticatedContent object in which the proposal was sent (see
hash-based-identifiers).
Paragraph (version A):
Construct an MLSMessageContent object containing the Commit
object.  Sign the MLSMessageContent using the old GroupContext as
context.
Paragraph (version A):
Use the MLSMessageContent to update the confirmed transcript
hash and update the new GroupContext.
Paragraph (version B):
Construct an MLSContent object containing the Commit object.  Sign
the MLSContent using the old GroupContext as context.
Paragraph (version B):
Use the MLSContent to update the confirmed transcript hash and
update the new GroupContext.
Paragraph (version A):
Use the "confirmation_key" for the new epoch to compute the
"confirmation_tag" value, and the "membership_key" for the old
epoch to compute the "membership_tag" value in the
MLSPlaintext.
Paragraph (version A):
Calculate the interim transcript hash using the new confirmed
transcript hash and the "confirmation_tag" from the
MLSMessageAuth.
Paragraph (version B):
Use the "confirmation_key" for the new epoch to compute the
"confirmation_tag" value.
Paragraph (version B):
Calculate the interim transcript hash using the new confirmed
transcript hash and the "confirmation_tag" from the
MLSContentAuthData.
Paragraph (version B):
If encoding as MLSPlaintext, compute the "membership_tag" value
using the "membership_key".
Paragraph (version B):
If encoding as an MLSCiphertext, encrypt the message using the
"sender_data_secret" and the next (key, nonce) pair from the
sender's handshake ratchet.
Paragraph (version A):
Verify that the signature on the MLSMessageContent message as
described in Section content-authentication.
Paragraph (version B):
If the message is encoded as MLSCiphertext, decrypt the message
using the "sender_data_secret" and the (key, nonce) pair from
the step on the sender's hash ratchet indicated by the
"generation" field.
Paragraph (version B):
Verify that the signature on the MLSContent message as described
in Section content-authentication.
Paragraph (version A):
Use the "confirmation_key" for the new epoch to compute the
confirmation tag for this message, as described below, and verify
that it is the same as the "confirmation_tag" field in the
MLSMessageAuth object.
Paragraph (version B):
Use the "confirmation_key" for the new epoch to compute the
confirmation tag for this message, as described below, and verify
that it is the same as the "confirmation_tag" field in the
MLSContentAuthData object.
Paragraph (version A):
In other words, to join a group via an External Commit, a new member
needs a GroupInfo with an "ExternalPub" extension present in the
"other_extensions".
Paragraph (version B):
In other words, to join a group via an External Commit, a new member
needs a GroupInfo with an "ExternalPub" extension present in its
"extensions" field.
Paragraph (version A):
External Commits MUST be signed by the new member.  In particular,
the signature on the enclosing MLSPlaintext MUST verify using the
public key for the credential in the "leaf_node" of the "path"
field.
Paragraph (version B):
External Commits MUST be signed by the new member.  In particular,
the signature on the enclosing MLSAuthenticatedContent MUST verify
using the public key for the credential in the "leaf_node" of the
"path" field.
Paragraph (version A):
The GroupContext contains the "group_id", "epoch", "tree_hash",
"confirmed_transcript_hash", and "group_context_extensions"
fields from the GroupInfo object.
Paragraph (version B):
The GroupContext is the "group_context" field from the
GroupInfo object.
Paragraph (version A):
In other words, an application can use GroupContext extensions to
ensure that all members of the group agree on a set of parameters.
Clients indicate their support for parameters in the "capabilities"
field of their LeafNode.  New members of a group are informed of the
group's GroupContext extensions via the "group_context_extensions"
field in the GroupInfo object.  The "other_extensions" field in a
GroupInfo object can be used to provide additional parameters to new
joiners that are used to join the group.
Paragraph (version B):
In other words, an application can use GroupContext extensions to
ensure that all members of the group agree on a set of parameters.
Clients indicate their support for parameters in the "capabilities"
field of their LeafNode.  New members of a group are informed of the
group's GroupContext extensions via the "extensions" field in the
"group_context" field of the GroupInfo object.  The "extensions"
field in a GroupInfo object (outside of the "group_context" field)
can be used to provide additional parameters to new joiners that are
used to join the group.
Paragraph (version A):
Each Commit message is premised on a given starting state, indicated
by the "epoch" field of the enclosing MLSMessageContent.  If the
changes implied by a Commit message are made starting from a
different state, the results will be incorrect.
Paragraph (version B):
Each Commit message is premised on a given starting state, indicated
by the "epoch" field of the enclosing MLSContent.  If the changes
implied by a Commit message are made starting from a different state,
the results will be incorrect.