<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc2629 version 1.3.23 -->

<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
]>

<?rfc toc="yes"?>
<?rfc sortrefs="yes"?>
<?rfc symrefs="yes"?>

<rfc ipr="trust200902" docName="draft-ietf-mls-protocol-11" category="info">

  <front>
    <title abbrev="MLS">The Messaging Layer Security (MLS) Protocol</title>

    <author initials="R." surname="Barnes" fullname="Richard Barnes">
      <organization>Cisco</organization>
      <address>
        <email>rlb@ipv.sx</email>
      </address>
    </author>
    <author initials="B." surname="Beurdouche" fullname="Benjamin Beurdouche">
      <organization>Inria</organization>
      <address>
        <email>benjamin.beurdouche@inria.fr</email>
      </address>
    </author>
    <author initials="J." surname="Millican" fullname="Jon Millican">
      <organization>Facebook</organization>
      <address>
        <email>jmillican@fb.com</email>
      </address>
    </author>
    <author initials="E." surname="Omara" fullname="Emad Omara">
      <organization>Google</organization>
      <address>
        <email>emadomara@google.com</email>
      </address>
    </author>
    <author initials="K." surname="Cohn-Gordon" fullname="Katriel Cohn-Gordon">
      <organization>University of Oxford</organization>
      <address>
        <email>me@katriel.co.uk</email>
      </address>
    </author>
    <author initials="R." surname="Robert" fullname="Raphael Robert">
      <organization>Wire</organization>
      <address>
        <email>raphael@wire.com</email>
      </address>
    </author>

    <date year="2020" month="December" day="22"/>

    <area>Security</area>
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<t>Messaging applications are increasingly making use of end-to-end
security mechanisms to ensure that messages are only accessible to
the communicating endpoints, and not to any servers involved in delivering
messages.  Establishing keys to provide such protections is
challenging for group chat settings, in which more than two
clients need to agree on a key but may not be online at the same
time.  In this document, we specify a key establishment
protocol that provides efficient asynchronous group key establishment
with forward secrecy and post-compromise security for groups
in size ranging from two to thousands.</t>



    </abstract>


  </front>

  <middle>


<section anchor="introduction" title="Introduction">

<t>DISCLAIMER: This is a work-in-progress draft of MLS and has not yet
seen significant security analysis. It should not be used as a basis
for building production systems.</t>

<t>RFC EDITOR: PLEASE REMOVE THE FOLLOWING PARAGRAPH The source for
this draft is maintained in GitHub. Suggested changes should be
submitted as pull requests at https://github.com/mlswg/mls-protocol.
Instructions are on that page as well. Editorial changes can be
managed in GitHub, but any substantive change should be discussed on
the MLS mailing list.</t>

<t>A group of users who want to send each other encrypted messages needs
a way to derive shared symmetric encryption keys. For two parties,
this problem has been studied thoroughly, with the Double Ratchet
emerging as a common solution <xref target="doubleratchet"/> <xref target="signal"/>.
Channels implementing the Double Ratchet enjoy fine-grained forward secrecy
as well as post-compromise security, but are nonetheless efficient
enough for heavy use over low-bandwidth networks.</t>

<t>For a group of size greater than two, a common strategy is to
unilaterally broadcast symmetric "sender" keys over existing shared
symmetric channels, and then for each member to send messages to the
group encrypted with their own sender key. Unfortunately, while this
improves efficiency over pairwise broadcast of individual messages and
provides forward secrecy (with the addition of a hash ratchet),
it is difficult to achieve post-compromise security with
sender keys. An adversary who learns a sender key can often indefinitely and
passively eavesdrop on that member's messages.  Generating and
distributing a new sender key provides a form of post-compromise
security with regard to that sender.  However, it requires
computation and communications resources that scale linearly with
the size of the group.</t>

<t>In this document, we describe a protocol based on tree structures
that enable asynchronous group keying with forward secrecy and
post-compromise security.  Based on earlier work on "asynchronous
ratcheting trees" <xref target="art"/>, the protocol presented here uses an
asynchronous key-encapsulation mechanism for tree structures.
This mechanism allows the members of the group to derive and update
shared keys with costs that scale as the log of the group size.</t>

<section anchor="change-log" title="Change Log">

<t>RFC EDITOR PLEASE DELETE THIS SECTION.</t>

<t>draft-10</t>

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

<t>draft-09</t>

<t><list style="symbols">
  <t>Remove blanking of nodes on Add (*)</t>
  <t>Change epoch numbers to uint64 (*)</t>
  <t>Add PSK inputs (*)</t>
  <t>Add key schedule exporter (*)</t>
  <t>Sign the updated direct path on Commit, using "parent hashes" and one
signature per leaf (*)</t>
  <t>Use structured types for external senders (*)</t>
  <t>Redesign Welcome to include confirmation and use derived keys (*)</t>
  <t>Remove ignored proposals (*)</t>
  <t>Always include an Update with a Commit (*)</t>
  <t>Add per-message entropy to guard against nonce reuse (*)</t>
  <t>Use the same hash ratchet construct for both application and handshake keys (*)</t>
  <t>Add more ciphersuites</t>
  <t>Use HKDF to derive key pairs (*)</t>
  <t>Mandate expiration of ClientInitKeys (*)</t>
  <t>Add extensions to GroupContext and flesh out the extensibility story (*)</t>
  <t>Rename ClientInitKey to KeyPackage</t>
</list></t>

<t>draft-08</t>

<t><list style="symbols">
  <t>Change ClientInitKeys so that they only refer to one ciphersuite (*)</t>
  <t>Decompose group operations into Proposals and Commits (*)</t>
  <t>Enable Add and Remove proposals from outside the group (*)</t>
  <t>Replace Init messages with multi-recipient Welcome message (*)</t>
  <t>Add extensions to ClientInitKeys for expiration and downgrade resistance (*)</t>
  <t>Allow multiple Proposals and a single Commit in one MLSPlaintext (*)</t>
</list></t>

<t>draft-07</t>

<t><list style="symbols">
  <t>Initial version of the Tree based Application Key Schedule (*)</t>
  <t>Initial definition of the Init message for group creation (*)</t>
  <t>Fix issue with the transcript used for newcomers (*)</t>
  <t>Clarifications on message framing and HPKE contexts (*)</t>
</list></t>

<t>draft-06</t>

<t><list style="symbols">
  <t>Reorder blanking and update in the Remove operation (*)</t>
  <t>Rename the GroupState structure to GroupContext (*)</t>
  <t>Rename UserInitKey to ClientInitKey</t>
  <t>Resolve the circular dependency that draft-05 introduced in the
confirmation MAC calculation (*)</t>
  <t>Cover the entire MLSPlaintext in the transcript hash (*)</t>
</list></t>

<t>draft-05</t>

<t><list style="symbols">
  <t>Common framing for handshake and application messages (*)</t>
  <t>Handshake message encryption (*)</t>
  <t>Convert from literal state to a commitment via the "tree hash" (*)</t>
  <t>Add credentials to the tree and remove the "roster" concept (*)</t>
  <t>Remove the secret field from tree node values</t>
</list></t>

<t>draft-04</t>

<t><list style="symbols">
  <t>Updating the language to be similar to the Architecture document</t>
  <t>ECIES is now renamed in favor of HPKE (*)</t>
  <t>Using a KDF instead of a Hash in TreeKEM (*)</t>
</list></t>

<t>draft-03</t>

<t><list style="symbols">
  <t>Added ciphersuites and signature schemes (*)</t>
  <t>Re-ordered fields in UserInitKey to make parsing easier (*)</t>
  <t>Fixed inconsistencies between Welcome and GroupState (*)</t>
  <t>Added encryption of the Welcome message (*)</t>
</list></t>

<t>draft-02</t>

<t><list style="symbols">
  <t>Removed ART (*)</t>
  <t>Allowed partial trees to avoid double-joins (*)</t>
  <t>Added explicit key confirmation (*)</t>
</list></t>

<t>draft-01</t>

<t><list style="symbols">
  <t>Initial description of the Message Protection mechanism. (*)</t>
  <t>Initial specification proposal for the Application Key Schedule
using the per-participant chaining of the Application Secret design. (*)</t>
  <t>Initial specification proposal for an encryption mechanism to protect
Application Messages using an AEAD scheme. (*)</t>
  <t>Initial specification proposal for an authentication mechanism
of Application Messages using signatures. (*)</t>
  <t>Initial specification proposal for a padding mechanism to improving
protection of Application Messages against traffic analysis. (*)</t>
  <t>Inversion of the Group Init Add and Application Secret derivations
in the Handshake Key Schedule to be ease chaining in case we switch
design. (*)</t>
  <t>Removal of the UserAdd construct and split of GroupAdd into Add
and Welcome messages (*)</t>
  <t>Initial proposal for authenticating handshake messages by signing
over group state and including group state in the key schedule (*)</t>
  <t>Added an appendix with example code for tree math</t>
  <t>Changed the ECIES mechanism used by TreeKEM so that it uses nonces
generated from the shared secret</t>
</list></t>

<t>draft-00</t>

<t><list style="symbols">
  <t>Initial adoption of draft-barnes-mls-protocol-01 as a WG item.</t>
</list></t>

</section>
</section>
<section anchor="terminology" title="Terminology">

<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in
BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they appear in all
capitals, as shown here.</t>

<t><list style="hanging">
  <t hangText="Client:">
  An agent that uses this protocol to establish shared cryptographic
state with other clients.  A client is defined by the
cryptographic keys it holds.</t>
  <t hangText="Group:">
  A collection of clients with shared cryptographic state.</t>
  <t hangText="Member:">
  A client that is included in the shared state of a group, hence
has access to the group's secrets.</t>
  <t hangText="Key Package:">
  A signed object describing a client's identity and capabilities, and including
a hybrid public-key encryption (HPKE <xref target="I-D.irtf-cfrg-hpke"/>) public key that
can be used to encrypt to that client.</t>
  <t hangText="Initialization Key (InitKey):">
  A key package that is prepublished by a client, which other clients can use to
introduce the client to a new group.</t>
  <t hangText="Signature Key:">
  A signing key pair used to authenticate the sender of a message.</t>
</list></t>

<t>Terminology specific to tree computations is described in
<xref target="ratchet-trees"/>.</t>

<t>We use the TLS presentation language <xref target="RFC8446"/> to
describe the structure of protocol messages.</t>

</section>
<section anchor="basic-assumptions" title="Basic Assumptions">

<t>This protocol is designed to execute in the context of a Service Provider (SP)
as described in <xref target="I-D.ietf-mls-architecture"/>.  In particular, we assume
the SP provides the following services:</t>

<t><list style="symbols">
  <t>A signature key provider which allows clients to authenticate
protocol messages in a group.</t>
  <t>A broadcast channel, for each group, which will relay a message to all members
of a group.  For the most part, we assume that this channel delivers messages
in the same order to all participants.  (See <xref target="sequencing"/> for further
considerations.)</t>
  <t>A directory to which clients can publish key packages and download
key packages for other participants.</t>
</list></t>

</section>
<section anchor="protocol-overview" title="Protocol Overview">

<t>The goal of this protocol is to allow a group of clients to exchange
confidential and authenticated messages. It does so by deriving a sequence
of secrets and keys known only to members. Those should be secret against an
active network adversary and should have both forward secrecy and
post-compromise security with respect to compromise of any members.</t>

<t>We describe the information stored by each client as <spanx style="emph">state</spanx>, which includes
both public and private data. An initial state is set up by a group creator,
which is a group containing only itself. The creator then sends <spanx style="emph">Add</spanx>
proposals for each client in the initial set of members, followed by a <spanx style="emph">Commit</spanx>
message which incorporates all of the <spanx style="emph">Adds</spanx> into the group state. Finally, the
group creator generates a <spanx style="emph">Welcome</spanx> message corresponding to the Commit and
sends this directly to all the new members, who can use the information
it contains to set up their own group state and derive a shared
secret. Members exchange Commit messages for post-compromise security, to add new
members, and to remove existing members. These messages produce new shared
secrets which are causally linked to their predecessors, forming a logical
Directed Acyclic Graph (DAG) of states.</t>

<t>The protocol algorithms we specify here follow. Each algorithm specifies
both (i) how a client performs the operation and (ii) how other clients
update their state based on it.</t>

<t>There are three major operations in the lifecycle of a group:</t>

<t><list style="symbols">
  <t>Adding a member, initiated by a current member;</t>
  <t>Updating the leaf secret of a member;</t>
  <t>Removing a member.</t>
</list></t>

<t>Each of these operations is "proposed" by sending a message of the corresponding
type (Add / Update / Remove).  The state of the group is not changed, however,
until a Commit message is sent to provide the group with fresh entropy.  In this
section, we show each proposal being committed immediately, but in more advanced
deployment cases an application might gather several proposals before
committing them all at once.</t>

<t>Before the initialization of a group, clients publish InitKeys (as KeyPackage
objects) to a directory provided by the Service Provider.</t>

<figure><artwork><![CDATA[
                                                               Group
A                B                C            Directory       Channel
|                |                |                |              |
| KeyPackageA    |                |                |              |
|------------------------------------------------->|              |
|                |                |                |              |
|                | KeyPackageB    |                |              |
|                |-------------------------------->|              |
|                |                |                |              |
|                |                | KeyPackageC    |              |
|                |                |--------------->|              |
|                |                |                |              |
]]></artwork></figure>

<t>When a client A wants to establish a group with B and C, it first initializes a
group state containing only itself and downloads KeyPackages for B and C. For
each member, A generates an Add and Commit message adding that member, and
broadcasts them to the group. It also generates a Welcome message and sends this
directly to the new member (there's no need to send it to the group). Only after
A has received its Commit message back from the server does it update its state
to reflect the new member's addition.</t>

<t>Upon receiving the Welcome message and the corresponding Commit, the new member
will be able to read and send new messages to the group. Messages received
before the client has joined the group are ignored.</t>

<figure><artwork><![CDATA[
                                                               Group
A              B              C          Directory            Channel
|              |              |              |                   |
|         KeyPackageB, KeyPackageC           |                   |
|<-------------------------------------------|                   |
|state.init()  |              |              |                   |
|              |              |              |                   |
|              |              |              | Add(A->AB)        |
|              |              |              | Commit(Add)       |
|--------------------------------------------------------------->|
|              |              |              |                   |
|  Welcome(B)  |              |              |                   |
|------------->|state.init()  |              |                   |
|              |              |              |                   |
|              |              |              | Add(A->AB)        |
|              |              |              | Commit(Add)       |
|<---------------------------------------------------------------|
|state.add(B)  |<------------------------------------------------|
|              |state.join()  |              |                   |
|              |              |              |                   |
|              |              |              | Add(AB->ABC)      |
|              |              |              | Commit(Add)       |
|--------------------------------------------------------------->|
|              |              |              |                   |
|              |  Welcome(C)  |              |                   |
|---------------------------->|state.init()  |                   |
|              |              |              |                   |
|              |              |              | Add(AB->ABC)      |
|              |              |              | Commit(Add)       |
|<---------------------------------------------------------------|
|state.add(C)  |<------------------------------------------------|
|              |state.add(C)  |<---------------------------------|
|              |              |state.join()  |                   |
]]></artwork></figure>

<t>Subsequent additions of group members proceed in the same way.  Any
member of the group can download a KeyPackage for a new client
and broadcast an Add message that the current group can use to update
their state, and a Welcome message that the new client can use to
initialize its state.</t>

<t>To enforce the forward secrecy and post-compromise security of messages,
each member periodically updates their leaf secret.
Any member can update this information at any time by generating a fresh
KeyPackage and sending an Update message followed by a Commit message.
Once all members have processed both, the group's secrets will be unknown to an
attacker that had compromised the sender's prior leaf secret.</t>

<t>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 to determine an appropriate amount of time
between Updates.</t>

<figure><artwork><![CDATA[
                                                          Group
A              B     ...      Z          Directory        Channel
|              |              |              |              |
|              | Update(B)    |              |              |
|              |------------------------------------------->|
| Commit(Upd)  |              |              |              |
|---------------------------------------------------------->|
|              |              |              |              |
|              |              |              | Update(B)    |
|              |              |              | Commit(Upd)  |
|<----------------------------------------------------------|
|state.upd(B)  |<-------------------------------------------|
|              |state.upd(B)  |<----------------------------|
|              |              |state.upd(B)  |              |
|              |              |              |              |
]]></artwork></figure>

<t>Members are removed from the group in a similar way.
Any member of the group can send a Remove proposal followed by a
Commit message, which adds new entropy to the group state
that's known to all except the removed member.
Note that this does not necessarily imply that any member
is actually allowed to evict other members; groups can
enforce access control policies on top of these
basic mechanism.</t>

<figure><artwork><![CDATA[
                                                          Group
A              B     ...      Z          Directory       Channel
|              |              |              |              |
|              |              | Remove(B)    |              |
|              |              | Commit(Rem)  |              |
|              |              |---------------------------->|
|              |              |              |              |
|              |              |              | Remove(B)    |
|              |              |              | Commit(Rem)  |
|<----------------------------------------------------------|
|state.rem(B)  |              |<----------------------------|
|              |              |state.rem(B)  |              |
|              |              |              |              |
|              |              |              |              |
]]></artwork></figure>

</section>
<section anchor="ratchet-trees" title="Ratchet Trees">

<t>The protocol uses "ratchet trees" for deriving shared secrets among
a group of clients.</t>

<section anchor="tree-computation-terminology" title="Tree Computation Terminology">

<t>Trees consist of <spanx style="emph">nodes</spanx>. A node is a
<spanx style="emph">leaf</spanx> if it has no children, and a <spanx style="emph">parent</spanx> otherwise; note that all
parents in our trees have precisely
two children, a <spanx style="emph">left</spanx> child and a <spanx style="emph">right</spanx> child. A node is the <spanx style="emph">root</spanx>
of a tree if it has no parents, and <spanx style="emph">intermediate</spanx> if it has both
children and parents. The <spanx style="emph">descendants</spanx> of a node are that node, its
children, and the descendants of its children, and we say a tree
<spanx style="emph">contains</spanx> a node if that node is a descendant of the root of the
tree. Nodes are <spanx style="emph">siblings</spanx> if they share the same parent.</t>

<t>A <spanx style="emph">subtree</spanx> of a tree is the tree given by the descendants of any
node, the <spanx style="emph">head</spanx> of the subtree. The <spanx style="emph">size</spanx> of a tree or subtree is the
number of leaf nodes it contains.  For a given parent node, its <spanx style="emph">left
subtree</spanx> is the subtree with its left child as head (respectively
<spanx style="emph">right subtree</spanx>).</t>

<t>All trees used in this protocol are left-balanced binary trees. A
binary tree is <spanx style="emph">full</spanx> (and <spanx style="emph">balanced</spanx>) if its size is a power of
two and for any parent node in the tree, its left and right subtrees
have the same size.</t>

<t>A binary tree is <spanx style="emph">left-balanced</spanx> if for every
parent, either the parent is balanced, or the left subtree of that
parent is the largest full subtree that could be constructed from
the leaves present in the parent's own subtree.
Given a list of <spanx style="verb">n</spanx> items, there is a unique left-balanced
binary tree structure with these elements as leaves.</t>

<t>(Note that left-balanced binary trees are the same structure that is
used for the Merkle trees in the Certificate Transparency protocol
<xref target="I-D.ietf-trans-rfc6962-bis"/>.)</t>

<t>The <spanx style="emph">direct path</spanx> of a root is the empty list, and of any other node
is the concatenation of that node's parent along with the parent's direct path.
The <spanx style="emph">copath</spanx> of a node is the node's sibling concatenated with the list of
siblings of all the nodes in its direct path, excluding the root.</t>

<t>For example, in the below tree:</t>

<t><list style="symbols">
  <t>The direct path of C is (CD, ABCD, ABCDEFG)</t>
  <t>The copath of C is (D, AB, EFG)</t>
</list></t>

<figure><artwork><![CDATA[
            ABCDEFG
           /      \
          /        \
         /          \
     ABCD            EFG
    /    \          /  \
   /      \        /    \
  AB      CD      EF    |
 / \     / \     / \    |
A   B   C   D   E   F   G

                    1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2
]]></artwork></figure>

<t>Each node in the tree is assigned a <spanx style="emph">node index</spanx>, starting at zero and
running from left to right.  A node is a leaf node if and only if it
has an even index.  The node indices for the nodes in the above tree
are as follows:</t>

<t><list style="symbols">
  <t>0 = A</t>
  <t>1 = AB</t>
  <t>2 = B</t>
  <t>3 = ABCD</t>
  <t>4 = C</t>
  <t>5 = CD</t>
  <t>6 = D</t>
  <t>7 = ABCDEFG</t>
  <t>8 = E</t>
  <t>9 = EF</t>
  <t>10 = F</t>
  <t>11 = EFG</t>
  <t>12 = G</t>
</list></t>

<t>The leaves of the tree are indexed separately, using a <spanx style="emph">leaf index</spanx>,
since the protocol messages only need to refer to leaves in the
tree.  Like nodes, leaves are numbered left to right.  The node with
leaf index <spanx style="verb">k</spanx> is also called the <spanx style="verb">k-th</spanx> leaf.  Note that
given the above numbering, a node is a leaf node if and only if it
has an even node index, and a leaf node's leaf index is half its
node index.  The leaf indices in the above tree are as follows:</t>

<t><list style="symbols">
  <t>0 = A</t>
  <t>1 = B</t>
  <t>2 = C</t>
  <t>3 = D</t>
  <t>4 = E</t>
  <t>5 = F</t>
  <t>6 = G</t>
</list></t>

</section>
<section anchor="resolution-example" title="Ratchet Tree Nodes">

<t>A particular instance of a ratchet tree is defined by the same parameters that
define an instance of HPKE, namely:</t>

<t><list style="symbols">
  <t>A Key Encapsulation Mechanism (KEM), including a <spanx style="verb">DeriveKeyPair</spanx> function that
creates a key pair for the KEM from a symmetric secret</t>
  <t>A Key Derivation Function (KDF), including <spanx style="verb">Extract</spanx> and <spanx style="verb">Expand</spanx> functions</t>
  <t>An AEAD encryption scheme</t>
</list></t>

<t>Each node in a ratchet tree contains up to five values:</t>

<t><list style="symbols">
  <t>A private key (only within the member's direct path, see below)</t>
  <t>A public key</t>
  <t>An ordered list of leaf indices for "unmerged" leaves (see
<xref target="views"/>)</t>
  <t>A credential (only for leaf nodes)</t>
  <t>A hash of certain information about the node's parent, as of the last time the
node was changed (see <xref target="parent-hash"/>).</t>
</list></t>

<t>The conditions under which each of these values must or must not be
present are laid out in <xref target="views"/>.</t>

<t>A node in the tree may also be <spanx style="emph">blank</spanx>, indicating that no value is
present at that node.  The <spanx style="emph">resolution</spanx> of a node is an ordered list
of non-blank nodes that collectively cover all non-blank descendants
of the node.</t>

<t><list style="symbols">
  <t>The resolution of a non-blank node comprises the node itself,
followed by its list of unmerged leaves, if any</t>
  <t>The resolution of a blank leaf node is the empty list</t>
  <t>The resolution of a blank intermediate node is the result of
concatenating the resolution of its left child with the resolution
of its right child, in that order</t>
</list></t>

<t>For example, consider the following tree, where the "_" character
represents a blank node:</t>

<figure><artwork><![CDATA[
      _
    /   \
   /     \
  _       CD[C]
 / \     / \
A   _   C   D

0 1 2 3 4 5 6
]]></artwork></figure>

<t>In this tree, we can see all of the above rules in play:</t>

<t><list style="symbols">
  <t>The resolution of node 5 is the list [CD, C]</t>
  <t>The resolution of node 2 is the empty list []</t>
  <t>The resolution of node 3 is the list [A, CD, C]</t>
</list></t>

<t>Every node, regardless of whether the node is blank or populated, has
a corresponding <spanx style="emph">hash</spanx> that summarizes the contents of the subtree
below that node.  The rules for computing these hashes are described
in <xref target="tree-hashes"/>.</t>

</section>
<section anchor="views" title="Views of a Ratchet Tree">

<t>We generally assume that each participant maintains a complete and
up-to-date view of the public state of the group's ratchet tree,
including the public keys for all nodes and the credentials
associated with the leaf nodes.</t>

<t>No participant in an MLS group knows the private key associated with
every node in the tree. Instead, each member is assigned to a leaf of the tree,
which determines the subset of private keys it knows. The
credential stored at that leaf is one provided by the member.</t>

<t>In particular, MLS maintains the members' views of the tree in such
a way as to maintain the <spanx style="emph">tree invariant</spanx>:</t>

<figure><artwork><![CDATA[
The private key for a node in the tree is known to a member of
the group only if that member's leaf is a descendant of
the node.
]]></artwork></figure>

<t>In other words, if a node is not blank, then it holds a public key.
The corresponding private key is known only to members occupying
leaves below that node.</t>

<t>The reverse implication is not true: A member may not know the private keys of
all the intermediate nodes they're below.  Such a member has an <spanx style="emph">unmerged</spanx> leaf.
Encrypting to an intermediate node requires encrypting to the node's public key,
as well as the public keys of all the unmerged leaves below it.  A leaf is
unmerged when it is first added, because the process of adding the leaf does not
give it access to all of the nodes above it in the tree.  Leaves are "merged" as
they receive the private keys for nodes, as described in
<xref target="ratchet-tree-evolution"/>.</t>

</section>
<section anchor="ratchet-tree-evolution" title="Ratchet Tree Evolution">

<t>A member of an MLS group advances the key schedule to provide forward secrecy
and post-compromise security by providing the group with fresh key material to
be added into the group's shared secret.
To do so, one member of the group generates fresh key
material, applies it to their local tree state, and then sends this key material
to other members in the group via an UpdatePath message (see <xref target="update-paths"/>) .
All other group members then apply the key material in the UpdatePath to their
own local tree state to derive the group's now-updated shared secret.</t>

<t>To begin, the generator of the UpdatePath 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.</t>

<t>The generator of the UpdatePath starts by sampling a fresh random value called
"leaf_secret", and uses the leaf_secret to generate their leaf HPKE key pair
(see <xref target="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,
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.</t>

<figure><artwork><![CDATA[
leaf_node_secret = DeriveSecret(leaf_secret, "node")
path_secret[0] = DeriveSecret(leaf_secret, "path")

path_secret[n] = DeriveSecret(path_secret[n-1], "path")
node_secret[n] = DeriveSecret(path_secret[n], "node")

leaf_priv, leaf_pub = KEM.DeriveKeyPair(leaf_node_secret)
node_priv[n], node_pub[n] = KEM.DeriveKeyPair(node_secret[n])
]]></artwork></figure>

<t>For example, suppose there is a group with four members:</t>

<figure><artwork><![CDATA[
      G
     / \
    /   \
   /     \
  E       _
 / \     / \
A   B   C   D
]]></artwork></figure>

<t>If member B subsequently generates an UpdatePath based on a secret
"leaf_secret", then it would generate the following sequence
of path secrets:</t>

<figure><artwork><![CDATA[
path_secret[1] --> node_secret[1] --> node_priv[1], node_pub[1]
     ^
     |
path_secret[0] --> node_secret[0] --> node_priv[0], node_pub[0]
     ^
     |
leaf_secret    --> leaf_node_secret --> leaf_priv, leaf_pub
                                     ~> leaf_key_package
]]></artwork></figure>

<t>After applying the UpdatePath, the tree will have the following structure, where
"np[i]" represents the node_priv values generated as described
above:</t>

<figure><artwork><![CDATA[
          np[1]
         /     \
     np[0]      _
     /  \      / \
    A    B    C   D
]]></artwork></figure>

<t>After performing these operations, the generator of the UpdatePath MUST
delete the leaf_secret.</t>

</section>
<section anchor="synchronizing-views-of-the-tree" title="Synchronizing Views of the Tree">

<t>After generating fresh key material and applying it to ratchet forward their
local tree state as described in the prior section, the generator must broadcast
this update to other members of the group in a Commit message, who
apply it to keep their local views of the tree in
sync with the sender's.  More specifically, when a member commits a change to
the tree (e.g., to add or remove a member), it transmits an UpdatePath message
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 use these values to update
their view of the tree, aligning their copy of the tree to the
sender's.</t>

<t>To transmit this update, the sender broadcasts to the group
the following information for each node in the direct path of the
leaf, including the root:</t>

<t><list style="symbols">
  <t>The public key for the node</t>
  <t>Zero or more encrypted copies of the path secret corresponding to
the node</t>
</list></t>

<t>The path secret value for a given node is encrypted for the subtree
corresponding to the parent's non-updated child, that is, the child
on the copath of the leaf node.
There is one encrypted path secret for each public key in the resolution
of the non-updated child.</t>

<t>The recipient of a path update processes it with the following steps:</t>

<t><list style="numbers">
  <t>Compute the updated path secrets.
  <list style="symbols">
      <t>Identify a node in the direct path for which the local member
is in the subtree of the non-updated child.</t>
      <t>Identify a node in the resolution of the copath node for
which this node has a private key.</t>
      <t>Decrypt the path secret for the parent of the copath node using
the private key from the resolution node.</t>
      <t>Derive path secrets for ancestors of that node using the
algorithm described above.</t>
      <t>The recipient SHOULD verify that the received public keys agree
with the public keys derived from the new path_secret values.</t>
    </list></t>
  <t>Merge the updated path secrets into the tree.
  <list style="symbols">
      <t>For all updated nodes,
      <list style="symbols">
          <t>Replace the public key for each node with the received public key.</t>
          <t>Set the list of unmerged leaves to the empty list.</t>
          <t>Store the updated hash of the node's parent (represented as a ParentNode
struct), going from root to leaf, so that each hash incorporates all the
nodes above it. The root node always has a zero-length hash for this
value.</t>
        </list></t>
      <t>For nodes where an updated path secret was computed in step 1,
compute the corresponding node key pair and replace the values
stored at the node with the computed values.</t>
    </list></t>
</list></t>

<t>For example, in order to communicate the example update described in
the previous section, the sender would transmit the following
values:</t>

<texttable>
      <ttcol align='left'>Public Key</ttcol>
      <ttcol align='left'>Ciphertext(s)</ttcol>
      <c>pk(ns[1])</c>
      <c>E(pk(C), ps[1]), E(pk(D), ps[1])</c>
      <c>pk(ns[0])</c>
      <c>E(pk(A), ps[0])</c>
</texttable>

<t>In this table, the value pk(ns[X]) represents the public key
derived from the node secret X, whereas pk(X) represents the public leaf key
for user X.  The value E(K, S) represents
the public-key encryption of the path secret S to the
public key K.</t>

<t>After processing the update, each recipient MUST delete outdated key material,
specifically:</t>

<t><list style="symbols">
  <t>The path secrets used to derive each updated node key pair.</t>
  <t>Each outdated node key pair that was replaced by the update.</t>
</list></t>

</section>
</section>
<section anchor="cryptographic-objects" title="Cryptographic Objects">

<section anchor="ciphersuites" title="Ciphersuites">

<t>Each MLS session uses a single ciphersuite that specifies the
following primitives to be used in group key computations:</t>

<t><list style="symbols">
  <t>HPKE parameters:
  <list style="symbols">
      <t>A Key Encapsulation Mechanism (KEM)</t>
      <t>A Key Derivation Function (KDF)</t>
      <t>An AEAD encryption algorithm</t>
    </list></t>
  <t>A hash algorithm</t>
  <t>A signature algorithm</t>
</list></t>

<t>MLS uses draft-07 of HPKE <xref target="I-D.irtf-cfrg-hpke"/> for public-key encryption.
The <spanx style="verb">DeriveKeyPair</spanx> function associated to the KEM for the ciphersuite maps
octet strings to HPKE key pairs.</t>

<t>Ciphersuites are represented with the CipherSuite type. HPKE public keys
are opaque values in a format defined by the underlying
protocol (see the Cryptographic Dependencies section of the HPKE specification for more
information).</t>

<figure><artwork><![CDATA[
opaque HPKEPublicKey<1..2^16-1>;
]]></artwork></figure>

<t>The signature algorithm specified in the ciphersuite is the mandatory algorithm
to be used for signatures in MLSPlaintext and the tree signatures.  It MUST be
the same as the signature algorithm specified in the credential field of the
KeyPackage objects in the leaves of the tree (including the InitKeys
used to add new members).</t>

<t>The ciphersuites are defined in section <xref target="mls-ciphersuites"/>.</t>

</section>
<section anchor="credentials" title="Credentials">

<t>A member of a group authenticates the identities of other participants by means
of credentials issued by some authentication system, like a PKI. Each type of
credential MUST express the following data in the context of the group it is
used with:</t>

<t><list style="symbols">
  <t>The public key of a signature key pair matching the SignatureScheme specified
by the CipherSuite of the group</t>
  <t>The identity of the holder of the private key</t>
</list></t>

<t>Credentials MAY also include information that allows a relying party
to verify the identity / signing key binding.</t>

<t>Additionally, Credentials SHOULD specify the signature scheme corresponding to
each contained public key.</t>

<figure><artwork><![CDATA[
// See RFC 8446 and the IANA TLS SignatureScheme registry
uint16 SignatureScheme;

// See IANA registry for registered values
uint16 CredentialType;

struct {
    opaque identity<0..2^16-1>;
    SignatureScheme signature_scheme;
    opaque signature_key<0..2^16-1>;
} BasicCredential;

struct {
    opaque cert_data<0..2^16-1>;
} Certificate;

struct {
    CredentialType credential_type;
    select (Credential.credential_type) {
        case basic:
            BasicCredential;

        case x509:
            Certificate chain<1..2^32-1>;
    };
} Credential;
]]></artwork></figure>

<t>A BasicCredential is a raw, unauthenticated assertion of an identity/key
binding. The format of the key in the <spanx style="verb">public_key</spanx> field is defined by the
relevant ciphersuite: the group ciphersuite for a credential in a ratchet tree,
the KeyPackage ciphersuite for a credential in a KeyPackage object.</t>

<t>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
<spanx style="verb">public_key</spanx> in the end-entity certificate MUST match the relevant
ciphersuite.</t>

<t>For ciphersuites using Ed25519 or Ed448 signature schemes, the public key is in
the format specified <xref target="RFC8032"/>.  For ciphersuites using ECDSA 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 <xref target="SECG"/>.</t>

<t>Note that each new credential that has not already been validated
by the application MUST be validated against the Authentication
Service.</t>

</section>
</section>
<section anchor="key-packages" title="Key Packages">

<t>In order to facilitate asynchronous addition of clients to a
group, it is possible to pre-publish key packages that
provide some public information about a user. KeyPackage
structures provide information about a client that any existing
member can use to add this client to the group asynchronously.</t>

<t>A KeyPackage object specifies a ciphersuite that the client
supports, as well as providing a public key that others can use
for key agreement. The client's signature key can be updated
throughout the lifetime of the group by sending a new KeyPackage
with a new Credential. However, the identity MUST be the same in
both Credentials and the new Credential MUST be validated by the
authentication service.</t>

<t>When used as InitKeys, KeyPackages are intended to be used only once and SHOULD NOT
be reused except in case of last resort. (See <xref target="initkey-reuse"/>).
Clients MAY generate and publish multiple InitKeys to
support multiple ciphersuites.</t>

<t>KeyPackages contain a public key chosen by the client, which the
client MUST ensure uniquely identifies a given KeyPackage object
among the set of KeyPackages created by this client.</t>

<t>The value for hpke_init_key MUST be a public key for the asymmetric
encryption scheme defined by cipher_suite. The whole structure
is signed using the client's signature key. A KeyPackage object
with an invalid signature field MUST be considered malformed.
The input to the signature computation comprises all of the fields
except for the signature field.</t>

<figure><artwork><![CDATA[
enum {
    reserved(0),
    mls10(1),
    (255)
} ProtocolVersion;

// See IANA registry for registered values
uint16 ExtensionType;

struct {
    ExtensionType extension_type;
    opaque extension_data<0..2^16-1>;
} Extension;

struct {
    ProtocolVersion version;
    CipherSuite cipher_suite;
    HPKEPublicKey hpke_init_key;
    Credential credential;
    Extension extensions<8..2^32-1>;
    opaque signature<0..2^16-1>;
} KeyPackage;
]]></artwork></figure>

<t>KeyPackage objects MUST contain at least two extensions, one of type
<spanx style="verb">capabilities</spanx>, and one of
type <spanx style="verb">lifetime</spanx>.  The <spanx style="verb">capabilities</spanx> extension
allow MLS session establishment to be safe from downgrade attacks on the
parameters described (as discussed in <xref target="group-creation"/>), while still only advertising
one version / ciphersuite per KeyPackage.</t>

<t>As the <spanx style="verb">KeyPackage</spanx> is a structure which is stored in the Ratchet
Tree and updated depending on the evolution of this tree, each
modification of its content MUST be reflected by a change of its
signature. This allow other members to control the validity of the KeyPackage
at any time and in particular in the case of a newcomer joining the group.</t>

<section anchor="client-capabilities" title="Client Capabilities">

<t>The <spanx style="verb">capabilities</spanx> extension indicates what protocol versions, ciphersuites, and
protocol extensions are supported by a client.</t>

<figure><artwork><![CDATA[
struct {
    ProtocolVersion versions<0..255>;
    CipherSuite ciphersuites<0..255>;
    ExtensionType extensions<0..255>;
} Capabilities;
]]></artwork></figure>

<t>This extension MUST be always present in a KeyPackage.  Extensions that appear
in the <spanx style="verb">extensions</spanx> field of a KeyPackage MUST be included in the <spanx style="verb">extensions</spanx>
field of the <spanx style="verb">capabilities</spanx> extension.</t>

</section>
<section anchor="lifetime" title="Lifetime">

<t>The <spanx style="verb">lifetime</spanx> extension represents the times between which clients will
consider a KeyPackage valid.  This time is represented as an absolute time,
measured in seconds since the Unix epoch (1970-01-01T00:00:00Z). A client MUST
NOT use the data in a KeyPackage for any processing before the <spanx style="verb">not_before</spanx>
date, or after the <spanx style="verb">not_after</spanx> date.</t>

<figure><artwork><![CDATA[
uint64 not_before;
uint64 not_after;
]]></artwork></figure>

<t>Applications MUST define a maximum total lifetime that is acceptable for a
KeyPackage, and reject any KeyPackage where the total lifetime is longer than
this duration.</t>

<t>This extension MUST always be present in a KeyPackage.</t>

</section>
<section anchor="keypackage-identifiers" title="KeyPackage Identifiers">

<t>Within MLS, a KeyPackage is identified by its hash (see, e.g.,
<xref target="welcoming-new-members"/>).  The <spanx style="verb">key_id</spanx> extension allows applications to add
an explicit, application-defined identifier to a KeyPackage.</t>

<figure><artwork><![CDATA[
opaque key_id<0..2^16-1>;
]]></artwork></figure>

</section>
<section anchor="parent-hash" title="Parent Hash">

<t>Consider a ratchet tree with a parent node P and children V and S. The parent hash
of P changes whenever an <spanx style="verb">UpdatePath</spanx> object is applied to the ratchet tree along
a path traversing node V (and hence also P). The new "Parent Hash of P (with Co-Path
Child S)" is obtained by hashing P's <spanx style="verb">ParentHashInput</spanx> struct using the resolution
of S to populate the <spanx style="verb">original_child_resolution</spanx> field. This way, P's Parent Hash
fixes the new HPKE public keys of all nodes on the path from P to the root.
Furthermore, for each such key PK the hash also binds the set of HPKE public keys
to which PK's secret key was encrypted in the commit packet that anounced the
<spanx style="verb">UpdatePath</spanx> object.</t>

<figure><artwork><![CDATA[
struct {
    HPKEPublicKey public_key;
    opaque parent_hash<0..255>;
    HPKEPublicKey original_child_resolution<0..2^32-1>;
} ParentHashInput;
]]></artwork></figure>

<t>The Parent Hash of P with Co-Path Child S is the hash of a <spanx style="verb">ParentHashInput</spanx> object
populated as follows. The field <spanx style="verb">public_key</spanx> contains the HPKE public key of P. If P
is the root, then <spanx style="verb">parent_hash</spanx> is set to a zero-length octet string.
Otherwise <spanx style="verb">parent_hash</spanx> is the Parent Hash of P's parent with P's sibling as the
co-path child.</t>

<t>Finally, <spanx style="verb">original_child_resolution</spanx> is the array of <spanx style="verb">HPKEPublicKey</spanx> values of the
nodes in the resolution of S but with the <spanx style="verb">unmerged_leaves</spanx> of P omitted. For
example, in the ratchet tree depicted in <xref target="resolution-example"/> the
<spanx style="verb">ParentHashInput</spanx> of node 5 with co-path child 4 would contain an empty
<spanx style="verb">original_child_resolution</spanx> since 4's resolution includes only itself but 4 is also
an unmerged leaf of 5. Meanwhile, the <spanx style="verb">ParentHashInput</spanx> of node 5 with co-path child
6 has an array with one element in it: the HPKE public key of 6.</t>

<section anchor="using-parent-hashes" title="Using Parent Hashes">

<t>The Parent Hash of P appears in three types of structs. If V is itself a parent node
then P's Parent Hash is stored in the <spanx style="verb">parent_hash</spanx> fields of both V's
<spanx style="verb">ParentHashInput</spanx> struct and V's <spanx style="verb">ParentNode</spanx> struct. (The <spanx style="verb">ParentNode</spanx> struct is
used to encapsulate all public information about V that must be conveyed to a new
member joining the group as well as to define the Tree Hash of node V.)</t>

<t>If, on the other hand, V is a leaf and its KeyPackage contains the <spanx style="verb">parent_hash</spanx>
extension then the Parent Hash of P (with V's sibling as co-path child) is stored in
that field. In particular, the extension MUST be present in the <spanx style="verb">leaf_key_package</spanx>
field of an <spanx style="verb">UpdatePath</spanx> object. (This way, the signature of such a KeyPackage also
serves to attest to which keys the group member introduced into the ratchet tree and
to whom the corresponding secret keys were sent. This helps prevent malicious insiders
from constructing artificial ratchet trees with a node V whose HPKE secret key is
known to the insider yet where the insider isn't assigned a leaf in the subtree rooted
at V. Indeed, such a ratchet tree would violate the tree invariant.)</t>

</section>
<section anchor="verifying-parent-hashes" title="Verifying Parent Hashes">

<t>To this end, when processing a Commit message clients MUST recompute the
expected value of <spanx style="verb">parent_hash</spanx> for the committer's new leaf and verify that it
matches the <spanx style="verb">parent_hash</spanx> value in the supplied <spanx style="verb">leaf_key_package</spanx>. Moreover, when
joining a group, new members MUST authenticate each non-blank parent node P. A parent
node P is authenticated by performing the following check:</t>

<t><list style="symbols">
  <t>Let L and R be the left and right children of P, respectively</t>
  <t>If L.parent_hash is equal to the Parent Hash of P with Co-Path Child R, the check passes</t>
  <t>If R is blank, replace R with its left child until R is either non-blank or a leaf node</t>
  <t>If R is a leaf node, the check fails</t>
  <t>If R.parent_hash is equal to the Parent Hash of P with Co-Path Child L, the check passes</t>
  <t>Otherwise, the check fails</t>
</list></t>

<t>The left-child recursion under the right child of P is necessary because the expansion of
the tree to the right due to Add proposals can cause blank nodes to be interposed
between a parent node and its right child.</t>

</section>
</section>
<section anchor="tree-hashes" title="Tree Hashes">

<t>To allow group members to verify that they agree on the public cryptographic state
of the group, this section defines a scheme for generating a hash value (called
the "tree hash") that represents the contents of the group's ratchet tree and the
members' KeyPackages. The tree hash of a tree is the tree hash of its root node,
which we define recursively, starting with the leaves.</t>

<t>As some nodes may be blank while others contain data we use the following struct
to include data if present.</t>

<figure><artwork><![CDATA[
struct {
    uint8 present;
    select (present) {
        case 0: struct{};
        case 1: T value;
    }
} optional<T>;
]]></artwork></figure>

<t>The tree hash of a leaf node is the hash of leaf's <spanx style="verb">LeafNodeHashInput</spanx> object which
might include a Key Package depending on whether or not it is blank.</t>

<figure><artwork><![CDATA[
struct {
    uint32 node_index;
    optional<KeyPackage> key_package;
} LeafNodeHashInput;
]]></artwork></figure>

<t>Note that the <spanx style="verb">node_index</spanx> field contains the index of the leaf among the nodes
in the tree, not its index among the leaves; <spanx style="verb">node_index = 2 * leaf_index</spanx>.</t>

<t>Now the tree hash of any non-leaf node is recursively defined to be the hash of
its <spanx style="verb">ParentNodeTreeHashInput</spanx>. This includes an optional <spanx style="verb">ParentNode</spanx>
object depending on if the node is blank or not.</t>

<figure><artwork><![CDATA[
struct {
    HPKEPublicKey public_key;
    opaque parent_hash<0..255>;
    uint32 unmerged_leaves<0..2^32-1>;
} ParentNode;

struct {
    uint32 node_index;
    optional<ParentNode> parent_node;
    opaque left_hash<0..255>;
    opaque right_hash<0..255>;
} ParentNodeTreeHashInput;
]]></artwork></figure>

<t>The <spanx style="verb">left_hash</spanx> and <spanx style="verb">right_hash</spanx> fields hold the tree hashes of the node's
left and right children, respectively.</t>

</section>
<section anchor="group-state" title="Group State">

<t>Each member of the group maintains a GroupContext object that
summarizes the state of the group:</t>

<figure><artwork><![CDATA[
struct {
    opaque group_id<0..255>;
    uint64 epoch;
    opaque tree_hash<0..255>;
    opaque confirmed_transcript_hash<0..255>;
    Extension extensions<0..2^32-1>;
} GroupContext;
]]></artwork></figure>

<t>The fields in this state have the following semantics:</t>

<t><list style="symbols">
  <t>The <spanx style="verb">group_id</spanx> field is an application-defined identifier for the
group.</t>
  <t>The <spanx style="verb">epoch</spanx> field represents the current version of the group key.</t>
  <t>The <spanx style="verb">tree_hash</spanx> field contains a commitment to the contents of the
group's ratchet tree and the credentials for the members of the
group, as described in <xref target="tree-hashes"/>.</t>
  <t>The <spanx style="verb">confirmed_transcript_hash</spanx> field contains a running hash over
the messages that led to this state.</t>
</list></t>

<t>When a new member is added to the group, an existing member of the
group provides the new member with a Welcome message.  The Welcome
message provides the information the new member needs to initialize
its GroupContext.</t>

<t>Different changes to the group will have different effects on the group state.
These effects are described in their respective subsections of <xref target="proposals"/>.
The following general rules apply:</t>

<t><list style="symbols">
  <t>The <spanx style="verb">group_id</spanx> field is constant</t>
  <t>The <spanx style="verb">epoch</spanx> field increments by one for each Commit message that
is processed</t>
  <t>The <spanx style="verb">tree_hash</spanx> is updated to represent the current tree and
credentials</t>
  <t>The <spanx style="verb">confirmed_transcript_hash</spanx> is updated with the data for an
MLSPlaintext message encoding a Commit message in two parts:</t>
</list></t>

<figure><artwork><![CDATA[
struct {
    opaque group_id<0..255>;
    uint64 epoch;
    Sender sender;
    ContentType content_type = commit;
    Commit commit;
    opaque signature<0..2^16-1>;
} MLSPlaintextCommitContent;

struct {
    MAC confirmation_tag;
} MLSPlaintextCommitAuthData;

interim_transcript_hash_[0] = ""; // zero-length octet string

confirmed_transcript_hash_[n] =
    Hash(interim_transcript_hash_[n] ||
        MLSPlaintextCommitContent_[n]);

interim_transcript_hash_[n+1] =
    Hash(confirmed_transcript_hash_[n] ||
        MLSPlaintextCommitAuthData_[n]);
]]></artwork></figure>

<t>Thus the <spanx style="verb">confirmed_transcript_hash</spanx> field in a GroupContext object represents a
transcript over the whole history of MLSPlaintext Commit messages, up to the
confirmation tag field in the current MLSPlaintext message.  The confirmation tag
is then included in the transcript for the next epoch.  The interim transcript
hash is passed to new members in the GroupInfo struct, and enables existing
members to incorporate a Commit message into the transcript without having to
store the whole MLSPlaintextCommitAuthData structure.</t>

<t>As shown above, when a new group is created, the <spanx style="verb">interim_transcript_hash</spanx> field
is set to the zero-length octet string.</t>

</section>
<section anchor="update-paths" title="Update Paths">

<t>As described in <xref target="commit"/>, each MLS Commit message may optionally
transmit a KeyPackage leaf and node values along its direct path.
The path contains a public key and encrypted secret value for all
intermediate nodes in the path above the leaf.  The path is ordered
from the closest node to the leaf to the root; each node MUST be the
parent of its predecessor.</t>

<figure><artwork><![CDATA[
struct {
    opaque kem_output<0..2^16-1>;
    opaque ciphertext<0..2^16-1>;
} HPKECiphertext;

struct {
    HPKEPublicKey public_key;
    HPKECiphertext encrypted_path_secret<0..2^32-1>;
} UpdatePathNode;

struct {
    KeyPackage leaf_key_package;
    UpdatePathNode nodes<0..2^32-1>;
} UpdatePath;
]]></artwork></figure>

<t>For each <spanx style="verb">UpdatePathNode</spanx>, 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 <spanx style="verb">encrypted_path_secret</spanx> vector MUST be
equal to the length of the filtered resolution, with each ciphertext being the
encryption to the respective resolution node.</t>

<t>The HPKECiphertext values are computed as</t>

<figure><artwork><![CDATA[
kem_output, context = SetupBaseS(node_public_key, "")
ciphertext = context.Seal(group_context, path_secret)
]]></artwork></figure>

<t>where <spanx style="verb">node_public_key</spanx> is the public key of the node that the path
secret is being encrypted for, group_context is the current GroupContext object
for the group, and the functions <spanx style="verb">SetupBaseS</spanx> and
<spanx style="verb">Seal</spanx> are defined according to <xref target="I-D.irtf-cfrg-hpke"/>.</t>

<t>Decryption is performed in the corresponding way, using the private
key of the resolution node and the ephemeral public key
transmitted in the message.</t>

</section>
</section>
<section anchor="key-schedule" title="Key Schedule">

<t>Group keys are derived using the <spanx style="verb">Extract</spanx> and <spanx style="verb">Expand</spanx> functions from the KDF
for the group's ciphersuite, as well as the functions defined below:</t>

<figure><artwork><![CDATA[
ExpandWithLabel(Secret, Label, Context, Length) =
    KDF.Expand(Secret, KDFLabel, Length)

Where KDFLabel is specified as:

struct {
    uint16 length = Length;
    opaque label<7..255> = "mls10 " + Label;
    opaque context<0..2^32-1> = Context;
} KDFLabel;

DeriveSecret(Secret, Label) =
    ExpandWithLabel(Secret, Label, "", KDF.Nh)
]]></artwork></figure>

<t>The value <spanx style="verb">KDF.Nh</spanx> is the size of an output from <spanx style="verb">KDF.Extract</spanx>, in bytes.  In
the below diagram:</t>

<t><list style="symbols">
  <t>KDF.Extract takes its salt argument from the top and its IKM
argument from the left</t>
  <t>DeriveSecret takes its Secret argument from the incoming arrow</t>
</list></t>

<t>When processing a handshake message, a client combines the
following information to derive new epoch secrets:</t>

<t><list style="symbols">
  <t>The init secret from the previous epoch</t>
  <t>The commit secret for the current epoch</t>
  <t>The GroupContext object for current epoch</t>
</list></t>

<t>Given these inputs, the derivation of secrets for an epoch
proceeds as shown in the following diagram:</t>

<figure><artwork><![CDATA[
                   init_secret_[n-1]
                         |
                         V
    commit_secret -> KDF.Extract
                         |
                         V
                   DeriveSecret(., "joiner")
                         |
                         V
                    joiner_secret
                         |
                         V
psk_secret (or 0) -> KDF.Extract
                         |
                         +--> DeriveSecret(., "welcome")
                         |    = welcome_secret
                         |
                         V
                   ExpandWithLabel(., "epoch", GroupContext_[n], KDF.Nh)
                         |
                         V
                    epoch_secret
                         |
                         +--> DeriveSecret(., <label>)
                         |    = <secret>
                         |
                         V
                   DeriveSecret(., "init")
                         |
                         V
                   init_secret_[n]
]]></artwork></figure>

<t>A number of secrets are derived from the epoch secret for different purposes:</t>

<texttable>
      <ttcol align='left'>Secret</ttcol>
      <ttcol align='left'>Label</ttcol>
      <c><spanx style="verb">sender_data_secret</spanx></c>
      <c>"sender data"</c>
      <c><spanx style="verb">encryption_secret</spanx></c>
      <c>"encryption"</c>
      <c><spanx style="verb">exporter_secret</spanx></c>
      <c>"exporter"</c>
      <c><spanx style="verb">authentication_secret</spanx></c>
      <c>"authentication"</c>
      <c><spanx style="verb">external_secret</spanx></c>
      <c>"external"</c>
      <c><spanx style="verb">confirmation_key</spanx></c>
      <c>"confirm"</c>
      <c><spanx style="verb">membership_key</spanx></c>
      <c>"membership"</c>
      <c><spanx style="verb">resumption_secret</spanx></c>
      <c>"resumption"</c>
</texttable>

<t>The "external secret" is used to derive an HPKE key pair whose private key is
held by the entire group:</t>

<figure><artwork><![CDATA[
external_priv, external_pub = KEM.DeriveKeyPair(external_secret)
]]></artwork></figure>

<t>The public key <spanx style="verb">external_pub</spanx> can be published as part of the <spanx style="verb">PublicGroupState</spanx>
struct in order to allow non-members to join the group using an external commit.</t>

<section anchor="external-initialization" title="External Initialization">

<t>In addition to initializing a new epoch via KDF invocations as described above,
an MLS group can also initialize a new epoch via an asymmetric interaction using
the external key pair for the previous epoch.  This is done when an new member
is joining via an external commit.</t>

<t>In this process, the joiner sends a new <spanx style="verb">init_secret</spanx> value to the group using
the HPKE export method.  The joiner then uses that <spanx style="verb">init_secret</spanx> with
information provided in the PublicGroupState and an external Commit to initialize
their copy of the key schedule for the new epoch.</t>

<figure><artwork><![CDATA[
kem_output, context = SetupBaseS(external_pub, PublicGroupState)
init_secret = context.export("MLS 1.0 external init secret", KDF.Nh)
]]></artwork></figure>

<t>Members of the group receive the <spanx style="verb">kem_output</spanx> in an ExternalInit proposal and
preform the corresponding calculation to retrieve the <spanx style="verb">init_secret</spanx> value.</t>

<figure><artwork><![CDATA[
context = SetupBaseR(kem_output, external_priv, PublicGroupState)
init_secret = context.export("MLS 1.0 external init secret", KDF.Nh)
]]></artwork></figure>

<t>In both cases, the <spanx style="verb">info</spanx> input to HPKE is set to the PublicGroupState for the
previous epoch, encoded using the TLS serialization.</t>

</section>
<section anchor="pre-shared-keys" title="Pre-Shared Keys">

<t>Groups which already have an out-of-band mechanism to generate
shared group secrets can inject those into the MLS key schedule to seed
the MLS group secrets computations by this external entropy.</t>

<t>Injecting an external PSK can improve security in the case
where having a full run of updates across members is too expensive, or if
the external group key establishment mechanism provides
stronger security against classical or quantum adversaries.</t>

<t>Note that, as a PSK may have a different lifetime than an update, it
does not necessarily provide the same Forward Secrecy (FS) or Post-Compromise
Security (PCS) guarantees as a Commit message.</t>

<!-- OPEN ISSUE: Clarify lifetime vs security level mandated above. E.g. if
the PSK security expires before the next update (shorter PSK lifetime than
update), does that constitute a weaker security level -->

<!-- OPEN ISSUE: Define "security level", and what it means to match the
security level of the ciphersuite used in the group. -->

<t>Each PSK in MLS has a type that designates how it was provisioned.
External PSKs are provided by the application, while recovery and re-init PSKs
are derived from the MLS key schedule and used in cases where it is
necessary to authenticate a member's participation in a prior group state.
In particular, in addition to external PSK types, a PSK derived from within MLS
may be used in the following cases:</t>

<t><list style="symbols">
  <t>Re-Initialization: If during the lifetime of a group, the group members
decide to switch to a more secure ciphersuite or newer protocol version,
a PSK can be used to carry entropy from the old group forward into a new
group with the desired parameters.</t>
  <t>Branching: A PSK may be used to bootstrap a subset of current group
members into a new group. This applies if a subset of current group
members wish to branch based on the current group state.</t>
</list></t>

<t>The injection of one or more PSKs into the key schedule is signaled in two ways:
1) as a <spanx style="verb">PreSharedKey</spanx> proposal, and 2) in the <spanx style="verb">GroupSecrets</spanx> object of a
Welcome message sent to new members added in that epoch.</t>

<figure><artwork><![CDATA[
enum {
  reserved(0),
  external(1),
  reinit(2),
  branch(3),
  (255)
} PSKType;

struct {
  PSKType psktype;
  select (PreSharedKeyID.psktype) {
    case external:
      opaque psk_id<0..255>;

    case reinit:
      opaque psk_group_id<0..255>;
      uint64 psk_epoch;

    case branch:
      opaque psk_group_id<0..255>;
      uint64 psk_epoch;
  }
  opaque psk_nonce<0..255>;
} PreSharedKeyID;

struct {
    PreSharedKeyID psks<0..2^16-1>;
} PreSharedKeys;
]]></artwork></figure>

<t>On receiving a Commit with a <spanx style="verb">PreSharedKey</spanx> proposal or a GroupSecrets object
with the <spanx style="verb">psks</spanx> field set, the receiving Client includes them in the key
schedule in the order listed in the Commit, or in the <spanx style="verb">psks</spanx> field respectively.
For resumption PSKs, the PSK is defined as the <spanx style="verb">resumption_secret</spanx> of the group and
epoch specified in the <spanx style="verb">PreSharedKeyID</spanx> object. Specifically, <spanx style="verb">psk_secret</spanx> is
computed as follows:</t>

<figure><artwork><![CDATA[
struct {
    PreSharedKeyID id;
    uint16 index;
    uint16 count;
} PSKLabel;

psk_input_[i] = KDF.Extract(0, psk_[i])
psk_secret_[i] = ExpandWithLabel(psk_input_[i], "derived psk", PSKLabel, KDF.Nh)
psk_secret     = psk_secret_[0] || ... || psk_secret_[n-1]
]]></artwork></figure>

<t>The <spanx style="verb">index</spanx> field in <spanx style="verb">PSKLabel</spanx> corresponds to the index of the PSK in the <spanx style="verb">psk</spanx>
array, while the <spanx style="verb">count</spanx> field contains the total number of PSKs.</t>

<!-- OPEN ISSUE: How to combine multiple PSKs such that the final PSK, is
pseudorandom if at least one of the PSKs used is pseudorandom. -->

</section>
<section anchor="secret-tree" title="Secret Tree">

<t>For the generation of encryption keys and nonces, the key schedule begins with
the <spanx style="verb">encryption_secret</spanx> at the root and derives a tree of secrets with the same
structure as the group's ratchet tree. Each leaf in the Secret Tree is
associated with the same group member as the corresponding leaf in the ratchet
tree. Nodes are also assigned an index according to their position in the array
representation of the tree (described in <xref target="tree-math"/>). If N is a node index in
the Secret Tree then left(N) and right(N) denote the children of N (if they
exist).</t>

<t>The secret of any other node in the tree is derived from its parent's secret
using a call to DeriveTreeSecret:</t>

<figure><artwork><![CDATA[
DeriveTreeSecret(Secret, Label, Node, Generation, Length) =
    ExpandWithLabel(Secret, Label, TreeContext, Length)

Where TreeContext is specified as:

struct {
    uint32 node = Node;
    uint32 generation = Generation;
} TreeContext;
]]></artwork></figure>

<t>If N is a node index in the Secret Tree then the secrets of the children
of N are defined to be:</t>

<figure><artwork><![CDATA[
tree_node_[N]_secret
        |
        |
        +--> DeriveTreeSecret(., "tree", left(N), 0, KDF.Nh)
        |    = tree_node_[left(N)]_secret
        |
        +--> DeriveTreeSecret(., "tree", right(N), 0, KDF.Nh)
             = tree_node_[right(N)]_secret
]]></artwork></figure>

<t>The secret in the leaf of the Secret Tree is used to initiate two symmetric hash
ratchets, from which a sequence of single-use keys and nonces are derived, as
described in <xref target="encryption-keys"/>. The root of each ratchet is computed as:</t>

<figure><artwork><![CDATA[
tree_node_[N]_secret
        |
        |
        +--> DeriveTreeSecret(., "handshake", N, 0, KDF.Nh)
        |    = handshake_ratchet_secret_[N]_[0]
        |
        +--> DeriveTreeSecret(., "application", N, 0, KDF.Nh)
             = application_ratchet_secret_[N]_[0]
]]></artwork></figure>

</section>
<section anchor="encryption-keys" title="Encryption Keys">

<t>As described in <xref target="message-framing"/>, MLS encrypts three different
types of information:</t>

<t><list style="symbols">
  <t>Metadata (sender information)</t>
  <t>Handshake messages (Proposal and Commit)</t>
  <t>Application messages</t>
</list></t>

<t>The sender information used to look up the key for content encryption is
encrypted with an AEAD where the key and nonce are derived from both
<spanx style="verb">sender_data_secret</spanx> and a sample of the encrypted message content.</t>

<t>For handshake and application messages, a sequence of keys is derived via a
"sender ratchet".  Each sender has their own sender ratchet, and each step along
the ratchet is called a "generation".</t>

<t>A sender ratchet starts from a per-sender base secret derived from a Secret
Tree, as described in <xref target="secret-tree"/>. The base secret initiates a symmetric
hash ratchet which generates a sequence of keys and nonces. The sender uses the
j-th key/nonce pair in the sequence to encrypt (using the AEAD) the j-th message
they send during that epoch. Each key/nonce pair MUST NOT be used to encrypt
more than one message.</t>

<t>Keys, nonces, and the secrets in ratchets are derived using
DeriveTreeSecret. The context in a given call consists of the index
of the sender's leaf in the ratchet tree and the current position in
the ratchet.  In particular, the node index of the sender's leaf in the
ratchet tree is the same as the node index of the leaf in the Secret Tree
used to initialize the sender's ratchet.</t>

<figure><artwork><![CDATA[
ratchet_secret_[N]_[j]
      |
      +--> DeriveTreeSecret(., "nonce", N, j, AEAD.Nn)
      |    = ratchet_nonce_[N]_[j]
      |
      +--> DeriveTreeSecret(., "key", N, j, AEAD.Nk)
      |    = ratchet_key_[N]_[j]
      |
      V
DeriveTreeSecret(., "secret", N, j, KDF.Nh)
= ratchet_secret_[N]_[j+1]
]]></artwork></figure>

<t>Here, AEAD.Nn and AEAD.Nk denote the lengths
in bytes of the nonce and key for the AEAD scheme defined by
the ciphersuite.</t>

</section>
<section anchor="deletion-schedule" title="Deletion Schedule">

<t>It is important to delete all security-sensitive values as soon as they are
<spanx style="emph">consumed</spanx>. A sensitive value S is said to be <spanx style="emph">consumed</spanx> if</t>

<t><list style="symbols">
  <t>S was used to encrypt or (successfully) decrypt a message, or if</t>
  <t>a key, nonce, or secret derived from S has been consumed. (This goes for
values derived via DeriveSecret as well as ExpandWithLabel.)</t>
</list></t>

<t>Here, S may be the <spanx style="verb">init_secret</spanx>, <spanx style="verb">commit_secret</spanx>, <spanx style="verb">epoch_secret</spanx>,
<spanx style="verb">encryption_secret</spanx> as well as any secret in a Secret Tree or one of the
ratchets.</t>

<t>As soon as a group member consumes a value they MUST immediately delete
(all representations of) that value. This is crucial to ensuring
forward secrecy for past messages. Members MAY keep unconsumed values around
for some reasonable amount of time to handle out-of-order message delivery.</t>

<t>For example, suppose a group member encrypts or (successfully) decrypts an
application message using the j-th key and nonce in the ratchet of node
index N in some epoch n. Then, for that member, at least the following
values have been consumed and MUST be deleted:</t>

<t><list style="symbols">
  <t>the <spanx style="verb">commit_secret</spanx>, <spanx style="verb">joiner_secret</spanx>, <spanx style="verb">epoch_secret</spanx>, <spanx style="verb">encryption_secret</spanx> of
that epoch n as well as the <spanx style="verb">init_secret</spanx> of the previous epoch n-1,</t>
  <t>all node secrets in the Secret Tree on the path from the root to the leaf with
node index N,</t>
  <t>the first j secrets in the application data ratchet of node index N and</t>
  <t><spanx style="verb">application_ratchet_nonce_[N]_[j]</spanx> and <spanx style="verb">application_ratchet_key_[N]_[j]</spanx>.</t>
</list></t>

<t>Concretely, suppose we have the following Secret Tree and ratchet for
participant D:</t>

<figure><artwork><![CDATA[
       G
     /   \
    /     \
   E       F
  / \     / \
 A   B   C   D
            / \
          HR0  AR0 -+- K0
                |   |
                |   +- N0
                |
               AR1 -+- K1
                |   |
                |   +- N1
                |
               AR2
]]></artwork></figure>

<t>Then if a client uses key K1 and nonce N1 during epoch n then it must consume
(at least) values G, F, D, AR0, AR1, K1, N1 as well as the key schedule secrets
used to derive G (the <spanx style="verb">encryption_secret</spanx>), namely <spanx style="verb">init_secret</spanx> of epoch n-1
and <spanx style="verb">commit_secret</spanx>, <spanx style="verb">joiner_secret</spanx>, <spanx style="verb">epoch_secret</spanx> of epoch n. The client MAY
retain (not consume) the values K0 and N0 to allow for out-of-order delivery,
and SHOULD retain AR2 for processing future messages.</t>

</section>
<section anchor="exporters" title="Exporters">

<t>The main MLS key schedule provides an <spanx style="verb">exporter_secret</spanx> which can
be used by an application as the basis to derive new secrets called
<spanx style="verb">exported_value</spanx> outside the MLS layer.</t>

<figure><artwork><![CDATA[
MLS-Exporter(Label, Context, key_length) =
       ExpandWithLabel(DeriveSecret(exporter_secret, Label),
                         "exporter", Hash(Context), key_length)
]]></artwork></figure>

<t>Each application SHOULD provide a unique label to <spanx style="verb">MLS-Exporter</spanx> that
identifies its use case. This is to prevent two
exported outputs from being generated with the same values and used
for different functionalities.</t>

<t>The exported values are bound to the group epoch from which the
<spanx style="verb">exporter_secret</spanx> is derived, hence reflects a particular state of
the group.</t>

<t>It is RECOMMENDED for the application generating exported values
to refresh those values after a Commit is processed.</t>

</section>
<section anchor="resumption-secret" title="Resumption Secret">

<t>The main MLS key schedule provides a <spanx style="verb">resumption_secret</spanx> which can provide extra
security in some cross-group operations.</t>

<t>The application SHOULD specify an upper limit on the number of past
epochs for which the <spanx style="verb">resumption_secret</spanx> may be stored.</t>

<t>There are two ways in which a <spanx style="verb">resumption_secret</spanx> can be used: to re-initialize
the group with different parameters, or to create a
sub-group of an existing group as detailed in <xref target="pre-shared-keys"/>.</t>

<t>Resumption keys are distinguished from exporter keys in that they have specific
use inside the MLS protocol, whereas the use of exporter secrets may be
decided by an external application. They are thus derived separately to avoid
key material reuse.</t>

</section>
<section anchor="state-authentication-keys" title="State Authentication Keys">

<t>The main MLS key schedule provides a per-epoch <spanx style="verb">authentication_secret</spanx>.
If one of the parties is being actively impersonated by an attacker, their
<spanx style="verb">authentication_secret</spanx> will differ from that of the other group members.
Thus, members of a group MAY use their <spanx style="verb">authentication_secrets</spanx> within
an out-of-band authentication protocol to ensure that they
share the same view of the group.</t>

</section>
</section>
<section anchor="message-framing" title="Message Framing">

<t>Handshake and application messages use a common framing structure.
This framing provides encryption to ensure confidentiality within the
group, as well as signing to authenticate the sender within the group.</t>

<t>The two main structures involved are MLSPlaintext and MLSCiphertext.
MLSCiphertext represents a signed and encrypted message, with
protections for both the content of the message and related
metadata.  MLSPlaintext represents a message that is only signed,
and not encrypted.  Applications MUST use MLSCiphertext to encrypt
application messages and SHOULD use MLSCiphertext to encode
handshake messages, but MAY transmit handshake messages encoded
as MLSPlaintext objects in cases where it is necessary for the
Delivery Service to examine such messages.</t>

<figure><artwork><![CDATA[
enum {
    reserved(0),
    application(1),
    proposal(2),
    commit(3),
    (255)
} ContentType;

enum {
    reserved(0),
    member(1),
    preconfigured(2),
    new_member(3),
    (255)
} SenderType;

struct {
    SenderType sender_type;
    uint32 sender;
} Sender;

struct {
    opaque mac_value<0..255>;
} MAC;

struct {
    opaque group_id<0..255>;
    uint64 epoch;
    Sender sender;
    opaque authenticated_data<0..2^32-1>;

    ContentType content_type;
    select (MLSPlaintext.content_type) {
        case application:
          opaque application_data<0..2^32-1>;

        case proposal:
          Proposal proposal;

        case commit:
          Commit commit;
    }

    opaque signature<0..2^16-1>;
    optional<MAC> confirmation_tag;
    optional<MAC> membership_tag;
} MLSPlaintext;

struct {
    opaque group_id<0..255>;
    uint64 epoch;
    ContentType content_type;
    opaque authenticated_data<0..2^32-1>;
    opaque encrypted_sender_data<0..255>;
    opaque ciphertext<0..2^32-1>;
} MLSCiphertext;
]]></artwork></figure>

<t>The field <spanx style="verb">confirmation_tag</spanx> MUST be present if <spanx style="verb">content_type</spanx> equals commit.
Otherwise, it MUST NOT be present.</t>

<t>External sender types are sent as MLSPlaintext, see <xref target="external-proposals"/>
for their use.</t>

<t>The remainder of this section describes how to compute the signature of an
MLSPlaintext object and how to convert it to an MLSCiphertext object for
<spanx style="verb">member</spanx> sender types.  The steps are:</t>

<t><list style="symbols">
  <t>Set group_id, epoch, content_type and authenticated_data fields from the
MLSPlaintext object directly</t>
  <t>Identify the key and key generation depending on the content type</t>
  <t>Encrypt an MLSCiphertextContent for the ciphertext field using the key
identified and MLSPlaintext object</t>
  <t>Encrypt the sender data using a key and nonce derived from the
<spanx style="verb">sender_data_secret</spanx> for the epoch and a sample of the encrypted
MLSCiphertextContent.</t>
</list></t>

<t>Decryption is done by decrypting the sender data, then the message, and then
verifying the content signature.</t>

<t>The following sections describe the encryption and signing processes in detail.</t>

<section anchor="content-authentication" title="Content Authentication">

<t>The <spanx style="verb">signature</spanx> field in an MLSPlaintext object is computed using the signing
private key corresponding to the public key, which was authenticated by the
credential at the leaf of the tree indicated by the sender field. The signature
covers the plaintext metadata and message content, which is all of MLSPlaintext
except for the <spanx style="verb">signature</spanx>, the <spanx style="verb">confirmation_tag</spanx> and <spanx style="verb">membership_tag</spanx> fields.
If the sender is a member of the group, the signature also covers the
GroupContext for the current epoch, so that signatures are specific to a given
group and epoch.</t>

<figure><artwork><![CDATA[
struct {
    select (MLSPlaintextTBS.sender.sender_type) {
        case member:
            GroupContext context;
    }

    opaque group_id<0..255>;
    uint64 epoch;
    Sender sender;
    opaque authenticated_data<0..2^32-1>;

    ContentType content_type;
    select (MLSPlaintextTBS.content_type) {
        case application:
          opaque application_data<0..2^32-1>;

        case proposal:
          Proposal proposal;

        case commit:
          Commit commit;
    }
} MLSPlaintextTBS;
]]></artwork></figure>

<t>The <spanx style="verb">membership_tag</spanx> field in the MLSPlaintext object authenticates the sender's
membership in the group. For an MLSPlaintext with a sender type other than
<spanx style="verb">member</spanx>, this field MUST be omitted. For messages sent by members, it MUST be
present and set to the following value:</t>

<figure><artwork><![CDATA[
struct {
  MLSPlaintextTBS tbs;
  opaque signature<0..2^16-1>;
  optional<MAC> confirmation_tag;
} MLSPlaintextTBM;

membership_tag = MAC(membership_key, MLSPlaintextTBM);
]]></artwork></figure>

<t>Note that the <spanx style="verb">membership_tag</spanx> only needs to be computed for MLSPlaintext
messages that will be sent over the wire, and isn't needed for those that will
be encrypted and transmitted as MLSCiphertext messages.</t>

</section>
<section anchor="content-encryption" title="Content Encryption">

<t>The <spanx style="verb">ciphertext</spanx> 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 the content and signature of the MLSPlaintext, plus
optional padding. These values are encoded in the following form:</t>

<figure><artwork><![CDATA[
struct {
    select (MLSCiphertext.content_type) {
        case application:
          opaque application_data<0..2^32-1>;

        case proposal:
          Proposal proposal;

        case commit:
          Commit commit;
    }

    opaque signature<0..2^16-1>;
    optional<MAC> confirmation_tag;
    opaque padding<0..2^16-1>;
} MLSCiphertextContent;
]]></artwork></figure>

<t>In the MLS key schedule, the sender creates two distinct key ratchets for
handshake and application messages for each member of the group. When encrypting
a message, the sender looks at the ratchets it derived for its own member and
chooses an unused generation from either the handshake or application ratchet
depending on the content type of the message. This generation of the ratchet is
used to derive a provisional nonce and key.</t>

<t>Before use in the encryption operation, the nonce is XORed with a fresh random
value to guard against reuse.  Because the key schedule generates nonces
deterministically, a client must keep persistent state as to where in the key
schedule it is; if this persistent state is lost or corrupted, a client might
reuse a generation that has already been used, causing reuse of a key/nonce pair.</t>

<t>To avoid this situation, the sender of a message MUST generate a fresh random
4-byte "reuse guard" value and XOR it with the first four bytes of the nonce
from the key schedule before using the nonce for encryption.  The sender MUST
include the reuse guard in the <spanx style="verb">reuse_guard</spanx> field of the sender data object, so
that the recipient of the message can use it to compute the nonce to be used for
decryption.</t>

<figure><artwork><![CDATA[
+-+-+-+-+---------...---+
|   Key Schedule Nonce  |
+-+-+-+-+---------...---+
           XOR
+-+-+-+-+---------...---+
| Guard |       0       |
+-+-+-+-+---------...---+
           ===
+-+-+-+-+---------...---+
| Encrypt/Decrypt Nonce |
+-+-+-+-+---------...---+
]]></artwork></figure>

<t>The Additional Authenticated Data (AAD) input to the encryption
contains an object of the following form, with the values used to
identify the key and nonce:</t>

<figure><artwork><![CDATA[
struct {
    opaque group_id<0..255>;
    uint64 epoch;
    ContentType content_type;
    opaque authenticated_data<0..2^32-1>;
} MLSCiphertextContentAAD;
]]></artwork></figure>

</section>
<section anchor="sender-data-encryption" title="Sender Data Encryption">

<t>The "sender data" used to look up the key for the content encryption is
encrypted with the ciphersuite's AEAD with a key and nonce derived from both the
<spanx style="verb">sender_data_secret</spanx> and a sample of the encrypted content. Before being
encrypted, the sender data is encoded as an object of the following form:</t>

<figure><artwork><![CDATA[
struct {
    uint32 sender;
    uint32 generation;
    opaque reuse_guard[4];
} MLSSenderData;
]]></artwork></figure>

<t>MLSSenderData.sender is assumed to be a <spanx style="verb">member</spanx> sender type.  When constructing
an MLSSenderData from a Sender object, the sender MUST verify Sender.sender_type
is <spanx style="verb">member</spanx> and use Sender.sender for MLSSenderData.sender.</t>

<t>The <spanx style="verb">reuse_guard</spanx> field contains a fresh random value used to avoid nonce reuse
in the case of state loss or corruption, as described in <xref target="content-encryption"/>.</t>

<t>The key and nonce provided to the AEAD are computed as the KDF of the first
<spanx style="verb">KDF.Nh</spanx> bytes of the ciphertext generated in the previous section. If the
length of the ciphertext is less than <spanx style="verb">KDF.Nh</spanx>, the whole ciphertext is used
without padding. In pseudocode, the key and nonce are derived as:</t>

<figure><artwork><![CDATA[
ciphertext_sample = ciphertext[0..KDF.Nh-1]

sender_data_key = ExpandWithLabel(sender_data_secret, "key", ciphertext_sample, AEAD.Nk)
sender_data_nonce = ExpandWithLabel(sender_data_secret, "nonce", ciphertext_sample, AEAD.Nn)
]]></artwork></figure>

<t>The Additional Authenticated Data (AAD) for the SenderData ciphertext is all the
fields of MLSCiphertext excluding <spanx style="verb">encrypted_sender_data</spanx>:</t>

<figure><artwork><![CDATA[
struct {
    opaque group_id<0..255>;
    uint64 epoch;
    ContentType content_type;
} MLSSenderDataAAD;
]]></artwork></figure>

<t>When parsing a SenderData struct as part of message decryption, the
recipient MUST verify that the sender field represents an occupied
leaf in the ratchet tree.  In particular, the sender index value
MUST be less than the number of leaves in the tree.</t>

</section>
</section>
<section anchor="group-creation" title="Group Creation">

<t>A group is always created with a single member, the "creator".  The other
members are added when the creator effectively sends itself an Add proposal and
commits it, then sends the corresponding Welcome message to the new
participants.  These processes are described in detail in <xref target="add"/>, <xref target="commit"/>,
and <xref target="welcoming-new-members"/>.</t>

<t>The creator of a group MUST take the following steps to initialize the group:</t>

<t><list style="symbols">
  <t>Fetch KeyPackages for the members to be added, and select a version and
ciphersuite according to the capabilities of the members.  To protect against
downgrade attacks, the creator MUST use the <spanx style="verb">capabilities</spanx> extensions
in these KeyPackages to verify that the
chosen version and ciphersuite is the best option supported by all members.</t>
  <t>Initialize a one-member group with the following initial values:
  <list style="symbols">
      <t>Ratchet tree: A tree with a single node, a leaf containing an HPKE public
key and credential for the creator</t>
      <t>Group ID: A value set by the creator</t>
      <t>Epoch: 0</t>
      <t>Tree hash: The root hash of the above ratchet tree</t>
      <t>Confirmed transcript hash: the zero-length octet string</t>
      <t>Interim transcript hash: the zero-length octet string</t>
      <t>Init secret: a fresh random value of size <spanx style="verb">KDF.Nh</spanx></t>
    </list></t>
  <t>For each member, construct an Add proposal from the KeyPackage for that
member (see <xref target="add"/>)</t>
  <t>Construct a Commit message that commits all of the Add proposals, in any order
chosen by the creator (see <xref target="commit"/>)</t>
  <t>Process the Commit message to obtain a new group state (for the epoch in which
the new members are added) and a Welcome message</t>
  <t>Transmit the Welcome message to the other new members</t>
</list></t>

<t>The recipient of a Welcome message processes it as described in
<xref target="welcoming-new-members"/>.</t>

<t>In principle, the above process could be streamlined by having the
creator directly create a tree and choose a random value for first
epoch's epoch secret.  We follow the steps above because it removes
unnecessary choices, by which, for example, bad randomness could be
introduced.  The only choices the creator makes here are its own
KeyPackage, the leaf secret from which the Commit is built, and the
intermediate key pairs along the direct path to the root.</t>

<section anchor="linking-a-new-group-to-an-existing-group" title="Linking a New Group to an Existing Group">

<t>A new group may be tied to an already existing group for the purpose of
re-initializing the existing group, or to branch into a sub-group.
Re-initializing an existing group may be used, for example, to restart the group
with a different ciphersuite or protocol version. Branching may be used to
bootstrap a new group consisting of a subset of current group members, based on
the current group state.</t>

<t>In both cases, the <spanx style="verb">psk_nonce</spanx> included in the <spanx style="verb">PreSharedKeyID</spanx> object must be a
randomly sampled nonce of length <spanx style="verb">KDF.Nh</spanx> to avoid key re-use.</t>

<section anchor="sub-group-branching" title="Sub-group Branching">

<t>If a client wants to create a subgroup of an existing group, they MAY choose to
include a <spanx style="verb">PreSharedKeyID</spanx> in the <spanx style="verb">GroupSecrets</spanx> object of the Welcome message choosing
the <spanx style="verb">psktype</spanx> <spanx style="verb">branch</spanx>, the <spanx style="verb">group_id</spanx> of the group from which a subgroup is to
be branched, as well as an epoch within the number of epochs for which a
<spanx style="verb">resumption_secret</spanx> is kept.</t>

</section>
</section>
</section>
<section anchor="group-evolution" title="Group Evolution">

<t>Over the lifetime of a group, its membership can change, and existing members
might want to change their keys in order to achieve post-compromise security. In
MLS, each such change is accomplished by a two-step process:</t>

<t><list style="numbers">
  <t>A proposal to make the change is broadcast to the group in a Proposal message</t>
  <t>A member of the group or a new member broadcasts a Commit message that causes one or more
proposed changes to enter into effect</t>
</list></t>

<t>The group thus evolves from one cryptographic state to another each time a
Commit message is sent and processed.  These states are referred to as "epochs"
and are uniquely identified among states of the group by eight-octet epoch values.
When a new group is initialized, its initial state epoch is 0x0000000000000000.  Each time
a state transition occurs, the epoch number is incremented by one.</t>

<section anchor="proposals" title="Proposals">

<t>Proposals are included in an MLSPlaintext by way of a Proposal structure that
indicates their type:</t>

<figure><artwork><![CDATA[
enum {
    reserved(0),
    add(1),
    update(2),
    remove(3),
    psk(4),
    reinit(5),
    external_init(6),
    app_ack(7),
    (255)
} ProposalType;

struct {
    ProposalType msg_type;
    select (Proposal.msg_type) {
        case add:           Add;
        case update:        Update;
        case remove:        Remove;
        case psk:           PreSharedKey;
        case reinit:        ReInit;
        case external_init: ExternalInit;
        case app_ack:       AppAck;
    };
} Proposal;
]]></artwork></figure>

<t>On receiving an MLSPlaintext containing a Proposal, a client MUST verify the
signature on the enclosing MLSPlaintext.  If the signature verifies
successfully, 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.</t>

<section anchor="add" title="Add">

<t>An Add proposal requests that a client with a specified KeyPackage be added
to the group.</t>

<figure><artwork><![CDATA[
struct {
    KeyPackage key_package;
} Add;
]]></artwork></figure>

<t>The proposer of the Add does not control where in the group's ratchet tree the
new member is added.  Instead, the sender of the Commit message chooses a
location for each added member and states it in the Commit message.</t>

<t>An Add is applied after being included in a Commit message.  The position of the
Add in the list of proposals determines the leaf index <spanx style="verb">index</spanx> where the new member
will be added.  For the first Add in the Commit, <spanx style="verb">index</spanx> is the leftmost empty
leaf in the tree, for the second Add, the next empty leaf to the right, etc.</t>

<t><list style="symbols">
  <t>If necessary, extend the tree to the right until it has at least index + 1
leaves</t>
  <t>For each non-blank intermediate node along the path from the leaf at position
<spanx style="verb">index</spanx> to the root, add <spanx style="verb">index</spanx> to the <spanx style="verb">unmerged_leaves</spanx> list for the node.</t>
  <t>Set the leaf node in the tree at position <spanx style="verb">index</spanx> to a new node containing the
public key from the KeyPackage in the Add, as well as the credential under
which the KeyPackage was signed</t>
</list></t>

</section>
<section anchor="update" title="Update">

<t>An Update proposal is a similar mechanism to Add with the distinction
that it is the sender's leaf KeyPackage in the tree which would be
updated with a new KeyPackage.</t>

<figure><artwork><![CDATA[
struct {
    KeyPackage key_package;
} Update;
]]></artwork></figure>

<t>A member of the group applies an Update message by taking the following steps:</t>

<t><list style="symbols">
  <t>Replace the sender's leaf KeyPackage with the one contained in
the Update proposal</t>
  <t>Blank the intermediate nodes along the path from the sender's leaf to the root</t>
</list></t>

</section>
<section anchor="remove" title="Remove">

<t>A Remove proposal requests that the client at a specified index in the tree be
removed from the group.</t>

<figure><artwork><![CDATA[
struct {
    uint32 removed;
} Remove;
]]></artwork></figure>

<t>A member of the group applies a Remove message by taking the following steps:</t>

<t><list style="symbols">
  <t>Replace the leaf node at position <spanx style="verb">removed</spanx> with a blank node</t>
  <t>Blank the intermediate nodes along the path from the removed leaf to the root</t>
</list></t>

</section>
<section anchor="presharedkey" title="PreSharedKey">

<t>A PreSharedKey proposal can be used to request that a pre-shared key be
injected into the key schedule in the process of advancing the epoch.</t>

<figure><artwork><![CDATA[
struct {
    PreSharedKeyID psk;
} PreSharedKey;
]]></artwork></figure>

<t>The <spanx style="verb">psktype</spanx> of the pre-shared key MUST be <spanx style="verb">external</spanx> and the <spanx style="verb">psk_nonce</spanx> MUST
be a randomly sampled nonce of length <spanx style="verb">KDF.Nh</spanx>. When processing a Commit message
that includes one or more PreSharedKey proposals, group members derive
<spanx style="verb">psk_secret</spanx> as described in <xref target="pre-shared-keys"/>, where the order of the PSKs
corresponds to the order of the <spanx style="verb">PreSharedKey</spanx> proposals in the Commit.</t>

</section>
<section anchor="reinit" title="ReInit">

<t>A ReInit proposal represents a request to re-initialize the group with different
parameters, for example, to increase the version number or to change the
ciphersuite. The re-initialization is done by creating a completely new group
and shutting down the old one.</t>

<figure><artwork><![CDATA[
struct {
    opaque group_id<0..255>;
    ProtocolVersion version;
    CipherSuite cipher_suite;
    Extension extensions<0..2^32-1>;
} ReInit;
]]></artwork></figure>

<t>A member of the group applies a ReInit proposal by waiting for the committer to
send the Welcome message and by checking that the <spanx style="verb">group_id</spanx> and the parameters
of the new group corresponds to the ones specified in the proposal. The Welcome
message MUST specify exactly one pre-shared key with <spanx style="verb">psktype = reinit</spanx>, and with
<spanx style="verb">psk_group_id</spanx> and <spanx style="verb">psk_epoch</spanx> equal to the <spanx style="verb">group_id</spanx> and <spanx style="verb">epoch</spanx> of the
existing group after the Commit containing the <spanx style="verb">reinit</spanx> Proposal was processed.
The Welcome message may specify the inclusion of other pre-shared keys with a
<spanx style="verb">psktype</spanx> different from <spanx style="verb">reinit</spanx>.</t>

<t>If a ReInit proposal is included in a Commit, it MUST be the only proposal
referenced by the Commit. If other non-ReInit proposals have been sent during
the epoch, the committer SHOULD prefer them over the ReInit proposal, allowing
the ReInit to be resent and applied in a subsequent epoch. The <spanx style="verb">version</spanx> field
in the ReInit proposal MUST be no less than the version for the current group.</t>

</section>
<section anchor="externalinit" title="ExternalInit">

<t>An ExternalInit proposal is used by new members that want to join a group by
using an external commit. This propsal can only be used in that context.</t>

<figure><artwork><![CDATA[
struct {
  opaque kem_output<0..2^16-1>;
} ExternalInit;
]]></artwork></figure>

<t>A member of the group applies an ExternalInit message by initializing the next
epoch using an init secret computed as described in <xref target="external-initialization"/>.
The <spanx style="verb">kem_output</spanx> field contains the required KEM output.</t>

</section>
<section anchor="appack" title="AppAck">

<t>An AppAck proposal is used to acknowledge receipt of application messages.
Though this information implies no change to the group, it is structured as a
Proposal message so that it is included in the group's transcript by being
included in Commit messages.</t>

<figure><artwork><![CDATA[
struct {
    uint32 sender;
    uint32 first_generation;
    uint32 last_generation;
} MessageRange;

struct {
    MessageRange received_ranges<0..2^32-1>;
} AppAck;
]]></artwork></figure>

<t>An AppAck proposal represents a set of messages received by the sender in the
current epoch.  Messages are represented by the <spanx style="verb">sender</spanx> and <spanx style="verb">generation</spanx> values
in the MLSCiphertext for the message.  Each MessageRange represents receipt of a
span of messages whose <spanx style="verb">generation</spanx> values form a continuous range from
<spanx style="verb">first_generation</spanx> to <spanx style="verb">last_generation</spanx>, inclusive.</t>

<t>AppAck proposals are sent as a guard against the Delivery Service dropping
application messages.  The sequential nature of the <spanx style="verb">generation</spanx> field provides
a degree of loss detection, since gaps in the <spanx style="verb">generation</spanx> sequence indicate
dropped messages.  AppAck completes this story by addressing the scenario where
the Delivery Service drops all messages after a certain point, so that a later
generation is never observed.  Obviously, there is a risk that AppAck messages
could be suppressed as well, but their inclusion in the transcript means that if
they are suppressed then the group cannot advance at all.</t>

<t>The schedule on which sending AppAck proposals are sent is up to the application,
and determines which cases of loss/suppression are detected.  For example:</t>

<t><list style="symbols">
  <t>The application might have the committer include an AppAck proposal whenever a
Commit is sent, so that other members could know when one of their messages
did not reach the committer.</t>
  <t>The application could have a client send an AppAck whenever an application
message is sent, covering all messages received since its last AppAck.  This
would provide a complete view of any losses experienced by active members.</t>
  <t>The application could simply have clients send AppAck proposals on a timer, so
that all participants' state would be known.</t>
</list></t>

<t>An application using AppAck proposals to guard against loss/suppression of
application messages also needs to ensure that AppAck messages and the Commits
that reference them are not dropped.  One way to do this is to always encrypt
Proposal and Commit messages, to make it more difficult for the Delivery Service
to recognize which messages conatain AppAcks.  The application can also have
clients enforce an AppAck schedule, reporting loss if an AppAck is not received
at the expected time.</t>

</section>
<section anchor="external-proposals" title="External Proposals">

<t>Add and Remove proposals can be constructed and sent to the group by a party
that is outside the group.  For example, a Delivery Service might propose to
remove a member of a group who 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 group are identified by a <spanx style="verb">preconfigured</spanx> or
<spanx style="verb">new_member</spanx> SenderType in MLSPlaintext.</t>

<t>ReInit proposals can also be sent to the group by a <spanx style="verb">preconfigured</spanx> sender, for
example to enforce a changed policy regarding MLS version or ciphersuite.</t>

<t>The <spanx style="verb">new_member</spanx> SenderType is used for clients proposing that they themselves
be added.  For this ID type the sender value MUST be zero and the Proposal type
MUST be Add. The MLSPlaintext MUST be signed with the private key corresponding
to the KeyPackage in the Add message.  Recipients MUST verify that the
MLSPlaintext carrying the Proposal message is validly signed with this key.</t>

<t>The <spanx style="verb">preconfigured</spanx> SenderType is reserved for signers that are pre-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 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.</t>

<t>An external proposal MUST be sent as an MLSPlaintext
object, since the sender will not have the keys necessary to construct an
MLSCiphertext object.</t>

<!-- TODO: Should recognized external signers be added to some object that the
group explicitly agrees on, e.g., as an extension to the GroupContext? -->

</section>
</section>
<section anchor="commit" title="Commit">

<t>A Commit message initiates a new epoch for the group, based on a collection of
Proposals. It instructs group members to update their representation of the
state of the group by applying the proposals and advancing the key schedule.</t>

<t>Each proposal covered by the Commit is included by a ProposalOrRef value, which
identifies the proposal to be applied by value or by reference.  Proposals
supplied by value are included directly in the Commit object.  Proposals
supplied by reference are specified by including the hash of the MLSPlaintext in
which the Proposal was sent, using the hash function from the group's
ciphersuite.  For proposals supplied by value, the sender of the proposal is the
same as the sender of the Commit.  Conversely, proposals sent by people other
than the committer MUST be included by reference.</t>

<figure><artwork><![CDATA[
enum {
  reserved(0),
  proposal(1)
  reference(2),
  (255)
} ProposalOrRefType;

struct {
  ProposalOrRefType type;
  select (ProposalOrRef.type) {
    case proposal:  Proposal proposal;
    case reference: opaque hash<0..255>;
  }
} ProposalOrRef;

struct {
    ProposalOrRef proposals<0..2^32-1>;
    optional<UpdatePath> path;
} Commit;
]]></artwork></figure>

<t>A group member that has observed one or more proposals within an epoch MUST send
a Commit message before sending application data. This ensures, for example,
that any members whose removal was proposed during the epoch are actually
removed before any application data is transmitted.</t>

<t>The sender of a Commit MUST include all valid proposals that it has received
during the current epoch. Invalid proposals include, for example, proposals with
an invalid signature or proposals that are semantically invalid, such as an Add
when the sender does not have the application-level permission to add new users.
If there are multiple proposals that apply to the same leaf, the committer
chooses one and includes only that one in the Commit, considering the rest
invalid. The committer MUST prefer any Remove received, or the most recent
Update for the leaf if there are no Removes. If there are multiple Add proposals
for the same client, the committer again chooses one to include and considers
the rest invalid.</t>

<t>The Commit MUST NOT combine proposals sent within different epochs. In the event
that a valid proposal is omitted from the next Commit, the sender of the
proposal SHOULD retransmit it in the new epoch.</t>

<t>A member of the group MAY send a Commit that references no proposals at all,
which would thus have an empty <spanx style="verb">proposals</spanx> vector.  Such
a Commit resets the sender's leaf and the nodes along its direct path, and
provides forward secrecy and post-compromise security with regard to the sender
of the Commit.  An Update proposal can be regarded as a "lazy" version of this
operation, where only the leaf changes and intermediate nodes are blanked out.</t>

<t>The <spanx style="verb">path</spanx> field of a Commit message MUST be populated if the Commit covers at
least one Update or Remove proposal. The <spanx style="verb">path</spanx> field MUST also be populated
if the Commit covers no proposals at all (i.e., if the proposals vector
is empty). The <spanx style="verb">path</spanx> field MAY be omitted if the Commit covers only Add
proposals.  In pseudocode, the logic for validating a Commit is as follows:</t>

<figure><artwork><![CDATA[
hasUpdates = false
hasRemoves = false

for i, id in commit.proposals:
    proposal = proposalCache[id]
    assert(proposal != null)

    hasUpdates = hasUpdates || proposal.msg_type == update
    hasRemoves = hasRemoves || proposal.msg_type == remove

if len(commit.proposals) == 0 || hasUpdates || hasRemoves:
  assert(commit.path != null)
]]></artwork></figure>

<t>To summarize, a Commit can have three different configurations, with different
uses:</t>

<t><list style="numbers">
  <t>An "empty" Commit that references no proposals, which updates the committer's
contribution to the group and provides PCS with regard to the committer.</t>
  <t>An "add-only" Commit that references only Add proposals, in which the path is
optional.  Such a commit provides PCS with regard to the committer only if
the path field is present.</t>
  <t>A "full" Commit that references proposals of any type, which provides FS with
regard to any removed members and PCS for the committer and any updated
members.</t>
</list></t>

<t>A member of the group creates a Commit message and the corresponding Welcome
message at the same time, by taking the following steps:</t>

<t><list style="symbols">
  <t>Construct an initial Commit object with the <spanx style="verb">proposals</spanx>
field populated from Proposals received during the current epoch, and an empty
<spanx style="verb">path</spanx> field.</t>
  <t>Generate a provisional GroupContext object by applying the proposals
referenced in the initial Commit object, as described in <xref target="proposals"/>. Update
proposals are applied first, followed by Remove proposals, and then finally
Add proposals. Add proposals are applied in the order listed in the
<spanx style="verb">proposals</spanx> vector, and always to the leftmost unoccupied leaf in the tree, or
the right edge of the tree if all leaves are occupied.  <list style="symbols">
      <t>Note that the order in which different types of proposals are applied should
be updated by the implementation to include any new proposals added by
negotiated group extensions.</t>
      <t>PreSharedKey proposals are processed later when deriving the <spanx style="verb">psk_secret</spanx> for the Key
Schedule.</t>
    </list></t>
  <t>Decide whether to populate the <spanx style="verb">path</spanx> field: If the <spanx style="verb">path</spanx> field is required
based on the proposals that are in the commit (see above), then it MUST be
populated.  Otherwise, the sender MAY omit the <spanx style="verb">path</spanx> field at its discretion.</t>
  <t>If populating the <spanx style="verb">path</spanx> field: Create an UpdatePath using the new 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 <spanx style="verb">group_id</spanx>, <spanx style="verb">epoch</spanx>, <spanx style="verb">tree_hash</spanx>, and <spanx style="verb">confirmed_transcript_hash</spanx> values
in the initial GroupContext object.  The <spanx style="verb">leaf_key_package</spanx> for this
UpdatePath must have a <spanx style="verb">parent_hash</spanx> extension.  <list style="symbols">
      <t>Assign this UpdatePath to the <spanx style="verb">path</spanx> field in the Commit.</t>
      <t>Apply the UpdatePath to the tree, as described in
<xref target="synchronizing-views-of-the-tree"/>. Define <spanx style="verb">commit_secret</spanx> as the value
<spanx style="verb">path_secret[n+1]</spanx> derived from the <spanx style="verb">path_secret[n]</spanx> value assigned to
the root node.</t>
    </list></t>
  <t>If not populating the <spanx style="verb">path</spanx> field: Set the <spanx style="verb">path</spanx> field in the Commit to the
null optional.  Define <spanx style="verb">commit_secret</spanx> as the all-zero vector of the same
length as a <spanx style="verb">path_secret</spanx> value would be.</t>
  <t>If one or more PreSharedKey proposals are part of the commit, derive the <spanx style="verb">psk_secret</spanx>
as specified in <xref target="pre-shared-keys"/>, where the order of PSKs in the derivation
corresponds to the order of PreSharedKey proposals in the <spanx style="verb">proposals</spanx> vector.
Otherwise, set <spanx style="verb">psk_secret</spanx> to a zero-length octet string.</t>
  <t>Construct an MLSPlaintext object containing the Commit object. Sign the MLSPlaintext
using the current epoch's GroupContext as context. Use the signature, the
<spanx style="verb">commit_secret</spanx> and the <spanx style="verb">psk_secret</spanx> to advance the key schedule and compute
the <spanx style="verb">confirmation_tag</spanx> value in the MLSPlaintext.</t>
  <t>Update the tree in the provisional state by applying the direct path</t>
  <t>Construct a GroupInfo reflecting the new state:
  <list style="symbols">
      <t>Group ID, epoch, tree, confirmed transcript hash, and interim transcript
hash from the new state</t>
      <t>The confirmation_tag from the MLSPlaintext object</t>
      <t>Sign the GroupInfo using the member's private signing key</t>
      <t>Encrypt the GroupInfo using the key and nonce derived from the <spanx style="verb">joiner_secret</spanx>
for the new epoch (see <xref target="welcoming-new-members"/>)</t>
    </list></t>
  <t>For each new member in the group:
  <list style="symbols">
      <t>Identify the lowest common ancestor in the tree of the new member's
leaf node and the member sending the Commit</t>
      <t>If the <spanx style="verb">path</spanx> field was populated above: Compute the path secret
corresponding to the common ancestor node</t>
      <t>Compute an EncryptedGroupSecrets object that encapsulates the <spanx style="verb">init_secret</spanx>
for the current epoch and the path secret (if present).</t>
    </list></t>
  <t>Construct a Welcome message from the encrypted GroupInfo object, the encrypted
key packages, and any PSKs for which a proposal was included in the Commit. The
order of the <spanx style="verb">psks</spanx> MUST be the same as the order of PreSharedKey proposals in the
<spanx style="verb">proposals</spanx> vector.</t>
  <t>If a ReInit proposal was part of the Commit, the committer MUST create a new
group with the parameters specified in the ReInit proposal,
and with the same members as the original group.
The Welcome message MUST include a <spanx style="verb">PreSharedKeyID</spanx> with <spanx style="verb">psktype</spanx>
<spanx style="verb">reinit</spanx> and with <spanx style="verb">psk_group_id</spanx> and <spanx style="verb">psk_epoch</spanx> corresponding to the current
group and the epoch after the commit was processed.</t>
</list></t>

<t>A member of the group applies a Commit message by taking the following steps:</t>

<t><list style="symbols">
  <t>Verify that the <spanx style="verb">epoch</spanx> field of the enclosing MLSPlaintext message is equal
to the <spanx style="verb">epoch</spanx> field of the current GroupContext object</t>
  <t>Verify that the signature on the MLSPlaintext message verifies using the
public key from the credential stored at the leaf in the tree indicated by
the <spanx style="verb">sender</spanx> field.</t>
  <t>Verify that all PSKs specified in any PreSharedKey proposals in the <spanx style="verb">proposals</spanx> vector
are available.</t>
  <t>Generate a provisional GroupContext object by applying the proposals
referenced in the initial Commit object, as described in <xref target="proposals"/>. Update
proposals are applied first, followed by Remove proposals, and then finally
Add proposals. Add proposals are applied in the order listed in the
<spanx style="verb">proposals</spanx> vector, and always to the leftmost unoccupied leaf in the tree, or
the right edge of the tree if all leaves are occupied.  <list style="symbols">
      <t>Note that the order in which different types of proposals are applied should
be updated by the implementation to include any new proposals added by
negotiated group extensions.</t>
    </list></t>
  <t>Verify that the <spanx style="verb">path</spanx> value is populated if the <spanx style="verb">proposals</spanx> vector contains
any Update or Remove proposals, or if it's empty. Otherwise, the <spanx style="verb">path</spanx> value
MAY be omitted.</t>
  <t>If the <spanx style="verb">path</spanx> value is populated: Process the <spanx style="verb">path</spanx> value using the ratchet
tree the provisional GroupContext, to update the ratchet tree and generate the
<spanx style="verb">commit_secret</spanx>:  <list style="symbols">
      <t>Apply the UpdatePath to the tree, as described in
<xref target="synchronizing-views-of-the-tree"/>, and store <spanx style="verb">leaf_key_package</spanx> at the
Committer's leaf.</t>
      <t>Verify that the KeyPackage has a <spanx style="verb">parent_hash</spanx> extension and that its value
matches the new parent of the sender's leaf node.</t>
      <t>Define <spanx style="verb">commit_secret</spanx> as the value <spanx style="verb">path_secret[n+1]</spanx> derived from the
<spanx style="verb">path_secret[n]</spanx> value assigned to the root node.</t>
    </list></t>
  <t>If the <spanx style="verb">path</spanx> value is not populated: Define <spanx style="verb">commit_secret</spanx> as the all-zero
vector of the same length as a <spanx style="verb">path_secret</spanx> value would be.</t>
  <t>Update the new GroupContext's confirmed and interim transcript hashes using the
new Commit.</t>
  <t>If the <spanx style="verb">proposals</spanx> vector contains any PreSharedKey proposals, derive the
<spanx style="verb">psk_secret</spanx> as specified in <xref target="pre-shared-keys"/>, where the order of PSKs in
the derivation corresponds to the order of PreSharedKey proposals in the
<spanx style="verb">proposals</spanx> vector. Otherwise, set <spanx style="verb">psk_secret</spanx> to 0.</t>
  <t>Use the <spanx style="verb">commit_secret</spanx>, the <spanx style="verb">psk_secret</spanx>, the provisional GroupContext, and
the init secret from the previous epoch to compute the epoch secret and
derived secrets for the new epoch.</t>
  <t>Use the <spanx style="verb">confirmation_key</spanx> for the new epoch to compute the confirmation tag
for this message, as described below, and verify that it is the same as the
<spanx style="verb">confirmation_tag</spanx> field in the MLSPlaintext object.</t>
  <t>If the above checks are successful, consider the updated GroupContext object
as the current state of the group.</t>
  <t>If the Commit included a ReInit proposal, the client MUST NOT use the group to
send messages anymore. Instead, it MUST wait for a Welcome message from the committer
and check that  <list style="symbols">
      <t>The <spanx style="verb">version</spanx>, <spanx style="verb">cipher_suite</spanx> and <spanx style="verb">extensions</spanx> fields of the new group
corresponds to the ones in the <spanx style="verb">ReInit</spanx> proposal, and that the <spanx style="verb">version</spanx>
is greater than or equal to that of the original group.</t>
      <t>The <spanx style="verb">psks</spanx> field in the Welcome message includes a <spanx style="verb">PreSharedKeyID</spanx> with
<spanx style="verb">psktype</spanx> = <spanx style="verb">reinit</spanx>, and <spanx style="verb">psk_epoch</spanx> and <spanx style="verb">psk_group_id</spanx> equal to the epoch
and group ID of the original group after processing the Commit.</t>
    </list></t>
</list></t>

<t>The confirmation tag value confirms that the members of the group have arrived
at the same state of the group:</t>

<figure><artwork><![CDATA[
MLSPlaintext.confirmation_tag =
    MAC(confirmation_key, GroupContext.confirmed_transcript_hash)
]]></artwork></figure>

<section anchor="external-commits" title="External Commits">

<t>External Commits are a mechanism for new members (external parties that want to
become members of the group) to add themselves to a group, without requiring
that an existing member has to come online to issue a Commit that references an
Add Proposal.</t>

<t>Whether existing members of the group will accept or reject an External Commit
follows the same rules that are applied to other handshake messages.</t>

<t>New members can create and issue an External Commit if they have access to the
following information for the group's current epoch:</t>

<t><list style="symbols">
  <t>group ID</t>
  <t>epoch ID</t>
  <t>ciphersuite</t>
  <t>public tree hash</t>
  <t>interim transcript hash</t>
  <t>group extensions</t>
  <t>external public key</t>
</list></t>

<t>This information is aggregated in a <spanx style="verb">PublicGroupState</spanx> object as follows:</t>

<figure><artwork><![CDATA[
struct {
    CipherSuite cipher_suite;
    opaque group_id<0..255>;
    uint64 epoch;
    opaque tree_hash<0..255>;
    opaque interim_transcript_hash<0..255>;
    Extension extensions<0..2^32-1>;
    HPKEPublicKey external_pub;
    uint32 signer_index;
    opaque signature<0..2^16-1>;
} PublicGroupState;
]]></artwork></figure>

<t>Note that the <spanx style="verb">tree_hash</spanx> field is used the same way as in the Welcome message.
The full tree can be included via the <spanx style="verb">ratchet_tree</spanx> extension
<xref target="ratchet-tree-extension"/>.</t>

<t>The signature MUST verify using the public key taken from the credential in the
leaf node at position <spanx style="verb">signer_index</spanx>.  The signature covers the following
structure, comprising all the fields in the PublicGroupState above <spanx style="verb">signer_index</spanx>:</t>

<figure><artwork><![CDATA[
struct {
    opaque group_id<0..255>;
    uint64 epoch;
    opaque tree_hash<0..255>;
    opaque interim_transcript_hash<0..255>;
    Extension extensions<0..2^32-1>;
    HPKEPublicKey external_pub;
} PublicGroupStateTBS;
]]></artwork></figure>

<t>This signature authenticates the HPKE public key, so that the joiner knows that
the public key was provided by a member of the group.  The fields that are not
signed are included in the key schedule via the GroupContext object.  If the
joiner is provided an inaccurate data for these fields, then its external Commit
will have an incorrect <spanx style="verb">confirmation_tag</spanx> and thus be rejected.</t>

<t>The information in a PublicGroupState is not deemed public in general, but
applications can choose to make it available to new members in order to allow
External Commits.</t>

<t>External Commits work like regular Commits, with a few differences:</t>

<t><list style="symbols">
  <t>External Commits MUST reference an Add Proposal that adds the issuing new
member to the group</t>
  <t>External Commits MUST contain a <spanx style="verb">path</spanx> field (and is therefore a "full"
Commit)</t>
  <t>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 <spanx style="verb">leaf_key_package</spanx> of the <spanx style="verb">path</spanx> field.</t>
  <t>An external commit MUST reference no more than one ExternalInit proposal, and the
ExternalInit proposal MUST be supplied by value, not by reference. When
processing a Commit, both existing and new members MUST use the external init
secret as described in <xref target="external-initialization"/>.</t>
  <t>The sender type for the MLSPlaintext encapsulating the External Commit MUST be
<spanx style="verb">new_member</spanx></t>
  <t>If the Add Proposal is also issued by the new member, its member SenderType
MUST be <spanx style="verb">new_member</spanx></t>
</list></t>

</section>
<section anchor="welcoming-new-members" title="Welcoming New Members">

<t>The sender of a Commit message is responsible for sending a Welcome message to
any new members added via Add proposals.  The Welcome message provides the new
members with the current state of the group, after the application of the Commit
message.  The new members will not be able to decrypt or verify the Commit
message, but will have the secrets they need to participate in the epoch
initiated by the Commit message.</t>

<t>In order to allow the same Welcome message to be sent to all new members,
information describing the group is encrypted with a symmetric key and nonce
derived from the <spanx style="verb">joiner_secret</spanx> for the new epoch.  The <spanx style="verb">joiner_secret</spanx> is
then encrypted to each new member using HPKE.  In the same encrypted package,
the committer transmits the path secret for the lowest node contained in the
direct paths of both the committer and the new member.  This allows the new
member to compute private keys for nodes in its direct path that are being
reset by the corresponding Commit.</t>

<t>If the sender of the Welcome message wants the receiving member to include a PSK
in the derivation of the <spanx style="verb">epoch_secret</spanx>, they can populate the <spanx style="verb">psks</spanx> field indicating which
PSK to use.</t>

<figure><artwork><![CDATA[
struct {
  opaque group_id<0..255>;
  uint64 epoch;
  opaque tree_hash<0..255>;
  opaque confirmed_transcript_hash<0..255>;
  Extension extensions<0..2^32-1>;
  MAC confirmation_tag;
  uint32 signer_index;
  opaque signature<0..2^16-1>;
} GroupInfo;

struct {
  opaque path_secret<1..255>;
} PathSecret;

struct {
  opaque joiner_secret<1..255>;
  optional<PathSecret> path_secret;
  optional<PreSharedKeys> psks;
} GroupSecrets;

struct {
  opaque key_package_hash<1..255>;
  HPKECiphertext encrypted_group_secrets;
} EncryptedGroupSecrets;

struct {
  ProtocolVersion version = mls10;
  CipherSuite cipher_suite;
  EncryptedGroupSecrets secrets<0..2^32-1>;
  opaque encrypted_group_info<1..2^32-1>;
} Welcome;
]]></artwork></figure>

<t>The client processing a Welcome message will need to have a copy of the group's
ratchet tree.  The tree can be provided in the Welcome message, in an extension
of type <spanx style="verb">ratchet_tree</spanx>.  If it is sent otherwise (e.g., provided by a caching
service on the Delivery Service), then the client MUST download the tree before
processing the Welcome.</t>

<t>On receiving a Welcome message, a client processes it using the following steps:</t>

<t><list style="symbols">
  <t>Identify an entry in the <spanx style="verb">secrets</spanx> array where the <spanx style="verb">key_package_hash</spanx>
value corresponds to one of this client's KeyPackages, using the hash
indicated by the <spanx style="verb">cipher_suite</spanx> field. If no such field exists, or if the
ciphersuite indicated in the KeyPackage does not match the one in the
Welcome message, return an error.</t>
  <t>Decrypt the <spanx style="verb">encrypted_group_secrets</spanx> using HPKE with the algorithms indicated
by the ciphersuite and the HPKE private key corresponding to the GroupSecrets.
If a <spanx style="verb">PreSharedKeyID</spanx> is part of the GroupSecrets and the client is not in
possession of the corresponding PSK, return an error.</t>
  <t>From the <spanx style="verb">joiner_secret</spanx> in the decrypted GroupSecrets object and the PSKs
specified in the <spanx style="verb">GroupSecrets</spanx>, derive the <spanx style="verb">welcome_secret</spanx> and using that
the <spanx style="verb">welcome_key</spanx> and <spanx style="verb">welcome_nonce</spanx>. Use the key and nonce to decrypt the
<spanx style="verb">encrypted_group_info</spanx> field.</t>
</list></t>

<figure><artwork><![CDATA[
welcome_nonce = KDF.Expand(welcome_secret, "nonce", AEAD.Nn)
welcome_key = KDF.Expand(welcome_secret, "key", AEAD.Nk)
]]></artwork></figure>

<t><list style="symbols">
  <t>Verify the signature on the GroupInfo object.  The signature input comprises
all of the fields in the GroupInfo object except the signature field.  The
public key and algorithm are taken from the credential in the leaf node at
position <spanx style="verb">signer_index</spanx>.  If this verification fails, return an error.</t>
  <t>Verify the integrity of the ratchet tree.  <list style="symbols">
      <t>Verify that the tree hash of the ratchet tree matches the <spanx style="verb">tree_hash</spanx> field
in the GroupInfo.</t>
      <t>For each non-empty parent node, verify that exactly one of the node's
children are non-empty and have the hash of this node set as their
<spanx style="verb">parent_hash</spanx> value (if the child is another parent) or has a <spanx style="verb">parent_hash</spanx>
extension in the KeyPackage containing the same value (if the child is a
leaf). If either of the node's children is empty, and in particular does not
have a parent hash, then its respective children's <spanx style="verb">parent_hash</spanx> values have
to be considered instead.</t>
      <t>For each non-empty leaf node, verify the signature on the KeyPackage.</t>
    </list></t>
  <t>Identify a leaf in the <spanx style="verb">tree</spanx> array (any even-numbered node) whose
<spanx style="verb">key_package</spanx> field is identical to the the KeyPackage.  If no such field
exists, return an error.  Let <spanx style="verb">index</spanx> represent the index of this node among
the leaves in the tree, namely the index of the node in the <spanx style="verb">tree</spanx> array
divided by two.</t>
  <t>Construct a new group state using the information in the GroupInfo object.
The new member's position in the tree is <spanx style="verb">index</spanx>, as defined above.  In
particular, the confirmed transcript hash for the new state is the
<spanx style="verb">prior_confirmed_transcript_hash</spanx> in the GroupInfo object.  <list style="symbols">
      <t>Update the leaf at index <spanx style="verb">index</spanx> with the private key corresponding to the
public key in the node.</t>
      <t>If the <spanx style="verb">path_secret</spanx> value is set in the GroupSecrets object: Identify the
lowest common ancestor of the leaves at <spanx style="verb">index</spanx> and at
<spanx style="verb">GroupInfo.signer_index</spanx>.  Set the private key for this node to the
private key derived from the <spanx style="verb">path_secret</spanx>.</t>
      <t>For each parent of the common ancestor, up to the root of the tree, derive
a new path secret and set the private key for the node to the private key
derived from the path secret.  The private key MUST be the private key
that corresponds to the public key in the node.</t>
    </list></t>
  <t>Use the <spanx style="verb">joiner_secret</spanx> from the GroupSecrets object to generate the epoch secret
and other derived secrets for the current epoch.</t>
  <t>Set the confirmed transcript hash in the new state to the value of the
<spanx style="verb">confirmed_transcript_hash</spanx> in the GroupInfo.</t>
  <t>Verify the confirmation tag in the GroupInfo using the derived confirmation
key and the <spanx style="verb">confirmed_transcript_hash</spanx> from the GroupInfo.</t>
  <t>Use the confirmed transcript hash and confirmation tag to compute the interim
transcript hash in the new state.</t>
</list></t>

</section>
</section>
<section anchor="ratchet-tree-extension" title="Ratchet Tree Extension">

<t>By default, a GroupInfo message only provides the joiner with a commitment
to the group's ratchet tree.  In order to process or generate handshake
messages, the joiner will need to get a copy of the ratchet tree from some other
source.  (For example, the DS might provide a cached copy.)  The inclusion of
the tree hash in the GroupInfo message means that the source of the ratchet
tree need not be trusted to maintain the integrity of tree.</t>

<t>In cases where the application does not wish to provide such an external source,
the whole public state of the ratchet tree can be provided in an extension of
type <spanx style="verb">ratchet_tree</spanx>, containing a <spanx style="verb">ratchet_tree</spanx> object of the following form:</t>

<figure><artwork><![CDATA[
enum {
    reserved(0),
    leaf(1),
    parent(2),
    (255)
} NodeType;

struct {
    NodeType node_type;
    select (Node.node_type) {
        case leaf:   KeyPackage key_package;
        case parent: ParentNode node;
    };
} Node;

optional<Node> ratchet_tree<1..2^32-1>;
]]></artwork></figure>

<t>The presence of a <spanx style="verb">ratchet_tree</spanx> extension in a GroupInfo message does not
result in any changes to the GroupContext extensions for the group.  The ratchet
tree provided is simply stored by the client and used for MLS operations.</t>

<t>If this extension is not provided in a Welcome message, then the client will
need to fetch the ratchet tree over some other channel before it can generate or
process Commit messages.  Applications should ensure that this out-of-band
channel is provided with security protections equivalent to the protections that
are afforded to Proposal and Commit messages.  For example, an application that
encrypts Proposal and Commit messages might distribute ratchet trees encrypted
using a key exchanged over the MLS channel.</t>

</section>
</section>
<section anchor="extensibility" title="Extensibility">

<t>This protocol includes a mechanism for negotiating extension parameters similar
to the one in TLS <xref target="RFC8446"/>.  In TLS, extension negotiation is one-to-one: The
client offers extensions in its ClientHello message, and the server expresses
its choices for the session with extensions in its ServerHello and
EncryptedExtensions messages.  In MLS, extensions appear in the following
places:</t>

<t><list style="symbols">
  <t>In KeyPackages, to describe client capabilities and aspects of their
participation in the group (once in the ratchet tree)</t>
  <t>In the Welcome message, to tell new members of a group what parameters are
being used by the group</t>
  <t>In the GroupContext object, to ensure that all members of the group have the
same view of the parameters in use</t>
</list></t>

<t>In other words, clients advertise their capabilities in KeyPackage
extensions, the creator of the group expresses its choices for the group in
Welcome extensions, and the GroupContext confirms that all members of the group
have the same view of the group's extensions.</t>

<t>This extension mechanism is designed to allow for secure and forward-compatible
negotiation of extensions.  For this to work, implementations MUST correctly
handle extensible fields:</t>

<t><list style="symbols">
  <t>A client that posts a KeyPackage MUST support all parameters advertised in
it.  Otherwise, another client might fail to interoperate by selecting one of
those parameters.</t>
  <t>A client initiating a group MUST ignore all unrecognized ciphersuites,
extensions, and other parameters.  Otherwise, it may fail to interoperate with
newer clients.</t>
  <t>A client adding a new member to a group MUST verify that the KeyPackage
for the new member contains extensions that are consistent with the group's
extensions.  For each extension in the GroupContext, the KeyPackage MUST
have an extension of the same type, and the contents of the extension MUST be
consistent with the value of the extension in the GroupContext, according to
the semantics of the specific extension.</t>
  <t>If any extension in a GroupInfo message is unrecognized (i.e., not contained
in the corresponding KeyPackage), then the client MUST reject the Welcome
message and not join the group.</t>
  <t>The extensions populated into a GroupContext object are drawn from those in
the GroupInfo object, according to the definitions of those extensions.</t>
</list></t>

<t>Note that the latter two requirements mean that all MLS extensions are
mandatory, in the sense that an extension in use by the group MUST be supported
by all members of the group.</t>

<t>This document does not define any way for the parameters of the group to change
once it has been created; such a behavior could be implemented as an extension.</t>

</section>
<section anchor="sequencing" title="Sequencing of State Changes">

<t>Each Commit message is premised on a given starting state,
indicated by the <spanx style="verb">epoch</spanx> field of the enclosing MLSPlaintext
message. If the changes implied by a Commit messages are made
starting from a different state, the results will be incorrect.</t>

<t>This need for sequencing is not a problem as long as each time a
group member sends a Commit message, it is based on the most
current state of the group.  In practice, however, there is a risk
that two members will generate Commit messages simultaneously,
based on the same state.</t>

<t>When this happens, there is a need for the members of the group to
deconflict the simultaneous Commit messages.  There are two
general approaches:</t>

<t><list style="symbols">
  <t>Have the Delivery Service enforce a total order</t>
  <t>Have a signal in the message that clients can use to break ties</t>
</list></t>

<t>As long as Commit messages cannot be merged, there is a risk of
starvation.  In a sufficiently busy group, a given member may never
be able to send a Commit message, because he always loses to other
members.  The degree to which this is a practical problem will depend
on the dynamics of the application.</t>

<t>It might be possible, because of the non-contributivity of intermediate
nodes, that Commit messages could be applied one after the other
without the Delivery Service having to reject any Commit message,
which would make MLS more resilient regarding the concurrency of
Commit messages.
The Messaging system can decide to choose the order for applying
the state changes. Note that there are certain cases (if no total
ordering is applied by the Delivery Service) where the ordering is
important for security, ie. all updates must be executed before
removes.</t>

<t>Regardless of how messages are kept in sequence, implementations
MUST only update their cryptographic state when valid Commit
messages are received.
Generation of Commit messages MUST NOT modify a client's state, since the
endpoint doesn't know at that time whether the changes implied by
the Commit message will succeed or not.</t>

<section anchor="server-enforced-ordering" title="Server-Enforced Ordering">

<t>With this approach, the Delivery Service ensures that incoming
messages are added to an ordered queue and outgoing messages are
dispatched in the same order. The server is trusted to break ties
when two members send a Commit message at the same time.</t>

<t>Messages should have a counter field sent in clear-text that can
be checked by the server and used for tie-breaking. The counter
starts at 0 and is incremented for every new incoming message.
If two group members send a message with the same counter, the
first message to arrive will be accepted by the server and the
second one will be rejected. The rejected message needs to be sent
again with the correct counter number.</t>

<t>To prevent counter manipulation by the server, the counter's
integrity can be ensured by including the counter in a signed
message envelope.</t>

<t>This applies to all messages, not only state changing messages.</t>

</section>
<section anchor="client-enforced-ordering" title="Client-Enforced Ordering">

<t>Order enforcement can be implemented on the client as well,
one way to achieve it is to use a two step update protocol: the
first client sends a proposal to update and the proposal is
accepted when it gets 50%+ approval from the rest of the group,
then it sends the approved update. Clients which didn't get
their proposal accepted, will wait for the winner to send their
update before retrying new proposals.</t>

<t>While this seems safer as it doesn't rely on the server, it is
more complex and harder to implement. It also could cause starvation
for some clients if they keep failing to get their proposal accepted.</t>

</section>
</section>
<section anchor="application-messages" title="Application Messages">

<t>The primary purpose of the Handshake protocol is to provide an
authenticated group key exchange to clients. In order to protect
Application messages sent among the members of a group, the Application
secret provided by the Handshake key schedule is used to derive nonces
and encryption keys for the Message Protection Layer according to
the Application Key Schedule. That is, each epoch is equipped with
a fresh Application Key Schedule which consist of a tree of Application
Secrets as well as one symmetric ratchet per group member.</t>

<t>Each client maintains their own local copy of the Application Key
Schedule for each epoch during which they are a group member. They
derive new keys, nonces and secrets as needed while deleting old
ones as soon as they have been used.</t>

<t>Application messages MUST be protected with the Authenticated-Encryption
with Associated-Data (AEAD) encryption scheme associated with the
MLS ciphersuite using the common framing mechanism.
Note that "Authenticated" in this context does not mean messages are
known to be sent by a specific client but only from a legitimate
member of the group.
To authenticate a message from a particular member, signatures are
required. Handshake messages MUST use asymmetric signatures to strongly
authenticate the sender of a message.</t>

<section anchor="message-encryption-and-decryption" title="Message Encryption and Decryption">

<t>The group members MUST use the AEAD algorithm associated with
the negotiated MLS ciphersuite to AEAD encrypt and decrypt their
Application messages according to the Message Framing section.</t>

<t>The group identifier and epoch allow a recipient to know which group secrets
should be used and from which Epoch secret to start computing other secrets
and keys. The sender identifier is used to identify the member's
symmetric ratchet from the initial group Application secret. The application
generation field is used to determine how far into the ratchet to iterate in
order to reproduce the required AEAD keys and nonce for performing decryption.</t>

<t>Application messages SHOULD be padded to provide some resistance
against traffic analysis techniques over encrypted traffic.
<xref target="CLINIC"/>
<xref target="HCJ16"/>
While MLS might deliver the same payload less frequently across
a lot of ciphertexts than traditional web servers, it might still provide
the attacker enough information to mount an attack. If Alice asks Bob:
"When are we going to the movie ?" the answer "Wednesday" might be leaked
to an adversary by the ciphertext length. An attacker expecting Alice to
answer Bob with a day of the week might find out the plaintext by
correlation between the question and the length.</t>

<t>Similarly to TLS 1.3, if padding is used, the MLS messages MUST be
padded with zero-valued bytes before AEAD encryption. Upon AEAD decryption,
the length field of the plaintext is used to compute the number of bytes
to be removed from the plaintext to get the correct data.
As the padding mechanism is used to improve protection against traffic
analysis, removal of the padding SHOULD be implemented in a "constant-time"
manner at the MLS layer and above layers to prevent timing side-channels that
would provide attackers with information on the size of the plaintext.
The padding length length_of_padding can be chosen at the time of the message
encryption by the sender. Recipients can calculate the padding size from knowing
the total size of the ApplicationPlaintext and the length of the content.</t>

</section>
<section anchor="restrictions" title="Restrictions">

<t>During each epoch senders MUST NOT encrypt more data than permitted by the
security bounds of the AEAD scheme used.</t>

<t>Note that each change to the Group through a Handshake message will also set a
new <spanx style="verb">encryption_secret</spanx>. Hence this change MUST be applied before encrypting
any new application message. This is required both to ensure that any users
removed from the group can no longer receive messages and to (potentially)
recover confidentiality and authenticity for future messages despite a past
state compromise.</t>

</section>
<section anchor="delayed-and-reordered-application-messages" title="Delayed and Reordered Application messages">

<t>Since each Application message contains the group identifier, the epoch and a
message counter, a client can receive messages out of order.
If they are able to retrieve or recompute the correct AEAD decryption key
from currently stored cryptographic material clients can decrypt
these messages.</t>

<t>For usability, MLS clients might be required to keep the AEAD key
and nonce for a certain amount of time to retain the ability to decrypt
delayed or out of order messages, possibly still in transit while a
decryption is being done.</t>

<!-- TODO: Describe here or in the Architecture spec the details. Depending
on which Secret or key is kept alive, the security guarantees will vary. -->

</section>
</section>
<section anchor="security-considerations" title="Security Considerations">

<t>The security goals of MLS are described in <xref target="I-D.ietf-mls-architecture"/>.
We describe here how the protocol achieves its goals at a high level,
though a complete security analysis is outside of the scope of this
document.</t>

<section anchor="confidentiality-of-the-group-secrets" title="Confidentiality of the Group Secrets">

<t>Group secrets are partly derived from the output of a ratchet tree. Ratchet
trees work by assigning each member of the group to a leaf in the tree and
maintaining the following property: the private key of a node in the tree is
known only to members of the group that are assigned a leaf in the node's
subtree. This is called the <spanx style="emph">ratchet tree invariant</spanx> and it makes it possible to
encrypt to all group members except one, with a number of ciphertexts that's
logarithmic in the number of group members.</t>

<t>The ability to efficiently encrypt to all members except one allows members to
be securely removed from a group. It also allows a member to rotate their
keypair such that the old private key can no longer be used to decrypt new
messages.</t>

</section>
<section anchor="authentication" title="Authentication">

<t>The first form of authentication we provide is that group members can verify a
message originated from one of the members of the group. For encrypted messages,
this is guaranteed because messages are encrypted with an AEAD under a key
derived from the group secrets. For plaintext messages, this is guaranteed by
the use of a <spanx style="verb">membership_tag</spanx> which constitutes a MAC over the message, under a
key derived from the group secrets.</t>

<t>The second form of authentication is that group members can verify a message
originated from a particular member of the group. This is guaranteed by a
digital signature on each message from the sender's identity key.</t>

</section>
<section anchor="forward-secrecy-and-post-compromise-security" title="Forward Secrecy and Post-Compromise Security">

<t>Post-compromise security is provided between epochs by members regularly
updating their leaf key in the ratchet tree. Updating their leaf key prevents
group secrets from continuing to be encrypted to previously compromised public
keys.</t>

<t>Forward-secrecy between epochs is provided by deleting private keys from past
version of the ratchet tree, as this prevents old group secrets from being
re-derived. Forward secrecy <spanx style="emph">within</spanx> an epoch is provided by deleting message
encryption keys once they've been used to encrypt or decrypt a message.</t>

<t>Post-compromise security is also provided for new groups by members regularly
generating new InitKeys and uploading them to the Delivery Service, such that
compromised key material won't be used when the member is added to a new group.</t>

</section>
<section anchor="initkey-reuse" title="InitKey Reuse">

<t>InitKeys are intended to be used only once.  That is, once an InitKey has been
used to introduce the corresponding client to a group, it SHOULD be deleted from
the InitKey publication system.  Reuse of InitKeys can lead to replay attacks.</t>

<t>An application MAY allow for reuse of a "last resort" InitKey in order to
prevent denial of service attacks.  Since an InitKey is needed to add a client
to a new group, an attacker could prevent a client being added to new groups by
exhausting all available InitKeys.</t>

</section>
<section anchor="group-fragmentation-by-malicious-insiders" title="Group Fragmentation by Malicious Insiders">

<t>It is possible for a malicious member of a group to "fragment" the group by
crafting an invalid UpdatePath.  Recall that an UpdatePath encrypts a sequence
of path secrets to different subtrees of the group's ratchet trees.  These path
secrets should be derived in a sequence as described in
<xref target="ratchet-tree-evolution"/>, but the UpdatePath syntax allows the sender to
encrypt arbitrary, unrelated secrets.  The syntax also does not guarantee that
the encrypted path secret encrypted for a given node corresponds to the public
key provided for that node.</t>

<t>Both of these types of corruption will cause processing of a Commit to fail for
some members of the group.  If the public key for a node does not match the path
secret, then the members that decrypt that path secret will reject the commit
based on this mismatch.  If the path secret sequence is incorrect at some point,
then members that can decrypt nodes before that point will compute a different
public key for the mismatched node than the one in the UpdatePath, which also
causes the Commit to fail.  Applications SHOULD provide mechanisms for failed
commits to be reported, so that group members who were not able to recognize the
error themselves can reject the commit and roll back to a previous state if
necessary.</t>

<t>Even with such an error reporting mechanism in place, however, it is still
possible for members to get locked out of the group by a malformed commit.
Since malformed Commits can only be recognized by certain members of the group,
in an asynchronous application, it may be the case that all members that could
detect a fault in a Commit are offline.  In such a case, the Commit will be
accepted by the group, and the resulting state possibly used as the basis for
further Commits.  When the affected members come back online, they will reject
the first commit, and thus be unable to catch up with the group.</t>

<t>Applications can address this risk by requiring certain members of the group to
acknowledge successful processing of a Commit before the group regards the
Commit as accepted.  The minimum set of acknowledgements necessary to verify
that a Commit is well-formed comprises an acknowledgement from one member per
node in the UpdatePath, that is, one member from each subtree rooted in the
copath node corresponding to the node in the UpdatePath.</t>

</section>
</section>
<section anchor="iana-considerations" title="IANA Considerations">

<t>This document requests the creation of the following new IANA registries:</t>

<t><list style="symbols">
  <t>MLS Ciphersuites (<xref target="mls-ciphersuites"/>)</t>
  <t>MLS Extension Types (<xref target="mls-extension-types"/>)</t>
  <t>MLS Credential Types (<xref target="mls-credential-types"/>)</t>
</list></t>

<t>All of these registries should be under a heading of "Messaging Layer Security",
and assignments are made via the Specification Required policy <xref target="RFC8126"/>. See
<xref target="de"/> for additional information about the MLS Designated Experts (DEs).</t>

<t>RFC EDITOR: Please replace XXXX throughout with the RFC number assigned to
this document</t>

<section anchor="mls-ciphersuites" title="MLS Ciphersuites">

<t>A ciphersuite is a combination of a protocol version and the set of
cryptographic algorithms that should be used.</t>

<t>Ciphersuite names follow the naming convention:</t>

<figure><artwork><![CDATA[
CipherSuite MLS_LVL_KEM_AEAD_HASH_SIG = VALUE;
]]></artwork></figure>

<t>Where VALUE is represented as a sixteen-bit integer:</t>

<figure><artwork><![CDATA[
uint16 CipherSuite;
]]></artwork></figure>

<texttable>
      <ttcol align='left'>Component</ttcol>
      <ttcol align='left'>Contents</ttcol>
      <c>MLS</c>
      <c>The string "MLS" followed by the major and minor version, e.g. "MLS10"</c>
      <c>LVL</c>
      <c>The security level</c>
      <c>KEM</c>
      <c>The KEM algorithm used for HPKE in TreeKEM group operations</c>
      <c>AEAD</c>
      <c>The AEAD algorithm used for HPKE and message protection</c>
      <c>HASH</c>
      <c>The hash algorithm used for HPKE and the MLS transcript hash</c>
      <c>SIG</c>
      <c>The Signature algorithm used for message authentication</c>
</texttable>

<t>The columns in the registry are as follows:</t>

<t><list style="symbols">
  <t>Value: The numeric value of the ciphersuite</t>
  <t>Name: The name of the ciphersuite</t>
  <t>Recommended: Whether support for this extension is recommended 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 <xref target="RFC8126"></xref>.  IESG Approval
is REQUIRED for a Y-&gt;N transition.</t>
  <t>Reference: The document where this ciphersuite is defined</t>
</list></t>

<t>Initial contents:</t>

<texttable>
      <ttcol align='left'>Value</ttcol>
      <ttcol align='left'>Name</ttcol>
      <ttcol align='left'>Recommended</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c>0x0000</c>
      <c>RESERVED</c>
      <c>N/A</c>
      <c>RFC XXXX</c>
      <c>0x0001</c>
      <c>MLS10_128_DHKEMX25519_AES128GCM_SHA256_Ed25519</c>
      <c>Y</c>
      <c>RFC XXXX</c>
      <c>0x0002</c>
      <c>MLS10_128_DHKEMP256_AES128GCM_SHA256_P256</c>
      <c>Y</c>
      <c>RFC XXXX</c>
      <c>0x0003</c>
      <c>MLS10_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519</c>
      <c>Y</c>
      <c>RFC XXXX</c>
      <c>0x0004</c>
      <c>MLS10_256_DHKEMX448_AES256GCM_SHA512_Ed448</c>
      <c>Y</c>
      <c>RFC XXXX</c>
      <c>0x0005</c>
      <c>MLS10_256_DHKEMP521_AES256GCM_SHA512_P521</c>
      <c>Y</c>
      <c>RFC XXXX</c>
      <c>0x0006</c>
      <c>MLS10_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448</c>
      <c>Y</c>
      <c>RFC XXXX</c>
      <c>0xff00 - 0xffff</c>
      <c>Reserved for Private Use</c>
      <c>N/A</c>
      <c>RFC XXXX</c>
</texttable>

<t>All of these ciphersuites use HMAC <xref target="RFC2104"/> as their MAC function, with
different hashes per ciphersuite.  The mapping of ciphersuites to HPKE
primitives, HMAC hash functions, and TLS signature schemes is as follows
<xref target="I-D.irtf-cfrg-hpke"/> <xref target="RFC8446"/>:</t>

<texttable>
      <ttcol align='left'>Value</ttcol>
      <ttcol align='left'>KEM</ttcol>
      <ttcol align='left'>KDF</ttcol>
      <ttcol align='left'>AEAD</ttcol>
      <ttcol align='left'>Hash</ttcol>
      <ttcol align='left'>Signature</ttcol>
      <c>0x0001</c>
      <c>0x0020</c>
      <c>0x0001</c>
      <c>0x0001</c>
      <c>SHA256</c>
      <c>ed25519</c>
      <c>0x0002</c>
      <c>0x0010</c>
      <c>0x0001</c>
      <c>0x0001</c>
      <c>SHA256</c>
      <c>ecdsa_secp256r1_sha256</c>
      <c>0x0003</c>
      <c>0x0020</c>
      <c>0x0001</c>
      <c>0x0003</c>
      <c>SHA256</c>
      <c>ed25519</c>
      <c>0x0004</c>
      <c>0x0021</c>
      <c>0x0003</c>
      <c>0x0002</c>
      <c>SHA512</c>
      <c>ed448</c>
      <c>0x0005</c>
      <c>0x0012</c>
      <c>0x0003</c>
      <c>0x0002</c>
      <c>SHA512</c>
      <c>ecdsa_secp521r1_sha512</c>
      <c>0x0006</c>
      <c>0x0021</c>
      <c>0x0003</c>
      <c>0x0003</c>
      <c>SHA512</c>
      <c>ed448</c>
</texttable>

<t>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 <xref target="SHS"/>.</t>

<t>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 algorithms.  Depending on their
requirements, clients can choose between two security levels (roughly 128-bit
and 256-bit). Within the security levels clients can choose between faster
X25519/X448 curves and FIPS 140-2 compliant curves for Diffie-Hellman key
negotiations. Additionally clients that run predominantly on mobile processors
can choose ChaCha20Poly1305 over AES-GCM for performance reasons. Since
ChaCha20Poly1305 is not listed by FIPS 140-2 it is not paired with FIPS 140-2
compliant curves. The security level of symmetric encryption algorithms and hash
functions is paired with the security level of the curves.</t>

<t>The mandatory-to-implement ciphersuite for MLS 1.0 is
<spanx style="verb">MLS10_128_DHKEMX25519_AES128GCM_SHA256_Ed25519</spanx> which uses
Curve25519 for key exchange, AES-128-GCM for HPKE, HKDF over SHA2-256, and
Ed25519 for signatures.</t>

<t>Values with the first byte 255 (decimal) are reserved for Private Use.</t>

<t>New ciphersuite values are assigned by IANA as described in
<xref target="iana-considerations"/>.</t>

</section>
<section anchor="mls-extension-types" title="MLS Extension Types">

<t>This registry lists identifiers for extensions to the MLS protocol.  The
extension type field is two bytes wide, so valid extension type values are in
the range 0x0000 to 0xffff.</t>

<t>Template:</t>

<t><list style="symbols">
  <t>Value: The numeric value of the extension type</t>
  <t>Name: The name of the extension type</t>
  <t>Message(s): The messages in which the extension may appear, drawn from the following
list:  <list style="symbols">
      <t>KP: KeyPackage messages</t>
      <t>GI: GroupInfo objects</t>
    </list></t>
  <t>Recommended: Whether support for this extension is recommended 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 <xref target="RFC8126"></xref>.  IESG Approval
is REQUIRED for a Y-&gt;N transition.</t>
  <t>Reference: The document where this extension is defined</t>
</list></t>

<t>Initial contents:</t>

<texttable>
      <ttcol align='left'>Value</ttcol>
      <ttcol align='left'>Name</ttcol>
      <ttcol align='left'>Message(s)</ttcol>
      <ttcol align='left'>Recommended</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c>0x0000</c>
      <c>RESERVED</c>
      <c>N/A</c>
      <c>N/A</c>
      <c>RFC XXXX</c>
      <c>0x0001</c>
      <c>capabilities</c>
      <c>KP</c>
      <c>Y</c>
      <c>RFC XXXX</c>
      <c>0x0002</c>
      <c>lifetime</c>
      <c>KP</c>
      <c>Y</c>
      <c>RFC XXXX</c>
      <c>0x0003</c>
      <c>key_id</c>
      <c>KP</c>
      <c>Y</c>
      <c>RFC XXXX</c>
      <c>0x0004</c>
      <c>parent_hash</c>
      <c>KP</c>
      <c>Y</c>
      <c>RFC XXXX</c>
      <c>0x0005</c>
      <c>ratchet_tree</c>
      <c>GI</c>
      <c>Y</c>
      <c>RFC XXXX</c>
      <c>0xff00  - 0xffff</c>
      <c>Reserved for Private Use</c>
      <c>N/A</c>
      <c>N/A</c>
      <c>RFC XXXX</c>
</texttable>

</section>
<section anchor="mls-credential-types" title="MLS Credential Types">

<t>This registry lists identifiers for types of credentials that can be used for
authentication in the MLS protocol.  The extension type field is two bytes wide,
so valid extension type values are in the range 0x0000 to 0xffff.</t>

<t>Template:</t>

<t><list style="symbols">
  <t>Value: The numeric value of the credential type</t>
  <t>Name: The name of the credential type</t>
  <t>Recommended: Whether support for this extension is recommended 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 <xref target="RFC8126"></xref>.  IESG Approval
is REQUIRED for a Y-&gt;N transition.</t>
  <t>Reference: The document where this extension is defined</t>
</list></t>

<t>Initial contents:</t>

<texttable>
      <ttcol align='left'>Value</ttcol>
      <ttcol align='left'>Name</ttcol>
      <ttcol align='left'>Recommended</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c>0x0000</c>
      <c>RESERVED</c>
      <c>N/A</c>
      <c>RFC XXXX</c>
      <c>0x0001</c>
      <c>basic</c>
      <c>Y</c>
      <c>RFC XXXX</c>
      <c>0x0002</c>
      <c>x509</c>
      <c>Y</c>
      <c>RFC XXXX</c>
      <c>0xff00  - 0xffff</c>
      <c>Reserved for Private Use</c>
      <c>N/A</c>
      <c>RFC XXXX</c>
</texttable>

</section>
<section anchor="de" title="MLS Designated Expert Pool">

<t>Specification Required <xref target="RFC8126"/> registry requests are registered
after a three-week review period on the MLS DEs' mailing list:
<eref target="mailto:mls-reg-review@ietf.org">mls-reg-review@ietf.org</eref>, on the advice of one or more of the MLS DEs. However,
to allow for the allocation of values prior to publication, the MLS
DEs may approve registration once they are satisfied that such a
specification will be published.</t>

<t>Registration requests sent to the MLS DEs mailing list for review
SHOULD use an appropriate subject (e.g., "Request to register value
in MLS Bar registry").</t>

<t>Within the review period, the MLS DEs will either approve or deny
the registration request, communicating this decision to the MLS DEs
mailing list and IANA. Denials SHOULD include an explanation and, if
applicable, suggestions as to how to make the request successful.
Registration requests that are undetermined for a period longer than
21 days can be brought to the IESG's attention for resolution using
the <eref target="mailto:iesg@ietf.org">iesg@ietf.org</eref> mailing list.</t>

<t>Criteria that SHOULD be applied by the MLS DEs includes determining
whether the proposed registration duplicates existing functionality,
whether it is likely to be of general applicability or useful only
for a single application, and whether the registration description
is clear. For example, the MLS DEs will apply the ciphersuite-related
advisory found in <xref target="ciphersuites"/>.</t>

<t>IANA MUST only accept registry updates from the MLS DEs and SHOULD
direct all requests for registration to the MLS DEs' mailing list.</t>

<t>It is suggested that multiple MLS DEs be appointed who are able to
represent the perspectives of different applications using this
specification, in order to enable broadly informed review of
registration decisions. In cases where a registration decision could
be perceived as creating a conflict of interest for a particular
MLS DE, that MLS DE SHOULD defer to the judgment of the other MLS DEs.</t>

</section>
</section>
<section anchor="contributors" title="Contributors">

<t><list style="symbols">
  <t>Joel Alwen <vspace />
Wickr <vspace />
joel.alwen@wickr.com</t>
  <t>Karthikeyan Bhargavan <vspace />
INRIA <vspace />
karthikeyan.bhargavan@inria.fr</t>
  <t>Cas Cremers <vspace />
University of Oxford <vspace />
cremers@cispa.de</t>
  <t>Alan Duric <vspace />
Wire <vspace />
alan@wire.com</t>
  <t>Britta Hale <vspace />
Naval Postgraduate School <vspace />
britta.hale@nps.edu</t>
  <t>Srinivas Inguva <vspace />
Twitter <vspace />
singuva@twitter.com</t>
  <t>Konrad Kohbrok <vspace />
Aalto University <vspace />
konrad.kohbrok@datashrine.de</t>
  <t>Albert Kwon <vspace />
MIT <vspace />
kwonal@mit.edu</t>
  <t>Brendan McMillion <vspace />
Cloudflare <vspace />
brendan@cloudflare.com</t>
  <t>Eric Rescorla <vspace />
Mozilla <vspace />
ekr@rtfm.com</t>
  <t>Michael Rosenberg <vspace />
Trail of Bits <vspace />
michael.rosenberg@trailofbits.com</t>
  <t>Thyla van der Merwe <vspace />
Royal Holloway, University of London <vspace />
thyla.van.der@merwe.tech</t>
</list></t>

</section>


  </middle>

  <back>

    <references title='Normative References'>





<reference  anchor="RFC2119" target='https://www.rfc-editor.org/info/rfc2119'>
<front>
<title>Key words for use in RFCs to Indicate Requirement Levels</title>
<author initials='S.' surname='Bradner' fullname='S. Bradner'><organization /></author>
<date year='1997' month='March' />
<abstract><t>In many standards track documents several words are used to signify the requirements in the specification.  These words are often capitalized. This document defines these words as they should be interpreted in IETF documents.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t></abstract>
</front>
<seriesInfo name='BCP' value='14'/>
<seriesInfo name='RFC' value='2119'/>
<seriesInfo name='DOI' value='10.17487/RFC2119'/>
</reference>



<reference  anchor="RFC8174" target='https://www.rfc-editor.org/info/rfc8174'>
<front>
<title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
<author initials='B.' surname='Leiba' fullname='B. Leiba'><organization /></author>
<date year='2017' month='May' />
<abstract><t>RFC 2119 specifies common key words that may be used in protocol  specifications.  This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the  defined special meanings.</t></abstract>
</front>
<seriesInfo name='BCP' value='14'/>
<seriesInfo name='RFC' value='8174'/>
<seriesInfo name='DOI' value='10.17487/RFC8174'/>
</reference>



<reference anchor="I-D.irtf-cfrg-hpke">
<front>
<title>Hybrid Public Key Encryption</title>

<author initials='R' surname='Barnes' fullname='Richard Barnes'>
    <organization />
</author>

<author initials='K' surname='Bhargavan' fullname='Karthikeyan Bhargavan'>
    <organization />
</author>

<author initials='B' surname='Lipp' fullname='Benjamin Lipp'>
    <organization />
</author>

<author initials='C' surname='Wood' fullname='Christopher Wood'>
    <organization />
</author>

<date month='December' day='16' year='2020' />

<abstract><t>This document describes a scheme for hybrid public-key encryption (HPKE).  This scheme provides authenticated public key encryption of arbitrary-sized plaintexts for a recipient public key.  HPKE works for any combination of an asymmetric key encapsulation mechanism (KEM), key derivation function (KDF), and authenticated encryption with additional data (AEAD) encryption function.  We provide instantiations of the scheme using widely used and efficient primitives, such as Elliptic Curve Diffie-Hellman key agreement, HKDF, and SHA2.  This document is a product of the Crypto Forum Research Group (CFRG) in the IRTF.</t></abstract>

</front>

<seriesInfo name='Internet-Draft' value='draft-irtf-cfrg-hpke-07' />
<format type='TXT'
        target='http://www.ietf.org/internet-drafts/draft-irtf-cfrg-hpke-07.txt' />
</reference>



<reference  anchor="RFC8446" target='https://www.rfc-editor.org/info/rfc8446'>
<front>
<title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
<author initials='E.' surname='Rescorla' fullname='E. Rescorla'><organization /></author>
<date year='2018' month='August' />
<abstract><t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol.  TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t><t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961.  This document also specifies new requirements for TLS 1.2 implementations.</t></abstract>
</front>
<seriesInfo name='RFC' value='8446'/>
<seriesInfo name='DOI' value='10.17487/RFC8446'/>
</reference>



<reference  anchor="RFC8126" target='https://www.rfc-editor.org/info/rfc8126'>
<front>
<title>Guidelines for Writing an IANA Considerations Section in RFCs</title>
<author initials='M.' surname='Cotton' fullname='M. Cotton'><organization /></author>
<author initials='B.' surname='Leiba' fullname='B. Leiba'><organization /></author>
<author initials='T.' surname='Narten' fullname='T. Narten'><organization /></author>
<date year='2017' month='June' />
<abstract><t>Many protocols make use of points of extensibility that use constants to identify various protocol parameters.  To ensure that the values in these fields do not have conflicting uses and to promote interoperability, their allocations are often coordinated by a central record keeper.  For IETF protocols, that role is filled by the Internet Assigned Numbers Authority (IANA).</t><t>To make assignments in a given registry prudently, guidance describing the conditions under which new values should be assigned, as well as when and how modifications to existing values can be made, is needed.  This document defines a framework for the documentation of these guidelines by specification authors, in order to assure that the provided guidance for the IANA Considerations is clear and addresses the various issues that are likely in the operation of a registry.</t><t>This is the third edition of this document; it obsoletes RFC 5226.</t></abstract>
</front>
<seriesInfo name='BCP' value='26'/>
<seriesInfo name='RFC' value='8126'/>
<seriesInfo name='DOI' value='10.17487/RFC8126'/>
</reference>



<reference  anchor="RFC2104" target='https://www.rfc-editor.org/info/rfc2104'>
<front>
<title>HMAC: Keyed-Hashing for Message Authentication</title>
<author initials='H.' surname='Krawczyk' fullname='H. Krawczyk'><organization /></author>
<author initials='M.' surname='Bellare' fullname='M. Bellare'><organization /></author>
<author initials='R.' surname='Canetti' fullname='R. Canetti'><organization /></author>
<date year='1997' month='February' />
<abstract><t>This document describes HMAC, a mechanism for message authentication using cryptographic hash functions. HMAC can be used with any iterative cryptographic hash function, e.g., MD5, SHA-1, in combination with a secret shared key.  The cryptographic strength of HMAC depends on the properties of the underlying hash function.  This memo provides information for the Internet community.  This memo does not specify an Internet standard of any kind</t></abstract>
</front>
<seriesInfo name='RFC' value='2104'/>
<seriesInfo name='DOI' value='10.17487/RFC2104'/>
</reference>




    </references>

    <references title='Informative References'>

<reference anchor="art" target="https://eprint.iacr.org/2017/666.pdf">
  <front>
    <title>On Ends-to-Ends Encryption: Asynchronous Group Messaging with Strong Security Guarantees</title>
    <author initials="K." surname="Cohn-Gordon" fullname="Katriel Cohn-Gordon">
      <organization></organization>
    </author>
    <author initials="C." surname="Cremers" fullname="Cas Cremers">
      <organization></organization>
    </author>
    <author initials="L." surname="Garratt" fullname="Luke Garratt">
      <organization></organization>
    </author>
    <author initials="J." surname="Millican" fullname="Jon Millican">
      <organization></organization>
    </author>
    <author initials="K." surname="Milner" fullname="Kevin Milner">
      <organization></organization>
    </author>
    <date year="2018" month="January" day="18"/>
  </front>
</reference>


<reference anchor="doubleratchet" >
  <front>
    <title>A Formal Security Analysis of the Signal Messaging Protocol</title>
    <author initials="K." surname="Cohn-Gordon" fullname="Katriel Cohn-Gordon">
      <organization></organization>
    </author>
    <author initials="C." surname="Cremers" fullname="Cas Cremers">
      <organization></organization>
    </author>
    <author initials="B." surname="Dowling" fullname="Benjamin Dowling">
      <organization></organization>
    </author>
    <author initials="L." surname="Garratt" fullname="Luke Garratt">
      <organization></organization>
    </author>
    <author initials="D." surname="Stebila" fullname="Douglas Stebila">
      <organization></organization>
    </author>
    <date year="2017" month="April"/>
  </front>
  <seriesInfo name="2017 IEEE European Symposium on Security and Privacy" value="(EuroS&amp;P)"/>
  <seriesInfo name="DOI" value="10.1109/eurosp.2017.27"/>
</reference>


<reference anchor="signal" target="https://www.signal.org/docs/specifications/doubleratchet/">
  <front>
    <title>The Double Ratchet Algorithm</title>
    <author initials="T." surname="Perrin(ed)" fullname="Trevor Perrin(ed)">
      <organization></organization>
    </author>
    <author initials="M." surname="Marlinspike" fullname="Moxie Marlinspike">
      <organization></organization>
    </author>
    <date year="2016" month="November" day="20"/>
  </front>
</reference>
<reference anchor="SECG" target="https://secg.org/sec1-v2.pdf">
  <front>
    <title>Elliptic Curve Cryptography, Standards for Efficient Cryptography Group, ver. 2</title>
    <author >
      <organization></organization>
    </author>
    <date year="2009"/>
  </front>
</reference>


<reference anchor="SHS" >
  <front>
    <title>Secure Hash Standard</title>
    <author initials="Q." surname="Dang" fullname="Quynh H. Dang">
      <organization></organization>
    </author>
    <date year="2015" month="July"/>
  </front>
  <seriesInfo name="National Institute of Standards and Technology" value="report"/>
  <seriesInfo name="DOI" value="10.6028/nist.fips.180-4"/>
</reference>



<reference anchor="I-D.ietf-mls-architecture">
<front>
<title>The Messaging Layer Security (MLS) Architecture</title>

<author initials='E' surname='Omara' fullname='Emad Omara'>
    <organization />
</author>

<author initials='B' surname='Beurdouche' fullname='Benjamin Beurdouche'>
    <organization />
</author>

<author initials='E' surname='Rescorla' fullname='Eric Rescorla'>
    <organization />
</author>

<author initials='S' surname='Inguva' fullname='Srinivas Inguva'>
    <organization />
</author>

<author initials='A' surname='Kwon' fullname='Albert Kwon'>
    <organization />
</author>

<author initials='A' surname='Duric' fullname='Alan Duric'>
    <organization />
</author>

<date month='July' day='26' year='2020' />

<abstract><t>This document describes the reference architecture, functional and security requirements for the Messaging Layer Security (MLS) protocol.  MLS provides a security layer for group messaging applications, where the number of clients ranges from two to many. It is meant to protect against eavesdropping, tampering, and message forgery.  Discussion Venues  This note is to be removed before publishing as an RFC.  Source for this draft and an issue tracker can be found at https://github.com/mlswg/mls-architecture.</t></abstract>

</front>

<seriesInfo name='Internet-Draft' value='draft-ietf-mls-architecture-05' />
<format type='TXT'
        target='http://www.ietf.org/internet-drafts/draft-ietf-mls-architecture-05.txt' />
</reference>



<reference anchor="I-D.ietf-trans-rfc6962-bis">
<front>
<title>Certificate Transparency Version 2.0</title>

<author initials='B' surname='Laurie' fullname='Ben Laurie'>
    <organization />
</author>

<author initials='A' surname='Langley' fullname='Adam Langley'>
    <organization />
</author>

<author initials='E' surname='Kasper' fullname='Emilia Kasper'>
    <organization />
</author>

<author initials='E' surname='Messeri' fullname='Eran Messeri'>
    <organization />
</author>

<author initials='R' surname='Stradling' fullname='Rob Stradling'>
    <organization />
</author>

<date month='November' day='4' year='2019' />

<abstract><t>This document describes version 2.0 of the Certificate Transparency (CT) protocol for publicly logging the existence of Transport Layer Security (TLS) server certificates as they are issued or observed, in a manner that allows anyone to audit certification authority (CA) activity and notice the issuance of suspect certificates as well as to audit the certificate logs themselves.  The intent is that eventually clients would refuse to honor certificates that do not appear in a log, effectively forcing CAs to add all issued certificates to the logs.  This document obsoletes RFC 6962.  It also specifies a new TLS extension that is used to send various CT log artifacts.  Logs are network services that implement the protocol operations for submissions and queries that are defined in this document.</t></abstract>

</front>

<seriesInfo name='Internet-Draft' value='draft-ietf-trans-rfc6962-bis-34' />
<format type='TXT'
        target='http://www.ietf.org/internet-drafts/draft-ietf-trans-rfc6962-bis-34.txt' />
</reference>



<reference  anchor="RFC8032" target='https://www.rfc-editor.org/info/rfc8032'>
<front>
<title>Edwards-Curve Digital Signature Algorithm (EdDSA)</title>
<author initials='S.' surname='Josefsson' fullname='S. Josefsson'><organization /></author>
<author initials='I.' surname='Liusvaara' fullname='I. Liusvaara'><organization /></author>
<date year='2017' month='January' />
<abstract><t>This document describes elliptic curve signature scheme Edwards-curve Digital Signature Algorithm (EdDSA).  The algorithm is instantiated with recommended parameters for the edwards25519 and edwards448 curves.  An example implementation and test vectors are provided.</t></abstract>
</front>
<seriesInfo name='RFC' value='8032'/>
<seriesInfo name='DOI' value='10.17487/RFC8032'/>
</reference>

<reference anchor="CLINIC" >
  <front>
    <title>I Know Why You Went to the Clinic: Risks and Realization of HTTPS Traffic Analysis</title>
    <author initials="B." surname="Miller" fullname="Brad Miller">
      <organization></organization>
    </author>
    <author initials="L." surname="Huang" fullname="Ling Huang">
      <organization></organization>
    </author>
    <author initials="A." surname="Joseph" fullname="A. D. Joseph">
      <organization></organization>
    </author>
    <author initials="J." surname="Tygar" fullname="J. D. Tygar">
      <organization></organization>
    </author>
    <date year="2014"/>
  </front>
  <seriesInfo name="Privacy Enhancing Technologies" value="pp. 143-163"/>
  <seriesInfo name="DOI" value="10.1007/978-3-319-08506-7_8"/>
</reference>

<reference anchor="HCJ16" >
  <front>
    <title>HTTPS traffic analysis and client identification using passive SSL/TLS fingerprinting</title>
    <author initials="M." surname="Husak" fullname="Martin Husak">
      <organization></organization>
    </author>
    <author initials="M." surname="Cermak" fullname="Milan Cermak">
      <organization></organization>
    </author>
    <author initials="T." surname="Jirsik" fullname="Tomas Jirsik">
      <organization></organization>
    </author>
    <author initials="P." surname="Celeda" fullname="Pavel Celeda">
      <organization></organization>
    </author>
    <date year="2016" month="February"/>
  </front>
  <seriesInfo name="EURASIP Journal on Information Security" value="Vol. 2016"/>
  <seriesInfo name="DOI" value="10.1186/s13635-016-0030-7"/>
</reference>




    </references>


<section anchor="tree-math" title="Tree Math">

<t>One benefit of using left-balanced trees is that they admit a simple
flat array representation.  In this representation, leaf nodes are
even-numbered nodes, with the n-th leaf at 2*n.  Intermediate nodes
are held in odd-numbered nodes.  For example, an 11-element tree has
the following structure:</t>

<figure><artwork><![CDATA[
                                             X
                     X
         X                       X                       X
   X           X           X           X           X
X     X     X     X     X     X     X     X     X     X     X
0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
]]></artwork></figure>

<t>This allows us to compute relationships between tree nodes simply by
manipulating indices, rather than having to maintain complicated
structures in memory, even for partial trees. The basic
rule is that the high-order bits of parent and child nodes have the
following relation (where <spanx style="verb">x</spanx> is an arbitrary bit string):</t>

<figure><artwork><![CDATA[
parent=01x => left=00x, right=10x
]]></artwork></figure>

<t>The following python code demonstrates the tree computations
necessary for MLS.  Test vectors can be derived from the diagram
above.</t>

<figure><artwork><![CDATA[
# The exponent of the largest power of 2 less than x. Equivalent to:
#   int(math.floor(math.log(x, 2)))
def log2(x):
    if x == 0:
        return 0

    k = 0
    while (x >> k) > 0:
        k += 1
    return k-1

# The level of a node in the tree. Leaves are level 0, their parents are
# level 1, etc. If a node's children are at different levels, then its
# level is the max level of its children plus one.
def level(x):
    if x & 0x01 == 0:
        return 0

    k = 0
    while ((x >> k) & 0x01) == 1:
        k += 1
    return k

# The number of nodes needed to represent a tree with n leaves.
def node_width(n):
    if n == 0:
        return 0
    else:
        return 2*(n - 1) + 1

# The index of the root node of a tree with n leaves.
def root(n):
    w = node_width(n)
    return (1 << log2(w)) - 1

# The left child of an intermediate node. Note that because the tree is
# left-balanced, there is no dependency on the size of the tree.
def left(x):
    k = level(x)
    if k == 0:
        raise Exception('leaf node has no children')

    return x ^ (0x01 << (k - 1))

# The right child of an intermediate node. Depends on the number of
# leaves because the straightforward calculation can take you beyond the
# edge of the tree.
def right(x, n):
    k = level(x)
    if k == 0:
        raise Exception('leaf node has no children')

    r = x ^ (0x03 << (k - 1))
    while r >= node_width(n):
        r = left(r)
    return r

# The immediate parent of a node. May be beyond the right edge of the
# tree.
def parent_step(x):
    k = level(x)
    b = (x >> (k + 1)) & 0x01
    return (x | (1 << k)) ^ (b << (k + 1))

# The parent of a node. As with the right child calculation, we have to
# walk back until the parent is within the range of the tree.
def parent(x, n):
    if x == root(n):
        raise Exception('root node has no parent')

    p = parent_step(x)
    while p >= node_width(n):
        p = parent_step(p)
    return p

# The other child of the node's parent.
def sibling(x, n):
    p = parent(x, n)
    if x < p:
        return right(p, n)
    else:
        return left(p)

# The direct path of a node, ordered from leaf to root.
def direct_path(x, n):
    r = root(n)
    if x == r:
        return []

    d = []
    while x != r:
        x = parent(x, n)
        d.append(x)
    return d

# The copath of a node, ordered from leaf to root.
def copath(x, n):
    if x == root(n):
        return []

    d = direct_path(x, n)
    d.insert(0, x)
    d.pop()
    return [sibling(y, n) for y in d]

# The common ancestor of two nodes is the lowest node that is in the
# direct paths of both leaves.
def common_ancestor_semantic(x, y, n):
    dx = set([x]) | set(direct_path(x, n))
    dy = set([y]) | set(direct_path(y, n))
    dxy = dx & dy
    if len(dxy) == 0:
        raise Exception('failed to find common ancestor')

    return min(dxy, key=level)

# The common ancestor of two nodes is the lowest node that is in the
# direct paths of both leaves.
def common_ancestor_direct(x, y, _):
    # Handle cases where one is an ancestor of the other
    lx, ly = level(x)+1, level(y)+1
    if (lx <= ly) and (x>>ly == y>>ly):
      return y
    elif (ly <= lx) and (x>>lx == y>>lx):
      return x

    # Handle other cases
    xn, yn = x, y
    k = 0
    while xn != yn:
       xn, yn = xn >> 1, yn >> 1
       k += 1
    return (xn << k) + (1 << (k-1)) - 1
]]></artwork></figure>

</section>


  </back>

<!-- ##markdown-source:
H4sIACQO4l8AA9S9a2PbRpIu/L1/BVbzIVKGpCVP4pnIk+zIkuzo+PpaTmZ2
kxwRIiEJMQlwAdCyxvH57aeu3dUNULaTzL57vDuRRAJ9ra6u61Pj8dh1Zbco
9rNXV0X2tGjb/LKsLrMn+U3RZKfFbN2U3U22/fTJ6U72oqm7elYvXH5+3hRv
9jP41M3rWZUvoYF5k19047LoLsbLRTteycPjvT03y7vism5u9rOyuqidK1fN
ftY167a7u7v71e5dlzdFvu+7c6+Lm+u6me9nJ1VXNFXRjY+wcefaLq/mZ/mi
rqDDm6J1q3I/+wH6GWVt3XRNcdHCbzdL/OUn5/J1d1U3+y4bZ9Bzu5+9nGQP
cmiwdRn843G/LGdXeTO3X9TNZV6V/8y7sq72s8OyndX0ebHMy8V+1izO/1au
3kzat6HlB9BysW7m9Xp2VZjWHxTVz/myrNJv4y5OqqbMbRfn8trk3L/2txIf
mlw00Ck9Sv3+r0n2tFwsyllemV7/V13FH8fdPcxnxXldv7Y9/ryU5/92cT6Z
1cuol+NJ9nyZN7np4niZz82HcQeP6vpyUdjm4ce8xqf/dknf9bp4PMkO66tq
/Ag2vrZzeZx3TVkset/GPX5XlW+KpkVirS+y528v4EHb/7L422tuCHqerF9H
fQNZvKzPi6azZJGvrnLo1nwR9/j3solm2PALf7uGz2l2Dom9WcLjbwqgwSxv
un16ocuby6Lbz666btXu37lTrJqy6iZlPmsm0Medu7t7f75z7969yWp+wS/w
Ed16XmXH1bwdd/UYf8Ifs+ZmxcM5aG+q2VVTV/W6zR419XpljvN12V1lpx18
exkO9aM1bAccsKLdol78aaF/4w8sf3jiMG+zw6ZYwvIn3zxZvy6yR3nT5F2X
fNWjUNNj8aakL6uioa/mwD72M1iVv4x398Z7f4EP4UicLwpoFw4GrOTR85PJ
3u5kb2/3qzvH66Y+fTHBRZzc/bODh9vyssoXw2t/fX094e9p6YGbtXfaVTEr
L2BkuLLtnaivO9GGINM8oq+BXuj77GABnA6We7kVj/0eMMLx3d2BlfYTfwVM
tW6yF0UD9LBdzHfSB57Wb0vg0nmzALJdla8LnN3p8eGj/WhUx7CsQBWz7HDd
vClgb4BG6kukz5sRUAGwUOB3bQbEmR1fwDzLouqip5h+RhmcqEl2d2tw4dpi
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
9k7iYqBAy1pulWTb4B7KfDCi4l8VTcz9Bj4bIs05xhGoP5uS9VdC+oTLVLOk
tZXMGBiSzhciy9p7LhyEI0pPadgMDYsHnQPpSE4zfGuFLs6FrfpktYTXSSIE
+Q89TFNvlf/bekp5C3ofMUiS3koY8/dUAZPR7AoS2r9X+Tw9nF/mZfqXv6Ds
Wkwuav74N/hplOFPTy7x2xGwSnzlBxjXORygDbCOb8+z+ix7n8nbxy9fHx/y
x4vw1OhUn3pSlMAMRrOaqqsiHjaayUFdoVf+WBYULcRpzD9dYdEm/mXCjz2Z
IAbsaEpi+yGw1hTRLSY6ctgH+pTBLzDkOtcRfwtcaIVAE3N54mWGoCeYRHVW
Z9M13lJv0P48559P6fnROTz/pFw2o3y6pmKONTCk9xlml5yt32f87NvLgooN
0B9IdPDLkxV/aStWldAN/OccKO2CHz3M5rBpbsq8avTk6IKffIJgHM15jeHG
OulTlJp+uKxkxV8cv5U3L5HXPcEAaxnut3AqprBGLyYvgKcU+sbTebWezuaZ
rtYpP/ZkYt/rsI9wbUHem1T1XGb7ovpPaEv+yC/qJ/VqttDnXxST8wzI6TUC
qsA4z2SFakyJgB39FoO86asFPzmq9cknK3yomp1iWLM09/Z8M0dFBo8TEHFe
X8qIX1cb2L3nZB7MNoMW3fxYlVOd6wqbGEETsHz1kwU2MUKUqiQZDocUHU0A
AlQg8gXG0X74jFJgFvAZBNKfSnShlKCU0IlinjLPZ6vhKdLYhJCtcvYQaw4z
sNopBR5ztbc8gSVdSaVl42QOzJ0jpaMfBqHYM0PZdYszN4NgMy+HBG/DFXgP
/vI5NxxQ0PkFKoR2Tuo6MMDptNVeT+mz8XiYi4dBaz8mcdgvVxNc17mVKuzV
Mbb9+7X/cff1r9vevK7FX7c8uPVz8qv77pP/PwH9CNQ20Lfupum9NL2fpg/S
9Ms0/SpNv07H+7CO6fggHd9Nx/fS8f10/CAdf5mOv0rHX6cH+6GOIWVuUkrV
uvEIUgqahbnXTXAdUhVNohCpKni6SQLUMYJjYVENJBS4k85F7HOQ9VZqk71c
BPyY2IaSvX6RL6gUCpIfe97wRkLLCeeevZXkhElSCzaqJfIj6MWQr1k80iml
utVa55DLtfPorSJYICuDCdvly/Xd1TuuJh/SyrBViUPdM+LjHh7tj6/SR4/p
nD7a37+CBUAolkfj/StfNNJhTWxW53RVY+4VTLmka1yyhbjyJ22FRMiH/ADx
taE1B2/t9yCVVLWJ1J1cdziMcNssEq7lrYP+TOxqEg+sxafhwsQ2l9Ulu8UP
GLyONvFqlB75wocPoREsBLTaRb41ms2rquaP8+psFxbgYG9vLwFBATSAs4Pd
K1gxpNxilsJCPUr3H9qBk6rs+1xn+iKFH+kTI8TsXqWPH6cXe+lj/85F+sWj
dJy41y+G40TmZb7MLmbHKP1RKmzX+tz+QMKAeCeZ+X0mP46BEFcTwsvLBKmD
CakWrDxMgjNhkH3ikiwHFGjNSLjEIrsKg+Oib9LUcr4muNsRrxg+Ey/Z/0AD
y/jTVs6Wjl/ew7fH166hrmCIjODzEhJxg1wsKL50I5RSuJyHT9VbL4vp6ny3
DHMotw0e/4Blyzs/HXy+W6bDFAb+RWqby9XeNckeC4zTHgdY4Z4B4WM2lEtY
pmiEfgV2x+k33zDFXu7tYeeBqGYr4SHYVxnV/OB0TlfQQtE07DQXTAzuFndV
V8pKCpVw+Y0uyhwXImbSmK2MMnDHlVZ0mS/ay5xhqv4RAawAK9m9Y9c8paKX
lRHhnb3EL8VV+r/SXSI6WJHdC9qIPV0N4m43LQdHqTQ6ISMqWgk6hX6ZkAFi
q1Iz0HDtSKPBnEs0T2yqNby0qQTk/7OUsrY6q0TDQyZU/teuFLSqy3Q3WqZw
Cuv08aO+E6Hv04bWERHWRusLXVC5x4ynjUBypOTCsBiyJ25BoJWwJOLGQnT9
7fRzCl8w14CZfIEzEd4RnZGr9Dc5KBfwAEz/VOb+hSeR7pAPXcyFJyC30wNE
xuHbuYJ2LrP5BecTrssVVicM7RbcWOTQ6dCB1KZ2hKD3T8QSenc/8BbZfW5M
934JSxWvqdv05TWb3n5xGe39UpdPyyAXAfNT7h9+mSeIiZsgTvgZhvb52zDt
b9Jlh8fySVnag72MmGh0aTsrJhrKAbTtHVhNFZI96OwQ/lIlQ+W3TvAtP1w8
A7IZ8QZ1RvHnv/LKT+EN+BxW+yr9XfT8Vd8K0Jsjqgk21c2Shqc6MclrvP2c
+IXb0Vd3Ep0V4V9GRdmAvr0LgsmVfrWslrvRmP+sO7/BF0kqJMyN6V/DZAiC
neIWtfbsZSUXuggkmETVrCyxfcW59sI73DaTLE2olP5a5R5OtIcTLUaJk9mE
JZnifjT5avfPV3/FkAn82Jm6THSjj256H924R6/w2SlKRtONLj3Iprvww95N
nJ1T6ikdH6GDW0vVuggXBTU6wACDR8Qu9/771phfkBU+kRX+jOBM53lkHSR8
AlZg/PCUtdCLc2hnvnG3wBfjgXzewGdd1t05MA94CBYWNandq8eP8a1H6QY/
GJHLem2EkdCLG3rxyr14pS9etV+8SuLZCAvEOdEPVxgbW+KdO5BO2iLvVYms
YFPa1odXSrzVxvQXftAHukLwLjxKVxtcZ7si/AzHIgyy+vR/AIhBsY+oNwIA

-->

</rfc>

