<?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.6.33 (Ruby 3.1.4) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-mcmillion-key-transparency-01" category="info" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.17.1 -->
  <front>
    <title>Key Transparency</title>
    <seriesInfo name="Internet-Draft" value="draft-mcmillion-key-transparency-01"/>
    <author fullname="Brendan McMillion">
      <organization/>
      <address>
        <email>brendanmcmillion@gmail.com</email>
      </address>
    </author>
    <date year="2023" month="May" day="16"/>
    <area>SEC</area>
    <workgroup>KT Working Group</workgroup>
    <keyword>end-to-end encryption</keyword>
    <keyword>append-only log</keyword>
    <abstract>
      <?line 45?>

<t>While there are several established protocols for end-to-end encryption,
relatively little attention has been given to securely distributing the end-user
public keys for such encryption. As a result, these protocols are often still
vulnerable to eavesdropping by active attackers. Key Transparency is a protocol
for distributing sensitive cryptographic information, such as public keys, in a
way that reliably either prevents interference or detects that it occurred in a
timely manner. In addition to distributing public keys, it can also be applied
to ensure that a group of users agree on a shared value or to keep
tamper-evident logs of security-critical events.</t>
    </abstract>
    <note removeInRFC="true">
      <name>Discussion Venues</name>
      <t>Source for this draft and an issue tracker can be found at
    <eref target="https://github.com/Bren2010/draft-key-transparency"/>.</t>
    </note>
  </front>
  <middle>
    <?line 57?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>Before any information can be exchanged in an end-to-end encrypted system, two
things must happen. First, participants in the system must provide to the
service operator any public keys they wish to use to receive messages. Second,
the service operator must distribute these public keys to any participants that
wish to send messages to those users.</t>
      <t>Typically this is done by having users upload their public keys to a simple
directory where other users can download them as necessary. With this approach,
the service operator is trusted to not manipulate the directory by inserting
malicious public keys, which means that the underlying encryption protocol can
only protect users against passive eavesdropping on their messages.</t>
      <t>However most messaging systems are designed such that all messages exchanged
between users flow through the service operator's servers, so it's extremely
easy for an operator to launch an active attack. That is, the service operator
can insert public keys into the directory that they know the private key for,
attach those public keys to a user's account without the user's knowledge, and
then inject these keys into active conversations with that user to receive
plaintext data.</t>
      <t>Key Transparency (KT) solves this problem by requiring the service operator to
store user public keys in a cryptographically-protected append-only log. Any
malicious entries added to such a log will generally be visible to all
users, in which case a user can detect that they're being impersonated
by viewing the public keys attached to their account. However, if the service
operator attempts to conceal some entries of the log from some users but not
others, this creates a "forked view" which is permanent and easily detectable
with out-of-band communication.</t>
      <t>The critical improvement of KT over related protocols like Certificate
Transparency  <xref target="RFC6962"/> is that KT includes an efficient
protocol to search the log for entries related to a specific participant. This
means users don't need to download the entire log, which may be substantial, to
find all entries that are relevant to them. It also means that KT can better
preserve user privacy by only showing entries of the log to participants that
genuinely need to see them.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

</section>
    <section anchor="protocol-overview">
      <name>Protocol Overview</name>
      <t>From a networking perspective, KT follows a client-server architecture with a
central <em>Transparency Log</em>, acting as a server, which holds the authoritative
copy of all information and exposes endpoints that allow clients to query or
modify stored data. Clients coordinate with each other through the server by
uploading their own public keys and downloading the public keys of other
clients. Clients are expected to maintain relatively little state, limited only
to what is required to interact with the log and ensure that it is behaving
honestly.</t>
      <t>From an application perspective, KT works as a versioned key-value database.
Clients insert key-value pairs into the database where, for example, the key is
their username and the value is their public key. Clients can update a key by
inserting a new version with new data. They can also look up the most recent
version of a key or any past version. From this point forward, "key" will refer
to a lookup key in a key-value database and "public key" or "private key" will
be specified if otherwise.</t>
      <t>While this document uses the TLS presentation language <xref target="RFC8446"/> to describe
the structure of protocol messages, it does not require the use of a specific
transport protocol. This is intended to allow applications to layer KT on top of
whatever transport protocol their application already uses. In particular, this
allows applications to continue relying on their existing access control system.</t>
      <t>Applications may enforce arbitrary access control rules on top of KT such as
requiring a user to be logged in to make KT requests, only allowing a user to
lookup the keys of another user if they're "friends", or simply applying a rate
limit. Applications <bcp14>SHOULD</bcp14> prevent users from modifying keys that they don't
own. The exact mechanism for rejecting requests, and possibly explaining the
reason for rejection, is left to the application.</t>
      <t>Finally, this document does not assume that clients can reliably communicate
with each other out-of-band (that is, away from any interference by the
Transparency Log operator), or communicate with the Transparency Log
anonymously. However, <xref target="detecting-forks"/> gives guidance on how these channels
can be utilized effectively when or if they're available.</t>
      <section anchor="basic-operations">
        <name>Basic Operations</name>
        <t>The operations that can be executed by a client are as follows:</t>
        <ol spacing="normal" type="1"><li>
            <strong>Search:</strong> Performs a lookup on a specific key in the most recent version of
the log. Clients may request either a specific version of the key, or the
most recent version available. If the key-version pair exists, the server
returns the corresponding value and a proof of inclusion.</li>
          <li>
            <strong>Update:</strong> Adds a new key-value pair to the log, for which the server
returns a proof of inclusion. Note that this means that new values are added
to the log immediately in response to an Update operation, and are not queued
for later insertion with a batch of other values.</li>
          <li>
            <strong>Monitor:</strong> While Search and Update are run by the client as necessary,
monitoring is done in the background on a recurring basis. It both checks
that the log is continuing to behave honestly (all previously returned keys
remain in the tree) and that no changes have been made to keys owned by the
client without the client's knowledge.</li>
        </ol>
      </section>
      <section anchor="deployment-modes">
        <name>Deployment Modes</name>
        <t>In the interest of satisfying the widest range of use-cases possible, three
different modes for deploying a Transparency Log are described in this document.
Each mode has slightly different requirements and efficiency considerations for
both the service operator and the end-user.</t>
        <t><strong>Third-party Management</strong> and <strong>Third-party Auditing</strong> are two deployment modes
that require the service operator to delegate part of the operation of the
Transparency Log to a third party. Users are able to run more efficiently as
long as they can assume that the service operator and the third party won't
collude to trick them into accepting malicious results.</t>
        <t>With both third-party modes, all requests from end-users are initially routed to
the service operator and the service operator coordinates with the third party
themself. End-users never contact the third party directly, however they will
need a signature public key from the third party to verify its assertions.</t>
        <t>With Third-party Management, the third party performs the majority of the work
of actually storing and operating the log, and the service operator only needs
to sign new entries as they're added. With Third-party Auditing, the service
operator performs the majority of the work of storing and operating the log, and
obtains signatures from a lightweight third-party auditor at regular intervals
asserting that the service operator has been constructing the tree correctly.</t>
        <t><strong>Contact Monitoring</strong>, on the other hand, supports a single-party deployment
with no third party. The tradeoff is that executing the background monitoring protocol
requires an amount of work that's proportional to the number of keys a user
has looked up in the past. As such, it's less suited to use-cases where users
look up a large number of ephemeral keys, but would work ideally in a use-case
where users look up a small number of keys repeatedly (for example, the keys of
regular contacts).</t>
        <t>The deployment mode of a Transparency Log is chosen when the log is first
created and isn't able to be changed over the log's lifetime. This makes it
important for operators to carefully consider the best long-term approach based
on the specifics of their application, although migrating from a log operating
in one deployment mode to another is possible if it becomes necessary
(see <xref target="combining-multiple-logs"/>).</t>
      </section>
      <section anchor="security-guarantees">
        <name>Security Guarantees</name>
        <t>A client that executes a Search or Update operation correctly (and does any
required monitoring afterwards) receives a guarantee that the Transparency Log
operator also executed the operation correctly and in a way that's globally
consistent with what it has shown all other clients. That is, when a client
searches for a key, they're guaranteed that the result they receive represents
the same result that any other client searching for the same key would've seen.
When a client updates a key, they're guaranteed that other clients will see the
update the next time they search for the key.</t>
        <t>If the Transparency Log operator does not execute an operation correctly, then
either:</t>
        <ol spacing="normal" type="1"><li>The client will detect the error immediately and reject the result of an operation, or</li>
          <li>The client will permanently enter an invalid state.</li>
        </ol>
        <t>Depending on the exact reason that the client enters an invalid state, it will
either be detected by background monitoring or the next time that out-of-band
communication is available. Importantly, this means that clients must stay
online for some fixed amount of time after entering an invalid state for it to
be successfully detected.</t>
        <t>The exact caveats of the above guarantee depend naturally on the security of
underlying cryptographic primitives, but also the deployment mode that the
Transparency Log relies on:</t>
        <ul spacing="normal">
          <li>Third-Party Management and Third-Party Auditing require an assumption that the
service operator and the third-party manager/auditor do not collude
to trick clients into accepting malicious results.</li>
          <li>Contact Monitoring requires an assumption that the client that owns a key and
all clients that look up the key do the necessary monitoring afterwards.</li>
        </ul>
      </section>
    </section>
    <section anchor="tree-construction">
      <name>Tree Construction</name>
      <t>KT relies on two combined hash tree structures: log trees and prefix trees. This
section describes the operation of both at a high level and the way that they're
combined. More precise algorithms for computing the intermediate and root values
of the trees are given in <xref target="cryptographic-computations"/>.</t>
      <t>Both types of trees consist of <em>nodes</em> which have a byte string as their <em>value</em>.
A node is either a <em>leaf</em> if it has no children, or a <em>parent</em> if it has either
a <em>left child</em> or a <em>right child</em>. A node is the <em>root</em> of a tree if it has no
parents, and an <em>intermediate</em> if it has both children and parents. Nodes are
<em>siblings</em> if they share the same parent.</t>
      <t>The <em>descendants</em> of a node are that node, its children, and the descendants of
its children. A <em>subtree</em> of a tree is the tree given by the descendants of a
node, called the <em>head</em> of the subtree.</t>
      <t>The <em>direct path</em> of a root node is the empty list, and of any other node is the
concatenation of that node's parent along with the parent's direct path. The
<em>copath</em> of a node is the node's sibling concatenated with the list of siblings
of all the nodes in its direct path, excluding the root.</t>
      <section anchor="log-tree">
        <name>Log Tree</name>
        <t>Log trees are used for storing information in the chronological order that it
was added and are constructed as <em>left-balanced</em> binary trees.</t>
        <t>A binary tree is <em>balanced</em> if its size is a power of two and for any parent
node in the tree, its left and right subtrees have the same size. A binary tree
is <em>left-balanced</em> if for every parent, either the parent is balanced, or the
left subtree of that parent is the largest balanced subtree that could be
constructed from the leaves present in the parent's own subtree. Given a list of
<tt>n</tt> items, there is a unique left-balanced binary tree structure with these
elements as leaves. Note also that every parent always has both a left and right
child.</t>
        <t>Log trees initially consist of a single leaf node. New leaves are added to the
right-most edge of the tree along with a single parent node, to construct the
left-balanced binary tree with <tt>n+1</tt> leaves.</t>
        <t>While leaves contain arbitrary data, the value of a parent node is always the
hash of the combined values of its left and right children.</t>
        <t>Log trees are special in that they can provide both <em>inclusion proofs</em>, which
demonstrate that a leaf is included in a log, and <em>consistency proofs</em>, which
demonstrate that a new version of a log is an extension of a past version of the
log.</t>
        <t>An inclusion proof is given by providing the copath values of a leaf. The proof
is verified by hashing together the leaf with the copath values and checking
that the result equals the root value of the log. Consistency proofs are a more
general version of the same idea. With a consistency proof, the prover provides
the minimum set of intermediate node values from the current tree that allows
the verifier to compute both the old root value and the current root value. An
algorithm for this is given in section 2.1.2 of <xref target="RFC6962"/>.</t>
      </section>
      <section anchor="prefix-tree">
        <name>Prefix Tree</name>
        <t>Prefix trees are used for storing key-value pairs while preserving the ability
to efficiently look up a value by its corresponding key.</t>
        <t>Each leaf node in a prefix tree represents a specific key-value pair, while each
parent node represents some prefix which all keys in the subtree headed by that
node have in common. The subtree headed by a parent's left child contains all
keys that share its prefix followed by an additional 0 bit, while the subtree
headed by a parent's right child contains all keys that share its prefix
followed by an additional 1 bit.</t>
        <t>The root node, in particular, represents the empty string as a prefix. The
root's left child contains all keys that begin with a 0 bit, while the right
child contains all keys that begin with a 1 bit.</t>
        <t>Every key stored in the tree is required to have the same length in bits, which
allows every leaf node to exist at the same level of the tree (that is, every
leaf has a direct path that's the same length). This effectively prevents users
from being able to infer the total number of key-value pairs stored in the tree.</t>
        <t>A prefix tree can be searched by starting at the root node, and moving to the
left child if the first bit of a search key is 0, or the right child if the
first bit is 1. This is then repeated for the second bit, third bit, and so on
until the search either terminates at the leaf node for the desired key, or a
parent node that lacks the desired child.</t>
        <t>New key-value pairs are added to the tree by searching it according to this
process. If the search terminates at a parent without a left or right child, the
parent's missing child is replaced with a series of intermediate nodes for each
remaining bit of the search key, followed by a new leaf. If the search
terminates at the leaf corresponding to the search key (indicating that this
search key already has a value in the tree), the old leaf value is simply
replaced with a new one.</t>
        <t>The value of a leaf node is the encoded key-value pair, while the value of a
parent node is the hash of the combined values of its left and right children
(or a stand-in value when one of the children doesn't exist).</t>
      </section>
      <section anchor="combined-tree">
        <name>Combined Tree</name>
        <t>Log trees are desirable because they can provide efficient consistency proofs to
assure verifiers that nothing has been removed from a log that was present in a
previous version. However, log trees can't be efficiently searched without
downloading the entire log. Prefix trees are efficient to search and can provide
inclusion proofs to convince verifiers that the returned search results are
correct. However, it's not possible to efficiently prove that a new version of a
prefix tree contains the same data as a previous version with only new keys
added.</t>
        <t>In the combined tree structure, which is based on <xref target="Merkle2"/>, a log tree
maintains a record of updates to key-value pairs while a prefix tree maintains a
map from each key to a pair of integers: a counter with the number of times the
key has been updated, and the position in the log of the first instance of the
key. Importantly, the root value of the prefix tree after adding the new key or
updating the counter/position pair of an existing key, is stored in the log tree
alongside the record of the update. With some caveats, this combined structure
supports both efficient consistency proofs and can efficiently authenticate
searches.</t>
        <t>To search the combined structure, the server first provides the user with the
position of the first instance of the key in the log. The user then follows a
binary search for the log entry where looking up the search key in the prefix
tree at that entry yields the desired version counter. As such, the entry that a
user arrives at through binary search contains the update with the key-value
pair that the user is looking for, even though the log itself is not sorted.</t>
        <t>Providing the position of the first instance of the key in the log is necessary
because the prefix tree structure used isn't able to provide proofs of
non-inclusion (which would leak information about the number of keys stored in
the prefix tree). Without proofs of non-inclusion, users aren't able to lookup
the same key in any version of the prefix tree -- only versions of the prefix
tree that were created after the key was initially added to the log. Because the
server provides this position, users are able to restrict their binary search to
only touching log entries where the search key can be successfully looked up in
the prefix tree.</t>
        <t>Following a binary search also ensures that all users will check the same or
similar entries when searching for the same key, which is necessary for the
efficient auditing of a Transparency Log. To maximize this effect, users rely on
an implicit binary tree structure constructed over the leaves of the log tree
(distinct from the structure of the log tree itself).</t>
        <section anchor="implicit-binary-search-tree">
          <name>Implicit Binary Search Tree</name>
          <t>Intuitively, the leaves of the log tree can be considered a flat array
representation of a left-balanced binary tree. In this representation, "leaf"
nodes are stored in even-numbered indices, while "intermediate" nodes are stored
in odd-numbered indices:</t>
          <figure>
            <name>A binary tree constructed from 14 entries in a log</name>
            <artset>
              <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="256" width="392" viewBox="0 0 392 256" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px">
                  <path d="M 144,112 L 144,128" fill="none" stroke="black"/>
                  <path d="M 240,48 L 240,64" fill="none" stroke="black"/>
                  <path d="M 336,112 L 336,128" fill="none" stroke="black"/>
                  <path d="M 160,64 L 320,64" fill="none" stroke="black"/>
                  <path d="M 112,128 L 176,128" fill="none" stroke="black"/>
                  <path d="M 304,128 L 368,128" fill="none" stroke="black"/>
                  <path d="M 104,176 L 112,192" fill="none" stroke="black"/>
                  <path d="M 176,128 L 184,144" fill="none" stroke="black"/>
                  <path d="M 200,176 L 208,192" fill="none" stroke="black"/>
                  <path d="M 296,176 L 304,192" fill="none" stroke="black"/>
                  <path d="M 320,64 L 328,80" fill="none" stroke="black"/>
                  <path d="M 368,128 L 376,144" fill="none" stroke="black"/>
                  <path d="M 80,192 L 88,176" fill="none" stroke="black"/>
                  <path d="M 104,144 L 112,128" fill="none" stroke="black"/>
                  <path d="M 152,80 L 160,64" fill="none" stroke="black"/>
                  <path d="M 176,192 L 184,176" fill="none" stroke="black"/>
                  <path d="M 272,192 L 280,176" fill="none" stroke="black"/>
                  <path d="M 296,144 L 304,128" fill="none" stroke="black"/>
                  <path d="M 368,192 L 376,176" fill="none" stroke="black"/>
                  <g class="text">
                    <text x="240" y="36">X</text>
                    <text x="144" y="100">X</text>
                    <text x="336" y="100">X</text>
                    <text x="96" y="164">X</text>
                    <text x="192" y="164">X</text>
                    <text x="288" y="164">X</text>
                    <text x="384" y="164">X</text>
                    <text x="72" y="212">X</text>
                    <text x="120" y="212">X</text>
                    <text x="168" y="212">X</text>
                    <text x="216" y="212">X</text>
                    <text x="264" y="212">X</text>
                    <text x="312" y="212">X</text>
                    <text x="360" y="212">X</text>
                    <text x="28" y="244">Index:</text>
                    <text x="72" y="244">0</text>
                    <text x="96" y="244">1</text>
                    <text x="120" y="244">2</text>
                    <text x="144" y="244">3</text>
                    <text x="168" y="244">4</text>
                    <text x="192" y="244">5</text>
                    <text x="216" y="244">6</text>
                    <text x="240" y="244">7</text>
                    <text x="264" y="244">8</text>
                    <text x="288" y="244">9</text>
                    <text x="308" y="244">10</text>
                    <text x="332" y="244">11</text>
                    <text x="356" y="244">12</text>
                    <text x="380" y="244">13</text>
                  </g>
                </svg>
              </artwork>
              <artwork type="ascii-art"><![CDATA[
                             X
                             |
                   .---------+---------.
                  /                     \
                 X                       X
                 |                       |
             .---+---.               .---+---.
            /         \             /         \
           X           X           X           X
          / \         / \         / \         /
         /   \       /   \       /   \       /
        X     X     X     X     X     X     X

Index:  0  1  2  3  4  5  6  7  8  9 10 11 12 13
]]></artwork>
            </artset>
          </figure>
          <t>Following the structure of this binary tree when executing searches makes
auditing the Transparency Log much more efficient because users can easily
reason about which nodes will be accessed when conducting a search. As such,
only nodes along a specific search path need to be checked for correctness.</t>
          <t>The following Python code demonstrates the computations used for following this
tree structure:</t>
          <sourcecode type="python"><![CDATA[
# The exponent of the largest power of 2 less than x. Equivalent to:
#   int(math.floor(math.log(x, 2)))
def log2(x):
    if x == 0:
        return 0
    k = 0
    while (x >> k) > 0:
        k += 1
    return k-1

# The level of a node in the tree. Leaves are level 0, their parents
# are level 1, etc. If a node's children are at different levels,
# then its level is the max level of its children plus one.
def level(x):
    if x & 0x01 == 0:
        return 0
    k = 0
    while ((x >> k) & 0x01) == 1:
        k += 1
    return k

def left_step(x):
    k = level(x)
    if k == 0:
        raise Exception('leaf node has no children')
    return x ^ (0x01 << (k - 1))

def right_step(x):
    k = level(x)
    if k == 0:
        raise Exception('leaf node has no children')
    return x ^ (0x03 << (k - 1))

def move_within(x, start, n):
    while x < start or x >= n:
        if x < start: x = right_step(x)
        else: x = left_step(x)
    return x

# The root index of a search, if the first instance of a key is at
# `start` and the log has `n` entries.
def root(start, n):
    return move_within((1 << log2(n)) - 1, start, n)

# The left child of an intermediate node.
def left(x, start, n):
    return move_within(left_step(x), start, n)

# The right child of an intermediate node.
def right(x, start, n):
    return move_within(right_step(x), start, n)
]]></sourcecode>
          <t>The <tt>root</tt> function returns the index in the log at which a search should
start. The <tt>left</tt> and <tt>right</tt> functions determine the subsequent index to be
accessed, depending on whether the search moves left or right.</t>
          <t>For example, in a search where the first instance of the key is at index 10 and
the log has 60 entries, instead of starting the search at the typical "middle"
entry of <tt>10+60/2 = 35</tt>, users would start at entry <tt>root(10, 60) = 31</tt>. If the
next step in the search is to move right, the next index to access would be
<tt>right(31, 10, 60) = 47</tt>. As more entries are added to the log, users will
consistently revisit entries 31 and 47, while they may never revisit entry 35
after even a single new entry is added to the log.</t>
          <t>Additionally, while users searching for a specific version of a key can jump
right into a binary search for the entry with that counter, other users may
instead wish to search for the "most recent" version of a key. That is, the key
with the highest counter possible. Users looking up the most recent version of a
key start by fetching the <strong>frontier</strong>, which they use to determine
what the highest counter for a key is.</t>
          <t>The frontier consists of the root node of a search, followed by the entries
produced by repeatedly calling <tt>right</tt> until reaching the last entry of the log.
Using the same example of a search where the first instance of a key is at index
10 and the log has 60 entries, the frontier would be entries: 31, 47, 55, 59.</t>
          <t>If we can assume that the log operator is behaving honestly, then checking only
the last entry of the log would be sufficient to find the most recent version of
any key. However, we can't assume this. Checking each entry along the frontier
is functionally the same as checking only the last entry, but also allows the
user to verify that the entire search path leading to the last entry is
constructed correctly.</t>
        </section>
        <section anchor="monitoring">
          <name>Monitoring</name>
          <t>As new entries are added to the log tree, the search path that's traversed to
find a specific version of a key may change. New intermediate nodes may become
established in between the search root and the leaf, or a new search root may be created. The
goal of monitoring a key is to efficiently ensure that, when these new parent
nodes are created, they're created correctly so that searches for the same
versions continue converging to the same entries in the log.</t>
          <t>To monitor a given search key, users maintain a small amount of state: a map
from a version counter, to an entry in the log where looking up the search key
in the prefix tree at that entry yields the given version. Users initially
populate this map by setting a version of the search key that they've looked up,
to map to the entry in the log where that version of the key is stored. A map
may track several different versions of a search key simultaneously, if a user
has been shown different versions of the same search key.</t>
          <t>To update this map, users receive the most recent tree head from the server and
follow these steps, for each entry in the map:</t>
          <ol spacing="normal" type="1"><li>Compute the entry's direct path based on the current tree size.</li>
            <li>If there are no entries in the direct path that are to the right of the
current node, then skip updating this entry (there's no new information to
update it with).</li>
            <li>
              <t>For each entry in the direct path that's to the right of the current node,
from low to high:
              </t>
              <ol spacing="normal" type="1"><li>Obtain a proof from the server that the prefix tree at that entry maps the
search key to a version counter that's greater than or equal to the
current version.</li>
                <li>If the above check was successful, remove the current version-node pair
from the map and replace it with a version-node pair corresponding to the
entry in the log that was just checked.</li>
              </ol>
            </li>
          </ol>
          <t>This algorithm progressively moves up the tree as new intermediate/root nodes
are established and verifies that they're constructed correctly. Note that users
can often execute this process with the output of Search or Update operations
for a key, without waiting to make explicit Monitor queries.</t>
          <t>It is also worth noting that the work required to monitor several versions of
the same key scales sublinearly, due to the fact that the direct paths of the
different versions will often intersect. Intersections reduce the total number
of entries in the map and therefore the amount of work that will be needed to
monitor the key from then on.</t>
          <t>Once a user has finished updating their monitoring map with the algorithm above,
all nodes in the map should lie on the frontier of the log. For all the
remaining nodes of the frontier, users request proofs from the server that the
prefix trees at those entries are also constructed correctly. That is, that they
map the search key to a version counter that's greater than or equal to what
would be expected. Rather than checking the version counter, the primary purpose
of these checks is to demonstrate that the <tt>position</tt> field in each prefix tree
has been set correctly.</t>
        </section>
      </section>
    </section>
    <section anchor="preserving-privacy">
      <name>Preserving Privacy</name>
      <t>In addition to being more convenient for many use-cases than similar
transparency protocols, KT is also better at preserving the privacy of a
Transparency Log's contents. This is important because in many practical
applications of KT, service operators expect to be able to control when
sensitive information is revealed. In particular, an operator can often only
reveal that a user is a member of their service to that user's friends or
contacts. Operators may also wish to conceal when individual users perform a
given task like rotate their public key or add a new device to their account, or
even conceal the exact number of users their application has overall.</t>
      <t>Applications are primarily able to manage the privacy of their data in KT by
enforcing access control policies on the basic operations performed by clients,
as discussed in <xref target="protocol-overview"/>. However, the proofs
given by a Transparency Log can indirectly leak information about
other entries and lookup keys.</t>
      <t>When users search for a key with the binary search algorithm described in
<xref target="combined-tree"/>, they necessarily see the values of several leaves while
conducting their search that they may not be authorized to view the contents of.
However, log entries generally don't need to be inspected except as specifically
allowed by the service.</t>
      <t>The privacy of log entries is maintained by storing only a cryptographic
commitment to the serialized, updated key-value pair in the leaf of the log tree
instead of the update itself. At the end of a successful search, the service
operator provides the committed update along with the commitment opening, which
allows the user to verify that the commitment in the log tree really does
correspond to the provided update. By logging commitments instead of plaintext
updates, users learn no information about an entry's contents unless the service
operator explicitly provides the commitment opening.</t>
      <t>Beyond the log tree, the second potential source of privacy leaks is the prefix
tree. When receiving proofs of inclusion from the prefix tree,
users also receive indirect information about what other valid lookup keys
exist. To prevent this, all lookup keys are processed through a Verifiable
Random Function, or VRF <xref target="I-D.irtf-cfrg-vrf"/>.</t>
      <t>A VRF deterministically maps each key to a fixed-length pseudorandom value. The
VRF can only be executed by the service operator, who holds a private key.
But critically, VRFs can still provide a proof that an input-output pair is valid,
which users verify with a public key. When a user requests to search for or
update a key, the service operator first executes its VRF on the input key to
obtain the output key that will actually be looked up or stored in the prefix
tree. The service operator then provides the output key, along with a proof that
the output key is correct, in its response to the user.</t>
      <t>The pseudorandom output of VRFs means that even if a user indirectly observes
that a search key exists in the prefix tree, they can't immediately learn which
user the search key identifies. The inability of users to execute the VRF
themselves also prevents offline "password cracking" approaches, where an
attacker tries all possibilities in a low entropy space (like the set of phone
numbers) to find the input that produces a given search key.</t>
    </section>
    <section anchor="ciphersuites">
      <name>Ciphersuites</name>
      <t>Each Transparency Log uses a single fixed ciphersuite, chosen when the log is
initially created, that specifies the following primitives to be used for
cryptographic computations:</t>
      <ul spacing="normal">
        <li>A hash algorithm</li>
        <li>A signature algorithm</li>
        <li>A Verifiable Random Function (VRF) algorithm</li>
      </ul>
      <t>The hash algorithm is used for computing the intermediate and root values of
hash trees. The signature algorithm is used for signatures from both the service
operator and the third party, if one is present. The VRF is used for preserving
the privacy of lookup keys. One of the VRF algorithms from <xref target="I-D.irtf-cfrg-vrf"/> must be used.</t>
      <t>Ciphersuites are represented with the CipherSuite type. The ciphersuites are
defined in <xref target="kt-ciphersuites"/>.</t>
    </section>
    <section anchor="cryptographic-computations">
      <name>Cryptographic Computations</name>
      <section anchor="commitment">
        <name>Commitment</name>
        <t>As discussed in <xref target="preserving-privacy"/>, commitments are stored in the leaves of
the log tree and correspond to updated key-value pairs. Commitments are computed
with HMAC <xref target="RFC2104"/>, using the hash function specified by the ciphersuite. To
produce a new commitment, the application generates a random 16 byte value
called <tt>opening</tt> and computes:</t>
        <sourcecode type="pseudocode"><![CDATA[
commitment = HMAC(fixedKey, CommitmentValue)
]]></sourcecode>
        <t>where <tt>fixedKey</tt> is the 16 byte hex-decoded value:</t>
        <artwork><![CDATA[
d821f8790d97709796b4d7903357c3f5
]]></artwork>
        <t>and CommitmentValue is specified as:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  opaque opening<16>;
  opaque search_key<0..2^8-1>;
  UpdateValue update;
} CommitmentValue;
]]></sourcecode>
        <t>This fixed key allows the HMAC function, and thereby the commitment scheme, to
be modeled as a random oracle. The <tt>search_key</tt> field of CommitmentValue
contains the search key being updated (the search key provided by the user, not
the VRF output) and the <tt>update</tt> field contains the value of the update.</t>
        <t>The output value <tt>commitment</tt> may be published, while <tt>opening</tt> should be kept
private until the commitment is meant to be revealed.</t>
      </section>
      <section anchor="prefix-tree-1">
        <name>Prefix Tree</name>
        <t>The leaf nodes of a prefix tree are serialized as:</t>
        <sourcecode type="tls"><![CDATA[
struct {
    opaque key<VRF.Nh>;
    uint32 counter;
    uint64 position;
} PrefixLeaf;
]]></sourcecode>
        <t>where <tt>key</tt> is the VRF-output search key, <tt>counter</tt> is the counter of times that the
key has been updated (starting at 0 for a key that was just created), <tt>position</tt>
is the position in the log of the first occurrence of this key, and <tt>VRF.Nh</tt> is
the output size of the ciphersuite VRF in bytes.</t>
        <t>The parent nodes of a prefix tree are serialized as:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  opaque value<Hash.Nh>;
} PrefixParent;
]]></sourcecode>
        <t>where <tt>Hash.Nh</tt> is the output length of the ciphersuite hash function. The value
of a parent node is computed by hashing together the values of its left and
right children:</t>
        <sourcecode type="pseudocode"><![CDATA[
parent.value = Hash(0x01 ||
                   nodeValue(parent.leftChild) ||
                   nodeValue(parent.rightChild))

nodeValue(node):
  if node.type == emptyNode:
    return standIn(seed, counter)
  else if node.type == leafNode:
    return Hash(0x00 || node.key || node.counter || node.position)
  else if node.type == parentNode:
    return node.value
]]></sourcecode>
        <t>where <tt>Hash</tt> denotes the ciphersuite hash function. Whenever a parent's left or
right child is missing, a stand-in value is computed from a random seed. The
stand-in value is computed as:</t>
        <sourcecode type="pseudocode"><![CDATA[
standIn(seed, counter):
  return Hash(0x02 || seed || counter)
]]></sourcecode>
        <t>The seed value is a randomly sampled byte string of 16 bytes and the
counter is an 8-bit integer. The counter starts at zero and increases by one for
each subsequent stand-in value that's needed, counting from the root
down.</t>
      </section>
      <section anchor="crypto-log-tree">
        <name>Log Tree</name>
        <t>The leaf and parent nodes of a log tree are serialized as:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  opaque commitment<Hash.Nh>;
  opaque prefix_tree<Hash.Nh>;
} LogLeaf;

struct {
  opaque value<Hash.Nh>;
} LogParent;
]]></sourcecode>
        <t>The value of a parent node is computed by hashing together the values of its
left and right children:</t>
        <sourcecode type="pseudocode"><![CDATA[
parent.value = Hash(hashContent(parent.leftChild) ||
                    hashContent(parent.rightChild))

hashContent(node):
  if node.type == leafNode:
    return 0x00 || nodeValue(node)
  else if node.type == parentNode:
    return 0x01 || nodeValue(node)

nodeValue(node):
  if node.type == leafNode:
    return Hash(node.commitment || node.prefix_tree)
  else if node.type == parentNode:
    return node.value
]]></sourcecode>
      </section>
      <section anchor="tree-head-signature">
        <name>Tree Head Signature</name>
        <t>The head of a Transparency Log, which represents the log's most recent state, is
represented as:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  uint64 tree_size;
  uint64 timestamp;
  opaque signature<0..2^16-1>;
} TreeHead;
]]></sourcecode>
        <t>where <tt>tree_size</tt> counts the number of entries in the log tree and <tt>timestamp</tt>
is the time that the structure was generated in milliseconds since the Unix
epoch. If the Transparency Log is deployed with Third-party Management then the
public key used to verify the signature belongs to the third-party manager;
otherwise the public key used belongs to the service operator.</t>
        <t>The signature itself is computed over a <tt>TreeHeadTBS</tt> structure, which
incorporates the log's current state as well as long-term log configuration:</t>
        <sourcecode type="tls"><![CDATA[
enum {
  reserved(0),
  contactMonitoring(1),
  thirdPartyManagement(2),
  thirdPartyAuditing(3),
  (255)
} DeploymentMode;

struct {
  CipherSuite ciphersuite;
  DeploymentMode mode;
  opaque signature_public_key<0..2^16-1>;
  opaque vrf_public_key<0..2^16-1>;

  select (Configuration.mode) {
    case contactMonitoring:
    case thirdPartyManagement:
      opaque leaf_public_key<0..2^16-1>;
    case thirdPartyAuditing:
      opaque auditor_public_key<0..2^16-1>;
  };
} Configuration;

struct {
  Configuration config;
  uint64 tree_size;
  uint64 timestamp;
  opaque root_value<Hash.Nh>;
} TreeHeadTBS;
]]></sourcecode>
      </section>
    </section>
    <section anchor="tree-proofs">
      <name>Tree Proofs</name>
      <section anchor="log-tree-1">
        <name>Log Tree</name>
        <t>An inclusion proof for a single leaf in a log tree is given by providing the
copath values of a leaf. Similarly, a bulk inclusion proof for any number of
leaves is given by providing the fewest node values that can be hashed together
with the specified leaves to produce the root value. Such a proof is encoded as:</t>
        <sourcecode type="tls"><![CDATA[
opaque NodeValue<Hash.Nh>;

struct {
  NodeValue elements<0..2^16-1>;
} InclusionProof;
]]></sourcecode>
        <t>Each <tt>NodeValue</tt> is a uniform size, computed by passing the relevant <tt>LogLeaf</tt>
or <tt>LogParent</tt> structures through the <tt>nodeValue</tt> function in
<xref target="crypto-log-tree"/>. Finally, the contents of the <tt>elements</tt> array is kept in
left-to-right order: if a node is present in the root's left subtree, its value
must be listed before any values provided from nodes that are in the root's
right subtree, and so on recursively.</t>
        <t>Consistency proofs are encoded similarly:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  NodeValue elements<0..2^8-1>;
} ConsistencyProof;
]]></sourcecode>
        <t>Again, each <tt>NodeValue</tt> is computed by passing the relevant <tt>LogLeaf</tt> or
<tt>LogParent</tt> structure through the <tt>nodeValue</tt> function. The nodes chosen
correspond to those output by the algorithm in Section 2.1.2 of <xref target="RFC6962"/>.</t>
      </section>
      <section anchor="prefix-tree-2">
        <name>Prefix Tree</name>
        <t>A proof from a prefix tree authenticates that a search was done correctly for a
given search key. Such a proof is encoded as:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  NodeValue elements<8*VRF.Nh>;
  uint32 counter;
} PrefixProof;
]]></sourcecode>
        <t>The <tt>elements</tt> array consists of the copath of the leaf node, in bottom-to-top
order. That is, the leaf's sibling would be first, followed by the leaf's
parent's sibling, and so on. In the event that a node is not present, then the
random value generated when computing the parent's value is provided instead.</t>
        <t>The proof is verified by hashing together the provided elements, in the
left/right arrangement dictated by the search key, and checking that the result
equals the root value of the prefix tree.</t>
        <t>The <tt>position</tt> field of the <tt>PrefixLeaf</tt> structure isn't provided in
<tt>PrefixProof</tt> to save space, as this value is expected to be the same across
several proofs.</t>
      </section>
      <section anchor="proof-combined-tree">
        <name>Combined Tree</name>
        <t>A proof from a combined log and prefix tree follows the execution of a binary
search through the leaves of the log tree, as described in <xref target="combined-tree"/>. It
is serialized as follows:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  PrefixProof prefix_proof;
  opaque commitment<Hash.Nh>;
} SearchStep;

struct {
  uint64 position;
  SearchStep steps<0..2^8-1>;
  InclusionProof inclusion;
} SearchProof;
]]></sourcecode>
        <t>Each <tt>SearchStep</tt> structure in <tt>steps</tt> is one leaf that was inspected as part of
the binary search. The steps of the binary search are determined by starting
with the "middle" leaf (according to the <tt>root</tt> function in
<xref target="implicit-binary-search-tree"/>), which represents the first node touched by the
search. From there, the user moves incrementally left or right, based on the
version counter found in each previous step.</t>
        <t>The <tt>prefix_proof</tt> field of a <tt>SearchStep</tt> is the output of searching the prefix
tree whose root is at that leaf for the search key, while the <tt>commitment</tt> field
is the commitment to the update at that leaf. The <tt>inclusion</tt> field of
<tt>SearchProof</tt> contains a batch inclusion proof for all of the leaves accessed by
the binary search, relating them to the root of the log tree.</t>
        <t>The proof can be verified by checking that:</t>
        <ol spacing="normal" type="1"><li>The elements of <tt>steps</tt> represent a monotonic series over the leaves of the
log, and</li>
          <li>The <tt>steps</tt> array has the expected number of entries (no more or less than
are necessary to execute the binary search).</li>
        </ol>
        <t>Once the validity of the search steps has been established, the verifier can
compute the root of each prefix tree represented by a <tt>prefix_proof</tt> and combine
it with the corresponding <tt>commitment</tt> to obtain the value of each leaf. These
leaf values can then be combined with the proof in <tt>inclusion</tt> to check that the
output matches the root of the log tree.</t>
      </section>
    </section>
    <section anchor="update-format">
      <name>Update Format</name>
      <t>The updates committed to by a combined tree structure contain the new value of a
search key, along with additional information depending on the deployment mode
of the Transparency Log. They are serialized as follows:</t>
      <sourcecode type="tls"><![CDATA[
struct {
  select (Configuration.mode) {
    case thirdPartyManagement:
      opaque signature<0..2^16-1>;
  };
} UpdatePrefix;

struct {
  UpdatePrefix prefix;
  opaque value<0..2^32-1>;
} UpdateValue;
]]></sourcecode>
      <t>The <tt>value</tt> field contains the new value of the search key.</t>
      <t>In the event that third-party management is used, the <tt>prefix</tt> field contains a
signature from the service operator, using the public key from
<tt>Configuration.leaf_public_key</tt>, over the following structure:</t>
      <sourcecode type="tls"><![CDATA[
struct {
  opaque search_key<0..2^8-1>;
  uint32 version;
  opaque value<0..2^32-1>;
} UpdateTBS;
]]></sourcecode>
      <t>The <tt>search_key</tt> field contains the search key being updated (the search key
provided by the user, not the VRF output), <tt>version</tt> contains the new key
version, and <tt>value</tt> contains the same contents as <tt>UpdateValue.value</tt>. Clients
<bcp14>MUST</bcp14> successfully verify this signature before consuming <tt>UpdateValue.value</tt>.</t>
    </section>
    <section anchor="user-operations">
      <name>User Operations</name>
      <t>The basic user operations are organized as a request-response protocol between a
user and the Transparency Log operator. Generally, users <bcp14>MUST</bcp14> retain the most
recent <tt>TreeHead</tt> they've successfully verified as part of any query response,
and populate the <tt>last</tt> field of any query request with the <tt>tree_size</tt> from
this <tt>TreeHead</tt>. This ensures that all operations performed by the user return
consistent results.</t>
      <section anchor="search">
        <name>Search</name>
        <t>Users initiate a Search operation by submitting a SearchRequest to the
Transparency Log containing the key that they're interested in. Users can
optionally specify a version of the key that they'd like to receive, if not the
most recent one. They can also include the <tt>tree_size</tt> of the last TreeHead that
they successfully verified.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  opaque search_key<0..2^8-1>;
  optional<uint32> version;
  optional<uint64> last;
} SearchRequest;
]]></sourcecode>
        <t>In turn, the Transparency Log responds with a SearchResponse structure:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  TreeHead tree_head;
  optional<ConsistencyProof> consistency;
  select (Configuration.mode) {
    case thirdPartyAuditing:
      AuditorTreeHead auditor_tree_head;
  };
} FullTreeHead;

struct {
  opaque index<VRF.Nh>;
  opaque proof<0..2^16-1>;
} VRFResult;

struct {
  FullTreeHead full_tree_head;
  VRFResult vrf_result;
  SearchProof search;

  opaque opening<16>;
  UpdateValue value;
} SearchResponse;
]]></sourcecode>
        <t>If <tt>last</tt> is present, then the Transparency Log <bcp14>MUST</bcp14> provide a consistency proof
between the current tree and the tree when it was this size, in the
<tt>consistency</tt> field of <tt>FullTreeHead</tt>.</t>
        <t>Users verify a search response by following these steps:</t>
        <ol spacing="normal" type="1"><li>Verify the VRF proof in <tt>VRFResult.proof</tt> against the requested search key
<tt>SearchRequest.search_key</tt> and the claimed VRF output <tt>VRFResult.index</tt>.</li>
          <li>Evaluate the search proof in <tt>search</tt> according to the steps in
<xref target="proof-combined-tree"/>. This will produce a verdict as to whether the search
was executed correctly, and also a candidate root value for the tree. If it's
determined that the search was executed incorrectly, abort with an error.</li>
          <li>If the user has monitoring information for this search key (because they own
it or are performing Contact Monitoring), verify that <tt>SearchProof.position</tt>
is the same as in previous requests, and that the entry's version and
position in the log are consistent with other known versions.</li>
          <li>
            <t>With the candidate root value for the tree:
            </t>
            <ol spacing="normal" type="1"><li>Verify the proof in <tt>FullTreeHead.consistency</tt>, if one is expected.</li>
              <li>Verify the signature in <tt>TreeHead.signature</tt>.</li>
              <li>Verify that the timestamp in <tt>TreeHead</tt> is sufficiently recent.
Additionally, verify that the <tt>timestamp</tt> and <tt>tree_size</tt> fields of the
<tt>TreeHead</tt> are greater than or equal to what they were before.</li>
              <li>If third-party auditing is used, verify <tt>auditor_tree_head</tt> with the steps
described in <xref target="auditing"/>.</li>
            </ol>
          </li>
          <li>Verify that the commitment in the terminal search step opens to
<tt>SearchResponse.value</tt> with opening <tt>SearchResponse.opening</tt>.</li>
        </ol>
        <t>Depending on the deployment mode of the Transparency Log, the <tt>value</tt> field may
or may not require additional verification, specified in <xref target="update-format"/>,
before its contents may be consumed.</t>
        <t>To be able to later perform monitoring, users retain the claimed position of the
key's first occurrence in the log, <tt>SearchProof.position</tt>. They also retain, for
each version of the key observed, the version number and its position in the
log. Users <bcp14>MUST</bcp14> retain this information if the Transparency Log's deployment
mode is Contact Monitoring, and they <bcp14>SHOULD</bcp14> retain the entire <tt>SearchResponse</tt>
structure to assist with debugging or to provide non-repudiable proof if
misbehavior is detected. If one of the third-party modes is being used, users
<bcp14>MAY</bcp14> retain this information to perform Contact Monitoring even though it is not
required.</t>
      </section>
      <section anchor="update">
        <name>Update</name>
        <t>Users initiate an Update operation by submitting an UpdateRequest to the
Transparency Log containing the new key and value to store. Users can also
optionally include the <tt>tree_size</tt> of the last TreeHead that they successfully
verified.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  opaque search_key<0..2^8-1>;
  opaque value<0..2^32-1>;
  optional<uint64> last;
} UpdateRequest;
]]></sourcecode>
        <t>If the request is acceptable by application-layer policies, the Transparency Log
adds the new key-value pair to the log and returns an UpdateResponse structure:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  FullTreeHead full_tree_head;
  VRFResult vrf_result;
  SearchProof search;

  opaque opening<16>;
  UpdatePrefix prefix;
} UpdateResponse;
]]></sourcecode>
        <t>Users verify the UpdateResponse as if it were a SearchResponse for the most
recent version of <tt>search_key</tt>, and they also check that their update is the
last entry in the log. To aid verification, the update response provides the
<tt>UpdatePrefix</tt> structure necessary to reconstruct the <tt>UpdateValue</tt>.</t>
        <t>Users <bcp14>MUST</bcp14> retain the information required to perform monitoring as described in
<xref target="search"/>.</t>
      </section>
      <section anchor="monitor">
        <name>Monitor</name>
        <t>Users initiate a Monitor operation by submitting a MonitorRequest to the
Transparency Log containing information about the keys they wish to monitor.
Similar to Search and Update operations, users can include the <tt>tree_size</tt> of
the last TreeHead that they successfully verified.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  opaque search_key<0..2^8-1>;
  uint64 entries<0..2^8-1>;
} MonitorKey;

struct {
  MonitorKey owned_keys<0..2^8-1>;
  MonitorKey contact_keys<0..2^8-1>;
  optional<uint64> last;
} MonitorRequest;
]]></sourcecode>
        <t>Users include each of the keys that they own in <tt>owned_keys</tt>. If the
Transparency Log is deployed with Contact Monitoring (or simply if the user
wants a higher degree of confidence in the log), they also include any keys
they've looked up in <tt>contact_keys</tt>.</t>
        <t>Each <tt>MonitorKey</tt> structure contains the key being monitored in <tt>search_key</tt>,
and a list of entries in the log tree corresponding to the values of the map
described in <xref target="monitoring"/>.</t>
        <t>The Transparency Log verifies the MonitorRequest by following these steps, for
each <tt>MonitorKey</tt> structure:</t>
        <ol spacing="normal" type="1"><li>Verify that the requested keys in <tt>owned_keys</tt> and <tt>contact_keys</tt> are all
distinct.</li>
          <li>Verify that the user owns every key in <tt>owned_keys</tt>, and is allowed to lookup
every key in <tt>contact_keys</tt>, based on the application's policy.</li>
          <li>Verify that each <tt>entries</tt> array is sorted in ascending order.</li>
          <li>Verify that the entries in each <tt>entries</tt> array are all between the initial
position of the requested key and the end of the log.</li>
          <li>Verify each entry lies on the direct path of different versions of the key.</li>
        </ol>
        <t>If the request is valid, the Transparency Log responds with a MonitorResponse
structure:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  PrefixProof prefix_proof;
  opaque commitment<Hash.Nh>;
} MonitorProofStep;

struct {
  MonitorProofStep steps<0..2^8-1>;
  InclusionProof inclusion;
} MonitorProof;

struct {
  FullTreeHead full_tree_head;
  MonitorProof owned_proofs<0..2^8-1>;
  MonitorProof contact_proofs<0..2^8-1>;
} MonitorResponse;
]]></sourcecode>
        <t>The elements of <tt>owned_proofs</tt> and <tt>contact_proofs</tt> correspond one-to-one with
the elements of <tt>owned_keys</tt> and <tt>contact_keys</tt>. Each <tt>MonitorProof</tt> is meant to
convince the user that the key they looked up is still properly included in the
log and has not been surreptitiously concealed.</t>
        <t>The steps of a <tt>MonitorProof</tt> consist of the proofs required to update the
user's monitoring data following the algorithm in <xref target="monitoring"/>, including
proofs along the current frontier of the log. The steps are provided in the
order that they're consumed by the monitoring algorithm. If same proof is
consumed by the monitoring algorithm multiple times, it is provided in the
<tt>MonitorProof</tt> structure only the first time. Proofs along the frontier are
provided from left to right, excluding any proofs that have already been
provided, and excluding any entries of the frontier which are to the left of the
leftmost entry being monitored.</t>
        <t>Users verify a MonitorResponse by following these steps:</t>
        <ol spacing="normal" type="1"><li>Verify that the lengths of <tt>owned_proofs</tt> and <tt>contact_proofs</tt> are the same
as the lengths of <tt>owned_keys</tt> and <tt>contact_keys</tt>.</li>
          <li>
            <t>For each <tt>MonitorProof</tt> structure:
            </t>
            <ol spacing="normal" type="1"><li>Evalute the monitoring algorithm in <xref target="monitoring"/>. Abort with an error if
the monitoring algorithm detects that the tree is constructed incorrectly,
or if there are fewer or more steps provided than would be expected.</li>
              <li>Construct a candidate root value for the tree by combining the
<tt>PrefixProof</tt> and commitment of each step, with the provided inclusion
proof.</li>
            </ol>
          </li>
          <li>
            <t>Verify that all of the candidate root values are the same. With the candidate
root value:
            </t>
            <ol spacing="normal" type="1"><li>Verify the proof in <tt>FullTreeHead.consistency</tt>, if one is expected.</li>
              <li>Verify the signature in <tt>TreeHead.signature</tt>.</li>
              <li>Verify that the timestamp in <tt>TreeHead</tt> is sufficiently recent.
Additionally, verify that the <tt>timestamp</tt> and <tt>tree_size</tt> fields of the
<tt>TreeHead</tt> are greater than or equal to what they were before.</li>
              <li>If third-party auditing is used, verify <tt>auditor_tree_head</tt> with the steps
described in <xref target="auditing"/>.</li>
            </ol>
          </li>
        </ol>
        <t>Some information is omitted from MonitorResponse in the interest of efficiency,
due to the fact that the user would have already seen and verified it as part of
conducting other queries. In particular, the VRF output and proof for each
search key is not provided, or each key's initial position in the log, given
that both of these can be cached from the original Search or Update query for
the key.</t>
      </section>
      <section anchor="distinguished">
        <name>Distinguished</name>
        <t>Users can request distinguished tree heads by submitting a DistinguishedRequest
to the Transparency Log containing the approximate timestamp of the tree head
they'd like to receive.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  uint64 timestamp;
  optional<uint64> last;
} DistinguishedRequest;
]]></sourcecode>
        <t>In turn, the Transparency Log responds with a DistinguishedResponse structure
containing the <tt>FullTreeHead</tt> with the timestamp closest to what the user
requested and the root hash of the tree at this point.</t>
        <sourcecode type="tls"><![CDATA[
struct {
  FullTreeHead full_tree_head;
  opaque root<Hash.Nh>;
} DistinguishedResponse;
]]></sourcecode>
        <t>If <tt>last</tt> is present, then the Transparency Log <bcp14>MUST</bcp14> provide a consistency proof
between the provided tree head and the tree when it had <tt>last</tt> entries, in the
<tt>consistency</tt> field of <tt>FullTreeHead</tt>. Unlike the other operations described in
this section, where <tt>last</tt> is always less than or equal to the <tt>tree_size</tt> in
the provided FullTreeHead, a DistinguishedResponse may contain a FullTreeHead
which comes either before or after <tt>last</tt>.</t>
        <t>Users verify a response by following these steps:</t>
        <ol spacing="normal" type="1"><li>Verify the proof in <tt>FullTreeHead.consistency</tt>, if one is expected.</li>
          <li>Verify the signature in <tt>TreeHead.signature</tt>.</li>
          <li>Verify that the <tt>timestamp</tt> and <tt>tree_size</tt> fields of the <tt>TreeHead</tt> are
consistent with the previously held <tt>TreeHead</tt>.</li>
          <li>If third-party auditing is used, verify <tt>auditor_tree_head</tt> with the steps
described in <xref target="auditing"/>.</li>
        </ol>
      </section>
    </section>
    <section anchor="third-parties">
      <name>Third Parties</name>
      <section anchor="management">
        <name>Management</name>
        <t>With the Third-party Management deployment mode, a third party is responsible
for the majority of the work of storing and operating the log, while the service
operator serves mainly to enforce access control and authenticate the addition
of new entries to the log. All user queries specified in <xref target="user-operations"/> are
initially sent by users directly to the service operator, and the service
operator proxies them to the third-party manager if they pass access control.</t>
        <t>The service operator only maintains one private key that is kept secret from the
third-party manager, which is the private key corresponding to
<tt>Configuration.leaf_public_key</tt>. This private key is used to sign new entries
before they're added to the log.</t>
        <t>As such, all requests and their corresponding responses from <xref target="user-operations"/>
are proxied between the user and the third-party manager unchanged with the
exception of <tt>UpdateRequest</tt>, which needs to carry the service operator's
signature over the update:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  UpdateRequest request;
  opaque signature<0..2^16-1>;
} ManagerUpdateRequest;
]]></sourcecode>
        <t>The signature is computed over the <tt>UpdateTBS</tt> structure from <xref target="update-format"/>.
The service operator <bcp14>MUST</bcp14> maintain its own records (independent of the
third-party manager) for the most recent version of each key, for the purpose of
producing this signature. The service operator <bcp14>SHOULD</bcp14> also attempt to
proactively detect forks presented by the third-party manager.</t>
      </section>
      <section anchor="auditing">
        <name>Auditing</name>
        <t>With the Third-party Auditing deployment mode, the service operator obtains
signatures from a lightweight third-party auditor attesting to the fact that the
service operator is constructing the tree correctly. These signatures are
provided to users along with the responses for their queries.</t>
        <t>The third-party auditor is expected to run asynchronously, downloading and
authenticating a log's contents in the background, so as not to become a
bottleneck for the service operator. This means that the signatures from the
auditor will usually be somewhat delayed. Applications <bcp14>MUST</bcp14> specify a maximum
amount of time after which an auditor signature will no longer be accepted. It
<bcp14>MUST</bcp14> also specify a maximum number of entries that an auditor's signature may be
behind the most recent <tt>TreeHead</tt> before it will no longer be accepted. Both of
these parameters <bcp14>SHOULD</bcp14> be small relative to the log's normal operating scale so
that misbehavior can be detected quickly.</t>
        <t>Failing to verify an auditor's signature in a query <bcp14>MUST</bcp14> result in an error that
prevents the query's response from being consumed or accepted by the
application.</t>
        <t>The service operator submits updates to the auditor in batches, in the order
that they were added to the log tree:</t>
        <sourcecode type="tls"><![CDATA[
enum {
  reserved(0),
  real(1),
  fake(2),
  (255)
} AuditorUpdateType;

struct {
  AuditorUpdateType update_type;
  opaque index<VRF.Nh>;
  opaque seed<16>;
  opaque commitment<Hash.Nh>;
} AuditorUpdate;

struct {
  AuditorUpdate updates<0..2^16-1>;
} AuditorRequest;
]]></sourcecode>
        <t>The <tt>update_type</tt> field of each <tt>AuditorUpdate</tt> specifies whether the update was
real or fake (see <xref target="obscuring-update-rate"/>). Real updates genuinely affect a leaf node of the prefix tree,
while fake updates only change the random stand-in value for a non-existent
child. The <tt>index</tt> field contains the VRF output of the search key that
was updated, <tt>seed</tt> contains the seed used to compute new random stand-in values
for non-existent children in the prefix tree, and <tt>commitment</tt> contains the
service provider's commitment to the update. The auditor responds with:</t>
        <artwork><![CDATA[
struct {
  TreeHead tree_head;
} AuditorResponse;
]]></artwork>
        <t>The <tt>tree_head</tt> field contains a signature from the auditor's private key,
corresponding to <tt>Configuration.auditor_public_key</tt>, over the serialized
<tt>TreeHeadTBS</tt> structure. The <tt>tree_size</tt> field of the <tt>TreeHead</tt> is equal to the
number of entries processed by the auditor and the <tt>timestamp</tt> field is set to
the time the signature was produced (in milliseconds since the Unix epoch).</t>
        <t>The auditor <tt>TreeHead</tt> from this response is provided to users wrapped in the
following struct:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  TreeHead tree_head;
  opaque root_value<Hash.Nh>;
  ConsistencyProof consistency;
} AuditorTreeHead;
]]></sourcecode>
        <t>The <tt>root_value</tt> field contains the root hash of the tree at the point that the
signature was produced and <tt>consistency</tt> contains a consistency proof between
the tree at this point and the most recent <tt>TreeHead</tt> provided by the service
operator.</t>
        <t>To check that an <tt>AuditorTreeHead</tt> structure is valid, users follow these steps:</t>
        <ol spacing="normal" type="1"><li>Verify the signature in <tt>TreeHead.signature</tt>.</li>
          <li>Verify that <tt>TreeHead.timestamp</tt> is sufficiently recent.</li>
          <li>Verify that <tt>TreeHead.tree_size</tt> is sufficiently close to the most recent
tree head from the service operator.</li>
          <li>Verify the consistency proof <tt>consistency</tt> between this tree head and the
most recent tree head from the service operator.</li>
        </ol>
        <!-- # Owner Signing

TODO -->

</section>
    </section>
    <section anchor="operational-considerations">
      <name>Operational Considerations</name>
      <section anchor="detecting-forks">
        <name>Detecting Forks</name>
        <t>It is sometimes possible for a Transparency Log to present forked views of data
to different users. This means that, from an individual user's perspective, a
log may appear to be operating correctly in the sense that all of a user's
Monitor operations succeed. However, the Transparency Log has presented a view
to the user that's not globally consistent with what it has shown other users.
As such, the log may be able to associate data with keys without the key owner's
awareness.</t>
        <t>The protocol is designed such that users always remember the last <tt>TreeHead</tt>
that they observed when querying the log, and require subsequent queries to
prove consistency against this tree head. As such, users always stay on an
individually-consistent view of the log. If a user is ever presented with a
forked view, they hold on to this forked view forever and reject the output of
any subsequent queries that are inconsistent with it.</t>
        <t>This provides ample opportunity for users to detect when a fork has been
presented, but isn't in itself sufficient for detection. To detect forks, users
must either use <strong>out-of-band communication</strong> with other users or <strong>anonymous
communication</strong> with the Transparency Log.</t>
        <t>With out-of-band communication, a user obtains a "distinguished" <tt>TreeHead</tt> that
was issued closest to a given time, like the start of the day, by sending a
<tt>Distinguished</tt> request to the Transparency Log. The user then sends the
<tt>TreeHead</tt> along with the root hash that it verifies against to other users over
some out-of-band communication channel (for example, an in-app screen with a QR
code / scanner). The other users check that the <tt>TreeHead</tt> verifies successfully
and matches their own view of the log. If the <tt>TreeHead</tt> verifies successfully
on its own but doesn't match a user's view of the log, this proves the existence
of a fork.</t>
        <t>With anonymous communication, a user first obtains a "distinguished" <tt>TreeHead</tt>
by sending a <tt>Distinguished</tt> request to the Transparency Log over their normal
communication channel. They then send the same <tt>Distinguished</tt> request, omitting
any identifying information and leaving the <tt>last</tt> field empty, over an
anonymous channel. If the log responds with a different <tt>TreeHead</tt> over the
anonymous channel, this proves the existence of a fork.</t>
        <t>In the event that a fork is successfully detected, the two signatures on the
differing views of the log provide non-repudiable proof of log misbehavior which
can be published.</t>
      </section>
      <section anchor="combining-multiple-logs">
        <name>Combining Multiple Logs</name>
        <t>There are some cases where it may make sense to operate multiple cooperating log
instances. For example, a service provider may decide that it's prudent to
migrate to a new deployment mode. They can do this by creating a new log
instance operating under the new deployment mode, and gradually migrating their
data from the old log to the new log while users are able to query both. In
another case, a service provider may choose to operate multiple logs to improve
their ability to scale or to provide higher availability. Similarly, a
federated system may allow each party in the federation to operate their own
log for their own users.</t>
        <t>When this happens, all users in the system <bcp14>MUST</bcp14> have a consistent policy for
executing Search, Update, and Monitor queries against the multiple logs that
maintains the high-level security guarantees of KT:</t>
        <ul spacing="normal">
          <li>If all logs behave honestly, then users observe a globally-consistent view of
the data associated with each key.</li>
          <li>If any log behaves dishonestly such that the prior guarantee is not met (some
users observe data associated with a key that others do not), this will be
detected either immediately or in a timely manner by background monitoring.</li>
        </ul>
        <t>In the specific case of migrating from an old log to a new one, this policy may
look like:</t>
        <ol spacing="normal" type="1"><li>Search queries should be executed against the old log first, and then against
the new log only if the most recent version of a key in the old log is a
tombstone.</li>
          <li>Update queries should only be executed against the new log, adding a
tombstone entry to the old log if one hasn't been already created.</li>
          <li>Both logs should be monitored as they would be if they were run individually.
Once the migration has completed and the old log has stopped accepting
changes, the old log <bcp14>SHOULD</bcp14> stay operational long enough for all users to
complete their monitoring of it (keeping in mind that some users may be
offline for a significant amount of time).</li>
        </ol>
        <t>Placing a tombstone entry for each key in the old log gives users a clear
indication as to which log contains the most recent version of a key and
prevents them from incorrectly accepting a stale version if the new log rejects
a search query.</t>
      </section>
      <section anchor="obscuring-update-rate">
        <name>Obscuring Update Rate</name>
        <t>While the protocol already prevents outside observers from determining the total
number of key-value pairs stored by a server, some applications may also wish to
obscure the frequency of updates. Revealing the frequency of updates may make it
possible to deduce the total size of the tree, or it may expose sensitive
information about an application's usage patterns. However, fully hiding the
frequency of updates is impossible with any hash-based KT construction. Instead,
an application may pad real updates with "fake" random updates, such that the
update rate measured by observers is fixed to an arbitrary upper-bound value.</t>
        <t>The service provider produces a fake update by first choosing three random
values: one to represent the VRF output of the key being updated, one to
represent the commitment to the update, and one which will be the seed for
generating a new stand-in value in the prefix tree. It then traverses the prefix
tree according to the random VRF output, and replaces the first stand-in value
it reaches with the one generated from the chosen seed. Note that this means
that fake updates don't affect a leaf of the prefix tree. Finally, the service
provider adds a new entry to the log tree with the random commitment value and
the updated prefix tree root.</t>
        <t>The VRF output and commitment value can be chosen randomly, instead of being
computed with the actual VRF or commitment scheme, because the server will never
be required to actually open either of these values. No legitimate search for a
key will ever terminate at this entry in the log.</t>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>While providing a formal security proof is outside the scope of this document,
this section attempts to explain the intuition behind the security of each
deployment mode.</t>
      <section anchor="security-contact-monitoring">
        <name>Contact Monitoring</name>
        <t>Contact Monitoring works by splitting the monitoring burden between both the
owner of a key and those that look it up. Stated as simply as possible, the
monitoring obligations of each party are:</t>
        <ol spacing="normal" type="1"><li>The key owner, on a regular basis, searches for the most recent version of
the key in the log. They verify that this search results in the expected
version of the key, at the expected position in the log.</li>
          <li>The user that looks up a key, whenever a new parent is established on
the key's direct path, searches for the key in the prefix tree stored in this
new parent. They verify that the version counter returned is greater
than or equal to the expected version.</li>
        </ol>
        <t>To understand why this is secure, we look at what happens when the service
operator tampers with the log in different ways.</t>
        <t>First, say that the service operator attempts to cover up the latest version of
a key, with the goal of causing a "most recent version" search for the key to
resolve in a lower version. To do this, the service operator must add a parent
over the latest version of the key with a prefix tree that contains an
incorrect version counter. Left unchanged, the key owner will observe that the
most recent version of their key is no longer available the next time they
perform monitoring. Alternatively, the service operator could add the new
version of the key back at a later position in the log. But even so, the key
owner will observe that the key's position has changed the next time they
perform monitoring. The service operator is unable to restore the latest version
of the key without violating the log's append-only property or presenting a
forked view of the log to different users.</t>
        <t>Second, say that the service operator attempts to present a fake new version of
a key, with the goal of causing a "most recent version" search for the key to
resolve to the fake version. To do this, the service operator can simply add the
new version of the key as the most recent entry to the log, with the next
highest version counter. Left unchanged, or if the log continues to be
constructed correctly, the key owner will observe that a new version of their
key has been added without their permission the next time they perform
monitoring. Alternatively, the service operator can add a parent over the
fake version with an incorrect version counter to attempt to conceal the
existence of the fake entry. However, the user that previously consumed the fake
version of the key will detect this attempt at concealment the next time they
perform monitoring.</t>
      </section>
      <section anchor="third-party-management">
        <name>Third-party Management</name>
        <t>Third-party Management works by separating the construction of the log from the
ability to approve which new entries are added to the log, such that tricking users
into accepting malicious data requires the collusion of both parties.</t>
        <t>The service operator maintains a private key that signs new entries before
they're added to the log, which means that it has the ability to sign malicious
new entries and have them successfully published. However, without the collusion
of the third-party manager to later conceal those entries by constructing the
tree incorrectly, their existence will be apparent to the key owner the next
time they perform monitoring.</t>
        <t>Similarly, while the third-party manager has the ability to construct the tree
incorrectly, it cannot add new entries on its own without the collusion of the
service operator. Without access to the service operator's signing key, the
third-party manager can only attempt to selectively conceal the latest version
of a key from certain users. However, as discussed in
<xref target="security-contact-monitoring"/>, this is also apparent to the key owner through
monitoring.</t>
      </section>
      <section anchor="third-party-auditing">
        <name>Third-party Auditing</name>
        <t>Third-party Auditing works by requiring users to verify a signature from a
third-party auditor attesting to the fact that the service operator has been
constructing the tree correctly.</t>
        <t>While the service operator can still construct the tree incorrectly and
temporarily trick users into accepting malicious data, an honest auditor will no
longer provide its signatures over the tree at this point. Once there are no
longer any sufficiently recent auditor tree roots, the log will become
non-functional as the service operator won't be able to produce any query
responses that would be accepted by users.</t>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document requests the creation of the following new IANA registries:</t>
      <ul spacing="normal">
        <li>KT Ciphersuites (<xref target="kt-ciphersuites"/>)</li>
      </ul>
      <t>All of these registries should be under a heading of "Key Transparency",
and assignments are made via the Specification Required policy <xref target="RFC8126"/>. See
<xref target="de"/> for additional information about the KT Designated Experts (DEs).</t>
      <t>RFC EDITOR: Please replace XXXX throughout with the RFC number assigned to
this document</t>
      <section anchor="kt-ciphersuites">
        <name>KT Ciphersuites</name>
        <sourcecode type="tls"><![CDATA[
uint16 CipherSuite;
]]></sourcecode>
        <t>TODO</t>
      </section>
      <section anchor="de">
        <name>KT Designated Expert Pool</name>
        <t>TODO</t>
      </section>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <reference anchor="RFC2104">
          <front>
            <title>HMAC: Keyed-Hashing for Message Authentication</title>
            <author fullname="H. Krawczyk" initials="H." surname="Krawczyk">
              <organization/>
            </author>
            <author fullname="M. Bellare" initials="M." surname="Bellare">
              <organization/>
            </author>
            <author fullname="R. Canetti" initials="R." surname="Canetti">
              <organization/>
            </author>
            <date month="February" year="1997"/>
          </front>
          <seriesInfo name="RFC Editor" value="report"/>
          <seriesInfo name="DOI" value="10.17487/rfc2104"/>
        </reference>
        <reference anchor="RFC6962">
          <front>
            <title>Certificate Transparency</title>
            <author fullname="B. Laurie" initials="B." surname="Laurie">
              <organization/>
            </author>
            <author fullname="A. Langley" initials="A." surname="Langley">
              <organization/>
            </author>
            <author fullname="E. Kasper" initials="E." surname="Kasper">
              <organization/>
            </author>
            <date month="June" year="2013"/>
          </front>
          <seriesInfo name="RFC Editor" value="report"/>
          <seriesInfo name="DOI" value="10.17487/rfc6962"/>
        </reference>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner">
              <organization/>
            </author>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification.  These words are often capitalized. This document defines these words as they should be interpreted in IETF documents.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba">
              <organization/>
            </author>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol  specifications.  This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the  defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="RFC8446">
          <front>
            <title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
            <author fullname="E. Rescorla" initials="E." surname="Rescorla">
              <organization/>
            </author>
            <date month="August" year="2018"/>
            <abstract>
              <t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol.  TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
              <t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961.  This document also specifies new requirements for TLS 1.2 implementations.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8446"/>
          <seriesInfo name="DOI" value="10.17487/RFC8446"/>
        </reference>
        <reference anchor="I-D.irtf-cfrg-vrf">
          <front>
            <title>Verifiable Random Functions (VRFs)</title>
            <author fullname="Sharon Goldberg" initials="S." surname="Goldberg">
              <organization>Boston University</organization>
            </author>
            <author fullname="Leonid Reyzin" initials="L." surname="Reyzin">
              <organization>Boston University and Algorand</organization>
            </author>
            <author fullname="Dimitrios Papadopoulos" initials="D." surname="Papadopoulos">
              <organization>Hong Kong University of Science and Technology</organization>
            </author>
            <author fullname="Jan Včelák" initials="J." surname="Včelák">
              <organization>NS1</organization>
            </author>
            <date day="9" month="August" year="2022"/>
            <abstract>
              <t>   A Verifiable Random Function (VRF) is the public-key version of a
   keyed cryptographic hash.  Only the holder of the secret key can
   compute the hash, but anyone with the public key can verify the
   correctness of the hash.  VRFs are useful for preventing enumeration
   of hash-based data structures.  This document specifies VRF
   constructions based on RSA and elliptic curves that are secure in the
   cryptographic random oracle model.

   This document is a product of the Crypto Forum Research Group (CFRG)
   in the IRTF.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-vrf-15"/>
        </reference>
        <reference anchor="RFC8126">
          <front>
            <title>Guidelines for Writing an IANA Considerations Section in RFCs</title>
            <author fullname="M. Cotton" initials="M." surname="Cotton">
              <organization/>
            </author>
            <author fullname="B. Leiba" initials="B." surname="Leiba">
              <organization/>
            </author>
            <author fullname="T. Narten" initials="T." surname="Narten">
              <organization/>
            </author>
            <date month="June" year="2017"/>
            <abstract>
              <t>Many protocols make use of points of extensibility that use constants to identify various protocol parameters.  To ensure that the values in these fields do not have conflicting uses and to promote interoperability, their allocations are often coordinated by a central record keeper.  For IETF protocols, that role is filled by the Internet Assigned Numbers Authority (IANA).</t>
              <t>To make assignments in a given registry prudently, guidance describing the conditions under which new values should be assigned, as well as when and how modifications to existing values can be made, is needed.  This document defines a framework for the documentation of these guidelines by specification authors, in order to assure that the provided guidance for the IANA Considerations is clear and addresses the various issues that are likely in the operation of a registry.</t>
              <t>This is the third edition of this document; it obsoletes RFC 5226.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="26"/>
          <seriesInfo name="RFC" value="8126"/>
          <seriesInfo name="DOI" value="10.17487/RFC8126"/>
        </reference>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="Merkle2" target="https://eprint.iacr.org/2021/453">
          <front>
            <title>Merkle^2: A Low-Latency Transparency Log System</title>
            <author initials="Y." surname="Hu" fullname="Yuncong Hu">
              <organization/>
            </author>
            <author initials="K." surname="Hooshmand" fullname="Kian Hooshmand">
              <organization/>
            </author>
            <author initials="H." surname="Kalidhindi" fullname="Harika Kalidhindi">
              <organization/>
            </author>
            <author initials="S. J." surname="Yang" fullname="Seung Jin Yang">
              <organization/>
            </author>
            <author initials="R. A." surname="Popa" fullname="Raluca Ada Popa">
              <organization/>
            </author>
            <date year="2021" month="April" day="08"/>
          </front>
        </reference>
      </references>
    </references>
    <?line 1598?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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
qdCQIfjDMK/kQkXLIenUaSCNMjjBynoF+mU1jST+kIkbBxaBTHCV5ufNNVi3
FzwUrpvrreaI7xN+Fqb0yZQTH2Ii7UI5ED/GSGhSVLXrm1vs3qdTpunySpu+
46KN5AaxNMQbEQlSeCNzjlbQROalm/FthLuTO2huH4ftFF26sxjPmqNWyoZN
QK4ULUGwoNV39ZYlar1WRYgS690m1X6sW90Go/WPA7NW6pjmk07P0TaUNhiT
LmUPFBxBhrTIXYFAg5RZYDyYWWR1R8SK4Z3R7SsvuUg+M/WXj4aRAW3CFKa3
MPXfJY+N9U+FN9UWAv0JQxHWGJuFsVOjpnVr7I9xZWw6tmndyDoOl8Ri4OiC
6S3JerMvCwlgYfQj5Ii8im95FRJhxbLpi6rbFqw7T+6YX49aQ9YoFndVUpJ7
k5Ggb9P2RKbfYzinzDaCXPrZxB+gHnDgKvV8GkaKpG7K955+AL0lb1UfOLAq
1oHvf0/xbsvl4PMz5/793//dZ1l7rbWr9vznT3c//rexxydT/c8/hr9ORl78
eHTIfxm++af7L+7f7rfQE1ncSe+18Hvyelzov/g9v9v3/3Sfv80HH5th9/7t
zM9xHXv/Dq//6T7/jddhmb898/6h96feP/L+sfdPvP/E+0+9/8z7z73/wp8+
9Ken/vSRP32M+OPenXEVt68PUp/nwJl3+iSQKnWVHPhbSxRH7jVK+tbphDQu
hhuHoEAKPXWBduFAg/Ch9ZaSQxLNS/l4LIrEBUI0JZGZLhNOvldEjLFAF1F9
1P0uOTZ7KZHZarWKkhIzFrmWnDwRrdlC/8nQpzUqKOIWyL0YrERxq9CUw7aD
VQDZqx0weJx/iSJbcCtpwlmMRIlG/pWBNyZ6J2RZiMKGhsXgn0vKnK8rKXjS
GW9ucFs/4vhqYFuVf3vin/9tW4AQx5otF1oECnW4xgiCFXDIhv+E8z98O/GP
jo6O3DJfIT48Onx7xKX7ipV/67/+2j88C0jMuq1/SD9c+a/lL6aBh2/9N9/4
qyP/jf3kyv/j1/7Uma+vpqdOthXssZnvO9hP/E/Ru8rvPZyI2CARKjBIfHgK
wmi3ILNUplEQMaylITE7JiHRN+0ERiD5nq0xOEyh+Qlv4+JsCIrfgNjGJiQC
GL6TQuy/+IdvH55+EOAC5PjbI/z49E4QOpl91f0F9KxNWAEOrWvSJV3115Jh
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
m1ckbnTkpb3ULD2r5CYqwEhUiCKCKXSIayLpOq4t1pV/f3z1CHM7pExy7Dyr
wgKVVL3JuH861QJvYJgLNA2gvxMtPcueLHQ0MXdbdyGVpCmdLi0nSzuwoJtp
W/dZhO1s6Ldqg9CktdfoZRYdE3JDptuM4vXuin0f7fUbg0yJuGUb1xPf46Wm
u3s+ZosxNSrz/vXcZ/swcuI4HHrGkaxv9riS3vQWO1hrSoAtlQFLUvWlRRoZ
N/ojs43/ptJW5dLRzw7PhJ0q13HEV2wEiEVDk8+SRaRxD5ZfP2iZV+/IfGDX
xKCRwzRhn9ywkYKJ24UqMhS1hmp1f1cGGUYHFOgkBbWlVEWi5terIfiDQUnq
SCnrMmqeKX1bmlpqtv4tfLi/hrE4BAfyDxe5uZ+ROCAk80v3Hrnl90cvyUT0
6TCGqf/0Q8OW7PcfZMi1HwqZ5wC1UULPryn2Dl+87cPTuB2ToA87U+9i6o8m
3hVUHAzBRE0Hj4145shw+275iU8oqoTOmJx0F1pCh7se7gg7YvKkNWUbSy8B
u4/KxNIopbQOboTUSW1N1JyBF3YFle3WWoe5RlyGALCsv1QxXcVIRwqCtlJW
qNzNnQEeJMZFqmmY0Nk0VDil4xPZDUaXabh16GagtvLR+q5xE1KhSwMpaV1E
hnziIVOrhXr1rIyoCySeTiZJjUh19/nMY4X0AhtekNlsIupqf1E9QJvmedqI
ge0eOMiJZHeMNHegMitp5DuFtqE0zaFt+VuBqeeSo9yMHIFxiTGlWdnAhdwR
ooSBmKOkXyrJ7tXL1d5GsZo5h9axOIR/k5OQiW1PZBi6KHqX+L4uCm3fQen2
977nWRNjZSnuqt0zyt7rjQw7lFLfd6JqKCa3RZfvR5yhYOOfDg36aJVhi+be
gdhKY5rLa2aPrUJsHQcaoNOI/ClV7DEHByutcZgaX7CAa2TOHdYXFlv2s6DI
3cPxQQF75InRXCMxJCdR0BJWFuoSSngYLmuSxH3pPRMuJYPRqQ/EGROhOLbM
NkGSMfcAjh7f//9Ogf9nnALuDTaz75VRriXIjwhtn1gFewRHXxCGCnQXcMf2
ln7nxvN0kxKS3FJ4Tiy2j2ZoG85tKtSyP0ur2vdrPHdJUJRE7muMLl4iE3kY
Uz2UFSh9Y2u8SOFjnrYJ5/JxjUCqhBarhUsb5oyCtkO8G9CrC/KpDOr7c0QP
6mJR3v7oI/8dqUoXW4pfVe6Bg6sQvrQvxD4h7cBck4wkWqGT43mf3ZeqBr4t
1iT4hLulpnCdk3XuQQDNuBVlPBV0j/libO2/K1ClN1Dfgup6+04DDOKNijBY
lHUr1q8bi94uamiqnRHRpFInFnAcVYnaZ4GU6HdYcE0CbaIGje71PyPKI3LM
0LVmNNbjEh7IKvLYLZGFxXsFfPhfq1CBkgmCCWRL7J7i5JfCZFK8IAAgK2+y
XWs6A/daqCS0nkYzm7RLmuxFsXW2C4HQWfKNVIjF7lrADAvahrgfMeSAOhry
UofS44dHtvxu5vzBnHmELd+bhfaYJ/KufkADb4ZjJoCTXyKGmEBH93+ced7F
Oak3K5a5xHAzbDFItvUQIO1cEKP2FJvoub4Rj0zdTO5nQEeNfRpd8IFkf0UB
OCRAUPcS9NeogIwKPd8IbWAoZUZKjSXqFe3kordUMb3kTAwqy5/3i/KTpdMk
qzKXEPkJ4/BtBzvTbtM/Lbm/gbLugScenk3jLb69pfOPRVspbWW+E4N/KNe7
p2JG8ACNllB/K6bSkHczUrJD9ANOP+5BQY0J/XrHpNBq0XnOVTNVpvk6aN44
0KQm74KA4EaWoLlhoZZ4HKpvSn5fjLyEe9khtOwqOnLh9tqD0ygItSGMNU+V
vvGkVoTC1QL0QW8nJVehPuvgtJ2YM95SVpPhKUnI9tg5bStuYhgzYlyuDbOJ
dSQO3ZkCFWtaEYYusqYZrxf+oDWZCyHHgM1A46bL1LfeqLzy3ho7TBCaMdfz
eUp0+xVfuug8TCu+BEinES4n45hLbD40IsQYEHT9oJeyASgdYkgixuyINroH
X48SH+1I51gVrifhRWm2gzI+RyGGnm9hz3tqi0uECEccgqay3pCVkYpcd9z+
i40DONdVkHWiRWtkAyx5a9DwHuKtj4ekewyHJNnLYFKrOcYlWq1uckrdHrAr
lABgV6029xroUm4wk7V6KNmPfiftwkQSQlxLYlRDI6e0GkgaSZjry+dW2L5i
5z1g6vp76drNFh0mO7itTV1JU0WsHFfWmVjels5wFtZdyqTTkGpg82xxddFg
ruoE8/nFAEwp4ShN+cxhTYEyr9DtH5NIe0WVmCSaovCJfBMbYTndEAXLbttQ
G7+FuUj2X+YY9IH9Jm1jHE6QCckH6wz0qO3axZ5jVPSK5TwxLVYBePHK06xV
TaWYSEKU2BMKTeo4DYduwWCqkUxMbVwg0zywiToc5ga0/3Ksaa8RzEKM3J1r
+5bVYsdCKaBGtsZA31ZvLgJwzdwDM2Gvc8NgqMkjEKzSSDHUYw5gzkq3jdYS
lVsjtgA1i8UVlTX5PitKuUAqOo/vnYRz1sQl6IIiY/BnNUZS1kYotY8Lpfcf
mHYEXBg9504nYj+vmwATTeE23sd9kgQr8G1IuhTQhKtVcSpyVJzYA+m61KY0
2j74HoW7sMOL1OpaZVe51ObSElySRSFcZ7fpVeEaPJZd/KWjV9+bQYFVMnvV
q/f4+5KZ7liEgrHHdeWdIb+dmQUbJZRt38nIM9M+wIbLi6/oJsNSfYjGDQHS
YwlRYMr1vF1sUVKfCnvGWiK3t0cn/jW+rad+AedTVMjKstUqJwtzKJ0yUpKD
eo5gTwScSccgmZQlJKblUgs1LfTJtbIwNJKaXKDqQoUoQ5I8piSMJTIaY9sg
k5SvDMbwS3bjBMMm8mU/7RCroqooqmnZKI2OLpW7YNqVhpKZo505xJcRE7Dt
3IGJCgtsHrR+X/EABoXewMS+JPXd35PpZBBu4LidGQ20nz7rR9JnIw0zIv3E
DSJMemrBsOabzZ6NOdJuTxlBQYe+9j6ivCPzt71oh6wodhfS0koq92i5dWM0
kLaKLfUb6WqntrieTQJxTbJZlii13lUu0lO5yCOhwDq52YIAuzAE3no3g7B0
0wBBj+7Ofg7yh6XC7S+J5wdltNL0uNt+dptFrzji6C2+w0KZs4HSyJ3j0Faf
YTTeGQwemA1VxXPj5tCAA3skkH5WdF/J5xB9E/YJXHzWA09alkgDWvhIh321
B/a0exjCejFO8SWD2PscU4/3fmsMkr1vySStRMtADo1Y0SK7NwU/DV/KRw4t
Pd+opaOBom/xxUnv0ci8V+bUffUP06n/yL+8qYBaYAVdUsTOX3730k+n36C9
LSSIA3GhG7GMCePoNyEpEK/f96j3adtjlNW5MQA3OCqV5w0s3pQqwFVSUHPE
it1FfkMGSgzyQM9JDJcidBloEhNR8QbNPR9QmjXVK6IE44yiWKg/KJAQjned
50bojSXfhLdh21OplCsO3UxGdoPAXenmjcJ40u1ysOXLzOrHGW1YPUQhUucB
a1kXZT3nLko9uyxpQmTcb7FvxU0llnkGUTQYqSgqWTWaRJO1bb2gEGQKpaEh
KcJQO113l5LBgqgB281ucAfAQWKBHE73pzhUvIeYmrnVPpaq2JLBH8sjET+i
xWBkcCQuRobWZBl2XJC4n9hTOTyfM45MEXW1cLI54jq9STGF1N4aUB0VPslC
gUpgsXbs1RVRqdxNDfCpBacNEXoR25pxKKU5W/aGOYPYEkuLXfE856bQyswb
+DdX5aft/jWXmPUg9jkMmhnbfyxJ2UeWotPe7SF4nkrgA/JiC+FthcZtvKCh
CZoYc264Xx4uL1T6cWF/Ez/fdlJkju1YWCY5EkkakkfiApB1YiTS5B0qwCke
GUwIPT6usc3fajrXyAxYICtwx8c2zZJXC3McH2cgou5A1W/d6Ptj9/BELE57
J5vowYpRCf55kLiBD9JiFCJ9F227xVzd6LHU/mtIESc+NnPrpDwF/mOZ7Sbk
S5YQ18zNEg/XLHii9/iSWVjUtncVDSQ5EsbJ07M0BUGkE3ISQpvDxalTYMML
Dqn7frCR+gNqlD+kKIC3hGkTJs9TILy+XTTIyMRV/M+vHVbN9B+jyQG+a454
J3bWNKPEQj2sN8liwjWZyksFBTqPXt17DVdHGy0iPHZiRZSnGQJD6A8/EQGr
oSJx+KNoUAvpxYJ3QHEwoO8eDJRUxXvgobM45D8Qh4JyUjRiEXKjRytpkAHP
GJ0xonHPhBMOcEHpAqmXNGLcDZJVKq6uHOICbEkW6tgi+hM2U4wg00W9iLW1
+gEJUYYwp627HY51x+F5e3hjdU2JWBYpCgVrGTPk7qa2pk8pD8hrxL0HEUi3
c2c2Zc2dmK2NjsvPi6UudLyyFTpxmp81oBSOnuv/SHweXXDub88+/KIjAWKN
pg6RiWqRfPIYl7qooygFK6KmzBmArJVgxkAKfN8QQKMv80WxzJUUkbK9XbJh
wK2LC5qLqCn3XU/cAaZCzFJ46lxaT/JNwG/smozUt62WIpuMDMxiB0zOooDn
hRTavNtxJHKIOyq5hqncL5lUPMEiajRRCmMTKEY0YWgVoiERPYT8XigtLut6
D/xhKmLexZoQ1/FF1h6n6Hkko26aoCtJQNl1VpTyalp53a3ypVTfbXdwB9Ys
QZPKxiX82HfOV0FelsRbXWIgwiSBR7cGklSRWLlZO53cJYrnlbRJ3kr2FNMY
XgAZjTmkzQrGnFnCiTZcKBaO6Y1UgGQLIh+nyu4qOtlCIz1oIlePPmZ8AQE2
LeHKY8Y+2hVh8xfbDEhpl3MY84/noL9OSTKkPs8XKDjRcrFva9tJ1XNtTS9y
L4oJIu2PCJzOi5gA6BaEd5Ew1dF3IpNW1AJc5qTWljqvkdDZdIfEIixeQ/RA
d/OHSAMwfixZ4uj0ppUb4S/Wz8ZxjoSKkttijoMFn4FIe7Z5L9vZMxKSyK+P
sgBe4uh+MkHJkfZq53ouRgTQjzdU1UJzK5kQADSUwjPKYF0DzIYg4YyNDxI5
GOInLmNEslRIsVijU0iNbNHKK33HSVS1EgQyE0tK3h7vbaapVXZ4DKKisYCG
tx1WxkKzhwltNEsd9Om265WFTCiYhMRNO6pE1QsVC5NzuBLIiyj9UAKIRpRK
5z4ypJAnipA+wiwm82Wag6qPNPCDPCjotbSaF8XnhkKkcrIAH9RF0HZd5jby
TxdKOnFXk5mQvUEoeGBwExnmJUtc3xYHGet+xtpBonJeUWUArTmr+hFHSvH8
QspMwDy1mvKHV3m+YQkHVq41Zoi18jDiAcT4eOkkrT00LirKgUbLXOK+RPPp
qzJbMEvrH5cG3Y4hzgV1VhYOBLoJIDepuCLXaQUidIuWMS61fT+Coh/ZuunW
fOtMEkA8Au4eV8ZCGHID9Fawttu6UFGK+CNLLS/Vh6PY/ppKMvwWYqyCQUJx
Mvbp3nZotlIi1oivWQshBed9DWszlvNed15t9jvfCWdG+w6dZmbd0Mwb21qT
rB07n3iNKxKHK26xLC4jdEJh79DQn2TknSh8FZ0LFjVS00P/EVp+0tKSPTJI
V1l6y99S8AfKb9Rp2w3zxNFfmyRrbtvsAgHQAayq1li2WKy9jF1cRteNpTjW
YcGSbsJF96ecIvrjuQmj4FYBVLMfs3yTRsS4g022JGdpGJ9GPEAP3IH6r+TR
JGV1TqsIkMCUZ1iYkc4yIkXototsAuZu5kXXYAGBLRCSZjonDsQNXlI3chDP
TMN14xSkoFHS30h0Y3hRuWNasGM/2xnRVormVnvouMNvUMR0Il+69Mt9jjVm
TpR4SNdduLMPvkEUn6ThQhSd+y0cB64/jI5glgdAQ3jmrXmFa48PKqfJkcVN
qpFvA0ROW8QT6NL5sfpzg6ROUYBIXWUbRQSRXPrTczfKX+ouND5TGzJbIBMv
7rJGDpd6gUd6MqQ9bNQrEtCBqo5kIdIv8NOQoR7tMAwHc2QMZiSu8eTStgho
uxFE7KVgDIbRJAmGhLbBnGh7DE8OImSRIdgtrCxbdGhNpxmasc7SpoqbUEUJ
U0Ey4eZ5ktPJo5XEZysVAkMuB18EPCSA+AWQKMqDEFbAPViuqHoFDE8WUqmc
1UV31qCsCMUMv1Exve/AYO4R+0OR8r7OjGAfeoYoE6F9LmD9ocvwsl5sqXd6
Ev2uUXIt11kHhI5ZPFtOcDGhP2E+iXtwffVWNPdBhYd3H+mnU8kgnJpEP+o0
1P/khgL00EwExLULsWtGfplvmyWVP2ePE2XcIA0lX0DC+j037eEq/yg/w8Xc
bkB45m4oKIdx+YkseoLotjgrLs3L4kLYZygLz7FtWhbh3HojJmSiB8S6wCwk
KlmM5J7wJAbN7RFbVBI3MlIZSpenuWixXqEU4dUPNM4OxxoW/ZqoJzeE442k
NJ1odf+Ymo3ww9gNhi5lT2h7XiQh0vYUkTxW2vechSgzP2htpYERkJhNW1LS
hjobuGkcME44CpkowWkrCy6blFPQgKTg8cJGsjwCXGQQdh+TFYbIPOxcylrz
deKGilxiBGF7wznGZCNgD4UlvyGoCz2+FDCgtIx0mMqYAtHng2FrrLO1mdnf
IETMXucFGQ7hpGhU5BgJhun56bwXdUauQySUTGUORnDzwFI6PSzi6m1dXufa
TQ8TZxVu5FBha9eecFhyrQAfCm1zXew70V93mFSUeosh3CEvRBhULsj3fUw4
8T9hmnYIE5+EYZl6EPVWc0KQzvaoGKxZheRBDXwUW5UI/lX+tgvRKTs3rM6E
2RAovmYcqLwHVAtSSBFWopK4EdCgLcKTlVeqEI7cbP8t8GEqK9fWYffujt3L
1Q1jkXIrQfb33OD52I4w5aBSUyMmjkqSQe/oXe/oUQ+4LurYL0VCROnCLadk
VuAyER1ZbUToZCuCdWTaVhdDL75zbyhQ6EMuXuynQuIatVX4v33vQjT4Vf4B
Fw9FLmV9jFIuXW2YKhsq2X1p0ewJccGRyba9x9ULefdBqS+qLce3zikJMyTt
m1q/77uvmR/upGhINAvNYDgS1sQSFFSxk9rI19UIVmtRNffB1zarEgIXnTr2
xEKlg710i8TTkNiglUxooMT1E3CBDqkX6hGZuUmZC7HJ+ukYYSEwi3OcWJ+u
hekurkW7Jd+DHnBr7NEUOIoDGEuNi2JhjtHj4fJb7dxe6RivH/0LlL98nYec
n5iblo2ERycqelNwWyUOCQAhuTZ2IxDJiwVVbSYDtKgU2n2qlPZQqMagqLrh
5MB9wd7Rmp8N88XQ9tYmK+fwe865Ht0Eb9YkNkhUDqlPxveCWV9hIy4BTiUJ
+mQ/S/yG0XcXMc2G6ITdKxUfy9kKRXMjVqPUHna4G2SysL6elADnSxzvgtoN
4Mz54glMIukI9Gpwy1NcNc6mmDI5to8RqKZ1HXHVLll1QY190amBRMIC3Tj1
RwGqmVfDRJbf5HXJUtyTEykJDwhQYkvdeBYXETDiqYb6cOcFTqsylGiEcWeh
b49fAENGJVOC5AK6ZOQBWmwp+FdqU+5XGW8nQfTmZK87jpfaLbrkLPuEJ2Z3
jSZ1BaLDVzoQAJtC0g/IzhIw3i99a0gFQjTT+5K4rI15nM1T4awhIqY2cLTk
wPHWTdYUmEiL9C74Nu8gdhQ4w+47n2RGVbUTcVg9uYjONqpAJf2R+gfBpyIO
/zgYB5cNQmTD3MH21MbYQiEFmAzmMEJBOzJmpUo3A8Dd1OxDCq7w0BVBu+64
mAbHzSfVYWTze1SUdB/5F09/eTow8JxbA01MnKWLTrEBkafFQHKkEjRak18A
tUNqcebcMZqqn8U2960/fPfuqpsuzE+3t0fOPQ2Vf7DRYhjCeMM44CCjUETx
Fx1gwVEbjnMgZS5bPFEuC5dR1hi2LS8yWvIbcX3yPl6roU18mu/e/cPr7599
fvroUyz49AYo47t3y/z2lk1p463fYrVY2Ox3OWMTDPn8LYr7sOXvnrfohIKB
/fPvXpy/fH3mX5V5Rjslo63/E/xHaQMOFkRX/EYrn7cSMEq5BeaIiH704EwB
/RjPj9VKTj+VZ2/wmcbcv/zupX45WLR/Vdelf/fREvvO8ptuOp2SKod483SB
3RrKfHlBUHbvzniR+fLrgxWQwPxAvgPE0zfzE/e/ARbqzqQjDQEA

-->

</rfc>
