<?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.21 (Ruby 3.3.6) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-kohbrok-mls-virtual-clients-02" category="info" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.25.0 -->
  <front>
    <title abbrev="MVC">MLS Virtual Clients</title>
    <seriesInfo name="Internet-Draft" value="draft-kohbrok-mls-virtual-clients-02"/>
    <author initials="J." surname="Alwen">
      <organization/>
      <address>
        <email>alwenjo@amazon.com</email>
      </address>
    </author>
    <author initials="K." surname="Kohbrok" fullname="Konrad Kohbrok">
      <organization>Phoenix R&amp;D</organization>
      <address>
        <email>konrad.kohbrok@datashrine.de</email>
      </address>
    </author>
    <author initials="R." surname="Robert" fullname="Raphael Robert">
      <organization>Phoenix R&amp;D</organization>
      <address>
        <email>ietf@raphaelrobert.com</email>
      </address>
    </author>
    <date year="2025" month="January" day="10"/>
    <area>Security</area>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <?line 26?>

<t>This document describes a method that allows multiple MLS clients to emulate a
virtual MLS client. A virtual client allows multiple emulator clients to jointly
participate in an MLS group under a single leaf. Depending on the design of the
application, virtual clients can help hide metadata and improve performance.</t>
    </abstract>
  </front>
  <middle>
    <?line 33?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>The MLS protocol facilitates communication between clients, where in an MLS
group, each client is represented by the leaf to which it holds the private key
material. In this document, we propose the notion of a virtual client that is
jointly emulated by a group of emulator clients, where each emulator client
holds the key material necessary to act as the virtual client.</t>
      <t>The use of a virtual client allows multiple distinct clients to be represented
by a single leaf in an MLS group. This pattern of shared group membership
provides a new way for applications to structure groups, can improve performance
and help hide group metadata. The effect of the use of virtual clients depends
largely on how it is applied (see <xref target="applications"/>).</t>
      <t>We discuss technical challenges and propose a concrete scheme that allows a
group of clients to emulate a virtual client that can participate in one or more
MLS groups.</t>
    </section>
    <section anchor="terminology">
      <name>Terminology</name>
      <ul spacing="normal">
        <li>
          <t>Client: Any MLS client including emulator clients, virtual clients and real
clients.</t>
        </li>
        <li>
          <t>Real Client: An MLS client whose secret key material is held by a single
agent.</t>
        </li>
        <li>
          <t>Virtual Client: A client for which the secret key material is held by one or
more other clients, each of which can act on behalf of the virtual client.</t>
        </li>
        <li>
          <t>Emulator Client: A client that collaborates with other emulator clients in
emulating a virtual client. Emulator clients can be real or virtual clients.</t>
        </li>
        <li>
          <t>Heirarchical group: A generalization of an MLS group in which members can be
either virtual or real clients. Heirarchical group members may also act as
emulator clients to collaboratively emulate a virtual client representing the
heirarchical group in one or more other heirarchical groups.</t>
        </li>
        <li>
          <t>Group representative: A group representative of (heirarchical group) G is a
virtual client emulated by the clients in G. The group representative of group
G in another group S is the representative of G that is a member S.</t>
        </li>
        <li>
          <t>Subgroup: A heirarchical group with a representative in one or more other
groups.</t>
        </li>
        <li>
          <t>Supergroup: A heirarchical group with one or more virtual members.</t>
        </li>
      </ul>
      <t>TODO: Terminology is up for debate. We’ve sometimes called this “user trees”,
but since there are other use cases, we should choose a more neutral name. For
now, it’s virtual client emulation.</t>
    </section>
    <section anchor="applications">
      <name>Applications</name>
      <t>Virtual clients generally allow multiple emulator clients to share membership in
an MLS group, where the virtual client is represented as a single leaf. This is
in contrast to the case where each individual emulator client is a regular
member of the group, each with its own leaf.</t>
      <t>Depending on the application, the use of virtual clients can have different
effects. However, in all cases, virtual client emulation introduces a small
amount of overhead for the emulator clients and certain limitations (see
<xref target="limitations"/>).</t>
      <section anchor="virtual-clients-for-performance">
        <name>Virtual clients for performance</name>
        <t>If a group of emulator clients emulate a virtual client in more than one group,
the overhead caused by the emulation process can be outweighed by two
performance benefits.</t>
        <t>On the one hand, the use of virtual clients makes the higher-level groups (in
which the virtual client is a member) smaller. Instead of one leaf for each
emulator client, it only has a single leaf for the virtual client. As the
complexity of most MLS operations depends on the number of group members, this
increases performance for all members of that group.</t>
        <t>At the same time, the virtual client emulation process (see
<xref target="client-emulation"/>) allows emulator clients to carry the benefit of a single
operation in the emulation group to all virtual clients emulated in that group.</t>
      </section>
      <section anchor="hidden-subgroups">
        <name>Hidden subgroups</name>
        <t>Virtual clients can be used to hide the emulator clients from other members of
higher-level groups. For example, removing group members of the emulator group
will only be visible in the higher-level group as a regular group update.
Similarly, when an emulator client wants to send a message in a higher-level
group, recipients will see the virtual client as the sender and won't be able to
discern which emulator client sent the message, or indeed the fact that the
sender is a virtual client at all.</t>
        <t>Hiding emulator clients behind their virtual client(s) can, for example, hide
the number of devices a human user has, or which device the user is sending
messages from.</t>
        <t>As hiding of emulator clients by design obfuscates the membership in
higher-level groups, it also means that other higher-level group members can't
identify the actual senders and recipients of messages. From the point of view
of other group members, the "end" of the end-to-end encryption and
authentication provided by MLS ends with the virtual client. The relevance of
this fact largely depends on the security goals of the application and the
design of the authentication service.</t>
        <t>If the virtual client is used to hide the emulator clients, the delivery service and
other higher-level group members also lose the ability to enforce policies to
evict stale clients. For example, an emulator client could become stale (i.e.
inactive), while another keeps sending updates. From the point of view of the
higher-level group, the virtual client would remain active.</t>
      </section>
      <section anchor="transparent-subgroups">
        <name>Transparent subgroups</name>
        <t>TODO: The following text assumes that we have some mechanism of adding one or
more additional signatures to MLS messages.</t>
        <t>While applications can choose to use virtual clients to hide the corresponding
emulator clients, they don't have to. When using the virtual client to send
messages, the sending emulator client can provide an addition signature using
either its leaf credential in the emulation group, or another AS-provided
credential that allows higher-level group members to authenticate the message.</t>
      </section>
    </section>
    <section anchor="limitations">
      <name>Limitations</name>
      <t>The use of virtual clients comes with a few limitations when compared to MLS,
where all emulator clients are themselves members of the higher-level groups.</t>
      <section anchor="external-remove-proposals">
        <name>External remove proposals</name>
        <t>In some cases, it is desirable for an external sender (e.g. the messaging
provider of a user) to be able to propose the removal of an individual
(non-virtual) client from a group without requiring another client of the same
user to be online. Doing so would allow another client to commit to said remove
proposal and thus remove the client in question from the group.</t>
        <t>This is not possible when using virtual clients. Here, the non-virtual client
would be the emulator client of a virtual client in a higher-level group. While
the server could propose the removal of the client from the emulation group,
this would not effectively remove the client's access to the higher-level groups
in which the virtual client is a member.</t>
        <t>For such a removal to take place, another emulator client would have to be
online to update the key material of the virtual client (in addition to the
removal in the emulation group).</t>
        <t>Another possibility would be for emulator clients to provision KeyPackages for
which only a subset of emulator clients have access to. The external sender
could then propose the removal of the virtual client, coupled with the immediate
addition of a new one using one of the KeyPackages.</t>
      </section>
      <section anchor="external-joins">
        <name>External joins</name>
        <t>When there are no subgroups and all (emulator) clients are members of each
higher-level group, new (emulator) clients would be able to join via external
commit without influencing the operation of any other emulator client and
without requiring another emulator client to be online.</t>
        <t>When using virtual clients and a client wishes to externally join the emulator
group, it will not have immediate access to the secrets of the virtual clients
associated with that group.</t>
        <t>This can be remedied via one of the following options:</t>
        <ul spacing="normal">
          <li>
            <t>Another emulator client could provide it with the necessary secrets</t>
          </li>
          <li>
            <t>The new emulator client could have the virtual client rejoin all higher-level groups</t>
          </li>
        </ul>
        <t>While the first option has the benefit of not requiring an external commit in
any higher-level groups (thus reducing overhead), it either requires another
emulator client to be online to share the necessary secrets directly, or a way
for the new emulator client to retrieve the necessary without the help of
another client. The latter can be achieved, for example, by encrypting the
relevant secrets such that the new client can retrieve and decrypt them.</t>
        <t>The second option on the other hand additionally requires the new emulator
client to re-upload all KeyPackages of the virtual client, thus further
increasing the difficulty of coordinating actions between emulation group and
higher-level groups.</t>
      </section>
    </section>
    <section anchor="client-emulation">
      <name>Client emulation</name>
      <t>A set C of emulator clients that want to emulate one or more virtual clients
must first form an MLS heirarchical group G with membership C. The emulator
clients use G to coordinate their shared virtual clients. Just like real
clients, a virtual client V can create, join or participate in any group S, even
acting as an emulator client itself for some other virtual client. If V joins a
group S then this makes G a subgroup of supergroup G where V is called G's
representative in V. G may have 0 or more representatives which can each be a
member of 0 or more supergroups. But G can have at most 1 representative in a
given supergroup. Emulating clients in G MUST ensure that G and all of its
supergroups have distinct group IDs.</t>
      <t>An emulator client E in G creates a new virtual client V of G by assigning the V
a fresh virtual client ID (unique among all virtual clients of G) and a
signature key pair. The new creation of V, its ID and key pair are communicated
to rest of G via a commit in G sent by E. As an invariant, emulator client's in
G maintain a copy of the complete local MLS state of V. This includes all MLS
related secrets currently held by V. Using this state, each emulator clients can
independently process MLS messages sent to V to update their copy of V's state.
Emulator client's in G can also act on behalf of V (subject to application
policy) by taking a new action. Possible actions include anything an MLS client
can perform such as generating and publishing a new key packages and sending
commits, proposals, welcome messages or application messages. To help other
members of G update their copies of V's state according to the action, E
anounces the action using a commit to G. Any secrets created by E as part of
implementing the action are generated deterministically by exporting seeds from
G. This allows other emulator clients in G to reproduce the same secrets and
update their own copies of the V's state maintaining the invariant.</t>
      <t>OPEN QUESTION: It's also conceivable that emulator clients announce their
actions via application messages. This is sufficient for operations that are
affect individual groups, because the DS of that group will enforce message
ordering.</t>
      <section anchor="generating-virtual-client-secrets">
        <name>Generating Virtual Client Secrets</name>
        <t>An emulator client V in a group G may sample four types of MLS-related secrets
on behalf of a virtual client V which must be reproducable by the other clients
in G: init_key KEM keys in KeyPackage structs, encryption_key KEM keys in
LeafNode structs, path_secrets for an UpdatePath structs and signature key
pairs. In each case, to do this V (and all other clients in G) do this by
constructing an appropriate label for the new secret and exporting from G with
the label.</t>
      </section>
      <section anchor="dsas-details">
        <name>DS/AS Details</name>
        <t>Virtual client emulation should be largely agnostic to specific details of the
AS and DS of the application. However, a few conditions must be met.</t>
        <ul spacing="normal">
          <li>
            <t>Access control: All emulator clients must be able to act as the virtual
client, including, for example, queue access and KeyPackage upload</t>
          </li>
          <li>
            <t>Queue compatibility: The queue system must allow all emulator clients to
retrieve messages for the virtual clients. (Although workarounds like one
emulator client retrieving messages and then sending them to the emulation
group are possible.)</t>
          </li>
        </ul>
      </section>
      <section anchor="adding-emulator-clients">
        <name>Adding emulator clients</name>
        <t>If a client is added to the emulation group, it has to be provisioned with the
private key material and the group states of all higher-level groups. While the
latter might be able to be provisioned by the higher-level DS, the former has to
be provided by another emulator client.</t>
        <t>The other emulator client can provide the secret key material used to derive all
key material relevant to the virtual client (higher-level group secrets,
KeyPackage secrets, etc.)</t>
        <t>TODO: This means that all such key material must be derived in a well-separated
and forward-secure way. (See TODO above to specify further details on how to
derive key material for the virtual client.)</t>
        <t>Since the new emulator client can only emulate the virtual client if it has
access to those secrets, it cannot join the emulation group via external commit,
except if said secrets are provided asynchronously.</t>
      </section>
      <section anchor="sending-application-messages">
        <name>Sending application messages</name>
        <t>MLS applications messages are encrypted using key material derived from the
secret tree, where a unique key/nonce pair is derived for each message and
irrevocably deleted after the message was encrypted or decrypted.</t>
        <t>This poses a problem in the context of virtual client emulation, because the use
of such key material cannot easily be coordinated between emulating clients.
However, reusing a key/nonce pair for different application messages leaks
information about the plaintexts. Moreover, any client receving the two would
not be able to decrypt the second message as the requisit key would already
be deleted.</t>
      </section>
      <section anchor="challenge-based-application-message-encryption">
        <name>Challenge-based application message encryption</name>
        <t>This problem can be solved by introducing a new type of application message
where the encryption keys are derived using a challenge-based approach.</t>
        <t>Using a forward-secret exporter secret (provided by the safe extension API),
each member creates a new secret tree. Whenever a group member wants to send a
message, it creates a fresh random challenge (see <xref target="challenge-generation"/>) for
that message. Each challenge is mapped to its own secret using a forward-secure
KDF implimented using a new secret tree (see <xref target="forward-secure-kdf"/>). The secret
is used to derive the key/nonce used to encrypt a message. The sender includes
the challenge in the AAD of the application message so that receivers can also
derive the decryption key. Finally, to ensure forward secrecy of the
challenge-based application message both sender and recipients apply the same
deletion schedule as for the standard secret tree in normal MLS.</t>
        <section anchor="challenge-generation">
          <name>Challenge generation</name>
          <t>To send an application message the sender must first sample a challenge. It is
crucial for application message confidentiality that challenges have high
entropy and are never used more than once. The following method for sampling
challenges ensures this by introducing sufficient entropy and guaranting that
two challenges can only ever be the same if they are sampled by the same sender,
in the same epoch, for the same message generation using the same entropy.</t>
          <t>For each epoch in which a client wants to send challenge-based application
messages it maintains a local uint32 message generation counter for the epoch.
The counter is initilized to 0 and incremented after each challenge is sampled.
If the counter wraps around to 0 then all subsequent attempts by the client to
send in the epoch MUST result in a failure.</t>
          <artwork><![CDATA[
uint32 generation;
]]></artwork>
          <t>To sample a challenge the sender first samples AEAD.Nk uniform random octets
called the challenge-seed. Next the they populate a ChallengeContext including
their leaf index in the group in which the message is sent, the current
generation counter and the confirmation tag of the current epoch (which in turn
contains the hashed group context).</t>
          <t>Additionally, the sender also includes their leaf index and the confirmation tag
of each hierarchical group between the sending (virtual) client and the real
client that actually samples the entropy.</t>
          <t>The application may supply further context in the applicaiton_context field.
Finally, the challenge is derived from the challenge-seed and ChallengeContext
using the FS-KDF and the generation counter is incremented.</t>
          <artwork><![CDATA[
struct {
  optional<GroupChallengeContext> subgroup_context;
  uint32 leaf_index;
  MAC confirmation_tag;
} GroupChallengeContext

struct {
  GroupChallengeContext group_challenge_context;
  uint32 generation;
  opaque application_context<V>;
} ChallengeContext

challenge = FS-KDF.Expand(challenge-seed, ChallengeContext, KDF.Nh)
]]></artwork>
        </section>
        <section anchor="message-framing">
          <name>Message Framing</name>
          <t>The following enum and structs define the wire format for challenge-based
application messages.</t>
          <artwork><![CDATA[
struct {
  opaque challenge<V>;
  uint32 sender_index;
} CBAMSender;

struct {
    ProtocolVersion version = mls10;
    WireFormat wire_format;
    CBAMPrivateMessage private_message;
} CBAMMLSMessage;
]]></artwork>
        </section>
        <section anchor="message-authentication">
          <name>Message Authentication</name>
          <t>The following structs are used to authenticate data in a challenge-based
application message.</t>
          <artwork><![CDATA[
// See the "MLS Wire Formats" IANA registry for values
uint16 WireFormat;

struct {
  opaque group_id<V>;
  uint64 epoch;
  CBAMSender sender;
  opaque authenticated_data<V>;
  opaque application_data<V>;
} CBAMFramedContent

struct {
  ProtocolVersion version = mls10;
  WireFormat wire_format;
  CBAMFramedContent content;
  GroupContext context;
} CBAMFramedContentTBS;

struct {
  /* SignWithLabel(., "CBAMFramedContentTBS", CBAMFramedContentTBS) */
  opaque signature<V>;
} CBAMFramedContentAuthData;

struct {
  WireFormat wire_format;
  CBAMFramedContent content;
  CBAMFramedContentAuthData auth_data;
} CBAMAuthenticatedContent;

]]></artwork>
          <t>Challenge-based application messages are encoded, authenticated and encrypted
much like MLS private messages using the CBAMPrivateMessage struct.</t>
          <artwork><![CDATA[
struct {
    opaque group_id<V>;
    uint64 epoch;
    opaque authenticated_data<V>;
    opaque encrypted_cbam_sender_data<V>;
    opaque cbam_encrypted_cbam_private_message_content<V>;
} CBAMPrivateMessage;
]]></artwork>
        </section>
        <section anchor="content-encryption">
          <name>Content Encryption</name>
          <t>Content to be encrypted is encoded with a CBAMPrivateMessageContent and the
Additional Authenticated data is encoded with a CBAMPrivateContentAAD. The key
and nonce used for encryption are derived from the encryption_secret and the
challenge C using the challenge-based secret tree as described in
<xref target="forward-secure-kdf"/>.</t>
          <artwork><![CDATA[
struct {
  opaque application_data<V>;
  CBAMFramedContentAuthData auth_data;
  opaque padding[length_of_padding];
} CBAMPrivateMessageContent;

struct {
  opaque group_id<V>;
  uint64 epoch;
  opaque cbam_authenticated_data<V>;
} CBMAPrivateContentAAD;

aead_key = aead_key[C]

aead_nonce = aead_nonce[C]
]]></artwork>
        </section>
        <section anchor="sender-data-encryption">
          <name>Sender Data Encryption</name>
          <t>The encrypted_cbam_sender_data is obtained by encrypting the CBAMSenderData
using keys derived from the cbam_sender_data_secret. This secret is exported
using the safe API's forward-secure exporter function MLS-FS-Exporter using the
label "CBAM Sender Data Secret" and an empty context. Other than that, the same
method is used to encrypt sender data as for standard application messages.</t>
          <artwork><![CDATA[
cbam_sender_data_secret = MLS-FS-Export("CBAM Sender Data Secret", "", KDF.Nk)

ciphertext_sample = ciphertext[0..KDF.Nh-1]

sender_data_key = ExpandWithLabel(cbam_sender_data_secret, "key",
                      ciphertext_sample, AEAD.Nk)
sender_data_nonce = ExpandWithLabel(cbam_sender_data_secret, "nonce",
                      ciphertext_sample, AEAD.Nn)
]]></artwork>
        </section>
        <section anchor="forward-secure-kdf">
          <name>Forward Secure KDF</name>
          <t>A consequence of the secret tree structure in MLS is that deriving the key/nonce
for a given application message requires knowing the leaf node of the client.</t>
          <t>The symmetric ratchets in MLS require performing as many (KDF and storage)
operations as application messages are being skipped. The challenge-based secret
tree (CBST) described in this section avoids these issues. Like the secret tree
in MLS, it consists of a binary tree of secrets. However, leaves are indexed by
challenges instead of leaf nodes which means the tree now has depth KDF.Nh.</t>
          <t>Nodes in the CBST are identified by the string encoding the path from the root
to the node. The root is identified by the empty string "". If a node is
identified by string <tt>N</tt> then its left child is identified the string <tt>N||0</tt> and
the right child by the string <tt>N||1</tt>. Each node is assigned a secret. The root
is assigned the cbam_encryption_secret which is exported from the MLS session
using the safe API's FS-Export function. All other nodes in the CBST are
assigned a secrety by applying ExpandWithLabel to its parents secret with
appropriate labels.</t>
          <artwork><![CDATA[
cbst_encryption_secret = MLS-FS-Export("CBST", "", KDF.Nh)

cbst_tree_node_[""]_secret = cbst_encryption_secret

cbst_tree_node_[N]_secret
        |
        |
        +--> ExpandWithLabel(., "CBST", "left", KDF.Nh)
        |    = cbst_tree_node_[left(N)]_secret
        |
        +--> ExpandWithLabel(., "CBST", "right", KDF.Nh)
             = cbst_tree_node_[right(N)]_secret
]]></artwork>
          <t>The key and nonce for a KDF.Nh octet long challenge C are derived from the
secret for leaf node identified by C.</t>
          <artwork><![CDATA[
aead_key[C] = ExpandWithLabel(cbst_tree_node[C]_secret, "CBST", "key", KDF.Nh)

nonce_key[C] = ExpandWithLabel(cbst_tree_node[C]_secret, "CBST", "nonce",
KDF.Nh)
]]></artwork>
          <t>The same deletion schedule applies to the CBST (including the
cbst_encryption_secret) as for the secret tree in MLS.</t>
        </section>
      </section>
      <section anchor="rotation-of-authentication-key-material">
        <name>Rotation of authentication key material</name>
        <t>If the design of the AS specifies the use of cross-group authentication key
material, emulator clients must coordinate the rotation of said key material in
the emulation group to avoid multiple emulator clients rotating a key at the
same time. Details depend on the design of the AS.</t>
      </section>
      <section anchor="example-protocol-flow">
        <name>Example protocol flow</name>
        <t>Virtual clients can, for example, be used by users with multiple devices. Here,
each device acts as an emulator client that emulates the virtual client which
represents Alice towards other users.</t>
        <t>A group with Alice and Bob would thus still only have two members, regardless of
the number of clients Alice and Bob have.</t>
        <t>Each of Alice's devices would thus keep the state of one emulator client, as
well as the virtual client jointly emulated by all of Alice's clients.</t>
        <t>If one of Alice's devices wanted to update its key material to achieve
post-compromise security, it would first perform a commit in the emulation
group, both to signal the action to other emulator clients and to update the key
material from which the randomness for the virtual client is sampled. From the
updated emulation group, the emulator client would then export the randomness to
perform an update in each group in which Alice (through the virtual client) is a
member.</t>
        <t>Alice's other clients would receive and process the commit in the emulation
group. Using the information included about the virtual client operation, they
also update their virtual client state.</t>
        <t>Bob (or other members in the higher level group) will only see the update in the
higher-level group, which they can simply process with their (virtual) clients.</t>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security considerations</name>
      <t>TODO: Detail security considerations once the protocol has evolved a little
more. Starting points:</t>
      <t>Some of the performance benefits of this scheme depend on the fact that one can
update once in the emulation group and “re-use” the new randomness for updates
in multiple higher-level groups. At that point, clients only really recover when
they update the emulation group, i.e. re-using somewhat old randomness of the
emulation group won’t provide real PCS in higher-level groups.</t>
    </section>
    <section anchor="privacy-considerations">
      <name>Privacy considerations</name>
      <t>TODO: Specify the metadata hiding properties of the protocol. The details depend
on how we solve some of the problems described throughout this document.
However, using a virtual client should mask add/remove activity in the
underlying emulation group. If it actually hides the identity of the members may
depend on the details of the AS, as well as how we solve the application
messages problem.</t>
    </section>
    <section anchor="performance-considerations">
      <name>Performance considerations</name>
      <t>There are several use cases, where a specific group of clients represents a
higher-level entity such as a user, or a part of an organization. If that group
of clients shares membership in a large number of groups, where its sole purpose
is to represent the higher-level entity, then instead emulating a virtual client
can yield a number of performance benefits, especially if this strategy is
employed across an implementation. Generally, the more emulator clients are
hidden behind a single virtual client and the more clients are replaced by
virtual clients, the higher the potential performance benefits.</t>
      <section anchor="smaller-trees">
        <name>Smaller Trees</name>
        <t>As a general rule, groups where one or more sets of clients are replaced by
virtual clients have fewer members, which leads to cheaper MLS operations where
the cost depends on the group size, e.g., commits with a path, the download size
of the group state for new members, etc. This increase in performance can offset
performance penalties, for example, when using a PQ-secure cipher suite, or if
the application requires high update frequencies (deniability).</t>
      </section>
      <section anchor="fewer-blanks">
        <name>Fewer blanks</name>
        <t>Blanks are typically created in the process of client removals. With virtual
clients, the removal of an emulator client will not cause the leaf of the
virtual client (or indeed any node in the virtual client’s direct path) to be
blanked, except if it is the last remaining emulator client. As a result,
fluctuation in emulator clients does not necessarily lead to blanks in the group
of the corresponding virtual clients, resulting in fewer overall blanks and
better performance for all group members.</t>
      </section>
    </section>
    <section anchor="emulation-costs">
      <name>Emulation costs</name>
      <t>From a performance standpoint, using virtual clients only makes sense if the
performance benefits from smaller trees and fewer blanks outweigh the
performance overhead incurred by emulating the virtual client in the first
place.</t>
    </section>
  </middle>
  <back>








  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA6U825LbxpXv/RVdStVqJkvScnYrVTuOUxlLo4liS1bMsfzg
co2bQHOIDAgwaHAo2smWfyNVyc/5S/bc+gKgOfLu6sGWQKD79Lnf+sznc9VX
fW0v9Osvlvpd1fV7U+vndWWb3imzWnX2AX5791yVbdGYLbxYdmbdz+/bzapr
7+fb2s0f+LN5wZ/Nn/1GFaa3d213vNBVs26Vqnbdhe67vet/8+zZf8ELprPm
Qi9tse+q/qju7fHQduWFftX0tmtsP3+B2yjletOUt6ZuG9j6aJ3aVRf6274t
Ztq1Xd/ZtYO/Hbf4l++UMvt+03YXSs817Owu9J8W+rI+2EZp+GO3pqovtMEH
f2n/YLbmh7ZZFO02vv/5Qn/OR6Mv+Mift01nysEPbXdnmuoH01dtc6Hfblrb
VO/1V//2It3onr5bCK7+UJreuE1XNXZR2rjlVwv9VbuyXZ/s+JXZbYyt0x9+
0Y6V7dd/6Pjjjr6l46n5fK7NyvWdKQCpN5vKaSDofgv00qV1RVetrNNGby3g
r9T9xvSApro9OL3d1321qy1xiJBY9y3suK+BytoooX/yAiBd+6f8ZLIaf952
6ZJ/aaumr49qZ7q+KqodLl812jS09F3X7nd635S2A0hd1dzBMrU164V+YXe2
KeGJbhsA3uKZqrtGt2v8lzK7XV0VhLnZCC6nC1h+Y+ud3lSlRQQYpBNsWupq
u+vaB6t3tlu33dY0hV0wLrdVWdZWqV8hw3ZtuS9wccQs4wm+Ax5ta702RVVX
PZwEdmq3230jgOiV7Q/WNh6OmT5sbJecV9F5Z9qaYuORCGTr7K6zDv5hS706
0mERB4i+w6aCV6teb9q6dPTTrqseEIsgX2oLf+kqUy8AZvgxYQHYG19td62z
9FnTEoiAPjOmI7FG5ZTQyrMBAWOERvDdmLz+eHSa0Y8qwgtwag+nbmxhnTPd
EQ8HjKsNvzSEaMFY3wPoOXjHfFdWrq8aWCzhu5VN0aroJAl/jXlwoUmAgD1R
V+GubgP6rJTTb+0WBM9tqp1C9gGuQslq7EEfzFEDI+mEH2l/kEtgoD2gh1YA
ZCFTZrhPIVdGZvX7McsiWIDg9drC6ZjzPVbGPF+SvDhVm+7OAhGB1pv2gKwD
5yLo4DRnzlr9448psH//+zmg+xvCYrF3ALwtNsjRsPQGMG2bOzwsAOm5yQDX
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

-->

</rfc>
