<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.24 (Ruby 3.3.6) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-kohbrok-mls-decentralized-mls-00" category="info" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.28.0 -->
  <front>
    <title abbrev="DMLS">Decentralized Messaging Layer Security</title>
    <seriesInfo name="Internet-Draft" value="draft-kohbrok-mls-decentralized-mls-00"/>
    <author fullname="Konrad Kohbrok">
      <organization>Phoenix R&amp;D</organization>
      <address>
        <email>konrad.kohbrok@datashrine.de</email>
      </address>
    </author>
    <date year="2025" month="March" day="17"/>
    <area/>
    <workgroup>Messaging Layer Security</workgroup>
    <keyword>security</keyword>
    <keyword>authenticated key exchange</keyword>
    <keyword>end-to-end encryption</keyword>
    <abstract>
      <?line 45?>

<t>Messaging Layer Security provides strong end-to-end security guarantees for
group messaging including Forward Secrecy (FS) and Post-Compromise Security
(PCS). However, MLS requires a Delivery Service (DS) to facilitate agreement
between group members on the order of Commit messages. In decentralized settings
the only way to implement a functional DS is to require group members to retain
key material so they can process commits out-of-order. Retaining key material
this way is in violation of the MLS deletion schedule and significantly reduces
the FS of the protocol. This draft specifies Decentralized MLS, based on the the
Fork-Resilient Continuous Group Key Agreement protocol FREEK proposed by Alwen
et al. <xref target="FRCGKA"/>. In essence, DMLS extends MLS such that key material can be
retained to process Commits out-of-order with minimal losses to FS, thus
allowing safer deployment in decentralized environments.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://phnx-im.github.io/dmls-spec/draft-kohbrok-mls-decentralized-mls.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-kohbrok-mls-decentralized-mls/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        Messaging Layer Security  mailing list (<eref target="mailto:mls@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/mls/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/mls/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/phnx-im/dmls-spec"/>.</t>
    </note>
  </front>
  <middle>
    <?line 60?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>TODO: Introduction</t>
      <t>Open Questions:
- Why do removed members need to receive their commit confirmation from their
  removers? They should be able to process the removing commit without the init
  secret in the first place.
- Is it safe to use the commit secret regularly in the key schedule <em>and</em> to
  derive the commit confirmation or do we need an additional derivation step to
  ensure domain separation?
- Why would we need to generate a fresh signature key pair with each update?
- Do we need an additional membership tag?</t>
    </section>
    <section anchor="epoch-identifiers">
      <name>Epoch identifiers</name>
      <t>In MLS, each epoch is identified by a 64 bit unsigned integer, with the epoch
increasing by one with each commit. The integer identifies epochs uniquely as
long as there is only one chain of Commits. However, in a decentralized context
there can be conflicting commits. For example, if two group member send a commit
at the same time with different subsets of group members receiving a different
commit first. After processing the newly arrived Commit, all group members would
be in the same epoch, but in different group states. For subsequently arriving
messages, it is unclear from the integer designating the epoch, which state the
message belongs to. In such scenarios it is important that epochs are uniquely
identifiable.</t>
      <t>When using DMLS, epochs are represented as byte strings of length <tt>KDF.Nh</tt> (thus
depending on the group's ciphersuite). The byte string identifying an epoch is
derived from the epoch's <tt>epoch_secret</tt> and can thus be learned when creating or
processing the commit that initiates that epoch.</t>
      <t><tt>pseudocode
epoch = DeriveSecret(epoch_secret, "epoch")
</tt></t>
    </section>
    <section anchor="dmls-key-schedule">
      <name>DMLS key schedule</name>
      <t>DMLS conceptually modifies the MLS key schedule by enabling the creation of
multiple <tt>init_secret</tt>s, where each init secret can be used to initialize a
subsequent epoch.</t>
      <t>The individual <tt>init_secret</tt>s are derived through a puncturable pseudorandom
function (PPRF, <xref target="puncturable-pseudorandom-function"/>) keyed by the
<tt>base_init_secret</tt>.</t>
      <figure>
        <name>The DMLS Key Schedule</name>
        <artset>
          <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="384" width="400" viewBox="0 0 400 384" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
              <path d="M 152,88 L 152,176" fill="none" stroke="black"/>
              <path d="M 152,248 L 152,272" fill="none" stroke="black"/>
              <path d="M 152,304 L 152,336" fill="none" stroke="black"/>
              <path d="M 152,128 L 176,128" fill="none" stroke="black"/>
              <polygon class="arrowhead" points="184,128 172,122.4 172,133.6" fill="black" transform="rotate(0,176,128)"/>
              <polygon class="arrowhead" points="160,336 148,330.4 148,341.6" fill="black" transform="rotate(90,152,336)"/>
              <polygon class="arrowhead" points="160,272 148,266.4 148,277.6" fill="black" transform="rotate(90,152,272)"/>
              <polygon class="arrowhead" points="160,176 148,170.4 148,181.6" fill="black" transform="rotate(90,152,176)"/>
              <g class="text">
                <text x="28" y="36">(above</text>
                <text x="72" y="36">the</text>
                <text x="108" y="36">same</text>
                <text x="140" y="36">as</text>
                <text x="168" y="36">the</text>
                <text x="200" y="36">MLS</text>
                <text x="232" y="36">key</text>
                <text x="288" y="36">schedule)</text>
                <text x="152" y="52">|</text>
                <text x="156" y="84">epoch_secret</text>
                <text x="248" y="132">DeriveSecret(.,</text>
                <text x="348" y="132">&lt;label&gt;)</text>
                <text x="192" y="148">=</text>
                <text x="236" y="148">&lt;secret&gt;</text>
                <text x="160" y="196">DeriveSecret(.,</text>
                <text x="284" y="196">"parent_init")</text>
                <text x="152" y="212">|</text>
                <text x="164" y="244">parent_init_secret</text>
                <text x="156" y="292">DeriveChildSecret(.,</text>
                <text x="296" y="292">"child_init",</text>
                <text x="316" y="308">commit_confirmation,</text>
                <text x="304" y="324">GroupContext_[n])</text>
                <text x="160" y="356">init_secret_[n]</text>
              </g>
            </svg>
          </artwork>
          <artwork type="ascii-art"><![CDATA[
        (above the same as the MLS key schedule)
                          |
                          V
                     epoch_secret
                          |
                          |
                          +--> DeriveSecret(., <label>)
                          |    = <secret>
                          |
                          V
                    DeriveSecret(., "parent_init")
                          |
                          V
                   parent_init_secret
                          |
                          V
                 DeriveChildSecret(., "child_init",
                          |          commit_confirmation,
                          |          GroupContext_[n])
                          V
                    init_secret_[n]
]]></artwork>
        </artset>
      </figure>
      <sourcecode type="pseudocode"><![CDATA[
commit_confirmation = DeriveSecret(path_secret[n], "conf")

DeriveChildSecret(prf_key, label, input_secret, context) =
  DeriveFSSecret(prf_key, ExpandWithLabel(input_secret, label, context, KDF.Nh))
]]></sourcecode>
    </section>
    <section anchor="puncturable-pseudorandom-function">
      <name>Puncturable pseudorandom function</name>
      <t>A PPRF allows the derivation of keys in a forward secure way. In particular, a
PRF that was evaluated with a given key and input can't be evaluated with those
same parameters again. Storing the original input key thus doesn't harm the
forward secrecy of (deleted) output keys.</t>
      <t>The MLS Secret Tree as defined in <xref target="RFC9420"/> already represents a PPRF an
needs to be modified only slightly for the purpose of this document.</t>
      <t>In the context of MLS, the Secret Tree has as many leaves as the group has
members. To derive child init secrets, the same tree is used but with <tt>KDF.Nh</tt>
leaves.</t>
      <t>The function <tt>DeriveFSSecret(secret, input)</tt> thus follows these steps:</t>
      <ul spacing="normal">
        <li>
          <t>Check if <tt>secret</tt> and <tt>input</tt> are of length <tt>KDF.Nh</tt></t>
        </li>
        <li>
          <t>With <tt>secret</tt> as the root node secret and <tt>input</tt> as the leaf index, derive
the direct path nodes and the copath nodes as defined in Section 9 of
<xref target="RFC9420"/></t>
        </li>
        <li>
          <t>With <tt>leaf_node_secret</tt> as the resulting secret compute the final output using
<tt>DeriveSecret(leaf_node_secret, "pprf")</tt></t>
        </li>
      </ul>
    </section>
    <section anchor="state-consolidation">
      <name>State consolidation</name>
      <t>The changes to MLS outlined above allow the processing of multiple commits for
each epoch with improved forward secrecy. However, once a fork was created, they
do not help in returning group members to a single, agreed-upon group state.</t>
      <t>There is no one semantic to consolidate forks that is optimal for all given
applications. Even more so if the application uses extensions that store
additional data in the group's context.</t>
      <t>This section thus details a simple state-consolitation procedure that focuses on
consolidating group membership and key material only. To keep it simple, our
approach makes a few assumptions.</t>
      <t>TODO: The following is work in progress. While the assumptions won't disappear
entirely, they will become weaker in future iterations.</t>
      <ul spacing="normal">
        <li>
          <t>One group forked at epoch e_i</t>
        </li>
        <li>
          <t>Only one partition, half of the group on one side, the other on the other side</t>
        </li>
        <li>
          <t>Both sides of the partition have a server that helps them agree on commit
ordering (imagine a netsplit in a federated approach with only two servers
involved)</t>
        </li>
        <li>
          <t>The two servers involved coordinate in allowing commits/preventing forks</t>
        </li>
        <li>
          <t>Neither clients nor servers keep around old messages, but do keep around old
group states s.t. they can process old messages</t>
        </li>
        <li>
          <t>No insider attacks, i.e. no insider is trying to create a fork and then make
the others accept the new state</t>
        </li>
        <li>
          <t>No access control: All parties can add and remove members as they please</t>
        </li>
        <li>
          <t>KeyPackages are accessible: All parties can access KeyPackages of all other
parties</t>
        </li>
      </ul>
      <t>Open Questions:
- How to determine which fork wins, i.e. which fork is merged into which?
  Options:
  - Arbitrary: The fork with the alphanumerically highest transcript hash wins
- Is it mandatory that the consolitation algorithm is deterministic s.t.
  everyone can compute it and arrive at the same result?</t>
      <t>Timeline:
- Alice, Alan, Bob and Betty are in a group
- Alice and Alan on server A, Bob and Betty on server B
- There is a disconnect between servers A and B
- All group members keep sending messages
- Alice adds Albert to the group
- Betty removes Bob from the group
- The servers reconnect
- All parties receive and process all messages from the other side
- All parties now have two forks of the same group
- One party (say Alice) starts the consolitation procedure (see below)</t>
      <section anchor="consolidation-algorithm">
        <name>Consolidation algorithm</name>
        <ul spacing="normal">
          <li>
            <t>Given two forks, choose the one with the alphanumerically larger transcript hash</t>
          </li>
          <li>
            <t>On the losing fork, create a commit with a proposal that indicates that this
fork is closed</t>
          </li>
          <li>
            <t>On the winning fork, create a commit that consolidates the group membership of
both forks:
            </t>
            <ul spacing="normal">
              <li>
                <t>If a member was removed in the losing fork but not on the winning fork,
remove it in the commit</t>
              </li>
              <li>
                <t>If a member was added in the losing fork, but not on the winning fork, add
it in the commit</t>
              </li>
            </ul>
          </li>
        </ul>
        <t>Open Questions:
- What if a member was removed in both forks and then re-added in the winning
  fork? Should it still be removed in the consolidating commit? Resolving this
  is tricky if not everyone has the message traces for both forks.
- What if there is no overlap in members? In that case, there is no way to
  consolidate, because no one can create a commit in the other fork.
  - Maybe that's okay? In that case, there's not much to consolidate. Should the
    losing fork be closed? Or should both forks live on? Might depend on the
    application.</t>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>TODO Security</t>
      <ul spacing="normal">
        <li>
          <t>Note that while the PPRF gives you FS for init secrets, you also need to keep
the secret state of old RatchetTree states around, thus damaging their FS</t>
        </li>
      </ul>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC9420">
          <front>
            <title>The Messaging Layer Security (MLS) Protocol</title>
            <author fullname="R. Barnes" initials="R." surname="Barnes"/>
            <author fullname="B. Beurdouche" initials="B." surname="Beurdouche"/>
            <author fullname="R. Robert" initials="R." surname="Robert"/>
            <author fullname="J. Millican" initials="J." surname="Millican"/>
            <author fullname="E. Omara" initials="E." surname="Omara"/>
            <author fullname="K. Cohn-Gordon" initials="K." surname="Cohn-Gordon"/>
            <date month="July" year="2023"/>
            <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 (FS) and post-compromise security (PCS) for groups in size ranging from two to thousands.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9420"/>
          <seriesInfo name="DOI" value="10.17487/RFC9420"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="FRCGKA" target="https://eprint.iacr.org/2023/394.pdf">
          <front>
            <title>Fork-Resilient Continuous Group Key Agreement</title>
            <author initials="J." surname="Alwen" fullname="Joël Alwen">
              <organization/>
            </author>
            <author initials="M." surname="Mularczyk" fullname="Marta Mularczyk">
              <organization/>
            </author>
            <author initials="Y." surname="Tselekounis" fullname="Yiannis Tselekounis">
              <organization/>
            </author>
            <date year="2024" month="February" day="22"/>
          </front>
        </reference>
      </references>
    </references>
    <?line 251?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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

-->

</rfc>
