<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.15 (Ruby 3.3.1) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-mcmillion-key-transparency-02" category="info" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.21.0 -->
  <front>
    <title>Key Transparency</title>
    <seriesInfo name="Internet-Draft" value="draft-mcmillion-key-transparency-02"/>
    <author fullname="Brendan McMillion">
      <organization/>
      <address>
        <email>brendanmcmillion@gmail.com</email>
      </address>
    </author>
    <date year="2024" month="June" day="17"/>
    <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>
            <t><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.</t>
          </li>
          <li>
            <t><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.</t>
          </li>
          <li>
            <t><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.</t>
          </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>
            <t>The client will detect the error immediately and reject the result of an operation, or</t>
          </li>
          <li>
            <t>The client will permanently enter an invalid state.</t>
          </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>
            <t>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.</t>
          </li>
          <li>
            <t>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.</t>
          </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" stroke-linecap="round">
                  <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 the position of an entry in the log to a version counter, where looking up
the search key in the prefix tree in the entry at that position yields the given
version. Users initially populate this map by setting the position of an entry
they've looked up, to map to the version of the key stored in that entry. 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>
              <t>Compute the entry's direct path (in terms of the Implicit Binary Search Tree)
based on the current tree size.</t>
            </li>
            <li>
              <t>If there are no entries in the direct path that are to the right of the
current entry, then skip updating this entry (there's no new information to
update it with).</t>
            </li>
            <li>
              <t>For each entry in the direct path that's to the right of the current entry,
from low to high:
              </t>
              <ol spacing="normal" type="1"><li>
                  <t>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.</t>
                </li>
                <li>
                  <t>If the above check was successful, remove the current position-version pair
from the map and replace it with a position-version pair corresponding to
the entry in the log that was just checked.</t>
                </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>
          <t>A hash algorithm</t>
        </li>
        <li>
          <t>A signature algorithm</t>
        </li>
        <li>
          <t>A Verifiable Random Function (VRF) algorithm</t>
        </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-presentation"><![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-presentation"><![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-presentation"><![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, level)
  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, level):
  return Hash(0x02 || seed || level)
]]></sourcecode>
        <t>The <tt>seed</tt> value is a randomly sampled byte string of 16 bytes and <tt>level</tt> is an
8-bit integer that represents the level of the prefix tree where the stand-in
value is stored.</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-presentation"><![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-presentation"><![CDATA[
struct {
  uint64 tree_size;
  int64 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-presentation"><![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;
  int64 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-presentation"><![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"/>. For individual inclusion proofs, the contents of the
<tt>elements</tt> array is kept in bottom-to-top order. For batch inclusion proofs, 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-presentation"><![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-presentation"><![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-presentation"><![CDATA[
struct {
  PrefixProof prefix_proof;
  opaque commitment<Hash.Nh>;
} ProofStep;

struct {
  uint64 position;
  ProofStep steps<0..2^8-1>;
  InclusionProof inclusion;
} SearchProof;
]]></sourcecode>
        <t>Each <tt>ProofStep</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>ProofStep</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>
            <t>The elements of <tt>steps</tt> represent a monotonic series over the leaves of the
log, and</t>
          </li>
          <li>
            <t>The <tt>steps</tt> array has the expected number of entries (no more or less than
are necessary to execute the binary search).</t>
          </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-presentation"><![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-presentation"><![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>consistency</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>
      <sourcecode type="tls-presentation"><![CDATA[
struct {
  uint64 last;
  optional<uint64> distinguished;
} Consistency;
]]></sourcecode>
      <t>Users may optionally also populate the <tt>distinguished</tt> field to request an
additional consistency proof with a distinguished tree head.</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.</t>
        <sourcecode type="tls-presentation"><![CDATA[
struct {
  opaque search_key<0..2^8-1>;
  optional<uint32> version;
  optional<Consistency> consistency;
} SearchRequest;
]]></sourcecode>
        <t>In turn, the Transparency Log responds with a SearchResponse structure:</t>
        <sourcecode type="tls-presentation"><![CDATA[
struct {
  TreeHead tree_head;
  optional<ConsistencyProof> consistency;
  optional<ConsistencyProof> distinguished;
  select (Configuration.mode) {
    case thirdPartyAuditing:
      AuditorTreeHead auditor_tree_head;
  };
} FullTreeHead;

struct {
  FullTreeHead full_tree_head;
  opaque vrf_proof<0..2^16-1>;
  SearchProof search;

  opaque opening<16>;
  UpdateValue value;
} SearchResponse;
]]></sourcecode>
        <t>If <tt>consistency</tt> is present, then the Transparency Log <bcp14>MUST</bcp14> provide a
consistency proof between the current tree and the tree when it had
<tt>Consistency.last</tt> entries, in the <tt>consistency</tt> field of <tt>FullTreeHead</tt>. If
<tt>consistency</tt> is present, and its <tt>distinguished</tt> field is present, then the
Transparency Log <bcp14>MUST</bcp14> provide a consistency proof between the current tree and
the tree when it had <tt>Consistency.distinguished</tt> entries, in the <tt>distinguished</tt>
field of <tt>FullTreeHead</tt>.</t>
        <t>Users verify a search response by following these steps:</t>
        <ol spacing="normal" type="1"><li>
            <t>Evaluate the VRF proof in <tt>vrf_proof</tt> against the requested search key
<tt>SearchRequest.search_key</tt> to obtain the search index.</t>
          </li>
          <li>
            <t>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.</t>
          </li>
          <li>
            <t>Verify that the commitment in the terminal search step opens to
<tt>SearchResponse.value</tt> with opening <tt>SearchResponse.opening</tt>.</t>
          </li>
          <li>
            <t>With the candidate root value for the tree:
            </t>
            <ol spacing="normal" type="1"><li>
                <t>Verify the proof in <tt>FullTreeHead.consistency</tt>, if one is expected.</t>
              </li>
              <li>
                <t>Verify the signature in <tt>TreeHead.signature</tt>.</t>
              </li>
              <li>
                <t>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.</t>
              </li>
              <li>
                <t>If third-party auditing is used, verify <tt>auditor_tree_head</tt> with the steps
described in <xref target="auditing"/>.</t>
              </li>
            </ol>
          </li>
          <li>
            <t>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.</t>
          </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.</t>
        <sourcecode type="tls-presentation"><![CDATA[
struct {
  opaque search_key<0..2^8-1>;
  opaque value<0..2^32-1>;
  optional<Consistency> consistency;
} 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-presentation"><![CDATA[
struct {
  FullTreeHead full_tree_head;
  opaque vrf_proof<0..2^16-1>;
  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>. 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.</t>
        <sourcecode type="tls-presentation"><![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<Consistency> consistency;
} 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 keys 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>
            <t>Verify that the requested keys in <tt>owned_keys</tt> and <tt>contact_keys</tt> are all
distinct.</t>
          </li>
          <li>
            <t>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.</t>
          </li>
          <li>
            <t>Verify that each <tt>entries</tt> array is sorted in ascending order.</t>
          </li>
          <li>
            <t>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.</t>
          </li>
          <li>
            <t>Verify each entry lies on the direct path of different versions of the key.</t>
          </li>
        </ol>
        <t>If the request is valid, the Transparency Log responds with a MonitorResponse
structure:</t>
        <sourcecode type="tls-presentation"><![CDATA[
struct {
  ProofStep steps<0..2^8-1>;
} MonitorProof;

struct {
  FullTreeHead full_tree_head;
  MonitorProof owned_proofs<0..2^8-1>;
  MonitorProof contact_proofs<0..2^8-1>;
  InclusionProof inclusion;
} 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>
            <t>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>.</t>
          </li>
          <li>
            <t>For each <tt>MonitorProof</tt> structure, 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.</t>
          </li>
          <li>
            <t>Construct a candidate root value for the tree by combining the
<tt>PrefixProof</tt> and commitment of <tt>ProofStep</tt>, with the provided inclusion
proof.</t>
          </li>
          <li>
            <t>Verify that all of the candidate root values are the same. With the candidate
root value, verify <tt>FullTreeHead</tt> as in <xref target="search"/>.</t>
          </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 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>
    <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-presentation"><![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-presentation"><![CDATA[
enum {
  reserved(0),
  newTree(1),
  emptyTree(2),
  differentKey(3),
  sameKey(4),
  (255)
} AuditorProofType;

struct {
  AuditorProofType proof_type;
  select (AuditorProof.proof_type) {
    case newTree:
    case emptyTree:
      opaque old_seed<16>;
    case differentKey:
      NodeValue copath<0..2^8-1>;
      opaque old_seed<16>;
    case sameKey:
      NodeValue copath<0..2^8-1>;
      uint32 counter;
      uint64 position;
  };
} AuditorProof;

enum {
  reserved(0),
  real(1),
  fake(2),
  (255)
} AuditorUpdateType;

struct {
  AuditorUpdateType update_type;
  opaque index<VRF.Nh>;
  opaque seed<16>;
  opaque commitment<Hash.Nh>;
  AuditorProof proof;
} 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 <tt>proof</tt> field
contains a cryptographic proof with the information necessary to compute both
the current prefix tree root value, and the prefix tree root value after the
update has been applied.</t>
        <t>The <tt>AuditorProof</tt> structure represents the result of searching for
<tt>AuditorUpdate.index</tt> in the prefix tree. The <tt>proof_type</tt> field specifies
whether the search results in:</t>
        <ul spacing="normal">
          <li>
            <t><tt>newTree</tt>: no search was done because this is the first modification to the tree.</t>
          </li>
          <li>
            <t><tt>emptyTree</tt>: no search was done because there are no populated leaf nodes in
the prefix tree, though there's a stand-in value for the root which can be
computed with <tt>old_seed</tt>.</t>
          </li>
          <li>
            <t><tt>differentKey</tt>: the search terminates at a stand-in value in the copath of
another key. The copath for <tt>AuditorUpdate.index</tt>, up to and including the
first bit difference between the two keys, is given in <tt>copath</tt>. The seed for
computing the stand-in value is provided in <tt>old_seed</tt>.</t>
          </li>
          <li>
            <t><tt>sameKey</tt>: the search terminates at a populated leaf node for
<tt>AuditorUpdate.index</tt>. The copath (excluding stand-in values, which can be
computed with <tt>AuditorUpdate.seed</tt>) is given in <tt>copath</tt>. The <tt>version</tt> and
<tt>position</tt> fields of the leaf node are also given.</t>
          </li>
        </ul>
        <t>An auditor processes a single <tt>AuditorUpdate</tt> by following these steps:</t>
        <ol spacing="normal" type="1"><li>
            <t>Evaluate the provided <tt>AuditorProof</tt> and verify that it's consistent with the
current prefix tree root.</t>
          </li>
          <li>
            <t>Use the information in the proof, along with <tt>AuditorUpdate.seed</tt>, to
determine the new prefix tree root. The auditor <bcp14>MUST</bcp14> return an error and
refuse to continue if the <tt>proof_type</tt> field is <tt>sameKey</tt> but the
<tt>update_type</tt> is <tt>fake</tt>.</t>
          </li>
          <li>
            <t>Combine the new prefix tree root with the provided <tt>commitment</tt> to produce
the leaf hash value.</t>
          </li>
          <li>
            <t>Combine the leaf hash value with the current log root to produce the new log
root.</t>
          </li>
        </ol>
        <t>With all <tt>AuditorUpdate</tt> structures processed, 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 an
<tt>AuditorTreeHead</tt> struct:</t>
        <sourcecode type="tls-presentation"><![CDATA[
struct {
  opaque root_value<Hash.Nh>;
  ConsistencyProof consistency;
} AuditorContext;

struct {
  TreeHead tree_head;
  optional<AuditorContext> context;
} AuditorTreeHead;
]]></sourcecode>
        <t>The <tt>context</tt> field is populated when the <tt>tree_size</tt> of the auditor's
<tt>TreeHead</tt> is less than the size of the most recent <tt>TreeHead</tt> provied to the
user by the service provider. 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>
            <t>Verify the signature in <tt>TreeHead.signature</tt>.</t>
          </li>
          <li>
            <t>Verify that <tt>TreeHead.timestamp</tt> is sufficiently recent.</t>
          </li>
          <li>
            <t>Verify that <tt>TreeHead.tree_size</tt> is less than or equal to, and sufficiently
close to the most recent tree head from the service operator.</t>
          </li>
          <li>
            <t>If required, verify the consistency proof <tt>AuditorContext.consistency</tt>
between this tree head and the most recent tree head from the service operator.</t>
          </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>, for
example by looking up a well-known key. The user then sends the root hash of the
<tt>TreeHead</tt> 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 root hash 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>.
They then send the same request, omitting any identifying information and
leaving the <tt>consistency</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>
            <t>If all logs behave honestly, then users observe a globally-consistent view of
the data associated with each key.</t>
          </li>
          <li>
            <t>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.</t>
          </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>
            <t>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.</t>
          </li>
          <li>
            <t>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.</t>
          </li>
          <li>
            <t>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).</t>
          </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>
            <t>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.</t>
          </li>
          <li>
            <t>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.</t>
          </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>
          <t>KT Ciphersuites (<xref target="kt-ciphersuites"/>)</t>
        </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-presentation"><![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 anchor="sec-normative-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="DOI" value="10.17487/rfc2104"/>
          <refcontent>RFC Editor</refcontent>
        </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="DOI" value="10.17487/rfc6962"/>
          <refcontent>RFC Editor</refcontent>
        </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"/>
            <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"/>
            <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"/>
            <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"/>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <author fullname="T. Narten" initials="T." surname="Narten"/>
            <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 anchor="sec-informative-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 1616?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA72963bcRpYm+j+eAi2vdUSyM2lR8q1ULs/Isl3W+CKPJZer
1sy0CWaCJEqZQHYCKSpbrX6W8yznyc7+9iViB4Ck6OqZqdVdRSWAuOzYse+X
+Xwe+rpfVY+Le99V++Lltmy6TbmtmsX+XliUfXXVbvePi7q5bENYtoumXNO7
y2152c/Xi3W9WtVtM39V7ee9+3T+4GHodhfruuvocb/f0DfPvn75TWh264tq
+zgsaeTHYdE2XdV0u+5x0W93VXj9uHgUaITycfHi66fhpt2+utq2u83j4ruX
xa/0r7q5Kv6MXwLNSI+Xj0MxL6pmOe/bOf0P/bnY7jc9TYoH5WaDZ22z2her
9ip8ULyumh1N/EFRFDryr3/mf8ka8znw+7qsV3jpv1ZvyvVmVZ0u2jU/KLeL
68fFdd9vuscffuiefqgjXtX99e7icfHLi69//vDnr396zr+uaONdP/3h909e
fv3iZQjlrr9ut9haoC+Ky91qJWD/koC7LJvih8UPAnh+XskaL+RhPJT/eoXf
eb2habfrsq9f09aL4udvnj48e/DR4+Kr589Ozx6cnn360Weffqi/yvNP/vDJ
w/Fz/BoCUMGN9kO1fbWqHj7mpfTl9qryu9ts66Y/rcvF9rTdXn348MHDsw8/
+viRvKx4JyP8C034pPi+vZl/TyAiHMpwkR5cFS/2XV+t7/HHjEAFxps/+Gj+
4DP+MQKO/zMvBGp/2zWEaFfFt7vBg+9qguW3bdtdr8tmOXj4bbmtX5XFd+Wq
Xl7XzbIePH9R7WjM/1Y3xd/K5mrw8OdytVuUxZNlWfzUbsoQ5nPCxouO7sii
D+HX63pVFf11ta0Ij6qiq15X23JVEGaUF6u6u66WxWbb9u2iXXUFgXsaxWdh
W634IIDfdU/gLMqegIeHxXXZFRdV1RAiEtYXfUvTLHZbvLusaSX1xa4HrtMy
ePhdV23DZkfzLwq6XTJvt1tcuxlPiyddURbbqtut+hk+7Sq3UuylvaQFFF1P
SBhe71YNbewCm22Lqnxddcttu9lg2ot9QbCgpWHJ5eJVte1OiyEJKmpMZxME
rChbO6hHzYPwCturbbm5pvVHHCUgyR4IGG5vM3qjKMNNuac9lD1taFXTMvdF
VeNUaEY6kabv6LW+2l5WWAxtjWav+mpBv/NXdV+0CwLplo6Lx+vrNcBL2ETb
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
oLjKNsKNPQpi7TqQjsS+BeJDsV91SP1ShuuOk6pS7zFEWlDGEJsmRPl+iAmn
xfdI5485e7M4rFAPpt5mTojS2QEVQzSrmCBsiSdqq1pZnNKbPga37MO4EhZS
UyG+lpIodgBUC1ZIAStVScIEaGCLkAhDLbk4cbOLL4kPcw29ro27D7fsXq9u
HIuVW814vOMGX07tCPmfjZkakRGuGZ+Dow+Do4ce8LpuU58fTdHhC7ecs1lB
yon0bLVRoVOsCN6T51u0jN3YIbzgOKPfc/FSHyAW17gDyP/pexez8V5Vv+Pi
QeQy1icoFfLVxqnKsZI9lBbdnoALgU223R2uXqr/YEo9Qho7cfwHX+LBFXh4
330ti/FO6i2LZikgnTORnDO95vKk67rjj8ZYbQXswu++tmWTEbjo1An+xGJR
jIN0i8XTmFhqFW94oMz1E3GBD2kQ65CYudW11dAFzg2zT6cIC4NZvcPM+mwt
QnexFmtNfgd6ID3pJ+sRsCN8qk5BEgsrZO/Fy++1c3+lU75k8i8QieAQBEvA
ToUCyon0tExF39bSDkx84iQkt85uRCJ5veAywWyAVpXCuqattK0Z1BiIqhup
1HAo2S5Z88tx8j5sb122ckl/lNp1k5uQzbrEUg1LYfXJ+V6Qgh83EjLgNFp5
g+1nmd8w+e4SpvkYlbh7o+JTCfSxQnDCakjtcYf7USax6OtZ3Re5xOkumN2A
zlwuXqqap6Qj0qvRLc9x1TmbUv2KqX1MQDWrocmySshWXXPnbDg1QCQ80J2b
fRKgKeVpmEj8q76uJSMOFKjQhFMAlNlSP51FzwSMeaqjPpL/KGntjhJNMO4y
tpgqFsSQoWRqlFhEl5I9QIsdxw5rHdDDKuO7WRS9Jdn+luPlfqEhO8sh4UnZ
9ZNJ9ZHoyJWOBMCn8A7jucsMjHdLnx9TgRjO874kem9jnmbzXGBtjIi5DRyW
HDredltua1Q1Ab2Lvs1biB3Hq4j7Lu5V87CDisPmyQU6+6gCk/THgbKn0acS
859sMImuGoWWxrmj7alLwXVKCpCMHxChYI1ECWvLbhpwN634kKIrPLaAsGZQ
IZUhkFRDcxj5/GoTJcMHxbMnPz4ZGXheegNNqmLCF51jAxJPS4kxoBI82ra6
ImoHavE4hBOYqp/WGzg4dzWshEdv377q5wv307t3xyE8iRWj0CA0DuG8YRJw
UHIsnvqL7qGgrA/RuqelSzucqJQPLDlrnw76dV3ykl+o61P28bMZ2tSn+fbt
P/38zdPPzh5+gtpgL4gyvn27rN69E1PadMvCVJmXNvtVJdhEQ379BuI+bfmr
rzs4oWjg4uuvnr18/vPj4qdVVfJO2Whb/JX+Y7QBg0XRFd9YmfdOIyY5NcEd
EdOPAZwPJAIgN/rsE33zBd60YPvnXz23cUZbKH5q21Xx9oMl2ijLm2E+n7Ni
Byx6skCY2qpaXjHMw9vHsuRq+ad7l0QQq3v6HaGhvVmdhv8fhE2bSOkQAQA=

-->

</rfc>
