<?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.10 -->

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

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

<rfc ipr="trust200902" docName="draft-ietf-mls-protocol-10" 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="October" day="31"/>

    <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="ratchet-tree-nodes" 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 the node's parent, as of the last time the node was changed.</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>The HPKE parameters are used to instantiate HPKE <xref target="I-D.irtf-cfrg-hpke"/> for the
purpose of 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>The <spanx style="verb">parent_hash</spanx> extension serves to bind a KeyPackage to all the nodes
above it in the group's ratchet tree. This enforces the tree invariant, meaning
that malicious members can't lie about the state of the ratchet tree when they
send Welcome messages to new members.</t>

<figure><artwork><![CDATA[
opaque parent_hash<0..255>;
]]></artwork></figure>

<t>This extension MUST be present in all Updates that are sent as part of a Commit
message. If the extension is present, clients MUST verify that <spanx style="verb">parent_hash</spanx>
matches the hash of the leaf's parent node when represented as a ParentNode
struct.</t>

<!-- OPEN ISSUE: This scheme, in which the tree hash covers the parent hash, is
designed to allow for more deniable deployments, since a signature by a member
covers only its direct path. The other possible scheme, in which the parent hash
covers the tree hash, provides better group agreement properties, since a
member's signature covers the entire membership of the trees it is in. Further
discussion is needed to determine whether the benefits to deniability justify
the harm to group agreement properties, or whether there are alternative
approaches to deniability that could be compatible with the other approach. -->

</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 that represents the contents of the group's
ratchet tree and the members' KeyPackages.</t>

<t>The hash of a tree is the hash of its root node, which we define
recursively, starting with the leaves.</t>

<t>Elements of the ratchet tree are called <spanx style="verb">Node</spanx> objects and
the leaves contain an optional <spanx style="verb">KeyPackage</spanx>, while the parents contain
an optional <spanx style="verb">ParentNode</spanx>.</t>

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

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

<t>When computing the hash of a parent node, the <spanx style="verb">ParentNodeHashInput</spanx>
structure is used:</t>

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

<t>The <spanx style="verb">left_hash</spanx> and <spanx style="verb">right_hash</spanx> fields hold the hashes of the node's
left and right children, respectively. When computing the hash of
a leaf node, the hash of a <spanx style="verb">LeafNodeHashInput</spanx> object is used:</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>

</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 = joiner_secret
                         |
                         V
                   Derive-Secret(., "member")
                         |
                         V
psk_secret (or 0) -> KDF.Extract = member_secret
                         |
                         +--> Derive-Secret(., "welcome")
                         |    = welcome_secret
                         |
                         V
                   ExpandWithLabel(., "epoch", GroupContext_[n], KDF.Nh)
                         |
                         V
                    epoch_secret
                         |
                         +--> Derive-Secret(., <label>)
                         |    = <secret>
                         |
                         V
                   Derive-Secret(., "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">member_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">member_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 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 (where "0"
represents an all-zero vector of size KDF.Nh):
  <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: 0</t>
      <t>Interim transcript hash: 0</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>

<!-- OPEN ISSUE: We can probably do without a nonce by simply using the GroupID
of the new group, provided the GroupId is long enough to prevent collisions.
However, GroupId is currently 'hidden' in the GroupInfo, which is only available
to the receiver _after_ the PSK would have to be injected. -->

<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>

<!-- OPEN ISSUE: It would be better to have non-linear epochs, in order to
tolerate forks in the history. There is a need to discuss whether we
want to keep lexicographical ordering for the public value we serialize
in the common framing, as it influence the ability of the DS to order
messages. -->

<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),
    (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;
    };
} 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="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 empty
<spanx style="verb">key_package</spanx> and <spanx style="verb">path</spanx> fields.</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 a 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.  <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>Generate a new KeyPackage for the Committer's own leaf, with a
<spanx style="verb">parent_hash</spanx> extension. Store it in the ratchet tree and assign it to the
<spanx style="verb">key_package</spanx> field in the Commit object.</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">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>

<!-- OPEN ISSUE: It is not possible for the recipient of a handshake
message to verify that ratchet tree information in the message is
accurate, because each node can only compute the secret and private
key for nodes in its direct path.  This creates the possibility
that a malicious participant could cause a denial of service by sending a
handshake message with invalid values for public keys in the ratchet
tree. -->

<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>

<t><spanx style="verb">
struct {
    CipherSuite cipher_suite;
    opaque group_id&lt;0..255&gt;;
    uint64 epoch;
    opaque tree_hash&lt;0..255&gt;;
    opaque interim_transcript_hash&lt;0..255&gt;;
    Extension extensions&lt;0..2^32-1&gt;;
    HPKEPublicKey external_pub;
} PublicGroupState;
</spanx></t>

<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 information above are not deemed public data in general, but applications
can choose to make them 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
randomly chosen by the sender.  This key and nonce are 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">member_secret</spanx> and using that the
<spanx style="verb">welcome_secret</spanx>, <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_secret = Derive-Secret(member_secret, "welcome")
welcome_nonce = KDF.Expand(welcome_secret, "nonce", nonce_length)
welcome_key = KDF.Expand(welcome_secret, "key", key_length)
]]></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).</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>

<!-- OPEN ISSUE: Should we put bounds on what an extension can change?  For
example, should we make an explicit guarantee that as long as you're speaking
MLS 1.0, the format of the KeyPackage will remain the same?  (Analogous to
the TLS invariant with regard to ClientHello.)  If we are explicit that
effectively arbitrary changes can be made to protocol behavior with the consent
of the members, we will need to note that some such changes can undermine the
security of the protocol. -->

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

<!-- OPEN ISSUE: This section has an initial set of considerations
regarding sequencing.  It would be good to have some more detailed
discussion, and hopefully have a mechanism to deal with this issue. -->

<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>

<!-- TODO: A preliminary formal security analysis has yet to be performed on
this authentication scheme. -->

<!-- OPEN ISSUE: Should the padding be required for handshake messages ?
Can an adversary get more than the position of a participant in the tree
without padding ? Should the base ciphertext block length be negotiated or
is is reasonable to allow to leak a range for the length of the plaintext
by allowing to send a variable number of ciphertext blocks ? -->

</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>
<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\_HPKE25519\_AES128GCM\_SHA256\_Ed25519</spanx> which uses
Curve25519 for key exchange, AES-128-GCM for HPKE, HKDF over SHA2-256,
AES for metadata masking, 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 />
cas.cremers@cs.ox.ac.uk</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='October' day='23' 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.</t></abstract>

</front>

<seriesInfo name='Internet-Draft' value='draft-irtf-cfrg-hpke-06' />
<format type='TXT'
        target='http://www.ietf.org/internet-drafts/draft-irtf-cfrg-hpke-06.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:
H4sIAPbGnV8AA+y9e3vbRpYn/H99Coz6j0hpkpbcSTqR25lWJNnx+vpaTnfv
JFkRJCEJMQlwANCy2sl+9vdcq04VQNlO0rOzz7Oe6UgigbqeOnWuvzMej11X
dsviMHt1VWRPi7bNL8vqMnuS3xRNdlbMN03Z3WS7T5+c7WUvmrqr5/XS5bNZ
U7w5zOBTt6jnVb6CBhZNftGNy6K7GK+W7XgtD48P9t0874rLurk5zMrqonau
XDeHWdds2u7u/v5X+3dd3hT5oe/OvS5urutmcZg9qrqiqYpufIKNO9d2ebU4
z5d1BR3eFK1bl4fZ99DPKGvrpmuKixZ+u1nhLz86l2+6q7o5dNk4g57bw+zl
JPsmhwZbl8E/HvfLcn6VNwv7Rd1c5lX5z7wr6+owOy7beU2fF6u8XB5mzXL2
13L9ZtK+DS1/Ay0Xm2ZRb+ZXhWn9m6L6KV+VVfpt3MWjqilz28VMXpvM/Gt/
LfGhyUUDndKj1O//mGRPy+WynOeV6fV/1FX8cdzdg3xezOr6te3xp5U8/9eL
2WRer6JeTifZ81Xe5KaL01W+MB/GHTys68tlYZuHH4san/7rJX3X6+LxJDuu
r6rxQ9j42s7lcd41ZbHsfRv3+F1VvimaFom1vsiev72AB23/q+Kvr7kh6Hmy
eR31DWTxsp4VTWfJIl9f5dCt+SLu8e9lE82w4Rf+eg2f0+wcEnuzgsffFECD
Wd50h/RClzeXRXeYXXXduj28c6dYN2XVTcp83kygjzt39w/+fOeLL76YrBcX
/AIf0Z3nVXZaLdpxV4/xJ/wxb27WPJyj9qaaXzV1VW/a7GFTb9bmOF+X3VV2
1sG3l+FQP9zAdsABK9od6sWfFvo3fs/yhyeO8zY7booVLH/yzZPN6yJ7mDdN
3nXJVz0KNT0Wb0r6sioa+moB7OMwg1X5crx/MD74Ej6EIzFbFtAuHAxYyZPn
jyYH+5ODg/2v7pxumvrsxQQXcXL3zw4ebsvLKl8Or/319fWEv6elB27W3mnX
xby8gJHhyrZ3or7uRBuCTPOEvgZ6oe+zoyVwOlju1U489i/GBwfju/sDK+0n
/gqYat1kL4oG6GG3WOylDzyt35bApfNmCWS7Ll8XOLuz0+OHh9GoTmFZgSrm
2fGmeVPA3gCN1JdInzcjoAJgocDv2gyIMzu9gHmWRdVFTzH9jDI4UZPs7s7g
wrXF/JKWDH45GL+564lVZ7z/FY3u2zO/PV/s3/3yzrNHZ68mDx69OJscfLk/
/sy58Xic5bO2a/I5cPhAs/l6vdQ9gLNTwFGdwzXRwnfLm2yVv8aHNm2B572o
Fngo4IdrlbxXBfD1qmxXbdbV8ES7gTa6q7yDb7CPglutK2gtn8/hsxL3satd
B7sKB3i1qah/6AYaXtdwRuF2gdXLqrrDNvPqJmuLBvkODO5NvXxTLOCXbFEs
kRnBi067mmTZKVxes2XZXmGDcMPRsOCWfFMuiqwFDo9/dMWcJ1y2Doa/XBYV
LQbu1SUd6jnOoC06HBcMB7q7voIbLFvVPL0q665rN1/iprZZVcCQcKiXTYFz
zXLsOpttYBXyG5rIjNagrIoMGsapt0BrIBWsChj0I2juqmzhvM03K2hxlF3D
A3Q+bqStQueF3zu99nmlZXptVng6yy2f4in1WyF+BXO+xosZdrQp5je08uu6
7cawN9DwqoS997vtF6gFtgsn/p8FMGRZO3gWFwXXAc7dpoWG2oljyluViwXc
VM79AYWNpl5saAOcO3l0dvzk6NHT05coG5W4IzBhEEtej8sKpRtY0bZlqQdJ
EGQhGuEVcENc1puiA1osKuI+xE2qLgw3B4Zz05ZAF4/gUxjUcqGbASS9gFWC
zmZA7K3Dmc025XKBc1n7EYKY03bFCify8sFxdnry6NVzGOqLJ6dHZ6fZy9On
z/92mr369jR78PzJk+d/f/TsYfbi6OXRw5dHL74lYa+tN828wIVzvMU0E/gF
rrOqg/8xMT8su283s0l2trkEOu7gQzxWeHpk2LPCtZvZquw6Hvd6s1xmTfGf
G3i6RZpSjnEJm7oh2eIOCIjXl3esmDhxjyrgAZt5OO91JUQEBwgbvi6Wy0l2
uig7YLD50o8DVhYHsYI1vbRjHhGZ0yHdzFByxItY3gqDzxYg3m1aXHTYdqR/
3Em80nG9gSI7WOEjoVTYZ9geOO7XV3V2jTsKNNUCd8iKHM5gDa83wCzoVoYG
PaPBY9g6IB84c/DGApjDGxwDTHOB8uqqgEt2rm/i7iKDmGQPYO+RctcgO5RF
O+KdgjUDTrUiUpsRiXWbRYkHHW6VenN5tQQ+T0eo691PDu9p5q9IYsjmkJbq
5Ya6ffcuuu1++QU+4evxl18m7hjWriqWcBZWaxgAnFRsqN8JTOSnGs4k0NAY
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
UUQ5UKd5heUmnYdm1CB+U75E/oShW6QlVXjXCJMJrxvLl8lkMgG+XBPXCTF6
B2jcv9c9imqzEpkWhR64uxa7+3tssQfd+WB/90D+2oULew/EUK3y9De+yX6V
snGqZcuHdI3oy1Dh3MjpogWErwZUAd9K2nwyfi1Nzi1bzZWphImEv41sPESa
RJlImPcSJcPc2vfiWZma7X/5MpHzUwUpmVMgM68BDFhaiLT8iafkCrzpr2vT
MwdRIsXAorqprUk41cKTZHwgI8RUL4Gp2hKjF0K7jut5WRuwLyewkjsTwSHz
i4IN/aEePSNRMlgYGjWDcTR4Y7B8yKJs55u21SJ1dB2NteQ7sFPiYHSUMWiK
uDYV5upK8tbitFQGuxNdwmu47cNq4g3OQt80fMgJ2RZjQwtciV9Ky7mzAkOg
Rqba+0JKq3NdBBat30SubJ+mRqGtq3oRjJAK0sOpWJ5/CNC/r8nDQTf8sPN0
hDyOcsmXvo6QD9quPWCbuGxAyAi2GXOvW5BTLlsZZ1czj5Sbj+5/RH9tCLY/
Cq4XCxxfL8eGkpj5byMuzUglJyQMxlt5ZT+BqO0VyNUf/EOB9umKl9szrlrp
ueKHMIyWDufnn3+9jXPwMOKntvA289Qv0YoY6zHGtfil8Ncge3QNwozVfyem
Q0mu5fqxThX6MIJpsODmQ4HqaTVV+6qzxt+t+8fb/kRYiey15yxmcolzD78O
9dnjGoYYGel8Vmo0cKJk4ld4qpBoyzZLXfKoCFCABnczArE/R0lHrcg1plQE
ZIjvqvJtVqxrGMHuwVd/3h/vH8D/v9rfP6T//4+9SShDS4GJWEhYU3fUQttH
Y65urPPQFL+Ygp53zn9PHbsT8XlyN/rv6c9pJv46phe8Z7/4LAuv37Mf0RvB
iBQ0xVbdk4xzACLJ23K1wZopHVxpXhXQ6q+YYLQmfy/Pw9xGI3Hjk96DEzRz
DonCSbslQwIzHHHFoY+LDYeCTobPgByAWbH1DBDVmd4fqejaAL/5OydnwIU1
ivelbIOM65PBycWHPiVg0BjJ6N69uyaMa9i2MfC7sTBVlOrlosSo33JhqVuN
1HbVWbt0CL7xFj/G6irmgbF3bfixc6ZhNM3IHcX9RvKDbDesBsehZN/CdOQY
CmYeTtCOlQRC9sKWVYIjbssSEtpGmlM2lDArF5EghhoEN595OSIfChVwozTJ
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
a8hmcJPRILpNfZqRAB6IcCTjYn946f74FKsAPLAsFjmFzfVb+2nF3o4eQLRl
2Bn9f59a7J3oAUdz8s8Vezd6wMMyd4r9/tlHF0t37o+6dH/0Sgi+mI4b7OOO
IPKMkcJtr4vOJnH6evFIupEj5Y4Dq3v+7Dqwko86sNL/vAPLMRrdfGINPPg/
Z8P/l2fDf8lx8J93AnyM0D/LGljog737RDl/ffewZ1r5qJL+QanWFWQix3r+
7PRlVS3T95/N89+TZIc3nc1u5EUPEs+iFvhigN9ikH7CaFPonQdhPqYsOoyq
QjAJkBqVoXdQa06aW5hQT6gNrGF+jcEFUNyYX3qEUc6Tqj5/ONIX0bjBgP4U
yFhzLohIFyl1kj4VaLgkAj2m95eYrq9Oc5EPxHhEIWAhBMZS8BIoUfVkSkOT
QdCsLQmMopFo4MuGSAPZp07omkkTDawCxlBdaO1gwKdQpI2t0k27rkXjJUE1
OFKJxPdQAnjJTYVe4eJoNgy2KkSje6+4eA7f4YnjcUBqYqzm26y2id7DWAdn
EYkmcxS1jPqVFyS+dagoKKzkEM16oI8jyuXflMpizKEQMFqN5Ja6CpKo6yht
8TqJ8folnawyAsa2zPChmURIwPOYaJlIdBKhrzWb83PO1CTzM0JKsjWMUM24
zTxWhCvVNIvNcrJjrixiG2NcJB96LqJZlr4EB2PKUnI0xWxTQ/88I5OUTTZK
+1sYld9ycIVMdANHFP1JUAg0qF+DPnoetkm0PDCGoy4opI2bF2LAOghnOoXG
E6BdwGo8FBfDqcCL0WTONxzxhfwFyOJG4JNiiKFg/5EVwhahZXGZc/T7Ge1d
B2xIk8Nh4JSygsidFCSX8Fhiz5dRbjqfvL6VceNyNuVijDVxxcJddxKzOfRW
MeHKde2XY8r1RRmH9tWKEhI3pVhg43ArNMWiqSPAsDH8TJCfigVnt22tn629
OE+JMJdnBFUry4wXgutevEdudRcAW4RloatYQsjJYr0MlfKKQEg2CnesfApT
ElPuwVomfgJ08+DUBd9R5hk9FKyjaGLpN/IxfmnOWYmw+rM5mYYlcVOkTLVI
OlPJgoHxczzdT9adc5EgFNmXcFIo49jhRucoO9LTDIxTcRZzEas+BDvhcRLU
Rf5DN9Pcm+z/vpmfrxztGiM66KmEAYGPFd0RbbKgof1blS/T4+VVXqa//oq6
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
9JzxqCsdAgA=

-->

</rfc>

