<?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.17 (Ruby 3.3.3) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-kohbrok-mls-virtual-clients-01" category="info" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.22.0 -->
  <front>
    <title abbrev="MVC">MLS Virtual Clients</title>
    <seriesInfo name="Internet-Draft" value="draft-kohbrok-mls-virtual-clients-01"/>
    <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="2024" month="July" day="03"/>
    <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:
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
I7STDkXfpDUWQG703xp3jy3cH8k0Chr7g1ws4kTzzTm6GeGRIsoqKW9vKim4
i4/bh+tuyfxZNXZR0nsE4KOg9dPe+g0wkVS+hy0pghamUyIhE1qF6QgOMcMt
12ECqfS7hhsOk0nQiQtihlpGDuvvlfHgF7kELjeqUPunE/MJefECj0r2odu4
Ya4NTyhDNYHXMcYzDeOYdvywRa9u32HTLAbQcpPKhvFwGaBnEvBLouP05GO6
QXfEJgPMIgQochoJnGXCIjFF5bVTj+3hNFEWBHJXt0dUfuR+ax4uzhfOBDvX
fj4r211q88pNAgJC0MRCGUwXBkqOB9tJ2wKtk86+AAThKBRK/IwuYsxSE0Ti
1/bcrZY9tXRr81BMfYPzb2k6nfGzZnW3Ry9abtsy2dI74E5mRPxC8Nh1XdtD
NJve0EGwWfIAyY01AOt4Tibtzc2SeMt4NLxNrg5UP+Dd0cXdYiY+Q5jghHkp
GavWHhq6qI9vq3TgrHi4aCXQcAQA8dJBuN5K8zeRu1N8Ugvdeg3YGAw7BRBN
jVp0FJQkU4OMfvtnn/Xn1C6IZNXLOET25dP8ZcipIo29uVl3nNVFfX0GnFXJ
2DcZG/uS8L2qTXMP5P2M/s8TqY47uQPp71SKcfVeRqCsHxaDl1YQof7O0oDt
hqOhJm6nnzsSO9wpwSAGb3wzJE6DxBQvZyGajBdHQ5V5iAURWWZXKTouFn7j
HQaekUUb48RinhmXuS7EN6Wlc26m1jVmxcPU0olEl63lqVB+FgZ25SM7EySM
7bRJzfPcYJrb+EbVTLbHn+BjFpmWLEDtF8UU5srSxaHcONjBXDQyNFfBGKIM
AS+85PFc6ddU0RGfJz9+hjwgHlIAWtr5NtHsmF+Ob2TqLg/YJr22TlgyTAye
rBJGD4PcYe8dl+qCus9FR+JBYlynSA0t1P8AmNqsiKFnAAA=

-->

</rfc>
