<?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.29 (Ruby 3.4.4) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-kohbrok-mls-virtual-clients-03" category="info" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.29.0 -->
  <front>
    <title abbrev="MVC">MLS Virtual Clients</title>
    <seriesInfo name="Internet-Draft" value="draft-kohbrok-mls-virtual-clients-03"/>
    <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="July" day="07"/>
    <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/RVdStVqJkvScrKVqh3HqYyl0USxJSvmWH5w
ucZNoDmEBwQYNDgU7WTLv5Gq5Of8JXtufQHQHDu7erAlEOg+fe63PvP5XPVV
X9sL/fqzpX5Xdf3e1Pp5Xdmmd8qsVp19gN/ePVdlWzRmCy+WnVn38/t2s+ra
+/m2dvMH/mxe8GfzZ79VhentXdsdL3TVrFulql13oftu7/rfPHv2389+o0xn
zYVe2mLfVf1R3dvjoe3KC/2q6W3X2H7+ArdRyvWmKW9N3Taw9dE6tasu9Nd9
W8y0a7u+s2sHfztu8S/fKGX2/abtLpSea9jZXeg/L/RlfbCN0vDHbk1VX2iD
D75r/2i25vu2WRTtNr7/6UJ/ykejL/jIn7ZNZ8rBD213Z5rqe9NXbXOh325a
21Tv9Rf/8SLd6J6+Wwiu/lia3rhNVzV2Udq45RcL/UW7sl2f7PiF2W2MrdMf
ftGOle3Xf+z4446+peOp+Xyuzcr1nSkAqTebymkg6H4L9NKldUVXrazTRm8t
4K/U/cb0gKa6PTi93dd9tastcYiQWPct7LivgcraKKF/8gIgXfun/GSyGn/e
dumS37VV09dHtTNdXxXVDpevGm0aWvqua/c7vW9K2wGkrmruYJnamvVCv7A7
25TwRLcNAG/xTNVdo9s1/kuZ3a6uCsLcbASX0wUsv7H1Tm+q0iICDNIJNi11
td117YPVO9ut225rmsIuGJfbqixrq9SvkGG7ttwXuDhilvEE3wGPtrVem6Kq
qx5OAju12+2+EUD0yvYHaxsPx0wfNrZLzqvovDNtTbHxSASydXbXWQf/sKVe
HemwiANE32FTwatVrzdtXTr6addVD4hFkC+1hb90lakXADP8mLAA7I2vtrvW
WfqsaQlEQJ8Z05FYo3JKaOXZgIAxQiP4bkxefzw6zehHFeEFOLWHUze2sM6Z
7oiHA8bVhl8aQrRgrO8B9By8Y74rK9dXDSyW8N3KpmhVdJKEv8Y8uNAkQMCe
qKtwV7cBfVbK6bd2C4LnNtVOIfsAV6FkNfagD+aogZF0wo+0P8glMNAe0EMr
ALKQKTPcp5ArI7P6/ZhlESxA8Hpt4XTM+R4rY54vSV6cqk13Z4GIQOtNe0DW
gXMRdHCaM2et/uGHFNi///0c0P0VYbHYOwDeFhvkaFh6A5i2zR0eFoD03GSA
65uis8CDrtjYrR3oFqMCw+Q0S5b3EDUjBQHGAdSj3radVYFKboHieWO7bdW0
dXt3BMkVy3ahL5tjoq5gjaLek/6Y8u0Yd3g6MF41qF15tICFv7DBbuLq6eKH
DSLCWcTCkMEB2UBMER1mOFjV3BFXz0fmGJb1KyIPsbAjjX9mZUYOrIvo0S18
kRyOxBGwz6shalHOSDsBPdeejcYSN9dXHk8T4JhIbV2bVduR3jtU/UY2nmj9
Ci0zP0X0j0m+iBul+poEFl6CxyPyIGx/slVnumJDfEm8gOABVm1narGgpCtS
uwJsxEgQ8ZV9ELqKQPcbwZ60t98ws11YYwsCb2rntVc46tDsRWRVDzaq1Cn/
ByWFqELDpoHKk82HAiGIn75HqLqmL8K6BAEhK/McUXY2XedcX5PWAGBG4Kam
Abko0lxfs7I6tQ09hwWvWfXyEfjlJW6Gq02/uvbGiRwZpIBe4iGX+1Xgggy+
iD3NeL0cFgGiiLrlHhTzz66bruHRI9yBhuvzF59fpDoKgYdPUcBLuwLkLfRX
9qcf/wEAuRYUfbVFPwI1bckm/Kcf/wk6vgPf2lr304//mqnVvkddUpAlh11N
4AE0BoVx1pG9d5t2Dxqi2LSspwnExu7BR6zJC13ol6A3mvYwA8MAMLg8fUGY
SNNeJnZCqXcjrSnSVx9Z9T/uB5I5TewoaolUWL0zMVVNYw/JuLGrSKYb/Beg
L1gmOKzrcUviT8BN6qZU4FKC+cbVR1Ayj3X2Dp52SnhNdGXqthELVHCo9tDw
/kpNfNWBd/qI0SZH1Tyg8QUb36HjxMYedVB7sA+2m5G81LUn8ymCwWvstZJr
4rbwiTLbdt+Q4wBOR7exEPAgGyJAExqhDSwguDCwXV1t0b8lXwZdBvXDD8kj
9hh+9Ss9ZghcO/Vs1Kv1Y/7jaaUIIBDrguyzyDIBFAIeTlIYQGpQRBEP4Kag
j+mNSrsHn7y628irh1YlIMILjV1XaGPU50w63A62LR+l29bcW1ZZG1y6m9dA
Kq+E9RnwdrTlU272quycyWQ7dN9dj4dCUjXioiI6keXUCHEou/AWyN1mLAuB
vGOTe0nQKghXQEDfQ3iOO21bEBSUwBZQIuQWN9IzcrP3cjCwgjPSVCBw4KYg
W6ZkZ3e4DjqRhQiUODvaSl327OMY9BxB+81yaJrSUxiRf5+H34EbveuZNcSm
65hDhNQcUYhnFg6OLDdkIz4vRilwlDH9gxmkz5KzgVT8CeJIiAGdWKiM4hTO
JPaFDcjvz8rkumu3ougjMlWG5Uiva/veIHlnoMW2EKSAOhq6LqLNwjZskg8V
HJDYaYVUcNWqth4d061Y/Yqa9PH7rkSzppagI+BpfSRlTgHWWMkejLcHwGUk
CBAN3nGIPNjNh8qdhZiAsUGAYgCTYRcJI3FVTCXA2oe2edrjkQyep28VxjcY
27FkjgFz7OdaD9EMTTxYC0tW2WLQL34wypHsQ7I8hoQiIWAF4INc9IFuOKyL
y1RjV/fMnSNzzFj0PTWRP9RQGEv7ULGi3+xB6DT5C6ANCGo+IL/ilRjB6thI
KTki8xcKpMM9yHxltDRoTZ96Wa33riD/nzGVGvMMV5KiIl95aw2GxYg+8V2n
jJU46U97BWcGn3jNogu4RyQx1n24FvgCNZmcCOQARYbSJJjMYN1tDwr1auJx
JmrM6iew7JMgHE0579s5cqcF7XbckTKAHSkPiTAVQS1hHoCsCupQ0prkHOT0
7w15t3Bc0pAgxOTpEVP5gH2keZ3kUfVdCyj04CWOBaEBmXGQGNMjMIH0yAcL
MsZ5c/Szemgm+bcanGhQprIkIeVnqUnkr30Syqwwc0bJH9sAkxdIJzhQhSzV
KmRZEMXe1CGyGGm2jEopyOddWbBtVr49qxZw4qoB9ALI56iOqtqGqOPe2l2Q
BtFeJ1nHJxynZ8zarQNB02HulgJv2J/Nwk0HIrAzHSmbaBskXEAN06IVozDQ
vkeN5vZbK0JzsOwmYsAAqC3AQanclkxZKX4nZQTIa8JHSHuUGGAMg1ko0rnI
pkFSlPqKkZImrtAySfQA76PzM7Z8KZ8UbQcr71rWKlmuAbYmPUzQ9y2EPmgY
9k6i3Uk2iA1D0FCzoNUzqpTTRiyGyBj+3PHUvJGSaB+ddnKSwGkh7YJJlazZ
JzXqueVyOfeyrpIv05zXI/yPDkSUSJuaGAqxPot+9SDpOYkU2q1Puxi9BrZM
fXSytujbUcqSKT1THPag+zJ19jnS2jpbP8CyIwch52AQD1+9x+woQEUOhs8v
g4iDdmmYOSVK4bQjaqaO7C/5hCC7fgExoGd2cbdIcILUEmR37Kih7TqXhK5Y
8kFamyDBFA7lfmJ4p86atvFlrPOQZUMRN0kwD9EBLPHXfdVRqqpJc2keHeio
Ko7ICQzwlbDeo1+0+A2oN5Z5DoJHS1AqaAuUItY2VSmoUx51osX3zuM0ZlWQ
Of+6t474cu2Vk/c0JejFvD4oLMdu2yFK1ziJpv8E3DCTUkDAjE/XH0SJ5vR/
Ngc/cdh8Hp20imKx7R4QE7T0CZolpw0nHAsj20qGEE/LETLn1SZIewrMXVC8
IBmADDOrkBh8PD4DLKPxcfuCk0kMNa4L4Z/e1aYgi5RNgwq8ovcw68hsQ3qV
LM60OJLNzGI0GVUbH0p5WPLqC8PzSwGLWYOtbiAyuZeZYIlEz+E6n9rjW1Pc
s5cIhoXRRVGCQfPlbJ91Fum8gQBSvhgKvWKGQJ34GFcMsTBDNtphiiy4WNV2
a8sKcKcCdohRsSqD5pDFgAwjr5icaaTOsPDl0CDaJsmwNW001CSmqErP/JHP
B8o00aAUsue8BQQs83mgildvCA0c3wTEKVEhXmFVzbreg3fqjWiMYkkLHvOJ
efLXTuu88dsDXSe4yWoWRk1g+8pt2Nvw0APL0IlSzeKjOzoUYBXFmlgnEHUk
xVwQcXnmcAqcpbaoKCIX/khictKUocSA68NriN+EN6Lz1ZLH7y6wtHR5AjdB
pZHrIZRh1RrqmwIxrHJDzw8nVmENMRX7zhLWkOdyKky8N4K96lwvcFNKaJTt
QOSm9I4CKXxFqdhjPpUlpqncE7f55Ns5kU78Kl6bioScUn+MlWIuOIsuXcJK
RY8pBPQYsLyqfE4rh0NYDT7rKvswXtBzOtkALK9C0DU0zqydair5ev4A2cW1
ylEIDjGejwalTCPBXB8AJyvhEwQEa+KlBhhRVkpLK5EDJpVuWAS8aE9DiQAl
tiLxCi492TzB9xgpKkXKHNRla1hppdr8hHolOq/3HRFQ8npev2Byuir2NWcN
i7btwB2X4l7BHqjvfBjnz1DnnHAnpcwYPwGjpdGuPM9aFo6DDB/PZ45zpRiv
E7Z7kAqWDUxN+tJgpqpzzfKb5DOei+UaIpZCZSxJtREJVhI50i4w8br+jFDU
1T1XN/1Cs6lD9Y6DL3irB4Yj2cd0+rht5uhrZjMN+ATBLZgOLhcaQ8Rja04K
k3POHDXOTbxaw+ZkAkPxfsnmmRwvznVfs90PyXwXSmWIPrKZ73QVClnXT52a
Vt/eLeBlLKCS0nsWSDd80yWlayq5oFwmFZn4XQQCMP0JCPt1rKgAt1B++8NM
FRCOCX9rku99URpxmdY09esvlzcg+27fSZvDdXAFABRAsEqA8LUcaUdh9Lx6
4cgfm1Dnindgkvt+kglXUBEUuwkchrVeJN8piALhVJvxB69e6LN9U0HcoM22
Rc7IpK9xzXM+h4rBMvqiO1N1i2CxCDTxK97NKICG9fE7/y45P7EJCkJkUj6u
Z7jRyppoZuAJ5VnhOFdUk6CQ7cGA94s6aISgp9RKgAxTNVSWwpV2xxA2UC0D
5KJuC+lUcz0phTUyGsdH1ASCyK3pDVTb5CV4rV3sO8zIYC1Feivg0y9F82HK
tCdxzLU4kU+hMEWMeTtexNcq0kyLpJZboOXA96+6cJx3T2WnhbrK4EDYOnQd
DHo53ukzkMvvsEEIcw0xm6Mos3Y8p7KXuedWDKQq6+yFfuujRq/EBVuoZeDw
7CvEphdF6Rau80hM5GvArIKwRWi/qsEBjHsxn4jpwTd8Dpp5AhRhyCFgBbsu
OMElmBv2VSVZ3ptWbDqZq8T5vp4guGKbF1CMjiXp7jvvW/LxZ/oK/YN9U4hl
5cfi85okjL9eUK9RYCGSX+KdK0QJqmx0Nipkz23s7PALosQI2iw6Az21CqDO
KMi8o6/xftd29J2ztuQ8vboWnpac08nmGzZQqPSoGhxrbR5gtMkDLGElO2KK
1EvAlhc+f4ggrlgxfXv1Rv/ly6vlzavP31zoVxR8I5Nif5itHjigQaWZqTYz
qhkC5TmQ9EWe4pLucHv0RULLVFK55IRcB+Egt8slpX5fjlhZKhrTQV4sh4VJ
DkR8Vlo2VsApFt1mDhivI7cPG7mw65m8/Zyef8fJEm8s0f458ivhBHtwbY87
RjyI2nykn9RA1DM+g/Q3oZMhHY9IdEK8FMYH3WGY+bjGBu6qv0XR/PTqNYoo
sU10EqV5EXvJQglk/Lr6zJr1m7ZMXgYnZXPrmUwSfl8Sn72FX/x7rAVSo6PQ
kDhqYeXGWOMwUdXqsmUlDCou2Nz0NMTs5+G11RG0SsPbiPYCXgL10lFAWZsV
+J9pMCFddrh2lDhKQ7FHSFks+ozJ/2L5weVSv7AgD/WkrJu4vtKGs7KhtmPu
mhYFnKKfnS0q4GEUfVzIFxhgaYTE8+UgM590g3D2F8OFivneE39rUSYhaOXA
mTph2vpCX+YSwP4jn3OYtuKGXshZbKUcRUXgZOxDoI6wJyzE0QeA8xd6iZLT
vSSiuN7BX7uj6+2W4ZEMag7evgV4QhQVC5jZdgfgpbPLGsO/u40+tN29AdHD
0hr54RAzTJv2/NrIAWF1KbA1oQCBEZu3GjFs0T7W6WzIxC7OiWMuy2wNWDpj
koxjWXLiPluMwPZv47uaQ44uyYWppCc8phMFfIHOccM6qpF8SkFSt7SeBMVb
eGvAJqP9RcUMFnuxnElGpdtyURqJ5z+UgumJpJNEwyeSLkm1J6aEhkf2pUxU
2g9U+1CD30PULqgep1ozhRxRaDOV6kd5pm1fIKV9EQ+jpVjpRjyTnzQAwUse
g1iybQDPp547C64D+dBIOcDfwXTlnOrAFhMhwNVLazVuBgRpObHM2uToQ/eo
VLj9G/seGBcDIE60CcFRlr7NMJ+yon6spJ81l0BfC8OqNIUX+6W5OlSgB9CP
M4MxcZDmP8X3min7vrA72oFKKcGh6RLuMu7YFJuuBf/C1UdW3EuR35xroai9
fFAFjQoA2wbZBMLK7AkO8OiJ6GsXSpgSWzd9R6PREo/Blx806Blx5ET1Mflc
Or1COwy6aBVEJg8t2nLsDcBIBw63RrFMaojAFy4BkXpM5R8+84kJdowuAUMg
xVtfM0D7gHXmSa0xkmLoMMH/FQX+Y44WUmLCiJuIYnKkHCeGYni9UMGkddY7
2SMUUc+s74zMUg8Luvfo1lD3GfvXK5/229XovMIhQbe9bjvbsgEF3z0o/YJV
Pr7dH6SSp/A0idJL8nU+URfo5PuW/7oHncjKyFcDISwoj4oknYjHrPjc36mY
rwwqq8yhEq/Lk1BIJ0lK19YPrEd9z2cMuNCbJCU/XVfFDtuktYX8OWR0z4wh
4JlC2rXApHCOL+WVREch17MTBQwq/z5LVT6HIWsuBzVUZLp8++ochNqEDv1R
LiQRJm4cQHYJnrR8MuooU6F/C5VMWI5zJR3IFQhqOJm/DxOP6uNZ7ivEyhep
cl+x11fkoIbvKT2227HR8U3BAvZ+iiRQ5OrTFy/xGlBdYWiYoHt0YA/a8Ov5
fbnG9lt9EwygSjp4RNVLYVEkyf8oNI9Nd34VbmWTTAn5vMkBWVlcXr7IdSB5
hnUtWzyUJ+wRciFfoRKQRI6E6Rb6ZUX57BkDRxk2OS0frfCpHpVhxQkMqxZj
jNj/lzSI4eueAbfYLwXySH56sbHlviYx9haRLqcGEIQWgIUG9QvlkEiOE0HW
kWdAXD0fNlkg+4jwJD0t0WAichAM0Y28AmIZb69z64EyWlfSkUJ9VXRRJ17b
onwkOjXKoqbYHTnpR7cCHvj6QDlotS6EK2I9TK6PUg4Z4aTkTdyBCed8BDbQ
SEmsnm5/twc3x6dFTK9Q8SYrRh8DIVwlCYxqzS1FCD/jLNEsW4/ZmRKmpWd2
1xabWSSvifmlhHBJRxJ/xeBKAwBn/3CheKUoFjwH+ucRTo1tl6CZfFoFdRPn
L/fw4Le/ycFWYBO/7WLrPkKyIE/Z/0SpTogH6+p7FvZnfNkV6ziiZ9h1sBP9
JYhc+P5Av+ShM1j2psiJV6RQiJ3alQOLx92uEL3tuEs0NmGg20no8M4d4Y5S
6cAr+1raR9bgqQLzAJb/B/4owUA8+Uf8nIRqIiKpLKVi5PTl1eWLxZt7dLso
Vylavy16zKiEmzaJmptjmm2h36A/RK4Actmu3fnrCUHWn4vTFCJixRk0uVJa
2vf+yKMbaKnLxp24PYdJkoBWGXr7+I2E3Hs3vbkLCXD+VLB7JleF4ZV912Am
hPmLAjTjNuEuqzh+1CSSlBVnKUIpixeS55MznoJMSfsDqBw7LrJ5R9DvgvJ2
Nu7P8gsntTKJpagDuD4GIrMX46X0ZmyYMMe2J7XvA6MikC41Y1XfNrf+p3Vl
axCEaJeGptBN3P0RBxH4Y15RUbW8XM7R+oe4fEpyLll4mfWCwSkt/YPSUiE2
9e/plt94rz+EEp0/00fwjcgV0u+W6IcPX18+H5DvFsj3kfq7zq6rUhCyb2jZ
1T/O7J/KNR7EUI0qEs1/8vt3f0BApjBEUnwsqFxcvd8BNs+GZJhNvp1pfPnN
5lwUCtrv1yKNLzuzRUFWQ7Nnm/2WU5WStiztmtoX4K1Dxa4KYI6U8kjpq2wG
O0dLQkH4mg4e0MWS6AkG+Pjk8vWSnn00IIfWb2UwwTtwvHDLB/n/x3pbuw+f
fUQvfQUwv2SQEfxbBp9/w6XfcgbJY0USSrcCvgcA3J/X/skUlZeD1vMxRkP+
t4s+6aA1lmY0cJnv5xHq8ak++EAv5U7IE4zk8aCaT+qe6FeXby7xtkoFu/NF
/QdT78HNRSx/+LsELUOsCm2Yq6syIc3v/osVLv470kTIlXJ2crTyFs8mi2Q4
P/zKWEaWtCXxbjOUvV9A6tOEnizNOrGhH1mqRZiD8GbguflkOUTVB7/Wy+qu
+arqN59hrvxsMdNPcp89mWVXO9e//iCiJVQGTuEDmewF4GsIxP/x1CdXJ/IR
XTwQlyk9n/slhAl/QVQfskltiSpqwB5cgvBZHLXFFAvlqnnuCOd2wzrRoGQE
l3GS0TaneHrK1T/PwuGNAPNtsTLbW9FZuTfp99HrIyVzK4RJKD88XKpzPDGv
klyJf8aJ6pgVq5zHu2+gn67tv/WXaqJrpAeUFy312IqelcALpVgKS1y4bBKO
U8IvuV6UpF9iG3SsvSWFqkE4rJ8nzDAOPdIA1rgwEgidcpXPK5y2UVll9QvF
Jyyy47sqXyOQ8Gu7vpUn3+TJHYXs31bMKdOd4GLc8fXlhGSwm7GmpHLnx9r/
9evn38hzJqL8Qv/A3yJfijkgJFwN8niPSQsyVLtCh51D2mGzYWJncF0VEtE5
j3S0svCOFNCFJ5B9OVdXqjTyXVvMyT114+JDSOyt9w03MWCtGnywK/9DWEVx
mZUMwAAZXCF/wgkIzAfv+qM3NAv9OfnolIRAf38WszWSf0iyXD6RJbEKj3bi
DE7I3jzmgp1AERB1cKqzk2cA+/ZEXMr7c/BLqx0Aj+e4lTD1Yx2fff1ssWDv
c/4hMFG6L/MY+7DRfJ4ADzaF95/MSKlO/0yAmPk4+Hywp+ffX74rffHv79uk
zvZLyestmZ8AH9jsidV6yiMUoQ87VVpxhFLFfUiVFNaI6T3XhkQn9QkbzZ19
uWRZ6Ju9b+Se3UZuzTfYxzC4jeL7co/bLRaGCw2RS7Gx3HOAsMhiviFKejC3
WFw480Ge69sONj5XSZeKcaedg5UlP/m+wowy2468UlecIX7+yfLmfKDYpWnN
SqfRQ1vxEC6H4avbYyPNZ+hXjFCt+FCcMwcowVvmSrFeQSyM9+dxPyz+cMUt
aUcA/D0I+BSqkP5KE4RVnGwQcO3CXB4jGQraAMhC9eLS7sCmstAAId7QFxK3
45l5N74gXCU5wL7jyA0Msycv9qRE5di1ba+k9ItwyL1ceEqR92RFVlKy7pMn
1CprmFtw+sHgfXnr2zffcqKMbxuuMR1b1eVo/QTcb9/87W/PvqWKH4FIJXf+
ZngufPHDb6UEITBIVyh6kDoqejlo+nMwDVOvQvJG0SREfFFPJXAoWrCsnQjK
MliGBfWbcAW/yRFOTUCmljfK0eMOI8XkCyt8czZYMGrPmXT3JCre9ZmjZjT8
8iZV5xtU5/gt8uMtwn/79ZMn38Tv8wtPP3rjvwlq82+Zv/3nfP6HiSbm8Inh
QgZKYAsr4H8EmGRTfPvszfkjW//shsR+mR11fkd6Pd1SErasl3X0elk386qc
idU1dienrmzOC/YFdfw+quqh5D33VE+8tayFS2GHd6KJ86cnAxs5gUD/fy3o
becw/XTjywyZShQN6gvXnkhozuIoO/L+syx4PihiDWtXvmilv2j7eE9sOCcg
reiHWQHDyQKXS9+7JvlXuapcdK1zc+mBmqwaZlRO+rulC214lQJUV4SRujyG
Q/AalesWwVQSGrtHZlDxur7LQPtBHn4IzcL39ckchuzUUUCBvznIjl6cCVq3
h+ygl/FFIgkAgW3xRrHc6I6TLHmuh1zW5dK4DPIwlDvLXvNIWmxtbpwmq/h4
H8OBjqbZIC06ZS6OEqMBZpehHxYg4xdRjj9pV9LaQFeFXB/GxvANtkMbp2p0
9g4WrrH5h0ZdpKNLPG6GK+MasPeVzC6kH5+6MOck2RiHN/hKLTf74yWgyYgk
4xQ2VeXni+rspFO+0uG3Dm0qKAxyU3AClqHSWmzrR0s14FdqraQrZWrXun6O
fZCg2ioXB3zwLUg6INexfI99enFiwPT+9iSVvLHyiDmzmssahb8mfKI/3DQp
vOJAq9gYhno3lqy4dNYgIfMtY2kFMQzQkO7yctrJGI8xvihNPhN7IOOd+zCy
C5nfY1qahUd1Nuaqs37TUfPnFOBzHmwYLnh7kg4bi/0UD2pn8MNPuZltYx8n
S7w+YnXaliTVtDLpTxqhMkQJPDlDURFu0Kg/+kCujCgUoDNshu/TSVGDEU46
aWk813Hkkx+nFLHan5h1EpjiSBV6hz0s8cKL70QFIMdFPb7s58eCc3xR+njI
906y8o1Db4ZvUWMC+/Ne4WKcYB+4Ecrouur72tL4k4Ve9oZbuWmOC97kXdLl
N1bhuelv/BuyMs+zHZqAOPoJ1QBe+hFsEVQn+heRZ3768Z94D9PZn378F8cc
9jAWKZk+gxFYsALZ5txLgYEONYtXuRq6ESoXQwtscaMpEIoolYj5tKt4Abgi
+HiMxdYe6IzI+BFG6cAZH+/QNj/9+I8+NOTS+NS3z5eIjlP3PSnXVpzigKU0
snKlXCZ2y1gqdPMt0DReUPF8wOFOOTDdSnpfD9IpJ3cfw4fYSpfmQ0VZsFQm
I7STDkXfpDUWQG703xp3jy3cH8g0Chr7g1ws4kTzzTm6GeGRIsoqKW9vKim4
i4/bh+tuyfxZNXZR0nsE4KOg9dPe+g0wkVS+hy0pghamUyIhE1qF6QgOMcMt
12ECqfS7hhsOk0nQiQtihlpGDuvvlfHgF7kELjeqUPunE/MJefECj0r2odu4
Ya4NTyhDNYHXMcYzDeOYdvywRa9u32HTLAbQcpPKhvFwGaBnEvBLouP05GO6
QXfEJgPMIgQochoJnGXCIjFF5bVTj+3hNFEWBHJXt0dUfuR+ax4uzhfOBDvX
fj4r211q88pNAgJC0MRCGUwXBkqOB9tJ2wKtk86+AAThKBRK/IwuYsxSE0Ti
1/bcrZY9tXRr81BMfYPzb2k6nfGzZnW3Ry9abtsy2dI74E5mRPxC8Nh1XdtD
NJve0EGwWfIAyY01AOt4Tibtzc2SeMt4NLxNrg5U3+Pd0cXdYiY+Q5jghHkp
GavWHhq6qI9vq3TgrHi4aCXQcAQA8dJBuN5K8zeRu1N8Ugvdeg3YGAw7BRBN
jVp0FJQkU4OMfvsXn/Xn1C6IZNXLOET25dP8ZcipIo29uVl3nNVFfX0GnFXJ
2DcZG/uS8L2qTXMP5P2E/s8TqY47uQPp71SKcfVeRqCsHxaDl1YQof7O0oDt
hqOhJm6nnzsSO9wpwSAGb3wzJE6DxBQvZyGajBdHQ5V5iAURWWZXKTouFn7j
HQaekUUb48RinhmXuS7EN6Wlc26m1jVmxcPU0olEl63lqVB+FgZ25SM7EySM
7bRJzfPcYJrb+EbVTLbHn+BjFpmWLEDtF8UU5srSxaHcONjBXDQyNFfBGKIM
AS+85PFc6ddU0RGfJz9+hjwgHlIAWtr5NtHsmF+Ob2TqLg/YJr22TlgyTAye
rBJGD4PcYe8dl+qCus9FR+JBYlynSA0t1P8CDfc2AqFnAAA=

-->

</rfc>
