<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.6.39 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-irtf-cfrg-vdaf-07" category="info" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.18.0 -->
  <front>
    <title abbrev="VDAF">Verifiable Distributed Aggregation Functions</title>
    <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-vdaf-07"/>
    <author initials="R. L." surname="Barnes" fullname="Richard L. Barnes">
      <organization>Cisco</organization>
      <address>
        <email>rlb@ipv.sx</email>
      </address>
    </author>
    <author initials="D." surname="Cook" fullname="David Cook">
      <organization>ISRG</organization>
      <address>
        <email>divergentdave@gmail.com</email>
      </address>
    </author>
    <author initials="C." surname="Patton" fullname="Christopher Patton">
      <organization>Cloudflare</organization>
      <address>
        <email>chrispatton+ietf@gmail.com</email>
      </address>
    </author>
    <author initials="P." surname="Schoppmann" fullname="Phillipp Schoppmann">
      <organization>Google</organization>
      <address>
        <email>schoppmann@google.com</email>
      </address>
    </author>
    <date year="2023" month="August" day="31"/>
    <area>IRTF</area>
    <workgroup>CFRG</workgroup>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <?line 182?>

<t>This document describes Verifiable Distributed Aggregation Functions (VDAFs), a
family of multi-party protocols for computing aggregate statistics over user
measurements. These protocols are designed to ensure that, as long as at least
one aggregation server executes the protocol honestly, individual measurements
are never seen by any server in the clear. At the same time, VDAFs allow the
servers to detect if a malicious or misconfigured client submitted an
measurement that would result in an invalid aggregate result.</t>
    </abstract>
    <note removeInRFC="true">
      <name>Discussion Venues</name>
      <t>Discussion of this document takes place on the
    Crypto Forum Research Group mailing list (cfrg@ietf.org),
    which is archived at <eref target="https://mailarchive.ietf.org/arch/search/?email_list=cfrg"/>.</t>
      <t>Source for this draft and an issue tracker can be found at
    <eref target="https://github.com/cjpatton/vdaf"/>.</t>
    </note>
  </front>
  <middle>
    <?line 192?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>[TO BE REMOVED BY RFC EDITOR: The source for this draft and and the reference
implementation can be found at https://github.com/cfrg/draft-irtf-cfrg-vdaf.]</t>
      <t>The ubiquity of the Internet makes it an ideal platform for measurement of
large-scale phenomena, whether public health trends or the behavior of computer
systems at scale. There is substantial overlap, however, between information
that is valuable to measure and information that users consider private.</t>
      <t>For example, consider an application that provides health information to users.
The operator of an application might want to know which parts of their
application are used most often, as a way to guide future development of the
application.  Specific users' patterns of usage, though, could reveal sensitive
things about them, such as which users are researching a given health condition.</t>
      <t>In many situations, the measurement collector is only interested in aggregate
statistics, e.g., which portions of an application are most used or what
fraction of people have experienced a given disease.  Thus systems that provide
aggregate statistics while protecting individual measurements can deliver the
value of the measurements while protecting users' privacy.</t>
      <t>Most prior approaches to this problem fall under the rubric of "differential
privacy (DP)" <xref target="Dwo06"/>. Roughly speaking, a data aggregation system that is
differentially private ensures that the degree to which any individual
measurement influences the value of the aggregate result can be precisely
controlled. For example, in systems like RAPPOR <xref target="EPK14"/>, each user samples
noise from a well-known distribution and adds it to their measurement before
submitting to the aggregation server. The aggregation server then adds up the
noisy measurements, and because it knows the distribution from whence the noise
was sampled, it can estimate the true sum with reasonable precision.</t>
      <t>Differentially private systems like RAPPOR are easy to deploy and provide a
useful guarantee. On its own, however, DP falls short of the strongest privacy
property one could hope for. Specifically, depending on the "amount" of noise a
client adds to its measurement, it may be possible for a curious aggregator to
make a reasonable guess of the measurement's true value. Indeed, the more noise
the clients add, the less reliable will be the server's estimate of the output.
Thus systems employing DP techniques alone must strike a delicate balance
between privacy and utility.</t>
      <t>The ideal goal for a privacy-preserving measurement system is that of secure
multi-party computation (MPC): No participant in the protocol should learn
anything about an individual measurement beyond what it can deduce from the
aggregate. In this document, we describe Verifiable Distributed Aggregation
Functions (VDAFs) as a general class of protocols that achieve this goal.</t>
      <t>VDAF schemes achieve their privacy goal by distributing the computation of the
aggregate among a number of non-colluding aggregation servers. As long as a
subset of the servers executes the protocol honestly, VDAFs guarantee that no
measurement is ever accessible to any party besides the client that submitted
it. At the same time, VDAFs are "verifiable" in the sense that malformed
measurements that would otherwise garble the result of the computation can be
detected and removed from the set of measurements. We refer to this property as
"robustness".</t>
      <t>In addition to these MPC-style security goals of privacy and robustness, VDAFs
can be composed with various mechanisms for differential privacy, thereby
providing the added assurance that the aggregate result itself does not leak
too much information about any one measurement.</t>
      <ul empty="true">
        <li>
          <t>TODO(issue #94) Provide guidance for local and central DP and point to it
here.</t>
        </li>
      </ul>
      <t>The cost of achieving these security properties is the need for multiple servers
to participate in the protocol, and the need to ensure they do not collude to
undermine the VDAF's privacy guarantees.  Recent implementation experience has
shown that practical challenges of coordinating multiple servers can be
overcome.  The Prio system <xref target="CGB17"/> (essentially a VDAF) has been deployed in
systems supporting hundreds of millions of users: The Mozilla Origin Telemetry
project <xref target="OriginTelemetry"/> and the Exposure Notification Private Analytics
collaboration among the Internet Security Research Group (ISRG), Google, Apple,
and others <xref target="ENPA"/>.</t>
      <t>The VDAF abstraction laid out in <xref target="vdaf"/> represents a class of multi-party
protocols for privacy-preserving measurement proposed in the literature. These
protocols vary in their operational and security requirements, sometimes in
subtle but consequential ways. This document therefore has two important goals:</t>
      <ol spacing="normal" type="1"><li>
          <t>Providing higher-level protocols like <xref target="DAP"/> with
a simple, uniform interface for accessing privacy-preserving measurement
schemes, documenting relevant operational and security requirements, and
specifying constraints for safe usage:  </t>
          <ol spacing="normal" type="1"><li>General patterns of communications among the various actors involved in
the system (clients, aggregation servers, and the collector of the
aggregate result);</li>
            <li>Capabilities of a malicious coalition of servers attempting to divulge
information about client measurements; and</li>
            <li>Conditions that are necessary to ensure that malicious clients cannot
corrupt the computation.</li>
          </ol>
        </li>
        <li>Providing cryptographers with design criteria that provide a clear
deployment roadmap for new constructions.</li>
      </ol>
      <t>This document also specifies two concrete VDAF schemes, each based on a protocol
from the literature.</t>
      <ul spacing="normal">
        <li>
          <t>The aforementioned Prio system <xref target="CGB17"/> allows for the privacy-preserving
computation of a variety aggregate statistics. The basic idea underlying Prio
is fairly simple:
          </t>
          <ol spacing="normal" type="1"><li>Each client shards its measurement into a sequence of additive shares and
distributes the shares among the aggregation servers.</li>
            <li>Next, each server adds up its shares locally, resulting in an additive
share of the aggregate.</li>
            <li>Finally, the aggregation servers send their aggregate shares to the data
collector, who combines them to obtain the aggregate result.</li>
          </ol>
          <t>
The difficult part of this system is ensuring that the servers hold shares of
a valid, aggregatable value, e.g., the measurement is an integer in a
specific range. Thus Prio specifies a multi-party protocol for accomplishing
this task.  </t>
          <t>
In <xref target="prio3"/> we describe Prio3, a VDAF that follows the same overall framework
as the original Prio protocol, but incorporates techniques introduced in
<xref target="BBCGGI19"/> that result in significant performance gains.</t>
        </li>
        <li>
          <t>More recently, Boneh et al. <xref target="BBCGGI21"/> described a protocol called Poplar
for solving the <tt>t</tt>-heavy-hitters problem in a privacy-preserving manner. Here
each client holds a bit-string of length <tt>n</tt>, and the goal of the aggregation
servers is to compute the set of strings that occur at least <tt>t</tt> times. The
core primitive used in their protocol is a specialized Distributed Point
Function (DPF) <xref target="GI14"/> that allows the servers to "query" their DPF shares on
any bit-string of length shorter than or equal to <tt>n</tt>. As a result of this
query, each of the servers has an additive share of a bit indicating whether
the string is a prefix of the client's string. The protocol also specifies a
multi-party computation for verifying that at most one string among a set of
candidates is a prefix of the client's string.  </t>
          <t>
In <xref target="poplar1"/> we describe a VDAF called Poplar1 that implements this
functionality.</t>
        </li>
      </ul>
      <t>Finally, perhaps the most complex aspect of schemes like Prio3 and Poplar1 is
the process by which the client-generated measurements are prepared for
aggregation. Because these constructions are based on secret sharing, the
servers will be required to exchange some amount of information in order to
verify the measurement is valid and can be aggregated. Depending on the
construction, this process may require multiple round trips over the network.</t>
      <t>There are applications in which this verification step may not be necessary,
e.g., when the client's software is run a trusted execution environment. To
support these applications, this document also defines Distributed Aggregation
Functions (DAFs) as a simpler class of protocols that aim to provide the same
privacy guarantee as VDAFs but fall short of being verifiable.</t>
      <ul empty="true">
        <li>
          <t>OPEN ISSUE Decide if we should give one or two example DAFs. There are natural
variants of Prio3 and Poplar1 that might be worth describing.</t>
        </li>
      </ul>
      <t>The remainder of this document is organized as follows: <xref target="overview"/> gives a
brief overview of DAFs and VDAFs; <xref target="daf"/> defines the syntax for DAFs; <xref target="vdaf"/>
defines the syntax for VDAFs; <xref target="prelim"/> defines various functionalities that
are common to our constructions; <xref target="prio3"/> describes the Prio3 construction;
<xref target="poplar1"/> describes the Poplar1 construction; and <xref target="security"/> enumerates the
security considerations for VDAFs.</t>
      <section anchor="change-log">
        <name>Change Log</name>
        <t>(*) Indicates a change that breaks wire compatibility with the previous draft.</t>
        <t>07:</t>
        <ul spacing="normal">
          <li>Rename PRG to XOF ("eXtendable Output Function"). Accordingly, rename PrgSha3
to XofShake128 and PrgFixedKeyAes128 to XofFixedKeyAes128. "PRG" is a misnomer
since we don't actually treat this object as a pseudorandom generator in
existing security analysis.</li>
          <li>Replace cSHAKE128 with SHAKE128, re-implementing domain separation for the
customization string using a simpler scheme. This change addresses the
reality that implementations of cSHAKE128 are less common. (*)</li>
          <li>Define a new VDAF, called Prio3SumVec, that generalizes Prio3Sum to a vector
of summands.</li>
          <li>Prio3Histogram: Update the codepoint and use the parallel sum optimization
introduced by Prio3SumVec to reduce the proof size. (*)</li>
          <li>Daf, Vdaf: Rename interface methods to match verbiage in the draft.</li>
          <li>Daf: Align with Vdaf by adding a nonce to <tt>shard()</tt> and <tt>prep()</tt>.</li>
          <li>Vdaf: Have <tt>prep_init()</tt> compute the first prep share. This change is
intended to simplify the interface by making the input to <tt>prep_next()</tt> not
optional.</li>
          <li>Prio3: Split sharding into two auxiliary functions, one for sharding with
joint randomness and another without. This change is intended to improve
readability.</li>
          <li>Fix bugs in the ping-pong interface discovered after implementing it.</li>
        </ul>
        <t>06:</t>
        <ul spacing="normal">
          <li>Vdaf: Define a wrapper interface for preparation that is suitable for the
"ping-pong" topology in which two Aggregators exchange messages over a
request/response protocol, like HTTP, and take turns executing the
computation until input from the peer is required.</li>
          <li>Prio3Histogram: Generalize the measurement type so that the histogram can be
used more easily with discrete domains. (*)</li>
          <li>Daf, Vdaf: Change the aggregation parameter validation algorithm to take the
set of previous parameters rather than a list. (The order of the parameters
is irrelevant.)</li>
          <li>Daf, Vdaf, Idpf: Add parameter <tt>RAND_SIZE</tt> that specifies the number of
random bytes consumed by the randomized algorithm (<tt>shard()</tt> for Daf and Vdaf
and <tt>gen()</tt> for Idpf).</li>
        </ul>
        <t>05:</t>
        <ul spacing="normal">
          <li>IdpfPoplar: Replace XofShake128 with XofFixedKeyAes128, a fixed-key mode for
AES-128 based on a construction from <xref target="GKWWY20"/>. This change is intended to
improve performance of IDPF evaluation. Note that the new XOF is not suitable
for all applications. (*)</li>
          <li>Idpf: Add a binder string to the key-generation and evaluation algorithms.
This is used to plumb the nonce generated by the Client to the XOF.</li>
          <li>Plumb random coins through the interface of randomized algorithms.
Specifically, add a random input to (V)DAF sharding algorithm and IDPF
key-generation algorithm and require implementations to specify the length of
the random input. Accordingly, update Prio3, Poplar1, and IdpfPoplar to match
the new interface. This change is intended to improve coverage of test
vectors.</li>
          <li>Use little-endian byte-order for field element encoding. (*)</li>
          <li>Poplar1: Move the last step of sketch evaluation from <tt>prep_next()</tt> to
<tt>prep_shares_to_prep()</tt>.</li>
        </ul>
        <t>04:</t>
        <ul spacing="normal">
          <li>Align security considerations with the security analysis of <xref target="DPRS23"/>.</li>
          <li>Vdaf: Pass the nonce to the sharding algorithm.</li>
          <li>Vdaf: Rather than allow the application to choose the nonce length, have each
implementation of the Vdaf interface specify the expected nonce length. (*)</li>
          <li>Xof: Split "info string" into two components: the "customization string",
intended for domain separation; and the "binder string", used to bind the
output to ephemeral values, like the nonce, associated with execution of a
(V)DAF.</li>
          <li>Replace XofAes128 with XofShake128, an implementation of the Xof interface based
on SHA-3, and use the new scheme as the default. Accordingly, replace
Prio3Aes128Count with Prio3Count, Poplar1Aes128 with Poplar1, and so on. SHA-3
is a safer choice for instantiating a random oracle, which is used in the
analysis of Prio3 of <xref target="DPRS23"/>. (*)</li>
          <li>Prio3, Poplar1: Ensure each invocation of the Xof uses a distinct
customization string, as suggested by <xref target="DPRS23"/>. This is intended to make
domain separation clearer, thereby simplifying security analysis. (*)</li>
          <li>Prio3: Replace "joint randomness hints" sent in each input share with "joint
randomness parts" sent in the public share. This reduces communication
overhead when the number of shares exceeds two. (*)</li>
          <li>Prio3: Bind nonce to joint randomness parts. This is intended to address
birthday attacks on robustness pointed out by <xref target="DPRS23"/>. (*)</li>
          <li>Poplar1: Use different Xof invocations for producing the correlated randomness
for inner and leaf nodes of the IDPF tree. This is intended to simplify
implementations. (*)</li>
          <li>Poplar1: Don't bind the candidate prefixes to the verifier randomness. This is
intended to improve performance, while not impacting security. According to
the analysis of <xref target="DPRS23"/>, it is necessary to restrict Poplar1 usage such
that no report is aggregated more than once at a given level of the IDPF tree;
otherwise, attacks on privacy may be possible. In light of this restriction,
there is no added benefit of binding to the prefixes themselves. (*)</li>
          <li>Poplar1: During preparation, assert that all candidate prefixes are unique
and appear in order. Uniqueness is required to avoid erroneously rejecting a
valid report; the ordering constraint ensures the uniqueness check can be
performed efficiently. (*)</li>
          <li>Poplar1: Increase the maximum candidate prefix count in the encoding of the
aggregation parameter. (*)</li>
          <li>Poplar1: Bind the nonce to the correlated randomness derivation. This is
intended to provide defense-in-depth by ensuring the Aggregators reject the
report if the nonce does not match what the Client used for sharding. (*)</li>
          <li>Poplar1: Clarify that the aggregation parameter encoding is <bcp14>OPTIONAL</bcp14>.
Accordingly, update implementation considerations around cross-aggregation
state.</li>
          <li>IdpfPoplar: Add implementation considerations around branching on the values
of control bits.</li>
          <li>IdpfPoplar: When decoding the the control bits in the public share, assert
that the trailing bits of the final byte are all zero. (*)</li>
        </ul>
        <t>03:</t>
        <ul spacing="normal">
          <li>Define codepoints for (V)DAFs and use them for domain separation in Prio3 and
Poplar1. (*)</li>
          <li>Prio3: Align joint randomness computation with revised paper <xref target="BBCGGI19"/>.
This change mitigates an attack on robustness. (*)</li>
          <li>Prio3: Remove an intermediate XOF evaluation from query randomness generation.
(*)</li>
          <li>Add additional guidance for choosing FFT-friendly fields.</li>
        </ul>
        <t>02:</t>
        <ul spacing="normal">
          <li>Complete the initial specification of Poplar1.</li>
          <li>Extend (V)DAF syntax to include a "public share" output by the Client and
distributed to all of the Aggregators. This is to accommodate "extractable"
IDPFs as required for Poplar1. (See <xref target="BBCGGI21"/>, Section 4.3 for details.)</li>
          <li>Extend (V)DAF syntax to allow the unsharding step to take into account the
number of measurements aggregated.</li>
          <li>Extend FLP syntax by adding a method for decoding the aggregate result from a
vector of field elements. The new method takes into account the number of
measurements.</li>
          <li>Prio3: Align aggregate result computation with updated FLP syntax.</li>
          <li>Xof: Add a method for statefully generating a vector of field elements.</li>
          <li>Field: Require that field elements are fully reduced before decoding. (*)</li>
          <li>Define new field Field255.</li>
        </ul>
        <t>01:</t>
        <ul spacing="normal">
          <li>Require that VDAFs specify serialization of aggregate shares.</li>
          <li>Define Distributed Aggregation Functions (DAFs).</li>
          <li>Prio3: Move proof verifier check from <tt>prep_next()</tt> to
<tt>prep_shares_to_prep()</tt>. (*)</li>
          <li>Remove public parameter and replace verification parameter with a
"verification key" and "Aggregator ID".</li>
        </ul>
      </section>
    </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?>

<t>Algorithms in this document are written in Python 3. Type hints are used to
define input and output types. A fatal error in a program (e.g., failure to
parse one of the function parameters) is usually handled by raising an
exception.</t>
      <t>A variable with type <tt>Bytes</tt> is a byte string. This document defines several
byte-string constants. When comprised of printable ASCII characters, they are
written as Python 3 byte-string literals (e.g., <tt>b'some constant string'</tt>).</t>
      <t>A global constant <tt>VERSION</tt> of type <tt>Unsigned</tt> is defined, which algorithms are
free to use as desired. Its value <bcp14>SHALL</bcp14> be <tt>7</tt>.</t>
      <t>This document describes algorithms for multi-party computations in which the
parties typically communicate over a network. Wherever a quantity is defined
that must be be transmitted from one party to another, this document prescribes
a particular encoding of that quantity as a byte string.</t>
      <ul empty="true">
        <li>
          <t>OPEN ISSUE It might be better to not be prescriptive about how quantities are
encoded on the wire. See issue #58.</t>
        </li>
      </ul>
      <t>Some common functionalities:</t>
      <ul spacing="normal">
        <li>
          <tt>zeros(len: Unsigned) -&gt; Bytes</tt> returns an array of zero bytes. The length of
<tt>output</tt> <bcp14>MUST</bcp14> be <tt>len</tt>.</li>
        <li>
          <tt>gen_rand(len: Unsigned) -&gt; Bytes</tt> returns an array of random bytes. The
length of <tt>output</tt> <bcp14>MUST</bcp14> be <tt>len</tt>.</li>
        <li>
          <tt>byte(int: Unsigned) -&gt; Bytes</tt> returns the representation of <tt>int</tt> as a byte
string. The value of <tt>int</tt> <bcp14>MUST</bcp14> be in <tt>[0,256)</tt>.</li>
        <li>
          <tt>concat(parts: Vec[Bytes]) -&gt; Bytes</tt> returns the concatenation of the input
byte strings, i.e., <tt>parts[0] || ... || parts[len(parts)-1]</tt>.</li>
        <li>
          <tt>front(length: Unsigned, vec: Vec[Any]) -&gt; (Vec[Any], Vec[Any])</tt> splits <tt>vec</tt>
into two vectors, where the first vector is made up of the first <tt>length</tt>
elements of the input. I.e., <tt>(vec[:length], vec[length:])</tt>.</li>
        <li>
          <tt>xor(left: Bytes, right: Bytes) -&gt; Bytes</tt> returns the bitwise XOR of <tt>left</tt>
and <tt>right</tt>. An exception is raised if the inputs are not the same length.</li>
        <li>
          <tt>to_be_bytes(val: Unsigned, length: Unsigned) -&gt; Bytes</tt> converts <tt>val</tt> to
big-endian bytes; its value <bcp14>MUST</bcp14> be in range <tt>[0, 2^(8*length))</tt>. Function
<tt>from_be_bytes(encoded: Bytes) -&gt; Unsigned</tt> computes the inverse.</li>
        <li>
          <tt>to_le_bytes(val: Unsigned, length: Unsigned) -&gt; Bytes</tt> converts <tt>val</tt> to
little-endian bytes; its value <bcp14>MUST</bcp14> be in range <tt>[0, 2^(8*length))</tt>. Function
<tt>from_le_bytes(encoded: Bytes) -&gt; Unsigned</tt> computes the inverse.</li>
        <li>
          <tt>next_power_of_2(n: Unsigned) -&gt; Unsigned</tt> returns the smallest integer
greater than or equal to <tt>n</tt> that is also a power of two.</li>
        <li>
          <tt>additive_secret_share(vec: Vec[Field], num_shares: Unsigned, field: type)
-&gt; Vec[Vec[Field]]</tt> takes a vector of field elements and returns multiple
vectors of the same length, such that they all add up to the input vector,
and each proper subset of the vectors are indistinguishable from random.</li>
      </ul>
    </section>
    <section anchor="overview">
      <name>Overview</name>
      <figure anchor="overall-flow">
        <name>Overall data flow of a (V)DAF</name>
        <artwork><![CDATA[
                 +--------------+
           +---->| Aggregator 0 |----+
           |     +--------------+    |
           |             ^           |
           |             |           |
           |             V           |
           |     +--------------+    |
           | +-->| Aggregator 1 |--+ |
           | |   +--------------+  | |
+--------+-+ |           ^         | +->+-----------+
| Client |---+           |         +--->| Collector |--> Aggregate
+--------+-+                         +->+-----------+
           |            ...          |
           |                         |
           |             |           |
           |             V           |
           |    +----------------+   |
           +--->| Aggregator N-1 |---+
                +----------------+

      Input shares           Aggregate shares
]]></artwork>
      </figure>
      <t>In a DAF- or VDAF-based private measurement system, we distinguish three types
of actors: Clients, Aggregators, and Collectors.  The overall flow of the
measurement process is as follows:</t>
      <ul spacing="normal">
        <li>To submit an individual measurement, the Client shards the measurement into
"input shares" and sends one input share to each Aggregator. We sometimes
refer to this sequence of input shares collectively as the Client's "report".</li>
        <li>
          <t>The Aggregators refine their input shares into "output shares".
          </t>
          <ul spacing="normal">
            <li>Output shares are in one-to-one correspondence with the input shares.</li>
            <li>Just as each Aggregator receives one input share of each measurement, if
this process succeeds, then each aggregator holds one output share.</li>
            <li>In VDAFs, Aggregators will need to exchange information among themselves
as part of the validation process.</li>
          </ul>
        </li>
        <li>Each Aggregator combines the output shares in the batch to compute the
"aggregate share" for that batch, i.e., its share of the desired aggregate
result.</li>
        <li>The Aggregators submit their aggregate shares to the Collector, who combines
them to obtain the aggregate result over the batch.</li>
      </ul>
      <t>Aggregators are a new class of actor relative to traditional measurement systems
where Clients submit measurements to a single server.  They are critical for
both the privacy properties of the system and, in the case of VDAFs, the
correctness of the measurements obtained.  The privacy properties of the system
are assured by non-collusion among Aggregators, and Aggregators are the entities
that perform validation of Client measurements.  Thus Clients trust Aggregators
not to collude (typically it is required that at least one Aggregator is
honest), and Collectors trust Aggregators to correctly run the protocol.</t>
      <t>Within the bounds of the non-collusion requirements of a given (V)DAF instance,
it is possible for the same entity to play more than one role.  For example, the
Collector could also act as an Aggregator, effectively using the other
Aggregator(s) to augment a basic client-server protocol.</t>
      <t>In this document, we describe the computations performed by the actors in this
system. It is up to the higher-level protocol making use of the (V)DAF to
arrange for the required information to be delivered to the proper actors in the
proper sequence. In general, we assume that all communications are confidential
and mutually authenticated, with the exception that Clients submitting
measurements may be anonymous.</t>
    </section>
    <section anchor="daf">
      <name>Definition of DAFs</name>
      <t>By way of a gentle introduction to VDAFs, this section describes a simpler class
of schemes called Distributed Aggregation Functions (DAFs). Unlike VDAFs, DAFs
do not provide verifiability of the computation. Clients must therefore be
trusted to compute their input shares correctly. Because of this fact, the use
of a DAF is <bcp14>NOT RECOMMENDED</bcp14> for most applications. See <xref target="security"/> for
additional discussion.</t>
      <t>A DAF scheme is used to compute a particular "aggregation function" over a set
of measurements generated by Clients. Depending on the aggregation function, the
Collector might select an "aggregation parameter" and disseminates it to the
Aggregators. The semantics of this parameter is specific to the aggregation
function, but in general it is used to represent the set of "queries" that can
be made on the measurement set. For example, the aggregation parameter is used
to represent the candidate prefixes in Poplar1 <xref target="poplar1"/>.</t>
      <t>Execution of a DAF has four distinct stages:</t>
      <ul spacing="normal">
        <li>Sharding - Each Client generates input shares from its measurement and
distributes them among the Aggregators.</li>
        <li>Preparation - Each Aggregator converts each input share into an output share
compatible with the aggregation function. This computation involves the
aggregation parameter. In general, each aggregation parameter may result in a
different an output share.</li>
        <li>Aggregation - Each Aggregator combines a sequence of output shares into its
aggregate share and sends the aggregate share to the Collector.</li>
        <li>Unsharding - The Collector combines the aggregate shares into the aggregate
result.</li>
      </ul>
      <t>Sharding and Preparation are done once per measurement. Aggregation and
Unsharding are done over a batch of measurements (more precisely, over the
recovered output shares).</t>
      <t>A concrete DAF specifies an algorithm for the computation needed in each of
these stages. The interface of each algorithm is defined in the remainder of
this section. In addition, a concrete DAF defines the associated constants and
types enumerated in the following table.</t>
      <table anchor="daf-param">
        <name>Constants and types defined by each concrete DAF.</name>
        <thead>
          <tr>
            <th align="left">Parameter</th>
            <th align="left">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">
              <tt>ID</tt></td>
            <td align="left">Algorithm identifier for this DAF. A 32-bit, unsigned integer.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>SHARES</tt></td>
            <td align="left">Number of input shares into which each measurement is sharded.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>NONCE_SIZE</tt></td>
            <td align="left">Size of the nonce passed by the application.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>RAND_SIZE</tt></td>
            <td align="left">Size of the random byte string passed to sharding algorithm.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>Measurement</tt></td>
            <td align="left">Type of each measurement.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>PublicShare</tt></td>
            <td align="left">Type of each public share.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>InputShare</tt></td>
            <td align="left">Type of each input share.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>AggParam</tt></td>
            <td align="left">Type of aggregation parameter.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>OutShare</tt></td>
            <td align="left">Type of each output share.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>AggShare</tt></td>
            <td align="left">Type of the aggregate share.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>AggResult</tt></td>
            <td align="left">Type of the aggregate result.</td>
          </tr>
        </tbody>
      </table>
      <t>These types define the inputs and outputs of DAF methods at various stages of
the computation. Some of these values need to be written to the network in
order to carry out the computation. In particular, it is <bcp14>RECOMMENDED</bcp14> that
concrete instantiations of the <tt>Daf</tt> interface specify a method of encoding the
<tt>PublicShare</tt>, <tt>InputShare</tt>, and <tt>AggShare</tt>.</t>
      <t>Each DAF is identified by a unique, 32-bit integer <tt>ID</tt>. Identifiers for each
(V)DAF specified in this document are defined in <xref target="codepoints"/>.</t>
      <section anchor="sec-daf-shard">
        <name>Sharding</name>
        <t>In order to protect the privacy of its measurements, a DAF Client shards its
measurements into a sequence of input shares. The <tt>shard</tt> method is used for
this purpose.</t>
        <ul spacing="normal">
          <li>
            <tt>Daf.shard(measurement: Measurement, nonce: bytes[Daf.NONCE_SIZE], rand:
bytes[Daf.RAND_SIZE]) -&gt; tuple[PublicShare, list[InputShare]]</tt> is the
randomized sharding algorithm run by each Client. The input <tt>rand</tt> consists
of the random bytes consumed by the algorithm. This value <bcp14>MUST</bcp14> be generated
using a cryptographically secure pseudorandom number generator (CSPRNG). It
consumes the measurement and produces a "public share", distributed to each
of the Aggregators, and a corresponding sequence of input shares, one for
each Aggregator. The length of the output vector <bcp14>MUST</bcp14> be <tt>SHARES</tt>.</li>
        </ul>
        <figure anchor="shard-flow">
          <name>The Client divides its measurement into input shares and distributes them to the Aggregators. The public share is broadcast to all Aggregators.</name>
          <artwork><![CDATA[
    Client
    ======

    measurement
      |
      V
    +----------------------------------------------+
    | shard                                        |
    +----------------------------------------------+
      |              |              |     |
      |              |         ...  |    public_share
      |              |              |     |
      |    +---------|-----+--------|-----+
      |    |         |     |        |     |
      V    |         V     |        V     |
     input_share_0  input_share_1  input_share_[SHARES-1]
      |    |         |     |   ...  |     |
      V    V         V     V        V     V
    Aggregator 0   Aggregator 1    Aggregator SHARES-1
]]></artwork>
        </figure>
      </section>
      <section anchor="sec-daf-prepare">
        <name>Preparation</name>
        <t>Once an Aggregator has received the public share and one of the input shares,
the next step is to prepare the input share for aggregation. This is
accomplished using the following algorithm:</t>
        <ul spacing="normal">
          <li>
            <tt>Daf.prep(agg_id: Unsigned, agg_param: AggParam, nonce: bytes[NONCE_SIZE],
public_share: PublicShare, input_share: InputShare) -&gt; OutShare</tt> is the
deterministic preparation algorithm. It takes as input the public share and
one of the input shares generated by a Client, the Aggregator's unique
identifier, the aggregation parameter selected by the Collector, and a nonce
and returns an output share.</li>
        </ul>
        <t>The protocol in which the DAF is used <bcp14>MUST</bcp14> ensure that the Aggregator's
identifier is equal to the integer in range <tt>[0, SHARES)</tt> that matches the index
of <tt>input_share</tt> in the sequence of input shares output by the Client.</t>
      </section>
      <section anchor="sec-daf-validity-scopes">
        <name>Validity of Aggregation Parameters</name>
        <t>Concrete DAFs implementations <bcp14>MAY</bcp14> impose certain restrictions for input shares
and aggregation parameters. Protocols using a DAF <bcp14>MUST</bcp14> ensure that for each
input share and aggregation parameter <tt>agg_param</tt>, <tt>Daf.prep</tt> is only called if
<tt>Daf.is_valid(agg_param, previous_agg_params)</tt> returns True, where
<tt>previous_agg_params</tt> contains all aggregation parameters that have previously
been used with the same input share.</t>
        <t>DAFs <bcp14>MUST</bcp14> implement the following function:</t>
        <ul spacing="normal">
          <li>
            <tt>Daf.is_valid(agg_param: AggParam, previous_agg_params: set[AggParam]) -&gt;
Bool</tt>: Checks if the <tt>agg_param</tt> is compatible with all elements of
<tt>previous_agg_params</tt>.</li>
        </ul>
      </section>
      <section anchor="sec-daf-aggregate">
        <name>Aggregation</name>
        <t>Once an Aggregator holds output shares for a batch of measurements (where
batches are defined by the application), it combines them into a share of the
desired aggregate result:</t>
        <ul spacing="normal">
          <li>
            <tt>Daf.aggregate(agg_param: AggParam, out_shares: list[OutShare]) -&gt; AggShare</tt>
is the deterministic aggregation algorithm. It is run by each Aggregator a
set of recovered output shares.</li>
        </ul>
        <figure anchor="aggregate-flow">
          <name>Aggregation of output shares. `B` indicates the number of measurements in the batch.</name>
          <artwork><![CDATA[
    Aggregator 0    Aggregator 1        Aggregator SHARES-1
    ============    ============        ===================

    out_share_0_0   out_share_1_0       out_share_[SHARES-1]_0
    out_share_0_1   out_share_1_1       out_share_[SHARES-1]_1
    out_share_0_2   out_share_1_2       out_share_[SHARES-1]_2
         ...             ...                     ...
    out_share_0_B   out_share_1_B       out_share_[SHARES-1]_B
      |               |                   |
      V               V                   V
    +-----------+   +-----------+       +-----------+
    | aggregate |   | aggregate |   ... | aggregate |
    +-----------+   +-----------+       +-----------+
      |               |                   |
      V               V                   V
    agg_share_0     agg_share_1         agg_share_[SHARES-1]
]]></artwork>
        </figure>
        <t>For simplicity, we have written this algorithm in a "one-shot" form, where all
output shares for a batch are provided at the same time. Many DAFs may also
support a "streaming" form, where shares are processed one at a time.</t>
        <t>Implementation note: For most natural DAFs (and VDAFs) it is not necessary for
an Aggregator to store all output shares individually before aggregating.
Typically it is possible to merge output shares into aggregate shares as they
arrive, merge these into other aggregate shares, and so on. In particular, this
is the case when the output shares are vectors over some finite field and
aggregating them involves merely adding up the vectors element-wise. Such is the
case for Prio3 <xref target="prio3"/> and Poplar1 <xref target="poplar1"/>.</t>
      </section>
      <section anchor="sec-daf-unshard">
        <name>Unsharding</name>
        <t>After the Aggregators have aggregated a sufficient number of output shares, each
sends its aggregate share to the Collector, who runs the following algorithm to
recover the following output:</t>
        <ul spacing="normal">
          <li>
            <tt>Daf.unshard(agg_param: AggParam, agg_shares: list[AggShare],
num_measurements: Unsigned) -&gt; AggResult</tt> is run by the Collector in order to
compute the aggregate result from the Aggregators' shares. The length of
<tt>agg_shares</tt> <bcp14>MUST</bcp14> be <tt>SHARES</tt>. <tt>num_measurements</tt> is the number of
measurements that contributed to each of the aggregate shares. This algorithm
is deterministic.</li>
        </ul>
        <figure anchor="unshard-flow">
          <name>Computation of the final aggregate result from aggregate shares.</name>
          <artwork><![CDATA[
    Aggregator 0    Aggregator 1        Aggregator SHARES-1
    ============    ============        ===================

    agg_share_0     agg_share_1         agg_share_[SHARES-1]
      |               |                   |
      V               V                   V
    +-----------------------------------------------+
    | unshard                                       |
    +-----------------------------------------------+
      |
      V
    agg_result

    Collector
    =========
]]></artwork>
        </figure>
        <ul empty="true">
          <li>
            <t>QUESTION Maybe the aggregation algorithms should be randomized in order to
allow the Aggregators (or the Collector) to add noise for differential
privacy. (See the security considerations of <xref target="DAP"/>.)
Or is this out-of-scope of this document? See
https://github.com/ietf-wg-ppm/ppm-specification/issues/19.</t>
          </li>
        </ul>
      </section>
      <section anchor="daf-execution">
        <name>Execution of a DAF</name>
        <t>Securely executing a DAF involves emulating the following procedure.</t>
        <!--
Simon Friedberger: I think this would be easier to understand (also a bit
longer) if there was an Aggregator class which behaved like an actual aggregator
but with messages being sent by calling functions.
-->
<figure anchor="run-daf">
          <name>Execution of a DAF.</name>
          <artwork><![CDATA[
def run_daf(Daf,
            agg_param: Daf.AggParam,
            measurements: list[Daf.Measurement],
            nonces: list[bytes[Daf.NONCE_SIZE]]):
    out_shares = [[] for j in range(Daf.SHARES)]
    for (measurement, nonce) in zip(measurements, nonces):
        # Each Client shards its measurement into input shares and
        # distributes them among the Aggregators.
        rand = gen_rand(Daf.RAND_SIZE)
        (public_share, input_shares) = \
            Daf.shard(measurement, nonce, rand)

        # Each Aggregator prepares its input share for aggregation.
        for j in range(Daf.SHARES):
            out_shares[j].append(
                Daf.prep(j, agg_param, nonce,
                         public_share, input_shares[j]))

    # Each Aggregator aggregates its output shares into an aggregate
    # share and sends it to the Collector.
    agg_shares = []
    for j in range(Daf.SHARES):
        agg_share_j = Daf.aggregate(agg_param,
                                    out_shares[j])
        agg_shares.append(agg_share_j)

    # Collector unshards the aggregate result.
    num_measurements = len(measurements)
    agg_result = Daf.unshard(agg_param, agg_shares,
                             num_measurements)
    return agg_result
]]></artwork>
        </figure>
        <t>The inputs to this procedure are the same as the aggregation function computed by
the DAF: An aggregation parameter and a sequence of measurements. The procedure
prescribes how a DAF is executed in a "benign" environment in which there is no
adversary and the messages are passed among the protocol participants over
secure point-to-point channels. In reality, these channels need to be
instantiated by some "wrapper protocol", such as <xref target="DAP"/>,
that realizes these channels using suitable cryptographic mechanisms. Moreover,
some fraction of the Aggregators (or Clients) may be malicious and diverge from
their prescribed behaviors. <xref target="security"/> describes the execution of the DAF in
various adversarial environments and what properties the wrapper protocol needs
to provide in each.</t>
      </section>
    </section>
    <section anchor="vdaf">
      <name>Definition of VDAFs</name>
      <t>Like DAFs described in the previous section, a VDAF scheme is used to compute a
particular aggregation function over a set of Client-generated measurements.
Evaluation of a VDAF involves the same four stages as for DAFs: Sharding,
Preparation, Aggregation, and Unsharding. However, the Preparation stage will
require interaction among the Aggregators in order to facilitate verifiability
of the computation's correctness. Accommodating this interaction will require
syntactic changes.</t>
      <t>Overall execution of a VDAF comprises the following stages:</t>
      <ul spacing="normal">
        <li>Sharding - Computing input shares from an individual measurement</li>
        <li>Preparation - Conversion and verification of input shares to output shares
compatible with the aggregation function being computed</li>
        <li>Aggregation - Combining a sequence of output shares into an aggregate share</li>
        <li>Unsharding - Combining a sequence of aggregate shares into an aggregate
result</li>
      </ul>
      <t>In contrast to DAFs, the Preparation stage for VDAFs now performs an additional
task: Verification of the validity of the recovered output shares. This process
ensures that aggregating the output shares will not lead to a garbled aggregate
result.</t>
      <!--
For some VDAFs, like Prio3 ({{prio3}}) or Poplar1 ({{poplar1}}), the output
shares are recovered first, then validated. For other protocols, like Prio+
[AGJOP21], there is no explicit verification step.
-->

<t>The remainder of this section defines the VDAF interface. The attributes are
listed in <xref target="vdaf-param"/> are defined by each concrete VDAF.</t>
      <table anchor="vdaf-param">
        <name>Constants and types defined by each concrete VDAF.</name>
        <thead>
          <tr>
            <th align="left">Parameter</th>
            <th align="left">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">
              <tt>ID</tt></td>
            <td align="left">Algorithm identifier for this VDAF.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>VERIFY_KEY_SIZE</tt></td>
            <td align="left">Size (in bytes) of the verification key (<xref target="sec-vdaf-prepare"/>).</td>
          </tr>
          <tr>
            <td align="left">
              <tt>RAND_SIZE</tt></td>
            <td align="left">Size of the random byte string passed to sharding algorithm.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>NONCE_SIZE</tt></td>
            <td align="left">Size (in bytes) of the nonce.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>ROUNDS</tt></td>
            <td align="left">Number of rounds of communication during the Preparation stage (<xref target="sec-vdaf-prepare"/>).</td>
          </tr>
          <tr>
            <td align="left">
              <tt>SHARES</tt></td>
            <td align="left">Number of input shares into which each measurement is sharded (<xref target="sec-vdaf-shard"/>).</td>
          </tr>
          <tr>
            <td align="left">
              <tt>Measurement</tt></td>
            <td align="left">Type of each measurement.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>PublicShare</tt></td>
            <td align="left">Type of each public share.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>InputShare</tt></td>
            <td align="left">Type of each input share.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>AggParam</tt></td>
            <td align="left">Type of aggregation parameter.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>OutShare</tt></td>
            <td align="left">Type of each output share.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>AggShare</tt></td>
            <td align="left">Type of the aggregate share.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>AggResult</tt></td>
            <td align="left">Type of the aggregate result.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>PrepState</tt></td>
            <td align="left">Aggregator's state during preparation.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>PrepShare</tt></td>
            <td align="left">Type of each prep share.</td>
          </tr>
          <tr>
            <td align="left">
              <tt>PrepMessage</tt></td>
            <td align="left">Type of each prep message.</td>
          </tr>
        </tbody>
      </table>
      <t>Some of these values need to be written to the network in order to carry out
the computation. In particular, it is <bcp14>RECOMMENDED</bcp14> that concrete instantiations
of the <tt>Vdaf</tt> interface specify a method of encoding the <tt>PublicShare</tt>,
<tt>InputShare</tt>, <tt>AggShare</tt>, <tt>PrepShare</tt>, and <tt>PrepMessage</tt>.</t>
      <t>Each VDAF is identified by a unique, 32-bit integer <tt>ID</tt>. Identifiers for each
(V)DAF specified in this document are defined in <xref target="codepoints"/>. The following
method is defined for every VDAF:</t>
      <artwork><![CDATA[
def domain_separation_tag(Vdaf, usage: Unsigned) -> Bytes:
    """
    Format domain separation tag for this VDAF with the given usage.
    """
    return format_dst(0, Vdaf.ID, usage)
]]></artwork>
      <t>It is used to construct a domain separation tag for an instance of <tt>Xof</tt> used by
the VDAF. (See <xref target="xof"/>.)</t>
      <section anchor="sec-vdaf-shard">
        <name>Sharding</name>
        <t>Sharding transforms a measurement into input shares as it does in DAFs
(cf. <xref target="sec-daf-shard"/>); in addition, it takes a nonce as input and
produces a public share:</t>
        <ul spacing="normal">
          <li>
            <tt>Vdaf.shard(measurement: Measurement, nonce: bytes[Vdaf.NONCE_SIZE], rand:
bytes[Vdaf.RAND_SIZE]) -&gt; tuple[PublicShare, list[InputShare]]</tt> is the
randomized sharding algorithm run by each Client. Input <tt>rand</tt> consists of
the random bytes consumed by the algorithm. It consumes the measurement and
the nonce and produces a public share, distributed to each of Aggregators,
and the corresponding sequence of input shares, one for each Aggregator.
Depending on the VDAF, the input shares may encode additional information
used to verify the recovered output shares (e.g., the "proof shares" in Prio3
<xref target="prio3"/>). The length of the output vector <bcp14>MUST</bcp14> be <tt>SHARES</tt>.</li>
        </ul>
        <t>In order to ensure privacy of the measurement, the Client <bcp14>MUST</bcp14> generate the
random bytes and nonce using a CSPRNG. (See <xref target="security"/> for details.)</t>
      </section>
      <section anchor="sec-vdaf-prepare">
        <name>Preparation</name>
        <t>To recover and verify output shares, the Aggregators interact with one another
over <tt>ROUNDS</tt> rounds. Prior to each round, each Aggregator constructs an
outbound message. Next, the sequence of outbound messages is combined into a
single message, called a "preparation message", or "prep message" for short.
(Each of the outbound messages are called "preparation-message shares", or
"prep shares" for short.) Finally, the preparation message is distributed to
the Aggregators to begin the next round.</t>
        <t>An Aggregator begins the first round with its input share and it begins each
subsequent round with the previous prep message. Its output in the last round
is its output share and its output in each of the preceding rounds is a prep
share.</t>
        <t>This process involves a value called the "aggregation parameter" used to map the
input shares to output shares. The Aggregators need to agree on this parameter
before they can begin preparing the measurement shares for aggregation.</t>
        <figure anchor="prep-flow">
          <name>VDAF preparation process on the input shares for a single measurement. At the end of the computation, each Aggregator holds an output share or an error.</name>
          <artwork><![CDATA[
    Aggregator 0   Aggregator 1        Aggregator SHARES-1
    ============   ============        ===================

    input_share_0  input_share_1       input_share_[SHARES-1]
      |              |              ...  |
      V              V                   V
    +-----------+  +-----------+       +-----------+
    | prep_init |  | prep_init |       | prep_init |
    +-----------+  +------------+      +-----------+
      |              |              ...  |
      V              V                   V
    +----------------------------------------------+   \
    | prep_shares_to_prep                          |   |
    +----------------------------------------------+   |
      |              |              ...  |             |
      V              V                   V             | x ROUNDS
    +-----------+  +-----------+       +-----------+   |
    | prep_next |  | prep_next |       | prep_next |   |
    +-----------+  +-----------+       +-----------+   |
      |              |              ...  |             |
      V              V                   V             /
     ...            ...                 ...
      |              |              ...  |
      V              V                   V
    out_share_0    out_share_1         out_share_[SHARES-1]
]]></artwork>
        </figure>
        <t>To facilitate the preparation process, a concrete VDAF implements the following
methods:</t>
        <ul spacing="normal">
          <li>
            <t><tt>Vdaf.prep_init(verify_key: bytes[Vdaf.VERIFY_KEY_SIZE], agg_id: Unsigned,
agg_param: AggParam, nonce: bytes[Vdaf.NONCE_SIZE], public_share:
PublicShare, input_share: InputShare) -&gt; tuple[PrepState, PrepShare]</tt> is the
deterministic preparation-state initialization algorithm run by each
Aggregator to begin processing its input share into an output share. Its
inputs are the shared verification key (<tt>verify_key</tt>), the Aggregator's
unique identifier (<tt>agg_id</tt>), the aggregation parameter (<tt>agg_param</tt>), the
nonce provided by the environment (<tt>nonce</tt>, see <xref target="run-vdaf"/>), the public
share (<tt>public_share</tt>), and one of the input shares generated by the Client
(<tt>input_share</tt>). Its output is the Aggregator's initial preparation state and
initial prep share.  </t>
            <t>
It is up to the high level protocol in which the VDAF is used to arrange for
the distribution of the verification key prior to generating and processing
reports. (See <xref target="security"/> for details.)  </t>
            <t>
Protocols using the VDAF <bcp14>MUST</bcp14> ensure that the Aggregator's identifier is equal
to the integer in range <tt>[0, SHARES)</tt> that matches the index of <tt>input_share</tt>
in the sequence of input shares output by the Client.  </t>
            <t>
Protocols <bcp14>MUST</bcp14> ensure that public share consumed by each of the Aggregators is
identical. This is security critical for VDAFs such as Poplar1.</t>
          </li>
          <li>
            <tt>Vdaf.prep_next(prep_state: PrepState, prep_msg: PrepMessage) -&gt;
Union[tuple[PrepState, PrepShare], OutShare]</tt> is the deterministic
preparation-state update algorithm run by each Aggregator. It updates the
Aggregator's preparation state (<tt>prep_state</tt>) and returns either its next
preparation state and its message share for the current round or, if this is
the last round, its output share. An exception is raised if a valid output
share could not be recovered. The input of this algorithm is the inbound
preparation message.</li>
          <li>
            <tt>Vdaf.prep_shares_to_prep(agg_param: AggParam, prep_shares: list[PrepShare])
-&gt; PrepMessage</tt> is the deterministic preparation-message pre-processing
algorithm. It combines the prep shares generated by the Aggregators in the
previous round into the prep message consumed by each in the next round.</li>
        </ul>
        <t>In effect, each Aggregator moves through a linear state machine with <tt>ROUNDS</tt>
states.  The Aggregator enters the first state on using the initialization
algorithm, and the update algorithm advances the Aggregator to the next state.
Thus, in addition to defining the number of rounds (<tt>ROUNDS</tt>), a VDAF instance
defines the state of the Aggregator after each round.</t>
        <ul empty="true">
          <li>
            <t>TODO Consider how to bake this "linear state machine" condition into the
syntax. Given that Python 3 is used as our pseudocode, it's easier to specify
the preparation state using a class.</t>
          </li>
        </ul>
        <t>The preparation-state update accomplishes two tasks: recovery of output shares
from the input shares and ensuring that the recovered output shares are valid.
The abstraction boundary is drawn so that an Aggregator only recovers an output
share if it is deemed valid (at least, based on the Aggregator's view of the
protocol). Another way to draw this boundary would be to have the Aggregators
recover output shares first, then verify that they are valid. However, this
would allow the possibility of misusing the API by, say, aggregating an invalid
output share. Moreover, in protocols like Prio+ <xref target="AGJOP21"/> based on oblivious
transfer, it is necessary for the Aggregators to interact in order to recover
aggregatable output shares at all.</t>
        <t>Note that it is possible for a VDAF to specify <tt>ROUNDS == 0</tt>, in which case each
Aggregator runs the preparation-state update algorithm once and immediately
recovers its output share without interacting with the other Aggregators.
However, most, if not all, constructions will require some amount of interaction
in order to ensure validity of the output shares (while also maintaining
privacy).</t>
        <ul empty="true">
          <li>
            <t>OPEN ISSUE accommodating 0-round VDAFs may require syntax changes if, for
example, public keys are required. On the other hand, we could consider
defining this class of schemes as a different primitive. See issue#77.</t>
          </li>
        </ul>
      </section>
      <section anchor="sec-vdaf-validity-scopes">
        <name>Validity of Aggregation Parameters</name>
        <t>Similar to DAFs (see <xref target="sec-daf-validity-scopes"/>), VDAFs <bcp14>MAY</bcp14> impose
restrictions for input shares and aggregation parameters. Protocols using a VDAF
<bcp14>MUST</bcp14> ensure that for each input share and aggregation parameter <tt>agg_param</tt>, the
preparation phase (including <tt>Vdaf.prep_init</tt>, <tt>Vdaf.prep_next</tt>, and
<tt>Vdaf.prep_shares_to_prep</tt>; see <xref target="sec-vdaf-prepare"/>) is only called if
<tt>Vdaf.is_valid(agg_param, previous_agg_params)</tt> returns True, where
<tt>previous_agg_params</tt> contains all aggregation parameters that have previously
been used with the same input share.</t>
        <t>VDAFs <bcp14>MUST</bcp14> implement the following function:</t>
        <ul spacing="normal">
          <li>
            <tt>Vdaf.is_valid(agg_param: AggParam, previous_agg_params: set[AggParam]) -&gt;
Bool</tt>: Checks if the <tt>agg_param</tt> is compatible with all elements of
<tt>previous_agg_params</tt>.</li>
        </ul>
      </section>
      <section anchor="sec-vdaf-aggregate">
        <name>Aggregation</name>
        <t>VDAF Aggregation is identical to DAF Aggregation (cf. <xref target="sec-daf-aggregate"/>):</t>
        <ul spacing="normal">
          <li>
            <tt>Vdaf.aggregate(agg_param: AggParam, out_shares: list[OutShare]) -&gt; AggShare</tt>
is the deterministic aggregation algorithm. It is run by each Aggregator over
the output shares it has computed for a batch of measurements.</li>
        </ul>
        <t>The data flow for this stage is illustrated in <xref target="aggregate-flow"/>. Here again,
we have the aggregation algorithm in a "one-shot" form, where all shares for a
batch are provided at the same time. VDAFs typically also support a "streaming"
form, where shares are processed one at a time.</t>
      </section>
      <section anchor="sec-vdaf-unshard">
        <name>Unsharding</name>
        <t>VDAF Unsharding is identical to DAF Unsharding (cf. <xref target="sec-daf-unshard"/>):</t>
        <ul spacing="normal">
          <li>
            <tt>Vdaf.unshard(agg_param: AggParam, agg_shares: list[AggShare],
num_measurements: Unsigned) -&gt; AggResult</tt> is run by the Collector in order to
compute the aggregate result from the Aggregators' shares. The length of
<tt>agg_shares</tt> <bcp14>MUST</bcp14> be <tt>SHARES</tt>. <tt>num_measurements</tt> is the number of
measurements that contributed to each of the aggregate shares. This algorithm
is deterministic.</li>
        </ul>
        <t>The data flow for this stage is illustrated in <xref target="unshard-flow"/>.</t>
      </section>
      <section anchor="vdaf-execution">
        <name>Execution of a VDAF</name>
        <t>Secure execution of a VDAF involves simulating the following procedure.</t>
        <figure anchor="run-vdaf">
          <name>Execution of a VDAF.</name>
          <artwork><![CDATA[
def run_vdaf(Vdaf,
             verify_key: bytes[Vdaf.VERIFY_KEY_SIZE],
             agg_param: Vdaf.AggParam,
             nonces: list[bytes[Vdaf.NONCE_SIZE]],
             measurements: list[Vdaf.Measurement]):
    out_shares = []
    for (nonce, measurement) in zip(nonces, measurements):
        # Each Client shards its measurement into input shares.
        rand = gen_rand(Vdaf.RAND_SIZE)
        (public_share, input_shares) = \
            Vdaf.shard(measurement, nonce, rand)

        # Each Aggregator initializes its preparation state.
        prep_states = []
        outbound = []
        for j in range(Vdaf.SHARES):
            (state, share) = Vdaf.prep_init(verify_key, j,
                                            agg_param,
                                            nonce,
                                            public_share,
                                            input_shares[j])
            prep_states.append(state)
            outbound.append(share)

        # Aggregators recover their output shares.
        for i in range(Vdaf.ROUNDS-1):
            prep_msg = Vdaf.prep_shares_to_prep(agg_param,
                                                outbound)
            outbound = []
            for j in range(Vdaf.SHARES):
                out = Vdaf.prep_next(prep_states[j], prep_msg)
                (prep_states[j], out) = out
                outbound.append(out)

        # The final outputs of the prepare phase are the output shares.
        prep_msg = Vdaf.prep_shares_to_prep(agg_param,
                                            outbound)
        outbound = []
        for j in range(Vdaf.SHARES):
            out_share = Vdaf.prep_next(prep_states[j], prep_msg)
            outbound.append(out_share)
        out_shares.append(outbound)

    # Each Aggregator aggregates its output shares into an
    # aggregate share. In a distributed VDAF computation, the
    # aggregate shares are sent over the network.
    agg_shares = []
    for j in range(Vdaf.SHARES):
        out_shares_j = [out[j] for out in out_shares]
        agg_share_j = Vdaf.aggregate(agg_param, out_shares_j)
        agg_shares.append(agg_share_j)

    # Collector unshards the aggregate.
    num_measurements = len(measurements)
    agg_result = Vdaf.unshard(agg_param, agg_shares,
                              num_measurements)
    return agg_result
]]></artwork>
        </figure>
        <t>The inputs to this algorithm are the aggregation parameter, a list of
measurements, and a nonce for each measurement. This document does not specify
how the nonces are chosen, but security requires that the nonces be unique. See
<xref target="security"/> for details. As explained in <xref target="daf-execution"/>, the secure
execution of a VDAF requires the application to instantiate secure channels
between each of the protocol participants.</t>
      </section>
      <section anchor="vdaf-prep-comm">
        <name>Communication Patterns for Preparation</name>
        <t>In each round of preparation, each Aggregator writes a prep share to some
broadcast channel, which is then processed into the prep message using the
public <tt>prep_shares_to_prep()</tt> algorithm and broadcast to the Aggregators to
start the next round. In this section we describe some approaches to realizing
this broadcast channel functionality in protocols that use VDAFs.</t>
        <t>The state machine of each Aggregator is shown in <xref target="vdaf-prep-state-machine"/>.</t>
        <figure anchor="vdaf-prep-state-machine">
          <name>State machine for VDAF preparation.</name>
          <sourcecode type="state"><![CDATA[
               +----------------+
               |                |
               v                |
Start ------> Continued(prep_state) --> Finished(out_share)
 |                |
 |                |
 +--> Rejected <--+
]]></sourcecode>
        </figure>
        <t>State transitions are made when the state is acted upon by the host's local
inputs and/or messages sent by the peers. The initial state is <tt>Start</tt>. The
terminal states are <tt>Rejected</tt>, which indicates that the report cannot be
processed any further, and <tt>Finished(out_share)</tt>, which indicates that the
Aggregator has recovered an output share <tt>out_share</tt>.</t>
        <artwork><![CDATA[
class State:
    pass

class Start(State):
    pass

class Continued(State):
    def __init__(self, prep_state):
        self.prep_state = prep_state

class Finished(State):
    def __init__(self, output_share):
        self.output_share = output_share

class Rejected(State):
    def __init__(self):
        pass
]]></artwork>
        <t>Note that there is no representation of the <tt>Start</tt> state as it is never
instantiated in the ping-pong topology.</t>
        <t>For convenience, the methods described in this section are defined in terms of
opaque byte strings. A compatible <tt>Vdaf</tt> <bcp14>MUST</bcp14> specify methods for encoding
public shares, input shares, prep shares, prep messages, and aggregation
parameters. Minimally:</t>
        <ul spacing="normal">
          <li>
            <tt>Vdaf.decode_public_share(encoded: bytes) -&gt; Vdaf.PublicShare</tt> decodes a
public share.</li>
          <li>
            <tt>Vdaf.decode_input_share(agg_id: Unsigned, encoded: bytes) -&gt;
Vdaf.InputShare</tt> decodes an input share, using the aggregator ID as optional
context.</li>
          <li>
            <tt>Vdaf.encode_prep_share(prep_share: Vdaf.PrepShare) -&gt; bytes</tt> encodes a prep
share.</li>
          <li>
            <tt>Vdaf.decode_prep_share(prep_state: Vdaf.PrepState, encoded: bytes) -&gt;
Vdaf.PrepShare</tt> decodes a prep share, using the prep state as optional
context.</li>
          <li>
            <tt>Vdaf.encode_prep_msg(prep_msg: Vdaf.PrepMessage) -&gt; bytes</tt> encodes a prep
message.</li>
          <li>
            <tt>Vdaf.decode_prep_msg(prep_state: Vdaf.PrepState, encoded: bytes) -&gt;
Vdaf.PrepMessage</tt> decodes a prep message, using the prep state as optional
decoding context.</li>
          <li>
            <tt>Vdaf.decode_agg_param(encoded: bytes) -&gt; Vdaf.AggParam</tt> decodes an
aggregation parameter.</li>
          <li>
            <tt>Vdaf.encode_agg_param(agg_param: Vdaf.AggParam) -&gt; bytes</tt> encodes an
aggregation parameter.</li>
        </ul>
        <t>Implementations of Prio3 and Poplar1 <bcp14>MUST</bcp14> use the encoding scheme specified in
<xref target="prio3-encode"/> and <xref target="poplar1-encode"/> respectively.</t>
      </section>
      <section anchor="ping-pong-topology-only-two-aggregators">
        <name>Ping-Pong Topology (Only Two Aggregators)</name>
        <t>For VDAFs with precisely two Aggregators (i.e., <tt>Vdaf.SHARES == 2</tt>), the
following "ping pong" communication pattern can be used. It is compatible with
any request/response transport protocol, such as HTTP.</t>
        <t>Let us call the initiating party the "Leader" and the responding party the
"Helper". The high-level idea is that the Leader and Helper will take turns
running the computation locally until input from their peer is required:</t>
        <ul spacing="normal">
          <li>For a 1-round VDAF (e.g., Prio3 (<xref target="prio3"/>)), the Leader sends its prep share
to the Helper, who computes the prep message locally, computes its output
share, then sends the prep message to the Leader. Preparation requires just
one round trip between the Leader and the Helper.</li>
          <li>For a 2-round VDAF (e.g., Poplar1 (<xref target="poplar1"/>)), the Leader sends its
first-round prep share to the Helper, who replies with the first-round prep
message and its second-round prep share. In the next request, the Leader
computes its second-round prep share locally, computes its output share, and
sends the second-round prep message to the Helper. Finally, the Helper
computes its own output share.</li>
          <li>In general, each request includes the Leader's prep share for the previous
round and/or the prep message for the current round; correspondingly, each
response consists of the prep message for the current round and the Helper's
prep share for the next round.</li>
        </ul>
        <t>The Aggregators proceed in this ping-ponging fashion until a step of the
computation fails (indicating the report is invalid and should be rejected) or
preparation is completed. All told there there are <tt>ceil((Vdaf.ROUNDS+1)/2)</tt>
requests sent.</t>
        <t>Each message in the ping-pong protocol is structured as follows (expressed in
TLS syntax as defined in <xref section="3" sectionFormat="of" target="RFC8446"/>):</t>
        <artwork><![CDATA[
enum {
  initialize(0),
  continue(1),
  finish(2),
  (255)
} MessageType;

struct {
  MessageType type;
  select (Message.type) {
    case initialize:
      opaque prep_share<0..2^32-1>;
    case continue:
      opaque prep_msg<0..2^32-1>;
      opaque prep_share<0..2^32-1>;
    case finish:
      opaque prep_msg<0..2^32-1>;
  };
} Message;
]]></artwork>
        <t>These messages are used to transition between the states described in
<xref target="vdaf-prep-comm"/>. They are encoded and decoded to or from byte buffers as
described <xref section="3" sectionFormat="of" target="RFC8446"/>) using the following routines:</t>
        <ul spacing="normal">
          <li>
            <tt>encode_ping_pong_message(message: Message) -&gt; bytes</tt> encodes a <tt>Message</tt> into
an opaque byte buffer.</li>
          <li>
            <tt>decode_pong_pong_message(encoded: bytes) -&gt; Message</tt> decodes an opaque byte
buffer into a <tt>Message</tt>, raising an error if the bytes are not a valid
encoding.</li>
        </ul>
        <t>The Leader's initial transition is computed with the following procedure:</t>
        <sourcecode type="transition"><![CDATA[
def ping_pong_leader_init(
            Vdaf,
            vdaf_verify_key: bytes[Vdaf.VERIFY_KEY_SIZE],
            agg_param: bytes,
            nonce: bytes[Vdaf.NONCE_SIZE],
            public_share: bytes,
            input_share: bytes,
        ) -> tuple[State, bytes]:
    try:
        (prep_state, prep_share) = Vdaf.prep_init(
            vdaf_verify_key,
            0,
            Vdaf.decode_agg_param(agg_param),
            nonce,
            Vdaf.decode_public_share(public_share),
            Vdaf.decode_input_share(0, input_share),
        )
        outbound = Message.initialize(
            Vdaf.encode_prep_share(prep_share))
        return (Continued(prep_state), encode_ping_pong_message(outbound))
    except:
        return (Rejected(), None)
]]></sourcecode>
        <t>The output is the <tt>State</tt> to which the Leader has transitioned and an encoded
<tt>Message</tt>. If the Leader's state is <tt>Rejected</tt>, then processing halts.
Otherwise, if the state is <tt>Continued</tt>, then processing continues.</t>
        <t>The Leader sends the outbound message to the Helper. The Helper's initial
transition is computed using the following procedure:</t>
        <sourcecode type="transition"><![CDATA[
def ping_pong_helper_init(
            Vdaf,
            vdaf_verify_key: bytes[Vdaf.VERIFY_KEY_SIZE],
            agg_param: bytes,
            nonce: bytes[Vdaf.NONCE_SIZE],
            public_share: bytes,
            input_share: bytes,
            inbound_encoded: bytes,
        ) -> tuple[State, bytes]:
    try:
        (prep_state, prep_share) = Vdaf.prep_init(
            vdaf_verify_key,
            1,
            Vdaf.decode_agg_param(agg_param),
            nonce,
            Vdaf.decode_public_share(public_share),
            Vdaf.decode_input_share(1, input_share),
        )

        inbound = decode_ping_pong_message(inbound_encoded)

        if inbound.type != 0: # initialize
            return (Rejected(), None)

        prep_shares = [
            Vdaf.decode_prep_share(prep_state, inbound.prep_share),
            prep_share,
        ]
        return Vdaf.ping_pong_transition(
            agg_param,
            prep_shares,
            prep_state,
        )
    except:
        return (Rejected(), None)
]]></sourcecode>
        <t>Procedure <tt>ping_pong_transition()</tt> takes in the prep shares, combines them into
the prep message, and computes the next prep state of the caller:</t>
        <artwork><![CDATA[
def ping_pong_transition(
            Vdaf,
            agg_param: Vdaf.AggParam,
            prep_shares: list[Vdaf.PrepShare],
            prep_state: Vdaf.PrepState,
         ) -> (State, bytes):
    prep_msg = Vdaf.prep_shares_to_prep(agg_param,
                                        prep_shares)
    out = Vdaf.prep_next(prep_state, prep_msg)
    if type(out) == Vdaf.OutShare:
        outbound = Message.finish(Vdaf.encode_prep_msg(prep_msg))
        return (Finished(out), encode_ping_pong_message(outbound))
    (prep_state, prep_share) = out
    outbound = Message.continue(
        Vdaf.encode_prep_msg(prep_msg),
        Vdaf.encode_prep_share(prep_share),
    )
    return (Continued(prep_state), encode_ping_pong_message(outbound))
]]></artwork>
        <t>The output is the <tt>State</tt> to which the Helper has transitioned and an encoded
<tt>Message</tt>. If the Helper's state is <tt>Finished</tt> or <tt>Rejected</tt>, then processing
halts. Otherwise, if the state is <tt>Continued</tt>, then processing continues.</t>
        <t>Next, the Helper sends the outbound message to the Leader. The Leader computes
its next state transition using the function <tt>ping_pong_leader_continued</tt>:</t>
        <sourcecode type="transition"><![CDATA[
def ping_pong_leader_continued(
            Vdaf,
            agg_param: bytes,
            state: State,
            inbound_encoded: bytes,
        ) -> (State, Optional[bytes]):
    return Vdaf.ping_pong_continued(
        True,
        agg_param,
        state,
        inbound_encoded,
    )

def ping_pong_continued(
            Vdaf,
            is_leader: bool,
            agg_param: bytes,
            state: State,
            inbound_encoded: bytes,
        ) -> (State, Optional[bytes]):
    try:
        inbound = decode_ping_pong_message(inbound_encoded)

        if inbound.type == 0: # initialize
            return (Rejected(), None)

        if !isinstance(state, Continued):
            return (Rejected(), None)

        prep_msg = Vdaf.decode_prep_msg(state.prep_state, inbound.prep_msg)
        out = Vdaf.prep_next(state.prep_state, prep_msg)
        if type(out) == tuple[Vdaf.PrepState, Vdaf.PrepShare] \
                and inbound.type == 1:
            # continue
            (prep_state, prep_share) = out
            prep_shares = [
                Vdaf.decode_prep_share(prep_state, inbound.prep_share),
                prep_share,
            ]
            if is_leader:
                prep_shares.reverse()
            return Vdaf.ping_pong_transition(
                Vdaf.decode_agg_param(agg_param),
                prep_shares,
                prep_state,
            )
        elif type(out) == Vdaf.OutShare and inbound.type == 2:
            # finish
            return (Finished(out), None)
        else:
            return (Rejected(), None)

    except:
        return (Rejected(), None)
]]></sourcecode>
        <t>If the Leader's state is <tt>Finished</tt> or <tt>Rejected</tt>, then processing halts.
Otherwise, the Leader sends the outbound message to the Helper. The Helper
computes its next state transition using the function
<tt>ping_pong_helper_continued</tt>:</t>
        <sourcecode type="transition"><![CDATA[
def ping_pong_helper_continued(
            Vdaf,
            agg_param: bytes,
            state: State,
            inbound_encoded: bytes,
        ) -> (State, Optional[bytes]):
    return Vdaf.ping_pong_continued(
        False,
        agg_param,
        state,
        inbound_encoded,
    )
]]></sourcecode>
        <t>They continue in this way until processing halts. Note that, depending on the
number of rounds of preparation that are required, there may be one more
message to send before the peer can also finish processing (i.e., <tt>outbound !=
None</tt>).</t>
      </section>
      <section anchor="star-topology-any-number-of-aggregators">
        <name>Star Topology (Any Number of Aggregators)</name>
        <t>The ping-pong topology of the previous section is only suitable for VDAFs
involving exactly two Aggregators. If more Aggregators are required, the star
topology described in this section can be used instead.</t>
        <ul empty="true">
          <li>
            <t>TODO Describe the Leader-emulated broadcast channel architecture that was
originally envisioned for DAP. (As of DAP-05 we are going with the ping pong
architecture described in the previous section.)</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="prelim">
      <name>Preliminaries</name>
      <t>This section describes the primitives that are common to the VDAFs specified in
this document.</t>
      <section anchor="field">
        <name>Finite Fields</name>
        <t>Both Prio3 and Poplar1 use finite fields of prime order. Finite field
elements are represented by a class <tt>Field</tt> with the following associated
parameters:</t>
        <ul spacing="normal">
          <li>
            <tt>MODULUS: Unsigned</tt> is the prime modulus that defines the field.</li>
          <li>
            <tt>ENCODED_SIZE: Unsigned</tt> is the number of bytes used to encode a field element
as a byte string.</li>
        </ul>
        <t>A concrete <tt>Field</tt> also implements the following class methods:</t>
        <ul spacing="normal">
          <li>
            <tt>Field.zeros(length: Unsigned) -&gt; output: Vec[Field]</tt> returns a vector of
zeros. The length of <tt>output</tt> <bcp14>MUST</bcp14> be <tt>length</tt>.</li>
          <li>
            <tt>Field.rand_vec(length: Unsigned) -&gt; output: Vec[Field]</tt> returns a vector of
random field elements. The length of <tt>output</tt> <bcp14>MUST</bcp14> be <tt>length</tt>.</li>
        </ul>
        <t>A field element is an instance of a concrete <tt>Field</tt>. The concrete class defines
the usual arithmetic operations on field elements. In addition, it defines the
following instance method for converting a field element to an unsigned integer:</t>
        <ul spacing="normal">
          <li>
            <tt>elem.as_unsigned() -&gt; Unsigned</tt> returns the integer representation of
field element <tt>elem</tt>.</li>
        </ul>
        <t>Likewise, each concrete <tt>Field</tt> implements a constructor for converting an
unsigned integer into a field element:</t>
        <ul spacing="normal">
          <li>
            <tt>Field(integer: Unsigned)</tt> returns <tt>integer</tt> represented as a field element.
The value of <tt>integer</tt> <bcp14>MUST</bcp14> be less than <tt>Field.MODULUS</tt>.</li>
        </ul>
        <t>Finally, each concrete <tt>Field</tt> has two derived class methods, one for encoding
a vector of field elements as a byte string and another for decoding a vector of
field elements.</t>
        <figure anchor="field-derived-methods">
          <name>Derived class methods for finite fields.</name>
          <artwork><![CDATA[
def encode_vec(Field, data: Vec[Field]) -> Bytes:
    encoded = Bytes()
    for x in data:
        encoded += to_le_bytes(x.as_unsigned(), Field.ENCODED_SIZE)
    return encoded

def decode_vec(Field, encoded: Bytes) -> Vec[Field]:
    L = Field.ENCODED_SIZE
    if len(encoded) % L != 0:
        raise ERR_DECODE

    vec = []
    for i in range(0, len(encoded), L):
        encoded_x = encoded[i:i+L]
        x = from_le_bytes(encoded_x)
        if x >= Field.MODULUS:
            raise ERR_DECODE # Integer is larger than modulus
        vec.append(Field(x))
    return vec
]]></artwork>
        </figure>
        <section anchor="auxiliary-functions">
          <name>Auxiliary Functions</name>
          <t>The following auxiliary functions on vectors of field elements are used in the
remainder of this document. Note that an exception is raised by each function if
the operands are not the same length.</t>
          <figure anchor="field-helper-functions">
            <name>Common functions for finite fields.</name>
            <artwork><![CDATA[
def vec_sub(left: Vec[Field], right: Vec[Field]):
    """
    Subtract the right operand from the left and return the result.
    """
    return list(map(lambda x: x[0] - x[1], zip(left, right)))

def vec_add(left: Vec[Field], right: Vec[Field]):
    """Add the right operand to the left and return the result."""
    return list(map(lambda x: x[0] + x[1], zip(left, right)))
]]></artwork>
          </figure>
        </section>
        <section anchor="field-fft-friendly">
          <name>FFT-Friendly Fields</name>
          <t>Some VDAFs require fields that are suitable for efficient computation of the
discrete Fourier transform, as this allows for fast polynomial interpolation.
(One example is Prio3 (<xref target="prio3"/>) when instantiated with the generic FLP of
<xref target="flp-generic-construction"/>.) Specifically, a field is said to be
"FFT-friendly" if, in addition to satisfying the interface described in
<xref target="field"/>, it implements the following method:</t>
          <ul spacing="normal">
            <li>
              <tt>Field.gen() -&gt; Field</tt> returns the generator of a large subgroup of the
multiplicative group. To be FFT-friendly, the order of this subgroup <bcp14>MUST</bcp14> be a
power of 2. In addition, the size of the subgroup dictates how large
interpolated polynomials can be. It is <bcp14>RECOMMENDED</bcp14> that a generator is chosen
with order at least <tt>2^20</tt>.</li>
          </ul>
          <t>FFT-friendly fields also define the following parameter:</t>
          <ul spacing="normal">
            <li>
              <tt>GEN_ORDER: Unsigned</tt> is the order of a multiplicative subgroup generated by
<tt>Field.gen()</tt>.</li>
          </ul>
        </section>
        <section anchor="parameters">
          <name>Parameters</name>
          <t>The tables below define finite fields used in the remainder of this document.</t>
          <table anchor="fields">
            <name>Parameters for the finite fields used in this document.</name>
            <thead>
              <tr>
                <th align="left">Parameter</th>
                <th align="left">Field64</th>
                <th align="left">Field128</th>
                <th align="left">Field255</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">MODULUS</td>
                <td align="left">2^32 * 4294967295 + 1</td>
                <td align="left">2^66 * 4611686018427387897 + 1</td>
                <td align="left">2^255 - 19</td>
              </tr>
              <tr>
                <td align="left">ENCODED_SIZE</td>
                <td align="left">8</td>
                <td align="left">16</td>
                <td align="left">32</td>
              </tr>
              <tr>
                <td align="left">Generator</td>
                <td align="left">7^4294967295</td>
                <td align="left">7^4611686018427387897</td>
                <td align="left">n/a</td>
              </tr>
              <tr>
                <td align="left">GEN_ORDER</td>
                <td align="left">2^32</td>
                <td align="left">2^66</td>
                <td align="left">n/a</td>
              </tr>
            </tbody>
          </table>
        </section>
      </section>
      <section anchor="xof">
        <name>Extendable Output Functions</name>
        <t>VDAFs in this specification use extendable output functions (XOFs) to extract
short, fixed-length strings we call "seeds" from long input strings and expand
seeds into long output strings. We specify a single interface that is suitable
for both purposes.</t>
        <t>XOFs are defined by a class <tt>Xof</tt> with the following associated parameter and
methods:</t>
        <ul spacing="normal">
          <li>
            <tt>SEED_SIZE: Unsigned</tt> is the size (in bytes) of a seed.</li>
          <li>
            <tt>Xof(seed: Bytes[Xof.SEED_SIZE], dst: Bytes, binder: Bytes)</tt> constructs an
instance of <tt>Xof</tt> from the given seed, domain separation tag, and binder
string. (See below for definitions of these.) The seed <bcp14>MUST</bcp14> be of length
<tt>SEED_SIZE</tt> and <bcp14>MUST</bcp14> be generated securely (i.e., it is either the output of
<tt>gen_rand</tt> or a previous invocation of the XOF).</li>
          <li>
            <tt>xof.next(length: Unsigned)</tt> returns the next <tt>length</tt> bytes of output of
<tt>xof</tt>.</li>
        </ul>
        <t>Each <tt>Xof</tt> has two derived methods. The first is used to derive a fresh seed
from an existing one. The second is used to compute a sequence of field
elements.</t>
        <figure anchor="xof-derived-methods">
          <name>Derived methods for XOFs.</name>
          <artwork><![CDATA[
def derive_seed(Xof,
                seed: Bytes[Xof.SEED_SIZE],
                dst: Bytes,
                binder: Bytes):
    """Derive a new seed."""
    xof = Xof(seed, dst, binder)
    return xof.next(Xof.SEED_SIZE)

def next_vec(self, Field, length: Unsigned):
    """Output the next `length` elements of `Field`."""
    m = next_power_of_2(Field.MODULUS) - 1
    vec = []
    while len(vec) < length:
        x = from_le_bytes(self.next(Field.ENCODED_SIZE))
        x &= m
        if x < Field.MODULUS:
            vec.append(Field(x))
    return vec

def expand_into_vec(Xof,
                    Field,
                    seed: Bytes[Xof.SEED_SIZE],
                    dst: Bytes,
                    binder: Bytes,
                    length: Unsigned):
    """
    Expand the input `seed` into vector of `length` field elements.
    """
    xof = Xof(seed, dst, binder)
    return xof.next_vec(Field, length)
]]></artwork>
        </figure>
        <section anchor="xof-shake128">
          <name>XofShake128</name>
          <t>This section describes XofShake128, a XOF based on the SHAKE128 mode of
operation for the Keccak permutation <xref target="FIPS202"/>. This XOF is <bcp14>RECOMMENDED</bcp14> for
all use cases within VDAFs. The length of the domain separation string <tt>dst</tt>
passed to XofShake128 <bcp14>MUST NOT</bcp14> exceed 255 bytes.</t>
          <figure>
            <name>Definition of XOF XofShake128.</name>
            <artwork><![CDATA[
class XofShake128(Xof):
    """XOF based on SHA-3 (SHAKE128)."""

    # Associated parameters
    SEED_SIZE = 16

    def __init__(self, seed, dst, binder):
        self.l = 0
        self.x = seed + binder
        self.s = dst

    def next(self, length: Unsigned) -> Bytes:
        self.l += length

        # Function `SHAKE128(x, l)` is as defined in
        # [FIPS 202, Section 6.2].
        #
        # Implementation note: Rather than re-generate the output
        # stream each time `next()` is invoked, most implementations
        # of SHA-3 will expose an "absorb-then-squeeze" API that
        # allows stateful handling of the stream.
        dst_length = to_le_bytes(len(self.s), 1)
        stream = SHAKE128(dst_length + self.s + self.x, self.l)
        return stream[-length:]
]]></artwork>
          </figure>
        </section>
        <section anchor="xof-fixed-key-aes128">
          <name>XofFixedKeyAes128</name>
          <t>While XofShake128 as described above can be securely used in all cases where a XOF
is needed in the VDAFs described in this document, there are some cases where
a more efficient instantiation based on fixed-key AES is possible. For now, this
is limited to the XOF used inside the Idpf <xref target="idpf"/> implementation in Poplar1
<xref target="idpf-poplar"/>. It is <bcp14>NOT RECOMMENDED</bcp14> to use this XOF anywhere else.
The length of the domain separation string <tt>dst</tt> passed to XofFixedKeyAes128
<bcp14>MUST NOT</bcp14> exceed 255 bytes. See Security Considerations <xref target="security"/> for a more
detailed discussion.</t>
          <artwork><![CDATA[
class XofFixedKeyAes128(Xof):
    """
    XOF based on a circular collision-resistant hash function from
    fixed-key AES.
    """

    # Associated parameters
    SEED_SIZE = 16

    def __init__(self, seed, dst, binder):
        self.length_consumed = 0

        # Use SHA-3 to derive a key from the binder string and domain
        # separation tag. Note that the AES key does not need to be
        # kept secret from any party. However, when used with
        # IdpfPoplar, we require the binder to be a random nonce.
        #
        # Implementation note: This step can be cached across XOF
        # evaluations with many different seeds.
        dst_length = to_le_bytes(len(dst), 1)
        self.fixed_key = SHAKE128(dst_length + dst + binder, 16)
        self.seed = seed

    def next(self, length: Unsigned) -> Bytes:
        offset = self.length_consumed % 16
        new_length = self.length_consumed + length
        block_range = range(
            int(self.length_consumed / 16),
            int(new_length / 16) + 1)
        self.length_consumed = new_length

        hashed_blocks = [
            self.hash_block(xor(self.seed, to_le_bytes(i, 16))) \
                         for i in block_range
        ]
        return concat(hashed_blocks)[offset:offset+length]

    def hash_block(self, block):
        """
        The multi-instance tweakable circular correlation-robust hash
        function of [GKWWY20] (Section 4.2). The tweak here is the key
        that stays constant for all XOF evaluations of the same Client,
        but differs between Clients.

        Function `AES128(key, block)` is the AES-128 blockcipher.
        """
        lo, hi = block[:8], block[8:]
        sigma_block = concat([hi, xor(hi, lo)])
        return xor(AES128(self.fixed_key, sigma_block), sigma_block)
]]></artwork>
        </section>
        <section anchor="the-domain-separation-tag-and-binder-string">
          <name>The Domain Separation Tag and Binder String</name>
          <t>XOFs are used to map a seed to a finite domain, e.g., a fresh seed or a vector
of field elements. To ensure domain separation, the derivation is needs to be
bound to some distinguished domain separation tag. The domain separation tag
encodes the following values:</t>
          <ol spacing="normal" type="1"><li>The document version (i.e.,<tt>VERSION</tt>);</li>
            <li>The "class" of the algorithm using the output (e.g., VDAF);</li>
            <li>A unique identifier for the algorithm; and</li>
            <li>Some indication of how the output is used (e.g., for deriving the measurement
shares in Prio3 <xref target="prio3"/>).</li>
          </ol>
          <t>The following algorithm is used in the remainder of this document in order to
format the domain separation tag:</t>
          <artwork><![CDATA[
def format_dst(algo_class: Unsigned,
               algo: Unsigned,
               usage: Unsigned) -> Bytes:
    """Format XOF domain separation tag for use within a (V)DAF."""
    return concat([
        to_be_bytes(VERSION, 1),
        to_be_bytes(algo_class, 1),
        to_be_bytes(algo, 4),
        to_be_bytes(usage, 2),
    ])
]]></artwork>
          <t>It is also sometimes necessary to bind the output to some ephemeral value that
multiple parties need to agree on. We call this input the "binder string".</t>
        </section>
      </section>
    </section>
    <section anchor="prio3">
      <name>Prio3</name>
      <t>This section describes Prio3, a VDAF for Prio <xref target="CGB17"/>. Prio is suitable for
a wide variety of aggregation functions, including (but not limited to) sum,
mean, standard deviation, estimation of quantiles (e.g., median), and linear
regression. In fact, the scheme described in this section is compatible with any
aggregation function that has the following structure:</t>
      <ul spacing="normal">
        <li>Each measurement is encoded as a vector over some finite field.</li>
        <li>Measurement validity is determined by an arithmetic circuit evaluated over
the encoded measurement. (An "arithmetic circuit" is a function comprised of
arithmetic operations in the field.) The circuit's output is a single field
element: if zero, then the measurement is said to be "valid"; otherwise, if
the output is non-zero, then the measurement is said to be "invalid".</li>
        <li>The aggregate result is obtained by summing up the encoded measurement
vectors and computing some function of the sum.</li>
      </ul>
      <t>At a high level, Prio3 distributes this computation as follows. Each Client
first shards its measurement by first encoding it, then splitting the vector into
secret shares and sending a share to each Aggregator. Next, in the preparation
phase, the Aggregators carry out a multi-party computation to determine if their
shares correspond to a valid measurement (as determined by the arithmetic
circuit). This computation involves a "proof" of validity generated by the
Client. Next, each Aggregator sums up its shares locally. Finally, the
Collector sums up the aggregate shares and computes the aggregate result.</t>
      <t>This VDAF does not have an aggregation parameter. Instead, the output share is
derived from the measurement share by applying a fixed map. See <xref target="poplar1"/> for
an example of a VDAF that makes meaningful use of the aggregation parameter.</t>
      <t>As the name implies, Prio3 is a descendant of the original Prio construction.
A second iteration was deployed in the <xref target="ENPA"/> system, and like the VDAF
described here, the ENPA system was built from techniques introduced in
<xref target="BBCGGI19"/> that significantly improve communication cost. That system was
specialized for a particular aggregation function; the goal of Prio3 is to
provide the same level of generality as the original construction.</t>
      <t>The core component of Prio3 is a "Fully Linear Proof (FLP)" system. Introduced
by <xref target="BBCGGI19"/>, the FLP encapsulates the functionality required for encoding
and validating measurements. Prio3 can be thought of as a transformation of a
particular class of FLPs into a VDAF.</t>
      <t>The remainder of this section is structured as follows. The syntax for FLPs is
described in <xref target="flp"/>. The generic transformation of an FLP into Prio3 is
specified in <xref target="prio3-construction"/>. Next, a concrete FLP suitable for any
validity circuit is specified in <xref target="flp-generic"/>. Finally, instantiations of
Prio3 for various types of measurements are specified in
<xref target="prio3-instantiations"/>. Test vectors can be found in <xref target="test-vectors"/>.</t>
      <section anchor="flp">
        <name>Fully Linear Proof (FLP) Systems</name>
        <t>Conceptually, an FLP is a two-party protocol executed by a prover and a
verifier. In actual use, however, the prover's computation is carried out by
the Client, and the verifier's computation is distributed among the
Aggregators. The Client generates a "proof" of its measurement's validity and
distributes shares of the proof to the Aggregators. Each Aggregator then
performs some computation on its measurement share and proof share locally and
sends the result to the other Aggregators. Combining the exchanged messages
allows each Aggregator to decide if it holds a share of a valid measurement.
(See <xref target="prio3-construction"/> for details.)</t>
        <t>As usual, we will describe the interface implemented by a concrete FLP in terms
of an abstract base class <tt>Flp</tt> that specifies the set of methods and parameters
a concrete FLP must provide.</t>
        <t>The parameters provided by a concrete FLP are listed in <xref target="flp-param"/>.</t>
        <table anchor="flp-param">
          <name>Constants and types defined by a concrete FLP.</name>
          <thead>
            <tr>
              <th align="left">Parameter</th>
              <th align="left">Description</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">
                <tt>PROVE_RAND_LEN</tt></td>
              <td align="left">Length of the prover randomness, the number of random field elements consumed by the prover when generating a proof</td>
            </tr>
            <tr>
              <td align="left">
                <tt>QUERY_RAND_LEN</tt></td>
              <td align="left">Length of the query randomness, the number of random field elements consumed by the verifier</td>
            </tr>
            <tr>
              <td align="left">
                <tt>JOINT_RAND_LEN</tt></td>
              <td align="left">Length of the joint randomness, the number of random field elements consumed by both the prover and verifier</td>
            </tr>
            <tr>
              <td align="left">
                <tt>MEAS_LEN</tt></td>
              <td align="left">Length of the encoded measurement (<xref target="flp-encode"/>)</td>
            </tr>
            <tr>
              <td align="left">
                <tt>OUTPUT_LEN</tt></td>
              <td align="left">Length of the aggregatable output (<xref target="flp-encode"/>)</td>
            </tr>
            <tr>
              <td align="left">
                <tt>PROOF_LEN</tt></td>
              <td align="left">Length of the proof</td>
            </tr>
            <tr>
              <td align="left">
                <tt>VERIFIER_LEN</tt></td>
              <td align="left">Length of the verifier message generated by querying the measurement and proof</td>
            </tr>
            <tr>
              <td align="left">
                <tt>Measurement</tt></td>
              <td align="left">Type of the measurement</td>
            </tr>
            <tr>
              <td align="left">
                <tt>AggResult</tt></td>
              <td align="left">Type of the aggregate result</td>
            </tr>
            <tr>
              <td align="left">
                <tt>Field</tt></td>
              <td align="left">As defined in (<xref target="field"/>)</td>
            </tr>
          </tbody>
        </table>
        <t>An FLP specifies the following algorithms for generating and verifying proofs of
validity (encoding is described below in <xref target="flp-encode"/>):</t>
        <ul spacing="normal">
          <li>
            <tt>Flp.prove(meas: Vec[Field], prove_rand: Vec[Field], joint_rand: Vec[Field])
-&gt; Vec[Field]</tt> is the deterministic proof-generation algorithm run by the
prover. Its inputs are the encoded measurement, the "prover randomness"
<tt>prove_rand</tt>, and the "joint randomness" <tt>joint_rand</tt>. The prover randomness
is used only by the prover, but the joint randomness is shared by both the
prover and verifier.</li>
          <li>
            <tt>Flp.query(meas: Vec[Field], proof: Vec[Field], query_rand: Vec[Field],
joint_rand: Vec[Field], num_shares: Unsigned) -&gt; Vec[Field]</tt> is the
query-generation algorithm run by the verifier. This is used to "query" the
measurement and proof. The result of the query (i.e., the output of this
function) is called the "verifier message". In addition to the measurement
and proof, this algorithm takes as input the query randomness <tt>query_rand</tt>
and the joint randomness <tt>joint_rand</tt>. The former is used only by the
verifier. <tt>num_shares</tt> specifies how many shares were generated.</li>
          <li>
            <tt>Flp.decide(verifier: Vec[Field]) -&gt; Bool</tt> is the deterministic decision
algorithm run by the verifier. It takes as input the verifier message and
outputs a boolean indicating if the measurement from which it was generated
is valid.</li>
        </ul>
        <t>Our application requires that the FLP is "fully linear" in the sense defined in
<xref target="BBCGGI19"/>. As a practical matter, what this property implies is that, when
run on a share of the measurement and proof, the query-generation algorithm
outputs a share of the verifier message. Furthermore, the privacy property of
the FLP system ensures that the verifier message reveals nothing about the measurement
other than whether it is valid. Therefore, to decide if a measurement is valid, the
Aggregators will run the query-generation algorithm locally, exchange verifier
shares, combine them to recover the verifier message, and run the decision
algorithm.</t>
        <t>The query-generation algorithm includes a parameter <tt>num_shares</tt> that specifies
the number of shares that were generated. If these data are not secret shared,
then <tt>num_shares == 1</tt>. This parameter is useful for certain FLP constructions.
For example, the FLP in <xref target="flp-generic"/> is defined in terms of an arithmetic
circuit; when the circuit contains constants, it is sometimes necessary to
normalize those constants to ensure that the circuit's output, when run on a
valid measurement, is the same regardless of the number of shares.</t>
        <t>An FLP is executed by the prover and verifier as follows:</t>
        <figure anchor="run-flp">
          <name>Execution of an FLP.</name>
          <artwork><![CDATA[
def run_flp(flp, meas: Vec[Flp.Field], num_shares: Unsigned):
    joint_rand = flp.Field.rand_vec(flp.JOINT_RAND_LEN)
    prove_rand = flp.Field.rand_vec(flp.PROVE_RAND_LEN)
    query_rand = flp.Field.rand_vec(flp.QUERY_RAND_LEN)

    # Prover generates the proof.
    proof = flp.prove(meas, prove_rand, joint_rand)

    # Shard the measurement and the proof.
    meas_shares = additive_secret_share(meas, num_shares, flp.Field)
    proof_shares = additive_secret_share(proof, num_shares, flp.Field)

    # Verifier queries the meas shares and proof shares.
    verifier_shares = [
        flp.query(
            meas_share,
            proof_share,
            query_rand,
            joint_rand,
            num_shares,
        )
        for meas_share, proof_share in zip(meas_shares, proof_shares)
    ]

    # Combine the verifier shares into the verifier.
    verifier = flp.Field.zeros(len(verifier_shares[0]))
    for verifier_share in verifier_shares:
        verifier = vec_add(verifier, verifier_share)

    # Verifier decides if the measurement is valid.
    return flp.decide(verifier)

]]></artwork>
        </figure>
        <t>The proof system is constructed so that, if <tt>meas</tt> is valid, then <tt>run_flp(Flp,
meas, 1)</tt> always returns <tt>True</tt>. On the other hand, if <tt>meas</tt> is invalid, then
as long as <tt>joint_rand</tt> and <tt>query_rand</tt> are generated uniform randomly, the
output is <tt>False</tt> with overwhelming probability.</t>
        <t>We remark that <xref target="BBCGGI19"/> defines a much larger class of fully linear proof
systems than we consider here. In particular, what is called an "FLP" here is
called a 1.5-round, public-coin, interactive oracle proof system in their paper.</t>
        <section anchor="flp-encode">
          <name>Encoding the Input</name>
          <t>The type of measurement being aggregated is defined by the FLP. Hence, the FLP
also specifies a method of encoding raw measurements as a vector of field
elements:</t>
          <ul spacing="normal">
            <li>
              <tt>Flp.encode(measurement: Measurement) -&gt; Vec[Field]</tt> encodes a raw measurement
as a vector of field elements. The return value <bcp14>MUST</bcp14> be of length <tt>MEAS_LEN</tt>.</li>
          </ul>
          <t>For some FLPs, the encoded measurement also includes redundant field elements
that are useful for checking the proof, but which are not needed after the
proof has been checked. An example is the "integer sum" data type from
<xref target="CGB17"/> in which an integer in range <tt>[0, 2^k)</tt> is encoded as a vector of <tt>k</tt>
field elements, each representing a bit of the integer (this type is also
defined in <xref target="prio3sum"/>). After consuming this vector, all that is needed is
the integer it represents. Thus the FLP defines an algorithm for truncating the
encoded measurement to the length of the aggregated output:</t>
          <ul spacing="normal">
            <li>
              <tt>Flp.truncate(meas: Vec[Field]) -&gt; Vec[Field]</tt> maps an encoded measurement
(e.g., the bit-encoding of the measurement) to an aggregatable output (e.g.,
the singleton vector containing the measurement). The length of the input
<bcp14>MUST</bcp14> be <tt>MEAS_LEN</tt> and the length of the output <bcp14>MUST</bcp14> be <tt>OUTPUT_LEN</tt>.</li>
          </ul>
          <t>Once the aggregate shares have been computed and combined together, their sum
can be converted into the aggregate result. This could be a projection from
the FLP's field to the integers, or it could include additional
post-processing.</t>
          <ul spacing="normal">
            <li>
              <tt>Flp.decode(output: Vec[Field], num_measurements: Unsigned) -&gt; AggResult</tt>
maps a sum of aggregate shares to an aggregate result. The length of the
input <bcp14>MUST</bcp14> be <tt>OUTPUT_LEN</tt>. <tt>num_measurements</tt> is the number of measurements
that contributed to the aggregated output.</li>
          </ul>
          <t>We remark that, taken together, these three functionalities correspond roughly
to the notion of "Affine-aggregatable encodings (AFEs)" from <xref target="CGB17"/>.</t>
        </section>
      </section>
      <section anchor="prio3-construction">
        <name>Construction</name>
        <t>This section specifies <tt>Prio3</tt>, an implementation of the <tt>Vdaf</tt> interface
(<xref target="vdaf"/>). It has two generic parameters: an <tt>Flp</tt> (<xref target="flp"/>) and a <tt>Xof</tt>
(<xref target="xof"/>). The associated constants and types required by the <tt>Vdaf</tt> interface
are defined in <xref target="prio3-param"/>. The methods required for sharding, preparation,
aggregation, and unsharding are described in the remaining subsections. These
methods refer to constants enumerated in <xref target="prio3-const"/>.</t>
        <table anchor="prio3-param">
          <name>VDAF parameters for Prio3.</name>
          <thead>
            <tr>
              <th align="left">Parameter</th>
              <th align="left">Value</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">
                <tt>VERIFY_KEY_SIZE</tt></td>
              <td align="left">
                <tt>Xof.SEED_SIZE</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>RAND_SIZE</tt></td>
              <td align="left">
                <tt>Xof.SEED_SIZE * (1 + 2 * (SHARES - 1)) if Flp.JOINT_RAND_LEN == 0 else Xof.SEED_SIZE * (1 + 2 * (SHARES - 1) + SHARES)</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>NONCE_SIZE</tt></td>
              <td align="left">
                <tt>16</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>ROUNDS</tt></td>
              <td align="left">
                <tt>1</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>SHARES</tt></td>
              <td align="left">in <tt>[2, 256)</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>Measurement</tt></td>
              <td align="left">
                <tt>Flp.Measurement</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>AggParam</tt></td>
              <td align="left">
                <tt>None</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>PublicShare</tt></td>
              <td align="left">
                <tt>Optional[list[bytes]]</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>InputShare</tt></td>
              <td align="left">
                <tt>Union[tuple[list[Flp.Field], list[Flp.Field], Optional[bytes]], tuple[bytes, bytes, Optional[bytes]]]</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>OutShare</tt></td>
              <td align="left">
                <tt>list[Flp.Field]</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>AggShare</tt></td>
              <td align="left">
                <tt>list[Flp.Field]</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>AggResult</tt></td>
              <td align="left">
                <tt>Flp.AggResult</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>PrepState</tt></td>
              <td align="left">
                <tt>tuple[list[Flp.Field], Optional[Bytes]]</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>PrepShare</tt></td>
              <td align="left">
                <tt>tuple[list[Flp.Field], Optional[Bytes]]</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>PrepMessage</tt></td>
              <td align="left">
                <tt>Optional[bytes]</tt></td>
            </tr>
          </tbody>
        </table>
        <table anchor="prio3-const">
          <name>Constants used by Prio3.</name>
          <thead>
            <tr>
              <th align="left">Variable</th>
              <th align="left">Value</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">
                <tt>USAGE_MEAS_SHARE: Unsigned</tt></td>
              <td align="left">1</td>
            </tr>
            <tr>
              <td align="left">
                <tt>USAGE_PROOF_SHARE: Unsigned</tt></td>
              <td align="left">2</td>
            </tr>
            <tr>
              <td align="left">
                <tt>USAGE_JOINT_RANDOMNESS: Unsigned</tt></td>
              <td align="left">3</td>
            </tr>
            <tr>
              <td align="left">
                <tt>USAGE_PROVE_RANDOMNESS: Unsigned</tt></td>
              <td align="left">4</td>
            </tr>
            <tr>
              <td align="left">
                <tt>USAGE_QUERY_RANDOMNESS: Unsigned</tt></td>
              <td align="left">5</td>
            </tr>
            <tr>
              <td align="left">
                <tt>USAGE_JOINT_RAND_SEED: Unsigned</tt></td>
              <td align="left">6</td>
            </tr>
            <tr>
              <td align="left">
                <tt>USAGE_JOINT_RAND_PART: Unsigned</tt></td>
              <td align="left">7</td>
            </tr>
          </tbody>
        </table>
        <section anchor="sharding">
          <name>Sharding</name>
          <t>Recall from <xref target="flp"/> that the FLP syntax calls for "joint randomness" shared by
the prover (i.e., the Client) and the verifier (i.e., the Aggregators). VDAFs
have no such notion. Instead, the Client derives the joint randomness from its
measurement in a way that allows the Aggregators to reconstruct it from their
shares. (This idea is based on the Fiat-Shamir heuristic and is described in
Section 6.2.3 of <xref target="BBCGGI19"/>.)</t>
          <t>The sharding algorithm involves the following steps:</t>
          <ol spacing="normal" type="1"><li>Encode the Client's measurement for the FLP</li>
            <li>Shard the measurement into a sequence of measurement shares</li>
            <li>Derive the joint randomness from the measurement shares and nonce</li>
            <li>Run the FLP proof-generation algorithm using the derived joint randomness</li>
            <li>Shard the proof into a sequence of proof shares</li>
            <li>Return the public share, consisting of the joint randomness parts, and the
input shares, each consisting of the measurement share, proof share, and
blind of one of the Aggregators</li>
          </ol>
          <t>Depending on the FLP, joint randomness may not be required. In particular, when
<tt>Flp.JOINT_RAND_LEN == 0</tt>, the Client does not derive the joint randomness
(Step 3). The sharding algorithm is specified below.</t>
          <figure anchor="prio3-eval-input">
            <name>Input-distribution algorithm for Prio3.</name>
            <artwork><![CDATA[
def shard(Prio3, measurement, nonce, rand):
    l = Prio3.Xof.SEED_SIZE
    seeds = [rand[i:i+l] for i in range(0, Prio3.RAND_SIZE, l)]

    meas = Prio3.Flp.encode(measurement)
    if Prio3.Flp.JOINT_RAND_LEN > 0:
        return Prio3.shard_with_joint_rand(meas, nonce, seeds)
    else:
        return Prio3.shard_without_joint_rand(meas, seeds)
]]></artwork>
          </figure>
          <t>It starts by splitting the randomness into seeds. It then encodes the
measurement as prescribed by the FLP and calls one of two methods, depending on
whether joint randomness is required by the FLP. The methods are defined in the
subsections below.</t>
          <section anchor="flps-without-joint-randomness">
            <name>FLPs without joint randomness</name>
            <t>The following method is used for FLPs that do not require joint randomness,
i.e., when <tt>Flp.JOINT_RAND_LEN == 0</tt>:</t>
            <figure anchor="prio3-shard-without-joint-rand">
              <name>Sharding an encoded measurement without joint randomness.</name>
              <artwork><![CDATA[
def shard_without_joint_rand(Prio3, meas, seeds):
    k_helper_seeds, seeds = front((Prio3.SHARES-1) * 2, seeds)
    k_helper_meas_shares = [
        k_helper_seeds[i]
        for i in range(0, (Prio3.SHARES-1) * 2, 2)
    ]
    k_helper_proof_shares = [
        k_helper_seeds[i]
        for i in range(1, (Prio3.SHARES-1) * 2, 2)
    ]
    (k_prove,), seeds = front(1, seeds)

    # Shard the encoded measurement into shares.
    leader_meas_share = meas
    for j in range(Prio3.SHARES-1):
        leader_meas_share = vec_sub(
            leader_meas_share,
            Prio3.helper_meas_share(j+1, k_helper_meas_shares[j]),
        )

    # Generate the proof and shard it into proof shares.
    prove_rand = Prio3.prove_rand(k_prove)
    leader_proof_share = Prio3.Flp.prove(meas, prove_rand, [])
    for j in range(Prio3.SHARES-1):
        leader_proof_share = vec_sub(
            leader_proof_share,
            Prio3.helper_proof_share(j+1, k_helper_proof_shares[j]),
        )

    # Each Aggregator's input share contains its measurement share
    # and proof share.
    input_shares = []
    input_shares.append((
        leader_meas_share,
        leader_proof_share,
        None,
    ))
    for j in range(Prio3.SHARES-1):
        input_shares.append((
            k_helper_meas_shares[j],
            k_helper_proof_shares[j],
            None,
        ))
    return (None, input_shares)
]]></artwork>
            </figure>
            <t>The steps in this method are as follows:</t>
            <ol spacing="normal" type="1"><li>Shard the encoded measurement into shares</li>
              <li>Generate the proof and shard the proof into shares</li>
              <li>Encode each measurement and proof share into an input share</li>
            </ol>
            <t>Notice that only one pair of measurement and proof shares (called the "leader"
shares above) are vectors of field elements. The other shares (called the
"helper" shares) are represented instead by XOF seeds, which are expanded into
vectors of field elements.</t>
            <t>The methods on <tt>Prio3</tt> for deriving the prover randomness, measurement shares,
and proof shares and the methods for encoding the input shares are defined in
<xref target="prio3-auxiliary"/>.</t>
          </section>
          <section anchor="flps-with-joint-randomness">
            <name>FLPs with joint randomness</name>
            <t>The following method is used for FLPs that require joint randomness,
i.e., for which <tt>Flp.JOINT_RAND_LEN &gt; 0</tt>:</t>
            <figure anchor="prio3-shard-with-joint-rand">
              <name>Sharding an encoded measurement with joint randomness.</name>
              <artwork><![CDATA[
def shard_with_joint_rand(Prio3, meas, nonce, seeds):
    k_helper_seeds, seeds = front((Prio3.SHARES-1) * 3, seeds)
    k_helper_meas_shares = [
        k_helper_seeds[i]
        for i in range(0, (Prio3.SHARES-1) * 3, 3)
    ]
    k_helper_proof_shares = [
        k_helper_seeds[i]
        for i in range(1, (Prio3.SHARES-1) * 3, 3)
    ]
    k_helper_blinds = [
        k_helper_seeds[i]
        for i in range(2, (Prio3.SHARES-1) * 3, 3)
    ]
    (k_leader_blind,), seeds = front(1, seeds)
    (k_prove,), seeds = front(1, seeds)

    # Shard the encoded measurement into shares and compute the
    # joint randomness parts.
    leader_meas_share = meas
    k_joint_rand_parts = []
    for j in range(Prio3.SHARES-1):
        helper_meas_share = Prio3.helper_meas_share(
            j+1, k_helper_meas_shares[j])
        leader_meas_share = vec_sub(leader_meas_share,
                                    helper_meas_share)
        k_joint_rand_parts.append(Prio3.joint_rand_part(
            j+1, k_helper_blinds[j], helper_meas_share, nonce))
    k_joint_rand_parts.insert(0, Prio3.joint_rand_part(
        0, k_leader_blind, leader_meas_share, nonce))

    # Generate the proof and shard it into proof shares.
    prove_rand = Prio3.prove_rand(k_prove)
    joint_rand = Prio3.joint_rand(
        Prio3.joint_rand_seed(k_joint_rand_parts))
    leader_proof_share = Prio3.Flp.prove(meas, prove_rand, joint_rand)
    for j in range(Prio3.SHARES-1):
        leader_proof_share = vec_sub(
            leader_proof_share,
            Prio3.helper_proof_share(j+1, k_helper_proof_shares[j]),
        )

    # Each Aggregator's input share contains its measurement share,
    # proof share, and blind. The public share contains the
    # Aggregators' joint randomness parts.
    input_shares = []
    input_shares.append((
        leader_meas_share,
        leader_proof_share,
        k_leader_blind,
    ))
    for j in range(Prio3.SHARES-1):
        input_shares.append((
            k_helper_meas_shares[j],
            k_helper_proof_shares[j],
            k_helper_blinds[j],
        ))
    return (k_joint_rand_parts, input_shares)
]]></artwork>
            </figure>
            <t>The difference between this procedure and previous one is that here we compute
joint randomness <tt>joint_rand</tt> and pass it to the proof generationg algorithm.
(In <xref target="prio3-shard-without-joint-rand"/> the joint randomness is the empty
vector, <tt>[]</tt>.) This requires generating an additional value, called the
"blind", that is incorporated into each input share.</t>
            <t>The joint randomness computation involves the following steps:</t>
            <ol spacing="normal" type="1"><li>Compute a "joint randomness part" from each measurement share and blind</li>
              <li>Compute a "joint randomness seed" from the joint randomness parts</li>
              <li>Compute the joint randomness from the joint randomness seed</li>
            </ol>
            <t>This three-step process is designed to ensure that the joint randomness does
not leak the measurement to the Aggregators while preventing a malicious Client
from tampering with the joint randomness in a way that allows it to break
robustness. To bootstrap the required check, the Client encodes the joint
randomness parts in the public share. (See <xref target="prio3-preparation"/> for details.)</t>
            <t>The methods used in this computation are defined in <xref target="prio3-auxiliary"/>.</t>
          </section>
        </section>
        <section anchor="prio3-preparation">
          <name>Preparation</name>
          <t>This section describes the process of recovering output shares from the input
shares. The high-level idea is that each Aggregator first queries its
measurement and proof share locally, then exchanges its verifier share with the
other Aggregators. The verifier shares are then combined into the verifier
message, which is used to decide whether to accept.</t>
          <t>In addition, for FLPs that require joint randomness, the Aggregators must
ensure that they have all used the same joint randomness for the
query-generation algorithm. To do so, they collectively re-derive the joint
randomness from their measurement shares just as the Client did during
sharding.</t>
          <t>In order to avoid extra round of communication, the Client sends each
Aggregator a "hint" consisting of the joint randomness parts. This leaves open
the possibility that the Client cheated by, say, forcing the Aggregators to use
joint randomness that biases the proof check procedure some way in its favor.
To mitigate this, the Aggregators also check that they have all computed the
same joint randomness seed before accepting their output shares. To do so, they
exchange their parts of the joint randomness along with their verifier shares.</t>
          <t>The definitions of constants and a few auxiliary functions are defined in
<xref target="prio3-auxiliary"/>.</t>
          <figure anchor="prio3-prep-state">
            <name>Preparation state for Prio3.</name>
            <artwork><![CDATA[
def prep_init(Prio3, verify_key, agg_id, _agg_param,
              nonce, public_share, input_share):
    k_joint_rand_parts = public_share
    (meas_share, proof_share, k_blind) = \
        Prio3.expand_input_share(agg_id, input_share)
    out_share = Prio3.Flp.truncate(meas_share)

    # Compute the joint randomness.
    joint_rand = []
    k_corrected_joint_rand, k_joint_rand_part = None, None
    if Prio3.Flp.JOINT_RAND_LEN > 0:
        k_joint_rand_part = Prio3.joint_rand_part(
            agg_id, k_blind, meas_share, nonce)
        k_joint_rand_parts[agg_id] = k_joint_rand_part
        k_corrected_joint_rand = Prio3.joint_rand_seed(
            k_joint_rand_parts)
        joint_rand = Prio3.joint_rand(k_corrected_joint_rand)

    # Query the measurement and proof share.
    query_rand = Prio3.query_rand(verify_key, nonce)
    verifier_share = Prio3.Flp.query(meas_share,
                                     proof_share,
                                     query_rand,
                                     joint_rand,
                                     Prio3.SHARES)

    prep_state = (out_share, k_corrected_joint_rand)
    prep_share = (verifier_share, k_joint_rand_part)
    return (prep_state, prep_share)

def prep_next(Prio3, prep, prep_msg):
    k_joint_rand = prep_msg
    (out_share, k_corrected_joint_rand) = prep

    # If joint randomness was used, check that the value computed by the
    # Aggregators matches the value indicated by the Client.
    if k_joint_rand != k_corrected_joint_rand:
        raise ERR_VERIFY  # joint randomness check failed

    return out_share

def prep_shares_to_prep(Prio3, _agg_param, prep_shares):
    # Unshard the verifier shares into the verifier message.
    verifier = Prio3.Flp.Field.zeros(Prio3.Flp.VERIFIER_LEN)
    k_joint_rand_parts = []
    for (verifier_share, k_joint_rand_part) in prep_shares:
        verifier = vec_add(verifier, verifier_share)
        if Prio3.Flp.JOINT_RAND_LEN > 0:
            k_joint_rand_parts.append(k_joint_rand_part)

    # Verify that the proof is well-formed and the input is valid.
    if not Prio3.Flp.decide(verifier):
        raise ERR_VERIFY  # proof verifier check failed

    # Combine the joint randomness parts computed by the
    # Aggregators into the true joint randomness seed. This is
    # used in the last step.
    k_joint_rand = None
    if Prio3.Flp.JOINT_RAND_LEN > 0:
        k_joint_rand = Prio3.joint_rand_seed(k_joint_rand_parts)
    return k_joint_rand
]]></artwork>
          </figure>
        </section>
        <section anchor="validity-of-aggregation-parameters">
          <name>Validity of Aggregation Parameters</name>
          <t>Every input share <bcp14>MUST</bcp14> only be used once, regardless of the aggregation
parameters used.</t>
          <figure anchor="prio3-validity-scope">
            <name>Validity of aggregation parameters for Prio3.</name>
            <artwork><![CDATA[
def is_valid(agg_param, previous_agg_params):
    return len(previous_agg_params) == 0
]]></artwork>
          </figure>
        </section>
        <section anchor="aggregation">
          <name>Aggregation</name>
          <t>Aggregating a set of output shares is simply a matter of adding up the vectors
element-wise.</t>
          <figure anchor="prio3-out2agg">
            <name>Aggregation algorithm for Prio3.</name>
            <artwork><![CDATA[
def aggregate(Prio3, _agg_param, out_shares):
    agg_share = Prio3.Flp.Field.zeros(Prio3.Flp.OUTPUT_LEN)
    for out_share in out_shares:
        agg_share = vec_add(agg_share, out_share)
    return agg_share
]]></artwork>
          </figure>
        </section>
        <section anchor="unsharding">
          <name>Unsharding</name>
          <t>To unshard a set of aggregate shares, the Collector first adds up the vectors
element-wise. It then converts each element of the vector into an integer.</t>
          <figure anchor="prio3-agg-output">
            <name>Computation of the aggregate result for Prio3.</name>
            <artwork><![CDATA[
def unshard(Prio3, _agg_param,
            agg_shares, num_measurements):
    agg = Prio3.Flp.Field.zeros(Prio3.Flp.OUTPUT_LEN)
    for agg_share in agg_shares:
        agg = vec_add(agg, agg_share)
    return Prio3.Flp.decode(agg, num_measurements)
]]></artwork>
          </figure>
        </section>
        <section anchor="prio3-auxiliary">
          <name>Auxiliary Functions</name>
          <t>This section defines a number of auxiliary functions referenced by the main
algorithms for Prio3 in the preceding sections.</t>
          <t>The following methods are called by the sharding and preparation algorithms.</t>
          <artwork><![CDATA[
def helper_meas_share(Prio3, agg_id, k_share):
    return Prio3.Xof.expand_into_vec(
        Prio3.Flp.Field,
        k_share,
        Prio3.domain_separation_tag(USAGE_MEAS_SHARE),
        byte(agg_id),
        Prio3.Flp.MEAS_LEN,
    )

def helper_proof_share(Prio3, agg_id, k_share):
    return Prio3.Xof.expand_into_vec(
        Prio3.Flp.Field,
        k_share,
        Prio3.domain_separation_tag(USAGE_PROOF_SHARE),
        byte(agg_id),
        Prio3.Flp.PROOF_LEN,
    )

def expand_input_share(Prio3, agg_id, input_share):
    (meas_share, proof_share, k_blind) = input_share
    if agg_id > 0:
        meas_share = Prio3.helper_meas_share(agg_id, meas_share)
        proof_share = Prio3.helper_proof_share(agg_id, proof_share)
    return (meas_share, proof_share, k_blind)

def prove_rand(Prio3, k_prove):
    return Prio3.Xof.expand_into_vec(
        Prio3.Flp.Field,
        k_prove,
        Prio3.domain_separation_tag(USAGE_PROVE_RANDOMNESS),
        b'',
        Prio3.Flp.PROVE_RAND_LEN,
    )

def query_rand(Prio3, verify_key, nonce):
    return Prio3.Xof.expand_into_vec(
        Prio3.Flp.Field,
        verify_key,
        Prio3.domain_separation_tag(USAGE_QUERY_RANDOMNESS),
        nonce,
        Prio3.Flp.QUERY_RAND_LEN,
    )

def joint_rand_part(Prio3, agg_id, k_blind, meas_share, nonce):
    return Prio3.Xof.derive_seed(
        k_blind,
        Prio3.domain_separation_tag(USAGE_JOINT_RAND_PART),
        byte(agg_id) + nonce + Prio3.Flp.Field.encode_vec(meas_share),
    )

def joint_rand_seed(Prio3, k_joint_rand_parts):
    """Derive the joint randomness seed from its parts."""
    return Prio3.Xof.derive_seed(
        zeros(Prio3.Xof.SEED_SIZE),
        Prio3.domain_separation_tag(USAGE_JOINT_RAND_SEED),
        concat(k_joint_rand_parts),
    )

def joint_rand(Prio3, k_joint_rand_seed):
    """Derive the joint randomness from its seed."""
    return Prio3.Xof.expand_into_vec(
        Prio3.Flp.Field,
        k_joint_rand_seed,
        Prio3.domain_separation_tag(USAGE_JOINT_RANDOMNESS),
        b'',
        Prio3.Flp.JOINT_RAND_LEN,
    )
]]></artwork>
        </section>
        <section anchor="prio3-encode">
          <name>Message Serialization</name>
          <t>This section defines serialization formats for messages exchanged over the
network while executing Prio3. It is <bcp14>RECOMMENDED</bcp14> that implementations provide
serialization methods for them.</t>
          <t>Message structures are defined following <xref section="3" sectionFormat="of" target="RFC8446"/>). In the
remainder we use <tt>S</tt> as an alias for <tt>Prio3.Xof.SEED_SIZE</tt> and <tt>F</tt> as an alias
for <tt>Prio3.Field.ENCODED_SIZE</tt>. XOF seeds are represented as follows:</t>
          <artwork><![CDATA[
opaque Prio3Seed[S];
]]></artwork>
          <t>Field elements are encoded in little-endian byte order (as defined in
<xref target="field"/>) and represented as follows:</t>
          <artwork><![CDATA[
opaque Prio3Field[F];
]]></artwork>
          <section anchor="public-share">
            <name>Public Share</name>
            <t>The encoding of the public share depends on whether joint randomness is
required for the underlying FLP (i.e., <tt>Prio3.Flp.JOINT_RAND_LEN &gt; 0</tt>). If
joint randomness is not used, then the public share is the empty string. If
joint randomness is used, then the public share encodes the joint randomness
parts as follows:</t>
            <artwork><![CDATA[
struct {
    Prio3Seed k_joint_rand_parts[S * Prio3.SHARES];
} Prio3PublicShareWithJointRand;
]]></artwork>
          </section>
          <section anchor="input-share">
            <name>Input share</name>
            <t>Just as for the public share, the encoding of the input shares depends on
whether joint randomness is used. If so, then each input share includes the
Aggregator's blind for generating its joint randomness part.</t>
            <t>In addition, the encoding of the input shares depends on which aggregator is
receiving the message. If the aggregator ID is <tt>0</tt>, then the input share
includes the full measurement and proof share. Otherwise, if the aggregator ID
is greater than <tt>0</tt>, then the measurement and proof shares are represented by
XOF seeds. We shall call the former the "Leader" and the latter the "Helpers".</t>
            <t>In total there are four variants of the input share. When joint randomness is
not used, the Leader's share is structured as follows:</t>
            <artwork><![CDATA[
struct {
    Prio3Field meas_share[F * Prio3.Flp.MEAS_LEN];
    Prio3Field proof_share[F * Prio3.Flp.PROOF_LEN];
} Prio3LeaderShare;
]]></artwork>
            <t>When joint randomness is not used, the Helpers' shares are structured
as follows:</t>
            <artwork><![CDATA[
struct {
    Prio3Seed k_meas_share;
    Prio3Seed k_proof_share;
} Prio3HelperShare;
]]></artwork>
            <t>When joint randomness is used, the Leader's input share is structured as
follows:</t>
            <artwork><![CDATA[
struct {
    Prio3LeaderShare inner;
    Prio3Seed k_blind;
} Prio3LeaderShareWithJointRand;
]]></artwork>
            <t>Finally, when joint randomness is used, the Helpers' shares are structured as
follows:</t>
            <artwork><![CDATA[
struct {
    Prio3HelperShare inner;
    Prio3Seed k_blind;
} Prio3HelperShareWithJointRand;
]]></artwork>
          </section>
          <section anchor="prep-share">
            <name>Prep Share</name>
            <t>When joint randomness is not used, the prep share is structured as follows:</t>
            <artwork><![CDATA[
struct {
    Prio3Field verifier_share[F * Prio3.Flp.VERIFIER_LEN];
} Prio3PrepShare;
]]></artwork>
            <t>When joint randomness is used, the prep share includes the Aggregator's joint
randomness part and is structured as follows:</t>
            <artwork><![CDATA[
struct {
    Prio3Field verifier_share[F * Prio3.Flp.VERIFIER_LEN];
    Prio3Seed k_joint_rand_part;
} Prio3PrepShareWithJointRand;
]]></artwork>
          </section>
          <section anchor="prep-message">
            <name>Prep Message</name>
            <t>When joint randomness is not used, the prep message is the empty string.
Otherwise the prep message consists of the joint randomness seed computed by
the Aggregators:</t>
            <artwork><![CDATA[
struct {
    Prio3Seed k_joint_rand;
} Prio3PrepMessageWithJointRand;
]]></artwork>
          </section>
          <section anchor="aggregation-1">
            <name>Aggregation</name>
            <t>Aggregate shares are structured as follows:</t>
            <artwork><![CDATA[
struct {
    Prio3Field agg_share[F * Prio3.Flp.OUTPUT_LEN];
} Prio3AggShare;
]]></artwork>
          </section>
        </section>
      </section>
      <section anchor="flp-generic">
        <name>A General-Purpose FLP</name>
        <t>This section describes an FLP based on the construction from in <xref target="BBCGGI19"/>,
Section 4.2. We begin in <xref target="flp-generic-overview"/> with an overview of their proof
system and the extensions to their proof system made here. The construction is
specified in <xref target="flp-generic-construction"/>.</t>
        <ul empty="true">
          <li>
            <t>OPEN ISSUE We're not yet sure if specifying this general-purpose FLP is
desirable. It might be preferable to specify specialized FLPs for each data
type that we want to standardize, for two reasons. First, clear and concise
specifications are likely easier to write for specialized FLPs rather than the
general one. Second, we may end up tailoring each FLP to the measurement type
in a way that improves performance, but breaks compatibility with the
general-purpose FLP.</t>
            <t>In any case, we can't make this decision until we know which data types to
standardize, so for now, we'll stick with the general-purpose construction.
The reference implementation can be found at
https://github.com/cfrg/draft-irtf-cfrg-vdaf/tree/main/poc.</t>
          </li>
        </ul>
        <ul empty="true">
          <li>
            <t>OPEN ISSUE Chris Wood points out that the this section reads more like a paper
than a standard. Eventually we'll want to work this into something that is
readily consumable by the CFRG.</t>
          </li>
        </ul>
        <section anchor="flp-generic-overview">
          <name>Overview</name>
          <t>In the proof system of <xref target="BBCGGI19"/>, validity is defined via an arithmetic
circuit evaluated over the encoded measurement: If the circuit output is zero,
then the measurement is deemed valid; otherwise, if the circuit output is
non-zero, then the measurement is deemed invalid. Thus the goal of the proof
system is merely to allow the verifier to evaluate the validity circuit over
the measurement. For our application (<xref target="prio3"/>), this computation is
distributed among multiple Aggregators, each of which has only a share of the
measurement.</t>
          <t>Suppose for a moment that the validity circuit <tt>C</tt> is affine, meaning its only
operations are addition and multiplication-by-constant. In particular, suppose
the circuit does not contain a multiplication gate whose operands are both
non-constant. Then to decide if a measurement <tt>x</tt> is valid, each Aggregator
could evaluate <tt>C</tt> on its share of <tt>x</tt> locally, broadcast the output share to
its peers, then combine the output shares locally to recover <tt>C(x)</tt>. This is
true because for any <tt>SHARES</tt>-way secret sharing of <tt>x</tt> it holds that</t>
          <artwork><![CDATA[
C(x_shares[0] + ... + x_shares[SHARES-1]) =
    C(x_shares[0]) + ... + C(x_shares[SHARES-1])
]]></artwork>
          <t>(Note that, for this equality to hold, it may be necessary to scale any
constants in the circuit by <tt>SHARES</tt>.) However this is not the case if <tt>C</tt> is
not-affine (i.e., it contains at least one multiplication gate whose operands
are non-constant). In the proof system of <xref target="BBCGGI19"/>, the proof is designed to
allow the (distributed) verifier to compute the non-affine operations using only
linear operations on (its share of) the measurement and proof.</t>
          <t>To make this work, the proof system is restricted to validity circuits that
exhibit a special structure. Specifically, an arithmetic circuit with "G-gates"
(see <xref target="BBCGGI19"/>, Definition 5.2) is composed of affine gates and any number of
instances of a distinguished gate <tt>G</tt>, which may be non-affine. We will refer to
this class of circuits as 'gadget circuits' and to <tt>G</tt> as the "gadget".</t>
          <t>As an illustrative example, consider a validity circuit <tt>C</tt> that recognizes the
set <tt>L = set([0], [1])</tt>. That is, <tt>C</tt> takes as input a length-1 vector <tt>x</tt> and
returns 0 if <tt>x[0]</tt> is in <tt>[0,2)</tt> and outputs something else otherwise. This
circuit can be expressed as the following degree-2 polynomial:</t>
          <artwork><![CDATA[
C(x) = (x[0] - 1) * x[0] = x[0]^2 - x[0]
]]></artwork>
          <t>This polynomial recognizes <tt>L</tt> because <tt>x[0]^2 = x[0]</tt> is only true if <tt>x[0] ==
0</tt> or <tt>x[0] == 1</tt>. Notice that the polynomial involves a non-affine operation,
<tt>x[0]^2</tt>. In order to apply <xref target="BBCGGI19"/>, Theorem 4.3, the circuit needs to be
rewritten in terms of a gadget that subsumes this non-affine operation. For
example, the gadget might be multiplication:</t>
          <artwork><![CDATA[
Mul(left, right) = left * right
]]></artwork>
          <t>The validity circuit can then be rewritten in terms of <tt>Mul</tt> like so:</t>
          <artwork><![CDATA[
C(x[0]) = Mul(x[0], x[0]) - x[0]
]]></artwork>
          <t>The proof system of <xref target="BBCGGI19"/> allows the verifier to evaluate each instance
of the gadget (i.e., <tt>Mul(x[0], x[0])</tt> in our example) using a linear function
of the measurement and proof. The proof is constructed roughly as follows. Let
<tt>C</tt> be the validity circuit and suppose the gadget is arity-<tt>L</tt> (i.e., it has
<tt>L</tt> input wires.). Let <tt>wire[j-1,k-1]</tt> denote the value of the <tt>j</tt>th wire of
the <tt>k</tt>th call to the gadget during the evaluation of <tt>C(x)</tt>. Suppose there are
<tt>M</tt> such calls and fix distinct field elements <tt>alpha[0], ..., alpha[M-1]</tt>. (We
will require these points to have a special property, as we'll discuss in
<xref target="flp-generic-overview-extensions"/>; but for the moment it is only important
that they are distinct.)</t>
          <t>The prover constructs from <tt>wire</tt> and <tt>alpha</tt> a polynomial that, when evaluated
at <tt>alpha[k-1]</tt>, produces the output of the <tt>k</tt>th call to the gadget. Let us
call this the "gadget polynomial". Polynomial evaluation is linear, which means
that, in the distributed setting, the Client can disseminate additive shares of
the gadget polynomial that the Aggregators then use to compute additive shares
of each gadget output, allowing each Aggregator to compute its share of <tt>C(x)</tt>
locally.</t>
          <t>There is one more wrinkle, however: It is still possible for a malicious prover
to produce a gadget polynomial that would result in <tt>C(x)</tt> being computed
incorrectly, potentially resulting in an invalid measurement being accepted. To
prevent this, the verifier performs a probabilistic test to check that the
gadget polynomial is well-formed. This test, and the procedure for constructing
the gadget polynomial, are described in detail in <xref target="flp-generic-construction"/>.</t>
          <section anchor="flp-generic-overview-extensions">
            <name>Extensions</name>
            <t>The FLP described in the next section extends the proof system of <xref target="BBCGGI19"/>,
Section 4.2 in three ways.</t>
            <t>First, the validity circuit in our construction includes an additional, random
input (this is the "joint randomness" derived from the measurement shares in
Prio3; see <xref target="prio3-construction"/>). This allows for circuit optimizations that
trade a small soundness error for a shorter proof. For example, consider a
circuit that recognizes the set of length-<tt>N</tt> vectors for which each element is
either one or zero. A deterministic circuit could be constructed for this
language, but it would involve a large number of multiplications that would
result in a large proof. (See the discussion in <xref target="BBCGGI19"/>, Section 5.2 for
details). A much shorter proof can be constructed for the following randomized
circuit:</t>
            <artwork><![CDATA[
C(meas, r) = r * Range2(meas[0]) + ... + r^N * Range2(meas[N-1])
]]></artwork>
            <t>(Note that this is a special case of <xref target="BBCGGI19"/>, Theorem 5.2.) Here <tt>meas</tt> is
the length-<tt>N</tt> input and <tt>r</tt> is a random field element. The gadget circuit
<tt>Range2</tt> is the "range-check" polynomial described above, i.e., <tt>Range2(x) =
x^2 - x</tt>. The idea is that, if <tt>meas</tt> is valid (i.e., each <tt>meas[j]</tt> is in
<tt>[0,2)</tt>), then the circuit will evaluate to 0 regardless of the value of <tt>r</tt>;
but if <tt>meas[j]</tt> is not in <tt>[0,2)</tt> for some <tt>j</tt>, the output will be non-zero
with high probability.</t>
            <t>The second extension implemented by our FLP allows the validity circuit to
contain multiple gadget types. (This generalization was suggested in
<xref target="BBCGGI19"/>, Remark 4.5.) This provides additional flexibility for designing
circuits by allowing multiple, non-affine sub-components. For example, the
following circuit is allowed:</t>
            <artwork><![CDATA[
C(meas, r) = r * Range2(meas[0]) + ... + r^L * Range2(meas[L-1]) + \
            r^(L+1) * Range3(meas[L]) + ... + r^N * Range3(meas[N-1])
]]></artwork>
            <t>where <tt>Range3(x) = x^3 - 3x^2 + 2x</tt>. This circuit checks that the first <tt>L</tt>
inputs are in range <tt>[0,2)</tt> and the last <tt>N-L</tt> inputs are in range <tt>[0,3)</tt>. Of
course, the same circuit can be expressed using a sub-component that the
gadgets have in common, namely <tt>Mul</tt>, but the resulting proof would be longer.</t>
            <t>Finally, <xref target="BBCGGI19"/>, Theorem 4.3 makes no restrictions on the choice of the
fixed points <tt>alpha[0], ..., alpha[M-1]</tt>, other than to require that the points
are distinct. In this document, the fixed points are chosen so that the gadget
polynomial can be constructed efficiently using the Cooley-Tukey FFT ("Fast
Fourier Transform") algorithm. Note that this requires the field to be
"FFT-friendly" as defined in <xref target="field-fft-friendly"/>.</t>
          </section>
        </section>
        <section anchor="flp-generic-valid">
          <name>Validity Circuits</name>
          <t>The FLP described in <xref target="flp-generic-construction"/> is defined in terms of a
validity circuit <tt>Valid</tt> that implements the interface described here.</t>
          <t>A concrete <tt>Valid</tt> defines the following parameters:</t>
          <table>
            <name>Validity circuit parameters.</name>
            <thead>
              <tr>
                <th align="left">Parameter</th>
                <th align="left">Description</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">
                  <tt>GADGETS</tt></td>
                <td align="left">A list of gadgets</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>GADGET_CALLS</tt></td>
                <td align="left">Number of times each gadget is called</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>MEAS_LEN</tt></td>
                <td align="left">Length of the measurement</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>OUTPUT_LEN</tt></td>
                <td align="left">Length of the aggregatable output</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>JOINT_RAND_LEN</tt></td>
                <td align="left">Length of the random input</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>Measurement</tt></td>
                <td align="left">The type of measurement</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>AggResult</tt></td>
                <td align="left">Type of the aggregate result</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>Field</tt></td>
                <td align="left">An FFT-friendly finite field as defined in <xref target="field-fft-friendly"/></td>
              </tr>
            </tbody>
          </table>
          <t>Each gadget <tt>G</tt> in <tt>GADGETS</tt> defines a constant <tt>DEGREE</tt> that specifies the
circuit's "arithmetic degree". This is defined to be the degree of the
polynomial that computes it. For example, the <tt>Mul</tt> circuit in
<xref target="flp-generic-overview"/> is defined by the polynomial <tt>Mul(x) = x * x</tt>, which
has degree <tt>2</tt>. Hence, the arithmetic degree of this gadget is <tt>2</tt>.</t>
          <t>Each gadget also defines a parameter <tt>ARITY</tt> that specifies the circuit's arity
(i.e., the number of input wires).</t>
          <t>Gadgets provide a method to evaluate their circuit on a list of inputs,
<tt>eval()</tt>. The inputs can either belong to the validity circuit's field, or the
polynomial ring over that field.</t>
          <t>A concrete <tt>Valid</tt> provides the following methods for encoding a measurement as
an input vector, truncating an input vector to the length of an aggregatable
output, and converting an aggregated output to an aggregate result:</t>
          <ul spacing="normal">
            <li>
              <tt>Valid.encode(measurement: Measurement) -&gt; Vec[Field]</tt> returns a vector of
length <tt>MEAS_LEN</tt> representing a measurement.</li>
            <li>
              <tt>Valid.truncate(meas: Vec[Field]) -&gt; Vec[Field]</tt> returns a vector of length
<tt>OUTPUT_LEN</tt> representing an aggregatable output.</li>
            <li>
              <tt>Valid.decode(output: Vec[Field], num_measurements: Unsigned) -&gt; AggResult</tt>
returns an aggregate result.</li>
          </ul>
          <t>Finally, the following methods are derived for each concrete <tt>Valid</tt>:</t>
          <figure>
            <name>Derived methods for validity circuits.</name>
            <artwork><![CDATA[
def prove_rand_len(self):
    """Length of the prover randomness."""
    return sum(g.ARITY for g in Valid.GADGETS)

def query_rand_len(self):
    """Length of the query randomness."""
    return len(Valid.GADGETS)

def proof_len(self):
    """Length of the proof."""
    length = 0
    for (g, g_calls) in zip(self.GADGETS, self.GADGET_CALLS):
        P = next_power_of_2(1 + g_calls)
        length += g.ARITY + g.DEGREE * (P - 1) + 1
    return length

def verifier_len(self):
    """Length of the verifier message."""
    length = 1
    for g in self.GADGETS:
        length += g.ARITY + 1
    return length
]]></artwork>
          </figure>
        </section>
        <section anchor="flp-generic-construction">
          <name>Construction</name>
          <t>This section specifies <tt>FlpGeneric</tt>, an implementation of the <tt>Flp</tt> interface
(<xref target="flp"/>). It has as a generic parameter a validity circuit <tt>Valid</tt> implementing
the interface defined in <xref target="flp-generic-valid"/>.</t>
          <ul empty="true">
            <li>
              <t>NOTE A reference implementation can be found in
https://github.com/cfrg/draft-irtf-cfrg-vdaf/blob/main/poc/flp_generic.py.</t>
            </li>
          </ul>
          <t>The FLP parameters for <tt>FlpGeneric</tt> are defined in <xref target="flp-generic-param"/>. The
required methods for generating the proof, generating the verifier, and deciding
validity are specified in the remaining subsections.</t>
          <t>In the remainder, we let <tt>[n]</tt> denote the set <tt>{1, ..., n}</tt> for positive integer
<tt>n</tt>. We also define the following constants:</t>
          <ul spacing="normal">
            <li>Let <tt>H = len(Valid.GADGETS)</tt></li>
            <li>
              <t>For each <tt>i</tt> in <tt>[H]</tt>:
              </t>
              <ul spacing="normal">
                <li>Let <tt>G_i = Valid.GADGETS[i]</tt></li>
                <li>Let <tt>L_i = Valid.GADGETS[i].ARITY</tt></li>
                <li>Let <tt>M_i = Valid.GADGET_CALLS[i]</tt></li>
                <li>Let <tt>P_i = next_power_of_2(M_i+1)</tt></li>
                <li>Let <tt>alpha_i = Field.gen()^(Field.GEN_ORDER / P_i)</tt></li>
              </ul>
            </li>
          </ul>
          <table anchor="flp-generic-param">
            <name>FLP Parameters of FlpGeneric.</name>
            <thead>
              <tr>
                <th align="left">Parameter</th>
                <th align="left">Value</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">
                  <tt>PROVE_RAND_LEN</tt></td>
                <td align="left">
                  <tt>Valid.prove_rand_len()</tt> (see <xref target="flp-generic-valid"/>)</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>QUERY_RAND_LEN</tt></td>
                <td align="left">
                  <tt>Valid.query_rand_len()</tt> (see <xref target="flp-generic-valid"/>)</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>JOINT_RAND_LEN</tt></td>
                <td align="left">
                  <tt>Valid.JOINT_RAND_LEN</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>MEAS_LEN</tt></td>
                <td align="left">
                  <tt>Valid.MEAS_LEN</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>OUTPUT_LEN</tt></td>
                <td align="left">
                  <tt>Valid.OUTPUT_LEN</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>PROOF_LEN</tt></td>
                <td align="left">
                  <tt>Valid.proof_len()</tt> (see <xref target="flp-generic-valid"/>)</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>VERIFIER_LEN</tt></td>
                <td align="left">
                  <tt>Valid.verifier_len()</tt> (see <xref target="flp-generic-valid"/>)</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>Measurement</tt></td>
                <td align="left">
                  <tt>Valid.Measurement</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>Field</tt></td>
                <td align="left">
                  <tt>Valid.Field</tt></td>
              </tr>
            </tbody>
          </table>
          <section anchor="flp-generic-construction-prove">
            <name>Proof Generation</name>
            <t>On input of <tt>meas</tt>, <tt>prove_rand</tt>, and <tt>joint_rand</tt>, the proof is computed as
follows:</t>
            <ol spacing="normal" type="1"><li>For each <tt>i</tt> in <tt>[H]</tt> create an empty table <tt>wire_i</tt>.</li>
              <li>Partition the prover randomness <tt>prove_rand</tt> into sub-vectors <tt>seed_1, ...,
seed_H</tt> where <tt>len(seed_i) == L_i</tt> for all <tt>i</tt> in <tt>[H]</tt>. Let us call these
the "wire seeds" of each gadget.</li>
              <li>Evaluate <tt>Valid</tt> on input of <tt>meas</tt> and <tt>joint_rand</tt>, recording the inputs
of each gadget in the corresponding table. Specifically, for every <tt>i</tt> in
<tt>[H]</tt>, set <tt>wire_i[j-1,k-1]</tt> to the value on the <tt>j</tt>th wire into the <tt>k</tt>th
call to gadget <tt>G_i</tt>.</li>
              <li>
                <t>Compute the "wire polynomials". That is, for every <tt>i</tt> in <tt>[H]</tt> and <tt>j</tt> in
<tt>[L_i]</tt>, construct <tt>poly_wire_i[j-1]</tt>, the <tt>j</tt>th wire polynomial for the
<tt>i</tt>th gadget, as follows:  </t>
                <ul spacing="normal">
                  <li>Let <tt>w = [seed_i[j-1], wire_i[j-1,0], ..., wire_i[j-1,M_i-1]]</tt>.</li>
                  <li>Let <tt>padded_w = w + Field.zeros(P_i - len(w))</tt>.</li>
                </ul>
                <ul empty="true">
                  <li>
                    <t>NOTE We pad <tt>w</tt> to the nearest power of 2 so that we can use FFT for
interpolating the wire polynomials. Perhaps there is some clever math for
picking <tt>wire_inp</tt> in a way that avoids having to pad.</t>
                  </li>
                </ul>
                <ul spacing="normal">
                  <li>Let <tt>poly_wire_i[j-1]</tt> be the lowest degree polynomial for which
<tt>poly_wire_i[j-1](alpha_i^k) == padded_w[k]</tt> for all <tt>k</tt> in <tt>[P_i]</tt>.</li>
                </ul>
              </li>
              <li>
                <t>Compute the "gadget polynomials". That is, for every <tt>i</tt> in <tt>[H]</tt>:  </t>
                <ul spacing="normal">
                  <li>Let <tt>poly_gadget_i = G_i(poly_wire_i[0], ..., poly_wire_i[L_i-1])</tt>. That
is, evaluate the circuit <tt>G_i</tt> on the wire polynomials for the <tt>i</tt>th
gadget. (Arithmetic is in the ring of polynomials over <tt>Field</tt>.)</li>
                </ul>
              </li>
            </ol>
            <t>The proof is the vector <tt>proof = seed_1 + coeff_1 + ... + seed_H + coeff_H</tt>,
where <tt>coeff_i</tt> is the vector of coefficients of <tt>poly_gadget_i</tt> for each <tt>i</tt> in
<tt>[H]</tt>.</t>
          </section>
          <section anchor="flp-generic-construction-query">
            <name>Query Generation</name>
            <t>On input of <tt>meas</tt>, <tt>proof</tt>, <tt>query_rand</tt>, and <tt>joint_rand</tt>, the verifier message
is generated as follows:</t>
            <ol spacing="normal" type="1"><li>For every <tt>i</tt> in <tt>[H]</tt> create an empty table <tt>wire_i</tt>.</li>
              <li>Partition <tt>proof</tt> into the sub-vectors <tt>seed_1</tt>, <tt>coeff_1</tt>, ..., <tt>seed_H</tt>,
<tt>coeff_H</tt> defined in <xref target="flp-generic-construction-prove"/>.</li>
              <li>Evaluate <tt>Valid</tt> on input of <tt>meas</tt> and <tt>joint_rand</tt>, recording the inputs
of each gadget in the corresponding table. This step is similar to the
prover's step (3.) except the verifier does not evaluate the gadgets.
Instead, it computes the output of the <tt>k</tt>th call to <tt>G_i</tt> by evaluating
<tt>poly_gadget_i(alpha_i^k)</tt>. Let <tt>v</tt> denote the output of the circuit
evaluation.</li>
              <li>Compute the wire polynomials just as in the prover's step (4.).</li>
              <li>
                <t>Compute the tests for well-formedness of the gadget polynomials. That is, for
every <tt>i</tt> in <tt>[H]</tt>:  </t>
                <ul spacing="normal">
                  <li>Let <tt>t = query_rand[i]</tt>. Check if <tt>t^(P_i) == 1</tt>: If so, then raise
ERR_ABORT and halt. (This prevents the verifier from inadvertently leaking
a gadget output in the verifier message.)</li>
                  <li>Let <tt>y_i = poly_gadget_i(t)</tt>.</li>
                  <li>For each <tt>j</tt> in <tt>[0,L_i)</tt> let <tt>x_i[j-1] = poly_wire_i[j-1](t)</tt>.</li>
                </ul>
              </li>
            </ol>
            <t>The verifier message is the vector <tt>verifier = [v] + x_1 + [y_1] + ... + x_H +
[y_H]</tt>.</t>
          </section>
          <section anchor="decision">
            <name>Decision</name>
            <t>On input of vector <tt>verifier</tt>, the verifier decides if the measurement is valid
as follows:</t>
            <ol spacing="normal" type="1"><li>Parse <tt>verifier</tt> into <tt>v</tt>, <tt>x_1</tt>, <tt>y_1</tt>, ..., <tt>x_H</tt>, <tt>y_H</tt> as defined in
<xref target="flp-generic-construction-query"/>.</li>
              <li>
                <t>Check for well-formedness of the gadget polynomials. For every <tt>i</tt> in <tt>[H]</tt>:  </t>
                <ul spacing="normal">
                  <li>Let <tt>z = G_i(x_i)</tt>. That is, evaluate the circuit <tt>G_i</tt> on <tt>x_i</tt> and set
<tt>z</tt> to the output.</li>
                  <li>If <tt>z != y_i</tt>, then return <tt>False</tt> and halt.</li>
                </ul>
              </li>
              <li>Return <tt>True</tt> if <tt>v == 0</tt> and <tt>False</tt> otherwise.</li>
            </ol>
          </section>
          <section anchor="encoding">
            <name>Encoding</name>
            <t>The FLP encoding and truncation methods invoke <tt>Valid.encode</tt>,
<tt>Valid.truncate</tt>, and <tt>Valid.decode</tt> in the natural way.</t>
          </section>
        </section>
      </section>
      <section anchor="prio3-instantiations">
        <name>Instantiations</name>
        <t>This section specifies instantiations of Prio3 for various measurement types.
Each uses <tt>FlpGeneric</tt> as the FLP (<xref target="flp-generic"/>) and is determined by a
validity circuit (<xref target="flp-generic-valid"/>) and a XOF (<xref target="xof"/>). Test vectors for
each can be found in <xref target="test-vectors"/>.</t>
        <ul empty="true">
          <li>
            <t>NOTE Reference implementations of each of these VDAFs can be found in
https://github.com/cfrg/draft-irtf-cfrg-vdaf/blob/main/poc/vdaf_prio3.sage.</t>
          </li>
        </ul>
        <section anchor="prio3count">
          <name>Prio3Count</name>
          <t>Our first instance of Prio3 is for a simple counter: Each measurement is either
one or zero and the aggregate result is the sum of the measurements.</t>
          <t>This instance uses XofShake128 (<xref target="xof-shake128"/>) as its XOF. Its validity
circuit, denoted <tt>Count</tt>, uses <tt>Field64</tt> (<xref target="fields"/>) as its finite field. Its
gadget, denoted <tt>Mul</tt>, is the degree-2, arity-2 gadget defined as</t>
          <artwork><![CDATA[
def eval(self, Field, inp):
    self.check_gadget_eval(inp)
    return inp[0] * inp[1]
]]></artwork>
          <t>The call to <tt>check_gadget_eval()</tt> raises an error if the length of the input is
not equal to the gadget's <tt>ARITY</tt> parameter.</t>
          <t>The <tt>Count</tt> validity circuit is defined as</t>
          <artwork><![CDATA[
def eval(self, meas, joint_rand, _num_shares):
    return self.GADGETS[0].eval(self.Field, [meas[0], meas[0]]) \
        - meas[0]
]]></artwork>
          <t>The measurement is encoded and decoded as a singleton vector in the natural
way. The parameters for this circuit are summarized below.</t>
          <table>
            <name>Parameters of validity circuit Count.</name>
            <thead>
              <tr>
                <th align="left">Parameter</th>
                <th align="left">Value</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">
                  <tt>GADGETS</tt></td>
                <td align="left">
                  <tt>[Mul]</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>GADGET_CALLS</tt></td>
                <td align="left">
                  <tt>[1]</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>MEAS_LEN</tt></td>
                <td align="left">
                  <tt>1</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>OUTPUT_LEN</tt></td>
                <td align="left">
                  <tt>1</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>JOINT_RAND_LEN</tt></td>
                <td align="left">
                  <tt>0</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>Measurement</tt></td>
                <td align="left">
                  <tt>Unsigned</tt>, in range <tt>[0,2)</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>AggResult</tt></td>
                <td align="left">
                  <tt>Unsigned</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>Field</tt></td>
                <td align="left">
                  <tt>Field64</tt> (<xref target="fields"/>)</td>
              </tr>
            </tbody>
          </table>
        </section>
        <section anchor="prio3sum">
          <name>Prio3Sum</name>
          <t>The next instance of Prio3 supports summing of integers in a pre-determined
range. Each measurement is an integer in range <tt>[0, 2^bits)</tt>, where <tt>bits</tt> is an
associated parameter.</t>
          <t>This instance of Prio3 uses XofShake128 (<xref target="xof-shake128"/>) as its XOF. Its validity
circuit, denoted <tt>Sum</tt>, uses <tt>Field128</tt> (<xref target="fields"/>) as its finite field. The
measurement is encoded as a length-<tt>bits</tt> vector of field elements, where the
<tt>l</tt>th element of the vector represents the <tt>l</tt>th bit of the summand:</t>
          <artwork><![CDATA[
def encode(self, measurement):
    if 0 > measurement or measurement >= 2 ** self.MEAS_LEN:
        raise ERR_INPUT

    encoded = []
    for l in range(self.MEAS_LEN):
        encoded.append(self.Field((measurement >> l) & 1))
    return encoded

def truncate(self, meas):
    decoded = self.Field(0)
    for (l, b) in enumerate(meas):
        w = self.Field(1 << l)
        decoded += w * b
    return [decoded]

def decode(self, output, _num_measurements):
    return output[0].as_unsigned()
]]></artwork>
          <t>The validity circuit checks that the input consists of ones and zeros. Its
gadget, denoted <tt>Range2</tt>, is the degree-2, arity-1 gadget defined as</t>
          <artwork><![CDATA[
def eval(self, Field, inp):
    self.check_gadget_eval(inp)
    return inp[0] * inp[0] - inp[0]
]]></artwork>
          <t>The <tt>Sum</tt> validity circuit is defined as</t>
          <artwork><![CDATA[
def eval(self, meas, joint_rand, _num_shares):
    self.check_valid_eval(meas, joint_rand)
    out = self.Field(0)
    r = joint_rand[0]
    for b in meas:
        out += r * self.GADGETS[0].eval(self.Field, [b])
        r *= joint_rand[0]
    return out
]]></artwork>
          <table>
            <name>Parameters of validity circuit Sum.</name>
            <thead>
              <tr>
                <th align="left">Parameter</th>
                <th align="left">Value</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">
                  <tt>GADGETS</tt></td>
                <td align="left">
                  <tt>[Range2]</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>GADGET_CALLS</tt></td>
                <td align="left">
                  <tt>[bits]</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>MEAS_LEN</tt></td>
                <td align="left">
                  <tt>bits</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>OUTPUT_LEN</tt></td>
                <td align="left">
                  <tt>1</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>JOINT_RAND_LEN</tt></td>
                <td align="left">
                  <tt>1</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>Measurement</tt></td>
                <td align="left">
                  <tt>Unsigned</tt>, in range <tt>[0, 2^bits)</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>AggResult</tt></td>
                <td align="left">
                  <tt>Unsigned</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>Field</tt></td>
                <td align="left">
                  <tt>Field128</tt> (<xref target="fields"/>)</td>
              </tr>
            </tbody>
          </table>
        </section>
        <section anchor="prio3sumvec">
          <name>Prio3SumVec</name>
          <t>This instance of Prio3 supports summing a vector of integers. It has three
parameters, <tt>length</tt>, <tt>bits</tt>, and <tt>chunk_length</tt>. Each measurement is a vector
of positive integers with length equal to the <tt>length</tt> parameter. Each element
of the measurement is an integer in the range <tt>[0, 2^bits)</tt>. It is <bcp14>RECOMMENDED</bcp14>
to set <tt>chunk_length</tt> to an integer near the square root of <tt>length * bits</tt>
(see <xref target="parallel-sum-chunk-length"/>).</t>
          <t>This instance uses XofShake128 (<xref target="xof-shake128"/>) as its XOF. Its validity circuit,
denoted <tt>SumVec</tt>, uses <tt>Field128</tt> (<xref target="fields"/>) as its finite field.</t>
          <t>Measurements are encoded as a vector of field elements with length <tt>length *
bits</tt>. The field elements in the encoded vector represent all the bits of the
measurement vector's elements, consecutively, in LSB to MSB order:</t>
          <artwork><![CDATA[
def encode(self, measurement: Vec[Unsigned]):
    if len(measurement) != self.length:
        raise ERR_INPUT

    encoded = []
    for val in measurement:
        if 0 > val or val >= 2 ** self.bits:
            raise ERR_INPUT

        for l in range(self.bits):
            encoded.append(self.Field((val >> l) & 1))

    return encoded

def truncate(self, meas):
    truncated = [self.Field(0) for _ in range(self.length)]
    for i in range(self.length):
        for j in range(self.bits):
            weight = self.Field(1 << j)
            truncated[i] += weight * meas[i * self.bits + j]
    return truncated

def decode(self, output, _num_measurements):
    return [x.as_unsigned() for x in output]
]]></artwork>
          <t>This validity circuit uses a <tt>ParallelSum</tt> gadget to achieve a smaller proof
size. This optimization for "parallel-sum circuits" is described in
<xref target="BBCGGI19"/>, section 4.4. Briefly, for circuits that add up the output of
multiple identical subcircuits, it is possible to achieve smaller proof sizes
(on the order of O(sqrt(MEAS_LEN)) instead of O(MEAS_LEN)) by packaging more
than one such subcircuit into a gadget.</t>
          <t>The <tt>ParallelSum</tt> gadget is parameterized with an arithmetic subcircuit, and a
<tt>count</tt> of how many times it evaluates that subcircuit. It takes in a list of
inputs and passes them through to instances of the subcircuit in the same order.
It returns the sum of the subcircuit outputs. Note that only the <tt>ParallelSum</tt>
gadget itself, and not its subcircuit, participates in <tt>FlpGeneric</tt>'s wire
recording during evaluation, gadget consistency proofs, and proof validation,
even though the subcircuit is provided to <tt>ParallelSum</tt> as an implementation
of the <tt>Gadget</tt> interface.</t>
          <artwork><![CDATA[
def eval(self, Field, inp):
    self.check_gadget_eval(inp)
    out = Field(0)
    for i in range(self.count):
        start_index = i * self.subcircuit.ARITY
        end_index = (i + 1) * self.subcircuit.ARITY
        out += self.subcircuit.eval(Field, inp[start_index:end_index])
    return out
]]></artwork>
          <t>The <tt>SumVec</tt> validity circuit checks that the encoded measurement consists of
ones and zeros. Rather than use the <tt>Range2</tt> gadget on each element, as in the
<tt>Sum</tt> validity circuit, it instead uses <tt>Mul</tt> subcircuits and "free" constant
multiplication and addition gates to simultaneously evaluate the same range
check polynomial on each element, and multiply by a constant. One of the two
<tt>Mul</tt> subcircuit inputs is equal to a measurement element multiplied by a power
of the joint randomness value, and the other is equal to the same measurement
element minus one. These <tt>Mul</tt> subcircuits are evaluated by a <tt>ParallelSum</tt>
gadget, and the results are added up both within the <tt>ParallelSum</tt> gadget and
after it.</t>
          <artwork><![CDATA[
def eval(self, meas, joint_rand, num_shares):
    self.check_valid_eval(meas, joint_rand)

    out = Field128(0)
    r = joint_rand[0]
    r_power = r
    shares_inv = self.Field(num_shares).inv()

    for i in range(self.GADGET_CALLS[0]):
        inputs = [None] * (2 * self.chunk_length)
        for j in range(self.chunk_length):
            index = i * self.chunk_length + j
            if index < len(meas):
                meas_elem = meas[index]
            else:
                meas_elem = self.Field(0)

            inputs[j * 2] = r_power * meas_elem
            inputs[j * 2 + 1] = meas_elem - shares_inv

            r_power *= r

        out += self.GADGETS[0].eval(self.Field, inputs)

    return out
]]></artwork>
          <table>
            <name>Parameters of validity circuit SumVec.</name>
            <thead>
              <tr>
                <th align="left">Parameter</th>
                <th align="left">Value</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">
                  <tt>GADGETS</tt></td>
                <td align="left">
                  <tt>[ParallelSum(Mul(), chunk_length)]</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>GADGET_CALLS</tt></td>
                <td align="left">
                  <tt>[(length * bits + chunk_length - 1) // chunk_length]</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>MEAS_LEN</tt></td>
                <td align="left">
                  <tt>length * bits</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>OUTPUT_LEN</tt></td>
                <td align="left">
                  <tt>length</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>JOINT_RAND_LEN</tt></td>
                <td align="left">
                  <tt>1</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>Measurement</tt></td>
                <td align="left">
                  <tt>Vec[Unsigned]</tt>, each element in range <tt>[0, 2^bits)</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>AggResult</tt></td>
                <td align="left">
                  <tt>Vec[Unsigned]</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>Field</tt></td>
                <td align="left">
                  <tt>Field128</tt> (<xref target="fields"/>)</td>
              </tr>
            </tbody>
          </table>
          <section anchor="parallel-sum-chunk-length">
            <name>Selection of <tt>ParallelSum</tt> chunk length</name>
            <t>The <tt>chunk_length</tt> parameter provides a trade-off between the arity of the
<tt>ParallelSum</tt> gadget and the number of times the gadget is called. The proof
length is asymptotically minimized when the chunk length is near the square root
of the length of the measurement. However, the relationship between VDAF
parameters and proof length is complicated, involving two forms of rounding (the
circuit pads the inputs to its last <tt>ParallelSum</tt> gadget call, up to the chunk
length, and FlpGeneric rounds the degree of wire polynomials -- determined by
the number of times a gadget is called -- up to the next power of two).
Therefore, the optimal choice of <tt>chunk_length</tt> for a concrete measurement size
will vary, and must be found through trial and error. Setting <tt>chunk_length</tt>
equal to the square root of the appropriate measurement length will result in
proofs up to 50% larger than the optimal proof size.</t>
          </section>
        </section>
        <section anchor="prio3histogram">
          <name>Prio3Histogram</name>
          <t>This instance of Prio3 allows for estimating the distribution of some quantity
by computing a simple histogram. Each measurement increments one histogram
bucket, out of a set of fixed buckets. (Bucket indexing begins at <tt>0</tt>.) For
example, the buckets might quantize the real numbers, and each measurement would
report the bucket that the corresponding client's real-numbered value falls
into. The aggregate result counts the number of measurements in each bucket.</t>
          <t>This instance of Prio3 uses XofShake128 (<xref target="xof-shake128"/>) as its XOF. Its validity
circuit, denoted <tt>Histogram</tt>, uses <tt>Field128</tt> (<xref target="fields"/>) as its finite field.
It has two parameters, <tt>length</tt>, the number of histogram buckets, and
<tt>chunk_length</tt>, which is used by by a circuit optimization described below. It
is <bcp14>RECOMMENDED</bcp14> to set <tt>chunk_length</tt> to an integer near the square root of
<tt>length</tt> (see <xref target="parallel-sum-chunk-length"/>).</t>
          <t>The measurement is encoded as a one-hot vector representing the bucket into
which the measurement falls:</t>
          <artwork><![CDATA[
def encode(self, measurement):
    encoded = [self.Field(0)] * self.length
    encoded[measurement] = self.Field(1)
    return encoded

def truncate(self, meas):
    return meas

def decode(self, output, _num_measurements):
    return [bucket_count.as_unsigned() for bucket_count in output]
]]></artwork>
          <t>The <tt>Histogram</tt> validity circuit checks for one-hotness in two steps, by
checking that the encoded measurement consists of ones and zeros, and by
checking that the sum of all elements in the encoded measurement is equal to
one. All the individual checks are combined together in a random linear
combination.</t>
          <t>As in the <tt>SumVec</tt> validity circuit (<xref target="prio3sumvec"/>), the first part of the
validity circuit uses the <tt>ParallelSum</tt> gadget to perform range checks while
achieving a smaller proof size. The <tt>ParallelSum</tt> gadget uses <tt>Mul</tt> subcircuits
to evaluate a range check polynomial on each element, and includes an additional
constant multiplication. One of the two <tt>Mul</tt> subcircuit inputs is equal to a
measurement element multiplied by a power of the first joint randomness value,
and the other is equal to the same measurement element minus one. The results
are added up both within the <tt>ParallelSum</tt> gadget and after it.</t>
          <artwork><![CDATA[
def eval(self, meas, joint_rand, num_shares):
    self.check_valid_eval(meas, joint_rand)

    # Check that each bucket is one or zero.
    range_check = self.Field(0)
    r = joint_rand[0]
    r_power = r
    shares_inv = self.Field(num_shares).inv()
    for i in range(self.GADGET_CALLS[0]):
        inputs = [None] * (2 * self.chunk_length)
        for j in range(self.chunk_length):
            index = i * self.chunk_length + j
            if index < len(meas):
                meas_elem = meas[index]
            else:
                meas_elem = self.Field(0)

            inputs[j * 2] = r_power * meas_elem
            inputs[j * 2 + 1] = meas_elem - shares_inv

            r_power *= r

        range_check += r * self.GADGETS[0].eval(self.Field, inputs)

    # Check that the buckets sum to 1.
    sum_check = -shares_inv
    for b in meas:
        sum_check += b

    out = joint_rand[1] * range_check + \
        joint_rand[1] ** 2 * sum_check
    return out
]]></artwork>
          <t>Note that this circuit depends on the number of shares into which the
measurement is sharded. This is provided to the FLP by Prio3.</t>
          <table>
            <name>Parameters of validity circuit Histogram.</name>
            <thead>
              <tr>
                <th align="left">Parameter</th>
                <th align="left">Value</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">
                  <tt>GADGETS</tt></td>
                <td align="left">
                  <tt>[ParallelSum(Mul(), chunk_length)]</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>GADGET_CALLS</tt></td>
                <td align="left">
                  <tt>[(length + chunk_length - 1) // chunk_length]</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>MEAS_LEN</tt></td>
                <td align="left">
                  <tt>length</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>OUTPUT_LEN</tt></td>
                <td align="left">
                  <tt>length</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>JOINT_RAND_LEN</tt></td>
                <td align="left">
                  <tt>2</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>Measurement</tt></td>
                <td align="left">
                  <tt>Unsigned</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>AggResult</tt></td>
                <td align="left">
                  <tt>Vec[Unsigned]</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>Field</tt></td>
                <td align="left">
                  <tt>Field128</tt> (<xref target="fields"/>)</td>
              </tr>
            </tbody>
          </table>
        </section>
      </section>
    </section>
    <section anchor="poplar1">
      <name>Poplar1</name>
      <t>This section specifies Poplar1, a VDAF for the following task. Each Client holds
a string of length <tt>BITS</tt> and the Aggregators hold a set of <tt>l</tt>-bit strings,
where <tt>l &lt;= BITS</tt>. We will refer to the latter as the set of "candidate
prefixes". The Aggregators' goal is to count how many measurements are prefixed
by each candidate prefix.</t>
      <t>This functionality is the core component of the Poplar protocol <xref target="BBCGGI21"/>,
which was designed to compute the heavy hitters over a set of input strings. At
a high level, the protocol works as follows.</t>
      <ol spacing="normal" type="1"><li>Each Client splits its string into input shares and sends one share to each
Aggregator.</li>
        <li>The Aggregators agree on an initial set of candidate prefixes, say <tt>0</tt> and
<tt>1</tt>.</li>
        <li>The Aggregators evaluate the VDAF on each set of input shares and aggregate
the recovered output shares. The aggregation parameter is the set of
candidate prefixes.</li>
        <li>The Aggregators send their aggregate shares to the Collector, who combines
them to recover the counts of each candidate prefix.</li>
        <li>Let <tt>H</tt> denote the set of prefixes that occurred at least <tt>t</tt> times. If the
prefixes all have length <tt>BITS</tt>, then <tt>H</tt> is the set of <tt>t</tt>-heavy-hitters.
Otherwise compute the next set of candidate prefixes, e.g., for each <tt>p</tt> in
<tt>H</tt>, add <tt>p || 0</tt> and <tt>p || 1</tt> to the set. Repeat step 3 with the new set of
candidate prefixes.</li>
      </ol>
      <t>Poplar1 is constructed from an "Incremental Distributed Point Function (IDPF)",
a primitive described by <xref target="BBCGGI21"/> that generalizes the notion of a
Distributed Point Function (DPF) <xref target="GI14"/>. Briefly, a DPF is used to distribute
the computation of a "point function", a function that evaluates to zero on
every input except at a programmable "point". The computation is distributed in
such a way that no one party knows either the point or what it evaluates to.</t>
      <t>An IDPF generalizes this "point" to a path on a full binary tree from the root
to one of the leaves. It is evaluated on an "index" representing a unique node
of the tree. If the node is on the programmed path, then the function evaluates
to a non-zero value; otherwise it evaluates to zero. This structure allows an
IDPF to provide the functionality required for the above protocol: To compute
the hit count for an index, just evaluate each set of IDPF shares at that index
and add up the results.</t>
      <t>Consider the sub-tree constructed from a set of input strings and a target
threshold <tt>t</tt> by including all indices that prefix at least <tt>t</tt> of the input
strings. We shall refer to this structure as the "prefix tree" for the batch of
inputs and target threshold. To compute the <tt>t</tt>-heavy hitters for a set of
inputs, the Aggregators and Collector first compute the prefix tree, then
extract the heavy hitters from the leaves of this tree. (Note that the prefix
tree may leak more information about the set than the heavy hitters themselves;
see <xref target="agg-param-privacy"/> for details.)</t>
      <t>Poplar1 composes an IDPF with the "secure sketching" protocol of <xref target="BBCGGI21"/>.
This protocol ensures that evaluating a set of input shares on a unique set of
candidate prefixes results in shares of a "one-hot" vector, i.e., a vector that
is zero everywhere except for one element, which is equal to one.</t>
      <t>The remainder of this section is structured as follows. IDPFs are defined in
<xref target="idpf"/>; a concrete instantiation is given <xref target="idpf-poplar"/>. The Poplar1 VDAF is
defined in <xref target="poplar1-construction"/> in terms of a generic IDPF. Finally, a
concrete instantiation of Poplar1 is specified in <xref target="poplar1-inst"/>;
test vectors can be found in <xref target="test-vectors"/>.</t>
      <section anchor="idpf">
        <name>Incremental Distributed Point Functions (IDPFs)</name>
        <t>An IDPF is defined over a domain of size <tt>2^BITS</tt>, where <tt>BITS</tt> is constant
defined by the IDPF. Indexes into the IDPF tree are encoded as integers in range
<tt>[0, 2^BITS)</tt>. The Client specifies an index <tt>alpha</tt> and a vector of
values <tt>beta</tt>, one for each "level" <tt>L</tt> in range <tt>[0, BITS)</tt>. The key generation
algorithm generates one IDPF "key" for each Aggregator. When evaluated at level
<tt>L</tt> and index <tt>0 &lt;= prefix &lt; 2^L</tt>, each IDPF key returns an additive share of
<tt>beta[L]</tt> if <tt>prefix</tt> is the <tt>L</tt>-bit prefix of <tt>alpha</tt> and shares of zero
otherwise.</t>
        <t>An index <tt>x</tt> is defined to be a prefix of another index <tt>y</tt> as follows. Let
<tt>LSB(x, N)</tt> denote the least significant <tt>N</tt> bits of positive integer <tt>x</tt>. By
definition, a positive integer <tt>0 &lt;= x &lt; 2^L</tt> is said to be the length-<tt>L</tt>
prefix of positive integer <tt>0 &lt;= y &lt; 2^BITS</tt> if <tt>LSB(x, L)</tt> is equal to the most
significant <tt>L</tt> bits of <tt>LSB(y, BITS)</tt>, For example, 6 (110 in binary) is the
length-3 prefix of 25 (11001), but 7 (111) is not.</t>
        <t>Each of the programmed points <tt>beta</tt> is a vector of elements of some finite
field. We distinguish two types of fields: One for inner nodes (denoted
<tt>FieldInner</tt>), and one for leaf nodes (<tt>FieldLeaf</tt>). (Our
instantiation of Poplar1 (<xref target="poplar1-inst"/>) will use a much larger field for
leaf nodes than for inner nodes. This is to ensure the IDPF is "extractable" as
defined in <xref target="BBCGGI21"/>, Definition 1.)</t>
        <t>A concrete IDPF defines the types and constants enumerated in <xref target="idpf-param"/>.
In the remainder we write <tt>Output</tt> as shorthand for the type
<tt>Union[list[list[FieldInner]], list[list[FieldLeaf]]]</tt>. (This type
denotes either a vector of inner node field elements or leaf node field
elements.) The scheme is comprised of the following algorithms:</t>
        <ul spacing="normal">
          <li>
            <t><tt>Idpf.gen(alpha: Unsigned, beta_inner: list[list[FieldInner]], beta_leaf:
list[FieldLeaf], binder: bytes, rand: bytes[Idpf.RAND_SIZE]) -&gt; tuple[bytes,
list[bytes]]</tt> is the randomized IDPF-key generation algorithm. (Input <tt>rand</tt>
consists of the random bytes it consumes.) Its inputs are the index <tt>alpha</tt>
the values <tt>beta</tt>, and a binder string. The value of <tt>alpha</tt> <bcp14>MUST</bcp14> be in range
<tt>[0, 2^BITS)</tt>. The output is a public part that is sent to all Aggregators
and a vector of private IDPF keys, one for each aggregator.  </t>
            <ul empty="true">
              <li>
                <t>TODO(issue #255) Decide whether to treat the public share as an opaque byte
string or to replace it with an explicit type.</t>
              </li>
            </ul>
          </li>
          <li>
            <t><tt>Idpf.eval(agg_id: Unsigned, public_share: bytes, key: bytes, level:
Unsigned, prefixes: tuple[Unsigned, ...], binder: Bytes) -&gt; Output</tt> is the
deterministic, stateless IDPF-key evaluation algorithm run by each
Aggregator. Its inputs are the Aggregator's unique identifier, the public
share distributed to all of the Aggregators, the Aggregator's IDPF key, the
"level" at which to evaluate the IDPF, the sequence of candidate prefixes,
and a binder string. It returns the share of the value corresponding to each
candidate prefix.  </t>
            <t>
The output type (i.e., <tt>Output</tt>) depends on the value of <tt>level</tt>: If <tt>level &lt;
Idpf.BITS-1</tt>, the output is the value for an inner node, which has type
<tt>list[list[Idpf.FieldInner]]</tt>; otherwise, if <tt>level == Idpf.BITS-1</tt>, then the
output is the value for a leaf node, which has type
<tt>list[list[Idpf.FieldLeaf]]</tt>.  </t>
            <t>
The value of <tt>level</tt> <bcp14>MUST</bcp14> be in range <tt>[0, BITS)</tt>. The indexes in <tt>prefixes</tt>
              <bcp14>MUST</bcp14> all be distinct and in range <tt>[0, 2^level)</tt>.  </t>
            <t>
Applications <bcp14>MUST</bcp14> ensure that the Aggregator's identifier is equal to the
integer in range <tt>[0, SHARES)</tt> that matches the index of <tt>key</tt> in the sequence
of IDPF keys output by the Client.</t>
          </li>
        </ul>
        <t>In addition, the following method is derived for each concrete <tt>Idpf</tt>:</t>
        <artwork><![CDATA[
def current_field(Idpf, level):
    return Idpf.FieldInner if level < Idpf.BITS-1 \
                else Idpf.FieldLeaf
]]></artwork>
        <t>Finally, an implementation note. The interface for IDPFs specified here is
stateless, in the sense that there is no state carried between IDPF evaluations.
This is to align the IDPF syntax with the VDAF abstraction boundary, which does
not include shared state across across VDAF evaluations. In practice, of course,
it will often be beneficial to expose a stateful API for IDPFs and carry the
state across evaluations. See <xref target="idpf-poplar"/> for details.</t>
        <table anchor="idpf-param">
          <name>Constants and types defined by a concrete IDPF.</name>
          <thead>
            <tr>
              <th align="left">Parameter</th>
              <th align="left">Description</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">SHARES</td>
              <td align="left">Number of IDPF keys output by IDPF-key generator</td>
            </tr>
            <tr>
              <td align="left">BITS</td>
              <td align="left">Length in bits of each input string</td>
            </tr>
            <tr>
              <td align="left">VALUE_LEN</td>
              <td align="left">Number of field elements of each output value</td>
            </tr>
            <tr>
              <td align="left">RAND_SIZE</td>
              <td align="left">Size of the random string consumed by the IDPF-key generator. Equal to twice the XOF's seed size.</td>
            </tr>
            <tr>
              <td align="left">KEY_SIZE</td>
              <td align="left">Size in bytes of each IDPF key</td>
            </tr>
            <tr>
              <td align="left">FieldInner</td>
              <td align="left">Implementation of <tt>Field</tt> (<xref target="field"/>) used for values of inner nodes</td>
            </tr>
            <tr>
              <td align="left">FieldLeaf</td>
              <td align="left">Implementation of <tt>Field</tt> used for values of leaf nodes</td>
            </tr>
            <tr>
              <td align="left">Output</td>
              <td align="left">Alias of <tt>Union[list[list[FieldInner]], list[list[FieldLeaf]]]</tt></td>
            </tr>
            <tr>
              <td align="left">FieldVec</td>
              <td align="left">Alias of <tt>Union[list[FieldInner], list[FieldLeaf]]</tt></td>
            </tr>
          </tbody>
        </table>
      </section>
      <section anchor="poplar1-construction">
        <name>Construction</name>
        <t>This section specifies <tt>Poplar1</tt>, an implementation of the <tt>Vdaf</tt> interface
(<xref target="vdaf"/>). It is defined in terms of any <tt>Idpf</tt> (<xref target="idpf"/>) for which
<tt>Idpf.SHARES == 2</tt> and <tt>Idpf.VALUE_LEN == 2</tt> and an implementation of <tt>Xof</tt>
(<xref target="xof"/>). The associated constants and types required by the <tt>Vdaf</tt> interface
are defined in <xref target="poplar1-param"/>. The methods required for sharding,
preparation, aggregation, and unsharding are described in the remaining
subsections. These methods make use of constants defined in <xref target="poplar1-const"/>.</t>
        <table anchor="poplar1-param">
          <name>VDAF parameters for Poplar1.</name>
          <thead>
            <tr>
              <th align="left">Parameter</th>
              <th align="left">Value</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">
                <tt>VERIFY_KEY_SIZE</tt></td>
              <td align="left">
                <tt>Xof.SEED_SIZE</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>RAND_SIZE</tt></td>
              <td align="left">
                <tt>Xof.SEED_SIZE * 3 + Idpf.RAND_SIZE</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>NONCE_SIZE</tt></td>
              <td align="left">
                <tt>16</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>ROUNDS</tt></td>
              <td align="left">
                <tt>2</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>SHARES</tt></td>
              <td align="left">
                <tt>2</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>Measurement</tt></td>
              <td align="left">
                <tt>Unsigned</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>AggParam</tt></td>
              <td align="left">
                <tt>Tuple[Unsigned, Tuple[Unsigned, ...]]</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>PublicShare</tt></td>
              <td align="left">
                <tt>bytes</tt> (IDPF public share)</td>
            </tr>
            <tr>
              <td align="left">
                <tt>InputShare</tt></td>
              <td align="left">
                <tt>tuple[bytes, bytes, list[Idpf.FieldInner], list[Idpf.FieldLeaf]]</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>OutShare</tt></td>
              <td align="left">
                <tt>Idpf.FieldVec</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>AggShare</tt></td>
              <td align="left">
                <tt>Idpf.FieldVec</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>AggResult</tt></td>
              <td align="left">
                <tt>Vec[Unsigned]</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>PrepState</tt></td>
              <td align="left">
                <tt>tuple[bytes, Unsigned, Idpf.FieldVec]</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>PrepShare</tt></td>
              <td align="left">
                <tt>Idpf.FieldVec</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>PrepMessage</tt></td>
              <td align="left">
                <tt>Optional[Idpf.FieldVec]</tt></td>
            </tr>
          </tbody>
        </table>
        <table anchor="poplar1-const">
          <name>Constants used by Poplar1.</name>
          <thead>
            <tr>
              <th align="left">Variable</th>
              <th align="left">Value</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">USAGE_SHARD_RAND: Unsigned</td>
              <td align="left">1</td>
            </tr>
            <tr>
              <td align="left">USAGE_CORR_INNER: Unsigned</td>
              <td align="left">2</td>
            </tr>
            <tr>
              <td align="left">USAGE_CORR_LEAF: Unsigned</td>
              <td align="left">3</td>
            </tr>
            <tr>
              <td align="left">USAGE_VERIFY_RAND: Unsigned</td>
              <td align="left">4</td>
            </tr>
          </tbody>
        </table>
        <section anchor="client">
          <name>Client</name>
          <t>The Client's measurement is interpreted as an IDPF index, denoted <tt>alpha</tt>. The
programmed IDPF values are pairs of field elements <tt>(1, k)</tt> where each <tt>k</tt> is
chosen at random. This random value is used as part of the secure sketching
protocol of <xref target="BBCGGI21"/>, Appendix C.4. After evaluating their IDPF key shares
on a given sequence of candidate prefixes, the sketching protocol is used by
the Aggregators to verify that they hold shares of a one-hot vector. In
addition, for each level of the tree, the prover generates random elements <tt>a</tt>,
<tt>b</tt>, and <tt>c</tt> and computes</t>
          <artwork><![CDATA[
    A = -2*a + k
    B = a^2 + b - k*a + c
]]></artwork>
          <t>and sends additive shares of <tt>a</tt>, <tt>b</tt>, <tt>c</tt>, <tt>A</tt> and <tt>B</tt> to the Aggregators.
Putting everything together, the sharding algorithm is defined as
follows.</t>
          <figure anchor="poplar1-mes2inp">
            <name>The sharding algorithm for Poplar1.</name>
            <artwork><![CDATA[
def shard(Poplar1, measurement, nonce, rand):
    l = Poplar1.Xof.SEED_SIZE

    # Split the random input into random input for IDPF key
    # generation, correlated randomness, and sharding.
    if len(rand) != Poplar1.RAND_SIZE:
        raise ERR_INPUT # unexpected length for random input
    idpf_rand, rand = front(Poplar1.Idpf.RAND_SIZE, rand)
    seeds = [rand[i:i+l] for i in range(0,3*l,l)]
    corr_seed, seeds = front(2, seeds)
    (k_shard,), seeds = front(1, seeds)

    xof = Poplar1.Xof(
        k_shard,
        Poplar1.domain_separation_tag(USAGE_SHARD_RAND),
        b'',
    )

    # Construct the IDPF values for each level of the IDPF tree.
    # Each "data" value is 1; in addition, the Client generates
    # a random "authenticator" value used by the Aggregators to
    # compute the sketch during preparation. This sketch is used
    # to verify the one-hotness of their output shares.
    beta_inner = [
        [Poplar1.Idpf.FieldInner(1), k]
        for k in xof.next_vec(Poplar1.Idpf.FieldInner,
                              Poplar1.Idpf.BITS - 1)
    ]
    beta_leaf = [Poplar1.Idpf.FieldLeaf(1)] + \
        xof.next_vec(Poplar1.Idpf.FieldLeaf, 1)

    # Generate the IDPF keys.
    (public_share, keys) = Poplar1.Idpf.gen(measurement,
                                            beta_inner,
                                            beta_leaf,
                                            idpf_rand)

    # Generate correlated randomness used by the Aggregators to
    # compute a sketch over their output shares. XOF seeds are
    # used to encode shares of the `(a, b, c)` triples.
    # (See [BBCGGI21, Appendix C.4].)
    corr_offsets = vec_add(
        Poplar1.Xof.expand_into_vec(
            Poplar1.Idpf.FieldInner,
            corr_seed[0],
            Poplar1.domain_separation_tag(USAGE_CORR_INNER),
            byte(0) + nonce,
            3 * (Poplar1.Idpf.BITS-1),
        ),
        Poplar1.Xof.expand_into_vec(
            Poplar1.Idpf.FieldInner,
            corr_seed[1],
            Poplar1.domain_separation_tag(USAGE_CORR_INNER),
            byte(1) + nonce,
            3 * (Poplar1.Idpf.BITS-1),
        ),
    )
    corr_offsets += vec_add(
        Poplar1.Xof.expand_into_vec(
            Poplar1.Idpf.FieldLeaf,
            corr_seed[0],
            Poplar1.domain_separation_tag(USAGE_CORR_LEAF),
            byte(0) + nonce,
            3,
        ),
        Poplar1.Xof.expand_into_vec(
            Poplar1.Idpf.FieldLeaf,
            corr_seed[1],
            Poplar1.domain_separation_tag(USAGE_CORR_LEAF),
            byte(1) + nonce,
            3,
        ),
    )

    # For each level of the IDPF tree, shares of the `(A, B)`
    # pairs are computed from the corresponding `(a, b, c)`
    # triple and authenticator value `k`.
    corr_inner = [[], []]
    for level in range(Poplar1.Idpf.BITS):
        Field = Poplar1.Idpf.current_field(level)
        k = beta_inner[level][1] if level < Poplar1.Idpf.BITS - 1 \
            else beta_leaf[1]
        (a, b, c), corr_offsets = corr_offsets[:3], corr_offsets[3:]
        A = -Field(2) * a + k
        B = a ** 2 + b - a * k + c
        corr1 = xof.next_vec(Field, 2)
        corr0 = vec_sub([A, B], corr1)
        if level < Poplar1.Idpf.BITS - 1:
            corr_inner[0] += corr0
            corr_inner[1] += corr1
        else:
            corr_leaf = [corr0, corr1]

    # Each input share consists of the Aggregator's IDPF key
    # and a share of the correlated randomness.
    input_shares = list(zip(keys, corr_seed, corr_inner, corr_leaf))
    return (public_share, input_shares)
]]></artwork>
          </figure>
        </section>
        <section anchor="poplar1-prep">
          <name>Preparation</name>
          <t>The aggregation parameter encodes a sequence of candidate prefixes. When an
Aggregator receives an input share from the Client, it begins by evaluating its
IDPF share on each candidate prefix, recovering a <tt>data_share</tt> and <tt>auth_share</tt>
for each. The Aggregators use these and the correlation shares provided by the
Client to verify that the sequence of <tt>data_share</tt> values are additive shares of
a one-hot vector.</t>
          <t>Aggregators <bcp14>MUST</bcp14> ensure the candidate prefixes are all unique and appear in
lexicographic order. (This is enforced in the definition of <tt>prep_init()</tt>
below.) Uniqueness is necessary to ensure the refined measurement (i.e., the sum
of the output shares) is in fact a one-hot vector. Otherwise, sketch
verification might fail, causing the Aggregators to erroneously reject a report
that is actually valid. Note that enforcing the order is not strictly necessary,
but this does allow uniqueness to be determined more efficiently.</t>
          <figure anchor="poplar1-prep-state">
            <name>Preparation state for Poplar1.</name>
            <artwork><![CDATA[
def prep_init(Poplar1, verify_key, agg_id, agg_param,
              nonce, public_share, input_share):
    (level, prefixes) = agg_param
    (key, corr_seed, corr_inner, corr_leaf) = input_share
    Field = Poplar1.Idpf.current_field(level)

    # Ensure that candidate prefixes are all unique and appear in
    # lexicographic order.
    for i in range(1,len(prefixes)):
        if prefixes[i-1] >= prefixes[i]:
            raise ERR_INPUT # out-of-order prefix

    # Evaluate the IDPF key at the given set of prefixes.
    value = Poplar1.Idpf.eval(
        agg_id, public_share, key, level, prefixes)

    # Get shares of the correlated randomness for computing the
    # Aggregator's share of the sketch for the given level of the IDPF
    # tree.
    if level < Poplar1.Idpf.BITS - 1:
        corr_xof = Poplar1.Xof(
            corr_seed,
            Poplar1.domain_separation_tag(USAGE_CORR_INNER),
            byte(agg_id) + nonce,
        )
        # Fast-forward the XOF state to the current level.
        corr_xof.next_vec(Field, 3 * level)
    else:
        corr_xof = Poplar1.Xof(
            corr_seed,
            Poplar1.domain_separation_tag(USAGE_CORR_LEAF),
            byte(agg_id) + nonce,
        )
    (a_share, b_share, c_share) = corr_xof.next_vec(Field, 3)
    (A_share, B_share) = corr_inner[2*level:2*(level+1)] \
        if level < Poplar1.Idpf.BITS - 1 else corr_leaf

    # Compute the Aggregator's first round of the sketch. These are
    # called the "masked input values" [BBCGGI21, Appendix C.4].
    verify_rand_xof = Poplar1.Xof(
        verify_key,
        Poplar1.domain_separation_tag(USAGE_VERIFY_RAND),
        nonce + to_be_bytes(level, 2),
    )
    verify_rand = verify_rand_xof.next_vec(Field, len(prefixes))
    sketch_share = [a_share, b_share, c_share]
    out_share = []
    for (i, r) in enumerate(verify_rand):
        [data_share, auth_share] = value[i]
        sketch_share[0] += data_share * r
        sketch_share[1] += data_share * r ** 2
        sketch_share[2] += auth_share * r
        out_share.append(data_share)

    prep_mem = [A_share, B_share, Field(agg_id)] + out_share
    return ((b'sketch round 1', level, prep_mem),
            sketch_share)

def prep_next(Poplar1, prep_state, prep_msg):
    prev_sketch = prep_msg
    (step, level, prep_mem) = prep_state
    Field = Poplar1.Idpf.current_field(level)

    if step == b'sketch round 1':
        if prev_sketch == None:
            prev_sketch = Field.zeros(3)
        elif len(prev_sketch) != 3:
            raise ERR_INPUT  # prep message malformed
        (A_share, B_share, agg_id), prep_mem = \
            prep_mem[:3], prep_mem[3:]
        sketch_share = [
            agg_id * (prev_sketch[0] ** 2
                      - prev_sketch[1]
                      - prev_sketch[2])
            + A_share * prev_sketch[0]
            + B_share
        ]
        return ((b'sketch round 2', level, prep_mem),
                sketch_share)

    elif step == b'sketch round 2':
        if prev_sketch == None:
            return prep_mem  # Output shares
        else:
            raise ERR_INPUT  # prep message malformed

    raise ERR_INPUT  # unexpected input

def prep_shares_to_prep(Poplar1, agg_param, prep_shares):
    if len(prep_shares) != 2:
        raise ERR_INPUT  # unexpected number of prep shares
    (level, _) = agg_param
    Field = Poplar1.Idpf.current_field(level)
    sketch = vec_add(prep_shares[0], prep_shares[1])
    if len(sketch) == 3:
        return sketch
    elif len(sketch) == 1:
        if sketch == Field.zeros(1):
            # In order to reduce communication overhead, let `None`
            # denote a successful sketch verification.
            return None
        else:
            raise ERR_VERIFY  # sketch verification failed
    else:
        raise ERR_INPUT  # unexpected input length
]]></artwork>
          </figure>
        </section>
        <section anchor="validity-of-aggregation-parameters-1">
          <name>Validity of Aggregation Parameters</name>
          <t>Aggregation parameters are valid for a given input share if no aggregation
parameter with the same level has been used with the same input share before.
The whole preparation phase <bcp14>MUST NOT</bcp14> be run more than once for a given
combination of input share and level.</t>
          <figure anchor="poplar1-validity-scope">
            <name>Validity of aggregation parameters for Poplar1.</name>
            <artwork><![CDATA[
def is_valid(agg_param, previous_agg_params):
    (level, _) = agg_param
    return all(
        level != other_level
        for (other_level, _) in previous_agg_params
    )
]]></artwork>
          </figure>
        </section>
        <section anchor="aggregation-2">
          <name>Aggregation</name>
          <t>Aggregation involves simply adding up the output shares.</t>
          <figure anchor="poplar1-out2agg">
            <name>Aggregation algorithm for Poplar1.</name>
            <artwork><![CDATA[
def aggregate(Poplar1, agg_param, out_shares):
    (level, prefixes) = agg_param
    Field = Poplar1.Idpf.current_field(level)
    agg_share = Field.zeros(len(prefixes))
    for out_share in out_shares:
        agg_share = vec_add(agg_share, out_share)
    return agg_share
]]></artwork>
          </figure>
        </section>
        <section anchor="unsharding-1">
          <name>Unsharding</name>
          <t>Finally, the Collector unshards the aggregate result by adding up the aggregate
shares.</t>
          <figure anchor="poplar1-agg-output">
            <name>Computation of the aggregate result for Poplar1.</name>
            <artwork><![CDATA[
def unshard(Poplar1, agg_param,
            agg_shares, _num_measurements):
    (level, prefixes) = agg_param
    Field = Poplar1.Idpf.current_field(level)
    agg = Field.zeros(len(prefixes))
    for agg_share in agg_shares:
        agg = vec_add(agg, agg_share)
    return list(map(lambda x: x.as_unsigned(), agg))
]]></artwork>
          </figure>
        </section>
        <section anchor="poplar1-encode">
          <name>Message Serialization</name>
          <t>This section defines serialization formats for messages exchanged over the
network while executing <tt>Poplar1</tt>. It is <bcp14>RECOMMENDED</bcp14> that implementations
provide serialization methods for them.</t>
          <t>Message structures are defined following <xref section="3" sectionFormat="of" target="RFC8446"/>). In the
remainder we use <tt>S</tt> as an alias for <tt>Poplar1.Xof.SEED_SIZE</tt>, <tt>Fi</tt> as an alias
for <tt>Poplar1.Idpf.FieldInner</tt> and <tt>Fl</tt> as an alias for
<tt>Poplar1.Idpf.FieldLeaf</tt>. XOF seeds are represented as follows:</t>
          <artwork><![CDATA[
opaque Poplar1Seed[S];
]]></artwork>
          <t>Elements of the inner field are encoded in little-endian byte order (as defined
in <xref target="field"/>) and are represented as follows:</t>
          <artwork><![CDATA[
opaque Poplar1FieldInner[Fi];
]]></artwork>
          <t>Likewise, elements of the leaf field are encoded in little-endian byte order
(as defined in <xref target="field"/>) and are represented as follows:</t>
          <artwork><![CDATA[
opaque Poplar1FieldLeaf[Fl];
]]></artwork>
          <section anchor="public-share-1">
            <name>Public Share</name>
            <t>The public share is equal to the IDPF public share, which is a byte string.
(See <xref target="idpf"/>.)</t>
          </section>
          <section anchor="input-share-1">
            <name>Input Share</name>
            <t>Each input share is structured as follows:</t>
            <artwork><![CDATA[
struct {
    opaque idpf_key[Poplar1.Idpf.KEY_SIZE];
    Poplar1Seed corr_seed;
    Poplar1FieldInner corr_inner[Fi * 2 * (Poplar1.Idpf.BITS - 1)];
    Poplar1FieldLeaf corr_leaf[Fl * 2];
} Poplar1InputShare;
]]></artwork>
          </section>
          <section anchor="prep-share-1">
            <name>Prep Share</name>
            <t>Encoding of the prep share depends on the round of sketching: if the first
round, then each sketch share has three field elements; if the second round,
then each sketch share has one field element. The field that is used depends on
the level of the IDPF tree specified by the aggregation parameter, either the
inner field or the leaf field.</t>
            <t>For the first round and inner field:</t>
            <artwork><![CDATA[
struct {
    Poplar1FieldInner sketch_share[Fi * 3];
} Poplar1PrepShareRoundOneInner;
]]></artwork>
            <t>For the first round and leaf field:</t>
            <artwork><![CDATA[
struct {
    Poplar1FieldLeaf sketch_share[Fl * 3];
} Poplar1PrepShareRoundOneLeaf;

For the second round and inner field:
]]></artwork>
            <artwork><![CDATA[
struct {
    Poplar1FieldInner sketch_share;
} Poplar1PrepShareRoundTwoInner;
]]></artwork>
            <t>For the second round and leaf field:</t>
            <artwork><![CDATA[
struct {
    Poplar1FieldLeaf sketch_share;
} Poplar1PrepShareRoundTwoLeaf;
]]></artwork>
          </section>
          <section anchor="prep-message-1">
            <name>Prep Message</name>
            <t>Likewise, the structure of the prep message for Poplar1 depends on the
sketching round and field. For the first round and inner field:</t>
            <artwork><![CDATA[
struct {
    Poplar1FieldInner[Fi * 3];
} Poplar1PrepMessageRoundOneInner;
]]></artwork>
            <t>For the first round and leaf field:</t>
            <artwork><![CDATA[
struct {
    Poplar1FieldLeaf sketch[Fl * 3];
} Poplar1PrepMessageRoundOneLeaf;
]]></artwork>
            <t>Note that these messages have the same structures as the prep shares for the
first round.</t>
            <t>The second-round prep message is the empty string. This is because the sketch
shares are expected to sum to a particular value if the output shares are
valid; we represent a successful preparation with the empty string and
otherwise return an error.</t>
          </section>
          <section anchor="aggregate-share">
            <name>Aggregate Share</name>
            <t>The encoding of the aggregate share depends on whether the inner or leaf field
is used, and the number of candidate prefixes. Both of these are determined by
 the aggregation parameter.</t>
            <t>Let <tt>prefix_count</tt> denote the number of candidate prefixes. For the inner field:</t>
            <artwork><![CDATA[
struct {
    Poplar1FieldInner agg_share[Fi * prefix_count];
} Poplar1AggShareInner;
]]></artwork>
            <t>For the leaf field:</t>
            <artwork><![CDATA[
struct {
    Poplar1FieldLeaf agg_share[Fl * prefix_count];
} Poplar1AggShareLeaf;
]]></artwork>
          </section>
          <section anchor="aggregation-parameter">
            <name>Aggregation Parameter</name>
            <t>The aggregation parameter is encoded as follows:</t>
            <ul empty="true">
              <li>
                <t>TODO(issue #255) Express the aggregation parameter encoding in TLS syntax.
Decide whether to RECOMMEND this encoding, and if so, add it to test vectors.</t>
              </li>
            </ul>
            <artwork><![CDATA[
def encode_agg_param(Poplar1, (level, prefixes)):
    if level > 2 ** 16 - 1:
        raise ERR_INPUT # level too deep
    if len(prefixes) > 2 ** 32 - 1:
        raise ERR_INPUT # too many prefixes
    encoded = Bytes()
    encoded += to_be_bytes(level, 2)
    encoded += to_be_bytes(len(prefixes), 4)
    packed = 0
    for (i, prefix) in enumerate(prefixes):
        packed |= prefix << ((level+1) * i)
    l = ((level+1) * len(prefixes) + 7) // 8
    encoded += to_be_bytes(packed, l)
    return encoded

def decode_agg_param(Poplar1, encoded):
    encoded_level, encoded = encoded[:2], encoded[2:]
    level = from_be_bytes(encoded_level)
    encoded_prefix_count, encoded = encoded[:4], encoded[4:]
    prefix_count = from_be_bytes(encoded_prefix_count)
    l = ((level+1) * prefix_count + 7) // 8
    encoded_packed, encoded = encoded[:l], encoded[l:]
    packed = from_be_bytes(encoded_packed)
    prefixes = []
    m = 2 ** (level+1) - 1
    for i in range(prefix_count):
        prefixes.append(packed >> ((level+1) * i) & m)
    if len(encoded) != 0:
        raise ERR_INPUT
    return (level, tuple(prefixes))
]]></artwork>
            <t>Implementation note: The aggregation parameter includes the level of the IDPF
tree and the sequence of indices to evaluate. For implementations that perform
per-report caching across executions of the VDAF, this may be more information
than is strictly needed. In particular, it may be sufficient to convey which
indices from the previous execution will have their children included in the
next. This would help reduce communication overhead.</t>
          </section>
        </section>
      </section>
      <section anchor="idpf-poplar">
        <name>The IDPF scheme of <xref target="BBCGGI21"/></name>
        <t>In this section we specify a concrete IDPF, called IdpfPoplar, suitable for
instantiating Poplar1. The scheme gets its name from the name of the protocol of
<xref target="BBCGGI21"/>.</t>
        <ul empty="true">
          <li>
            <t>TODO We should consider giving <tt>IdpfPoplar</tt> a more distinctive name.</t>
          </li>
        </ul>
        <t>The constant and type definitions required by the <tt>Idpf</tt> interface are given in
<xref target="idpf-poplar-param"/>.</t>
        <t>IdpfPoplar requires a XOF for deriving the output shares, as well as a variety
of other artifacts used internally. For performance reasons, we instantiate
this object using XofFixedKeyAes128 (<xref target="xof-fixed-key-aes128"/>). See
<xref target="xof-vs-ro"/> for justification of this choice.</t>
        <table anchor="idpf-poplar-param">
          <name>Constants and type definitions for IdpfPoplar.</name>
          <thead>
            <tr>
              <th align="left">Parameter</th>
              <th align="left">Value</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">SHARES</td>
              <td align="left">
                <tt>2</tt></td>
            </tr>
            <tr>
              <td align="left">BITS</td>
              <td align="left">any positive integer</td>
            </tr>
            <tr>
              <td align="left">VALUE_LEN</td>
              <td align="left">any positive integer</td>
            </tr>
            <tr>
              <td align="left">KEY_SIZE</td>
              <td align="left">
                <tt>Xof.SEED_SIZE</tt></td>
            </tr>
            <tr>
              <td align="left">FieldInner</td>
              <td align="left">
                <tt>Field64</tt> (<xref target="fields"/>)</td>
            </tr>
            <tr>
              <td align="left">FieldLeaf</td>
              <td align="left">
                <tt>Field255</tt> (<xref target="fields"/>)</td>
            </tr>
          </tbody>
        </table>
        <section anchor="key-generation">
          <name>Key Generation</name>
          <ul empty="true">
            <li>
              <t>TODO Describe the construction in prose, beginning with a gentle introduction
to the high level idea.</t>
            </li>
          </ul>
          <t>The description of the IDPF-key generation algorithm makes use of auxiliary
functions <tt>extend()</tt>, <tt>convert()</tt>, and <tt>encode_public_share()</tt> defined in
<xref target="idpf-poplar-helper-functions"/>. In the following, we let <tt>Field2</tt> denote the
field <tt>GF(2)</tt>.</t>
          <figure anchor="idpf-poplar-gen">
            <name>IDPF-key generation algorithm of IdpfPoplar.</name>
            <artwork><![CDATA[
def gen(IdpfPoplar, alpha, beta_inner, beta_leaf, binder, rand):
    if alpha >= 2 ** IdpfPoplar.BITS:
        raise ERR_INPUT # alpha too long
    if len(beta_inner) != IdpfPoplar.BITS - 1:
        raise ERR_INPUT # beta_inner vector is the wrong size
    if len(rand) != IdpfPoplar.RAND_SIZE:
        raise ERR_INPUT # unexpected length for random input

    init_seed = [
        rand[:XofFixedKeyAes128.SEED_SIZE],
        rand[XofFixedKeyAes128.SEED_SIZE:],
    ]

    seed = init_seed.copy()
    ctrl = [Field2(0), Field2(1)]
    correction_words = []
    for level in range(IdpfPoplar.BITS):
        Field = IdpfPoplar.current_field(level)
        keep = (alpha >> (IdpfPoplar.BITS - level - 1)) & 1
        lose = 1 - keep
        bit = Field2(keep)

        (s0, t0) = IdpfPoplar.extend(seed[0], binder)
        (s1, t1) = IdpfPoplar.extend(seed[1], binder)
        seed_cw = xor(s0[lose], s1[lose])
        ctrl_cw = (
            t0[0] + t1[0] + bit + Field2(1),
            t0[1] + t1[1] + bit,
        )

        x0 = xor(s0[keep], ctrl[0].conditional_select(seed_cw))
        x1 = xor(s1[keep], ctrl[1].conditional_select(seed_cw))
        (seed[0], w0) = IdpfPoplar.convert(level, x0, binder)
        (seed[1], w1) = IdpfPoplar.convert(level, x1, binder)
        ctrl[0] = t0[keep] + ctrl[0] * ctrl_cw[keep]
        ctrl[1] = t1[keep] + ctrl[1] * ctrl_cw[keep]

        b = beta_inner[level] if level < IdpfPoplar.BITS-1 \
                else beta_leaf
        if len(b) != IdpfPoplar.VALUE_LEN:
            raise ERR_INPUT # beta too long or too short

        w_cw = vec_add(vec_sub(b, w0), w1)
        # Implementation note: Here we negate the correction word if
        # the control bit `ctrl[1]` is set. We avoid branching on the
        # value in order to reduce leakage via timing side channels.
        mask = Field(1) - Field(2) * Field(ctrl[1].as_unsigned())
        for i in range(len(w_cw)):
            w_cw[i] *= mask

        correction_words.append((seed_cw, ctrl_cw, w_cw))

    public_share = IdpfPoplar.encode_public_share(correction_words)
    return (public_share, init_seed)
]]></artwork>
          </figure>
        </section>
        <section anchor="key-evaluation">
          <name>Key Evaluation</name>
          <ul empty="true">
            <li>
              <t>TODO Describe in prose how IDPF-key evaluation algorithm works.</t>
            </li>
          </ul>
          <t>The description of the IDPF-evaluation algorithm makes use of auxiliary
functions <tt>extend()</tt>, <tt>convert()</tt>, and <tt>decode_public_share()</tt> defined in
<xref target="idpf-poplar-helper-functions"/>.</t>
          <figure anchor="idpf-poplar-eval">
            <name>IDPF-evaluation generation algorithm of IdpfPoplar.</name>
            <artwork><![CDATA[
def eval(IdpfPoplar, agg_id, public_share, init_seed,
         level, prefixes, binder):
    if agg_id >= IdpfPoplar.SHARES:
        raise ERR_INPUT # invalid aggregator ID
    if level >= IdpfPoplar.BITS:
        raise ERR_INPUT # level too deep
    if len(set(prefixes)) != len(prefixes):
        raise ERR_INPUT # candidate prefixes are non-unique

    correction_words = IdpfPoplar.decode_public_share(public_share)
    out_share = []
    for prefix in prefixes:
        if prefix >= 2 ** (level+1):
            raise ERR_INPUT # prefix too long

        # The Aggregator's output share is the value of a node of
        # the IDPF tree at the given `level`. The node's value is
        # computed by traversing the path defined by the candidate
        # `prefix`. Each node in the tree is represented by a seed
        # (`seed`) and a set of control bits (`ctrl`).
        seed = init_seed
        ctrl = Field2(agg_id)
        for current_level in range(level+1):
            bit = (prefix >> (level - current_level)) & 1

            # Implementation note: Typically the current round of
            # candidate prefixes would have been derived from
            # aggregate results computed during previous rounds. For
            # example, when using `IdpfPoplar` to compute heavy
            # hitters, a string whose hit count exceeded the given
            # threshold in the last round would be the prefix of each
            # `prefix` in the current round. (See [BBCGGI21,
            # Section 5.1].) In this case, part of the path would
            # have already been traversed.
            #
            # Re-computing nodes along previously traversed paths is
            # wasteful. Implementations can eliminate this added
            # complexity by caching nodes (i.e., `(seed, ctrl)`
            # pairs) output by previous calls to `eval_next()`.
            (seed, ctrl, y) = IdpfPoplar.eval_next(
                seed,
                ctrl,
                correction_words[current_level],
                current_level,
                bit,
                binder,
            )
        out_share.append(y if agg_id == 0 else vec_neg(y))
    return out_share

def eval_next(IdpfPoplar, prev_seed, prev_ctrl,
              correction_word, level, bit, binder):
    """
    Compute the next node in the IDPF tree along the path determined by
    a candidate prefix. The next node is determined by `bit`, the bit of
    the prefix corresponding to the next level of the tree.

    TODO Consider implementing some version of the optimization
    discussed at the end of [BBCGGI21, Appendix C.2]. This could on
    average reduce the number of AES calls by a constant factor.
    """

    Field = IdpfPoplar.current_field(level)
    (seed_cw, ctrl_cw, w_cw) = correction_word
    (s, t) = IdpfPoplar.extend(prev_seed, binder)
    s[0] = xor(s[0], prev_ctrl.conditional_select(seed_cw))
    s[1] = xor(s[1], prev_ctrl.conditional_select(seed_cw))
    t[0] += ctrl_cw[0] * prev_ctrl
    t[1] += ctrl_cw[1] * prev_ctrl

    next_ctrl = t[bit]
    (next_seed, y) = IdpfPoplar.convert(level, s[bit], binder)
    # Implementation note: Here we add the correction word to the
    # output if `next_ctrl` is set. We avoid branching on the value of
    # the control bit in order to reduce side channel leakage.
    mask = Field(next_ctrl.as_unsigned())
    for i in range(len(y)):
        y[i] += w_cw[i] * mask

    return (next_seed, next_ctrl, y)
]]></artwork>
          </figure>
        </section>
        <section anchor="idpf-poplar-helper-functions">
          <name>Auxiliary Functions</name>
          <figure anchor="idpf-poplar-helpers">
            <name>Helper functions for IdpfPoplar.</name>
            <artwork><![CDATA[
def extend(IdpfPoplar, seed, binder):
    xof = XofFixedKeyAes128(seed, format_dst(1, 0, 0), binder)
    s = [
        xof.next(XofFixedKeyAes128.SEED_SIZE),
        xof.next(XofFixedKeyAes128.SEED_SIZE),
    ]
    b = xof.next(1)[0]
    t = [Field2(b & 1), Field2((b >> 1) & 1)]
    return (s, t)

def convert(IdpfPoplar, level, seed, binder):
    xof = XofFixedKeyAes128(seed, format_dst(1, 0, 1), binder)
    next_seed = xof.next(XofFixedKeyAes128.SEED_SIZE)
    Field = IdpfPoplar.current_field(level)
    w = xof.next_vec(Field, IdpfPoplar.VALUE_LEN)
    return (next_seed, w)

def encode_public_share(IdpfPoplar, correction_words):
    encoded = Bytes()
    control_bits = list(itertools.chain.from_iterable(
        cw[1] for cw in correction_words
    ))
    encoded += pack_bits(control_bits)
    for (level, (seed_cw, _, w_cw)) \
        in enumerate(correction_words):
        Field = IdpfPoplar.current_field(level)
        encoded += seed_cw
        encoded += Field.encode_vec(w_cw)
    return encoded

def decode_public_share(IdpfPoplar, encoded):
    l = (2*IdpfPoplar.BITS + 7) // 8
    encoded_ctrl, encoded = encoded[:l], encoded[l:]
    control_bits = unpack_bits(encoded_ctrl, 2 * IdpfPoplar.BITS)
    correction_words = []
    for level in range(IdpfPoplar.BITS):
        Field = IdpfPoplar.current_field(level)
        ctrl_cw = (
            control_bits[level * 2],
            control_bits[level * 2 + 1],
        )
        l = XofFixedKeyAes128.SEED_SIZE
        seed_cw, encoded = encoded[:l], encoded[l:]
        l = Field.ENCODED_SIZE * IdpfPoplar.VALUE_LEN
        encoded_w_cw, encoded = encoded[:l], encoded[l:]
        w_cw = Field.decode_vec(encoded_w_cw)
        correction_words.append((seed_cw, ctrl_cw, w_cw))
    if len(encoded) != 0:
        raise ERR_DECODE
    return correction_words
]]></artwork>
          </figure>
          <t>Here, <tt>pack_bits()</tt> takes a list of bits, packs each group of eight bits into a
byte, in LSB to MSB order, padding the most significant bits of the last byte
with zeros as necessary, and returns the byte array. <tt>unpack_bits()</tt> performs
the reverse operation: it takes in a byte array and a number of bits, and
returns a list of bits, extracting eight bits from each byte in turn, in LSB to
MSB order, and stopping after the requested number of bits. If the byte array
has an incorrect length, or if unused bits in the last bytes are not zero, it
throws an error.</t>
        </section>
      </section>
      <section anchor="poplar1-inst">
        <name>Instantiation</name>
        <t>By default, Poplar1 is instantiated with IdpfPoplar (<tt>VALUE_LEN == 2</tt>) and
XofShake128 (<xref target="xof-shake128"/>). This VDAF is suitable for any positive value of
<tt>BITS</tt>. Test vectors can be found in <xref target="test-vectors"/>.</t>
      </section>
    </section>
    <section anchor="security">
      <name>Security Considerations</name>
      <t>VDAFs have two essential security goals:</t>
      <ol spacing="normal" type="1"><li>Privacy: An attacker that controls the network, the Collector, and a subset
of Clients and Aggregators learns nothing about the measurements of honest
Clients beyond what it can deduce from the aggregate result.</li>
        <li>Robustness: An attacker that controls the network and a subset of Clients
cannot cause the Collector to compute anything other than the aggregate of
the measurements of honest Clients.</li>
      </ol>
      <t>Formal definitions of privacy and robustness can be found in <xref target="DPRS23"/>. A VDAF
is the core cryptographic primitive of a protocol that achieves the above
privacy and robustness goals. It is not sufficient on its own, however. The
application will need to assure a few security properties, for example:</t>
      <ul spacing="normal">
        <li>Securely distributing the long-lived parameters, in particular the
verification key.</li>
        <li>
          <t>Establishing secure channels:  </t>
          <ul spacing="normal">
            <li>Confidential and authentic channels among Aggregators, and between the
Aggregators and the Collector; and</li>
            <li>Confidential and Aggregator-authenticated channels between Clients and
Aggregators.</li>
          </ul>
        </li>
        <li>Enforcing the non-collusion properties required of the specific VDAF in use.</li>
      </ul>
      <t>In such an environment, a VDAF provides the high-level privacy property
described above: The Collector learns only the aggregate measurement, and
nothing about individual measurements aside from what can be inferred from the
aggregate result.  The Aggregators learn neither individual measurements nor the
aggregate result.  The Collector is assured that the aggregate statistic
accurately reflects the inputs as long as the Aggregators correctly executed
their role in the VDAF.</t>
      <t>On their own, VDAFs do not mitigate Sybil attacks <xref target="Dou02"/>. In this attack, the
adversary observes a subset of input shares transmitted by a Client it is
interested in. It allows the input shares to be processed, but corrupts and
picks bogus measurements for the remaining Clients.  Applications can guard
against these risks by adding additional controls on report submission,
such as Client authentication and rate limits.</t>
      <t>VDAFs do not inherently provide differential privacy <xref target="Dwo06"/>.  The VDAF approach
to private measurement can be viewed as complementary to differential privacy,
relying on non-collusion instead of statistical noise to protect the privacy of
the inputs.  It is possible that a future VDAF could incorporate differential
privacy features, e.g., by injecting noise before the sharding stage and
removing it after unsharding.</t>
      <section anchor="requirements-for-the-verification-key">
        <name>Requirements for the Verification Key</name>
        <t>The Aggregators are responsible for exchanging the verification key in advance
of executing the VDAF. Any procedure is acceptable as long as the following
conditions are met:</t>
        <ol spacing="normal" type="1"><li>To ensure robustness of the computation, the Aggregators <bcp14>MUST NOT</bcp14> reveal the
verification key to the Clients. Otherwise, a malicious Client might be able
to exploit knowledge of this key to craft an invalid report that would be
accepted by the Aggregators.</li>
          <li>To ensure privacy of the measurements, the Aggregators <bcp14>MUST</bcp14> commit to the
verification key prior to processing reports generated by Clients. Otherwise,
a malicious Aggregator may be able to craft a verification key that, for a
given report, causes an honest Aggregator to leak information about the
measurement during preparation.</li>
        </ol>
        <t>Meeting these conditions is required in order to leverage security analysis in
the framework of <xref target="DPRS23"/>. Their definition of robustness allows the attacker,
playing the role of a cohort of malicious Clients, to submit arbitrary reports
to the Aggregators and eavesdrop on their communications as they process them.
Security in this model is achievable as long as the verification key is kept
secret from the attacker.</t>
        <t>The privacy definition of <xref target="DPRS23"/> considers an active attacker that controls
the network and a subset of Aggregators; in addition, the attacker is allowed to
choose the verification key used by each honest Aggregator over the course of
the experiment. Security is achievable in this model as long as the key is
picked at the start of the experiment, prior to any reports being generated.
(The model also requires nonces to be generated at random; see
<xref target="nonce-requirements"/> below.)</t>
        <t>Meeting these requirements is relatively straightforward. For example, the
Aggregators may designate one of their peers to generate the verification key
and distribute it to the others. To assure Clients of key commitment, the
Clients and (honest) Aggregators could bind reports to a shared context string
derived from the key. For instance, the "task ID" of DAP <xref target="DAP"/> could be set to
the hash of the verification key; then as long as honest Aggregators only
consume reports for the task indicated by the Client, forging a new key after
the fact would reduce to finding collisions in the underlying hash function.
(Keeping the key secret from the Clients would require the hash function to be
one-way.) However, since rotating the key implies rotating the task ID, this
scheme would not allow key rotation over the lifetime of a task.</t>
      </section>
      <section anchor="nonce-requirements">
        <name>Requirements for the Nonce</name>
        <t>The sharding and preparation steps of VDAF execution depend on a nonce
associated with the Client's report. To ensure privacy of the underlying
measurement, the Client <bcp14>MUST</bcp14> generate this nonce using a CSPRNG. This is
required in order to leverage security analysis for the privacy definition of
<xref target="DPRS23"/>, which assumes the nonce is chosen at random prior to generating the
report.</t>
        <t>Other security considerations may require the nonce to be non-repeating. For
example, to achieve differential privacy it is necessary to avoid "over
exposing" a measurement by including it too many times in a single batch or
across multiple batches. It is <bcp14>RECOMMENDED</bcp14> that the nonce generated by the
Client be used by the Aggregators for replay protection.</t>
      </section>
      <section anchor="requirements-for-the-aggregation-parameters">
        <name>Requirements for the Aggregation Parameters</name>
        <t>As described in <xref target="sec-daf-validity-scopes"/> and <xref target="sec-vdaf-validity-scopes"/>
respectively, DAFs and VDAFs may impose restrictions on the re-use of input
shares. This is to ensure that correlated randomness provided by the Client
through the input share is not used more than once, which might compromise
confidentiality of the Client's measurements.</t>
        <t>Protocols that make use of VDAFs therefore <bcp14>MUST</bcp14> call <tt>Vdaf.is_valid</tt>
on the set of all aggregation parameters used for a Client's input share, and
only proceed with the preparation and aggregation phases if that function call
returns <tt>True</tt>.</t>
        <section anchor="agg-param-privacy">
          <name>Additional Privacy Considerations</name>
          <t>Aggregating a batch of reports multiple times, each time with a different
aggregation parameter, could result in information leakage beyond what is used
by the application.</t>
          <t>For example, when Poplar1 is used for heavy hitters, the Aggregators learn not
only the heavy hitters themselves, but also the prefix tree (as defined in
<xref target="poplar1"/>) computed along the way. Indeed, this leakage is inherent to any
construction that uses an IDPF (<xref target="idpf"/>) in the same way. Depending on the
distribution of the measurements, the prefix tree can leak a significant amount
of information about unpopular inputs. For instance, it is possible (though
perhaps unlikely) for a large set of non-heavy-hitter values to share a common
prefix, which would be leaked by a prefix tree with a sufficiently small
threshold.</t>
          <t>The only known, general-purpose approach to mitigating this leakage is via
differential privacy.</t>
          <ul empty="true">
            <li>
              <t>TODO(issue #94) Describe (or point to some description of) the central DP
mechanism for Poplar described in <xref target="BBCGGI21"/>.</t>
            </li>
          </ul>
        </section>
      </section>
      <section anchor="xof-vs-ro">
        <name>Requirements for XOFs</name>
        <t>XofShake128 is designed to be indifferentiable from a random oracle <xref target="MRH04"/>,
making it a suitable choice for most situations, in particular wherever the XOF
is modeled as a random oracle in existing security analysis.</t>
        <t>XofFixedKeyAes128 is known to be differentiable from a random oracle
<xref target="GKWWY20"/> and is therefore <bcp14>NOT RECOMMENDED</bcp14> for general use. It is used only by
IdpfPoplar (<xref target="idpf-poplar"/>) whose security analysis does not require a random
oracle.</t>
        <ul empty="true">
          <li>
            <t>TODO(issue #216) Justify this claim.</t>
          </li>
        </ul>
        <ul empty="true">
          <li>
            <t>OPEN ISSUE: We may want to drop the common interface for XOFs and random
oracles. See issue #159.</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>A codepoint for each (V)DAF in this document is defined in the table below. Note
that <tt>0xFFFF0000</tt> through <tt>0xFFFFFFFF</tt> are reserved for private use.</t>
      <table anchor="codepoints">
        <name>Unique identifiers for (V)DAFs.</name>
        <thead>
          <tr>
            <th align="left">Value</th>
            <th align="left">Scheme</th>
            <th align="left">Type</th>
            <th align="left">Reference</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">
              <tt>0x00000000</tt></td>
            <td align="left">Prio3Count</td>
            <td align="left">VDAF</td>
            <td align="left">
              <xref target="prio3count"/></td>
          </tr>
          <tr>
            <td align="left">
              <tt>0x00000001</tt></td>
            <td align="left">Prio3Sum</td>
            <td align="left">VDAF</td>
            <td align="left">
              <xref target="prio3sum"/></td>
          </tr>
          <tr>
            <td align="left">
              <tt>0x00000002</tt></td>
            <td align="left">Prio3SumVec</td>
            <td align="left">VDAF</td>
            <td align="left">
              <xref target="prio3sumvec"/></td>
          </tr>
          <tr>
            <td align="left">
              <tt>0x00000003</tt></td>
            <td align="left">Prio3Histogram</td>
            <td align="left">VDAF</td>
            <td align="left">
              <xref target="prio3histogram"/></td>
          </tr>
          <tr>
            <td align="left">
              <tt>0x00000004</tt> to <tt>0x00000FFF</tt></td>
            <td align="left">reserved for Prio3</td>
            <td align="left">VDAF</td>
            <td align="left">n/a</td>
          </tr>
          <tr>
            <td align="left">
              <tt>0x00001000</tt></td>
            <td align="left">Poplar1</td>
            <td align="left">VDAF</td>
            <td align="left">
              <xref target="poplar1-inst"/></td>
          </tr>
          <tr>
            <td align="left">
              <tt>0xFFFF0000</tt> to <tt>0xFFFFFFFF</tt></td>
            <td align="left">reserved</td>
            <td align="left">n/a</td>
            <td align="left">n/a</td>
          </tr>
        </tbody>
      </table>
      <ul empty="true">
        <li>
          <t>TODO Add IANA considerations for the codepoints summarized in <xref target="codepoints"/>.</t>
        </li>
      </ul>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <reference anchor="FIPS202">
          <front>
            <title>SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions</title>
            <author>
              <organization/>
            </author>
            <date year="2015" month="August"/>
          </front>
          <seriesInfo name="NIST FIPS PUB 202" value=""/>
        </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>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="AGJOP21" target="https://ia.cr/2021/576">
          <front>
            <title>Prio+: Privacy Preserving Aggregate Statistics via Boolean Shares</title>
            <author initials="S." surname="Addanki">
              <organization/>
            </author>
            <author initials="K." surname="Garbe">
              <organization/>
            </author>
            <author initials="E." surname="Jaffe">
              <organization/>
            </author>
            <author initials="R." surname="Ostrovsky">
              <organization/>
            </author>
            <author initials="A." surname="Polychroniadou">
              <organization/>
            </author>
            <date year="2021"/>
          </front>
        </reference>
        <reference anchor="BBCGGI19" target="https://ia.cr/2019/188">
          <front>
            <title>Zero-Knowledge Proofs on Secret-Shared Data via Fully Linear PCPs</title>
            <author initials="D." surname="Boneh">
              <organization/>
            </author>
            <author initials="E." surname="Boyle">
              <organization/>
            </author>
            <author initials="H." surname="Corrigan-Gibbs">
              <organization/>
            </author>
            <author initials="N." surname="Gilboa">
              <organization/>
            </author>
            <author initials="Y." surname="Ishai">
              <organization/>
            </author>
            <date year="2019"/>
          </front>
          <seriesInfo name="CRYPTO 2019" value=""/>
        </reference>
        <reference anchor="BBCGGI21" target="https://ia.cr/2021/017">
          <front>
            <title>Lightweight Techniques for Private Heavy Hitters</title>
            <author initials="D." surname="Boneh">
              <organization/>
            </author>
            <author initials="E." surname="Boyle">
              <organization/>
            </author>
            <author initials="H." surname="Corrigan-Gibbs">
              <organization/>
            </author>
            <author initials="N." surname="Gilboa">
              <organization/>
            </author>
            <author initials="Y." surname="Ishai">
              <organization/>
            </author>
            <date year="2021"/>
          </front>
          <seriesInfo name="IEEE S&amp;P 2021" value=""/>
        </reference>
        <reference anchor="CGB17" target="https://dl.acm.org/doi/10.5555/3154630.3154652">
          <front>
            <title>Prio: Private, Robust, and Scalable Computation of Aggregate Statistics</title>
            <author initials="H." surname="Corrigan-Gibbs">
              <organization/>
            </author>
            <author initials="D." surname="Boneh">
              <organization/>
            </author>
            <date year="2017"/>
          </front>
          <seriesInfo name="NSDI 2017" value=""/>
        </reference>
        <reference anchor="Dou02" target="https://doi.org/10.1007/3-540-45748-8_24">
          <front>
            <title>The Sybil Attack</title>
            <author initials="J." surname="Douceur">
              <organization/>
            </author>
            <date year="2002"/>
          </front>
          <seriesInfo name="IPTPS 2002" value=""/>
        </reference>
        <reference anchor="DPRS23" target="https://ia.cr/2023/130">
          <front>
            <title>Verifiable Distributed Aggregation Functions</title>
            <author initials="H." surname="Davis">
              <organization/>
            </author>
            <author initials="C." surname="Patton">
              <organization/>
            </author>
            <author initials="M." surname="Rosulek">
              <organization/>
            </author>
            <author initials="P." surname="Schoppmann">
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="Dwo06" target="https://link.springer.com/chapter/10.1007/11787006_1">
          <front>
            <title>Differential Privacy</title>
            <author initials="C." surname="Dwork">
              <organization/>
            </author>
            <date year="2006"/>
          </front>
          <seriesInfo name="ICALP 2006" value=""/>
        </reference>
        <reference anchor="EPK14" target="https://dl.acm.org/doi/10.1145/2660267.2660348">
          <front>
            <title>RAPPOR: Randomized Aggregatable Privacy-Preserving Ordinal Response</title>
            <author initials="Ú." surname="Erlingsson">
              <organization/>
            </author>
            <author initials="V." surname="Pihur">
              <organization/>
            </author>
            <author initials="A." surname="Korolova">
              <organization/>
            </author>
            <date year="2014"/>
          </front>
          <seriesInfo name="CCS 2014" value=""/>
        </reference>
        <reference anchor="ENPA" target="https://covid19-static.cdn-apple.com/applications/covid19/current/static/contact-tracing/pdf/ENPA_White_Paper.pdf">
          <front>
            <title>Exposure Notification Privacy-preserving Analytics (ENPA) White Paper</title>
            <author>
              <organization/>
            </author>
            <date year="2021"/>
          </front>
        </reference>
        <reference anchor="GI14" target="https://link.springer.com/chapter/10.1007/978-3-642-55220-5_35">
          <front>
            <title>Distributed Point Functions and Their Applications</title>
            <author initials="N." surname="Gilboa">
              <organization/>
            </author>
            <author initials="Y." surname="Ishai">
              <organization/>
            </author>
            <date year="2014"/>
          </front>
          <seriesInfo name="EUROCRYPT 2014" value=""/>
        </reference>
        <reference anchor="GKWWY20" target="https://link.springer.com/chapter/10.1007/978-3-030-56880-1_28">
          <front>
            <title>Better concrete security for half-gates garbling (in the multi-instance setting)</title>
            <author>
              <organization/>
            </author>
            <date year="2020"/>
          </front>
          <seriesInfo name="CRYPTO 2020" value=""/>
        </reference>
        <reference anchor="MRH04" target="https://doi.org/10.1007/978-3-540-24638-1_2">
          <front>
            <title>Indifferentiability, impossibility results on reductions, and applications to the random oracle methodology</title>
            <author initials="U." surname="Maurer" fullname="Ueli Maurer">
              <organization>ETH Zurich</organization>
            </author>
            <author initials="R." surname="Renner" fullname="Renato Renner">
              <organization>ETH Zurich</organization>
            </author>
            <author initials="C." surname="Holenstein" fullname="Clemens Holenstein">
              <organization>ETH Zurich</organization>
            </author>
            <date year="2004" month="February"/>
          </front>
          <seriesInfo name="In" value="TCC 2004: Theory of Cryptography"/>
          <seriesInfo name="pages" value="21-39"/>
          <seriesInfo name="DOI" value="10.1007/978-3-540-24638-1_2"/>
        </reference>
        <reference anchor="OriginTelemetry" target="https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/collection/origin.html">
          <front>
            <title>Origin Telemetry</title>
            <author>
              <organization/>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="DAP">
          <front>
            <title>Distributed Aggregation Protocol for Privacy Preserving Measurement</title>
            <author fullname="Tim Geoghegan" initials="T." surname="Geoghegan">
              <organization>ISRG</organization>
            </author>
            <author fullname="Christopher Patton" initials="C." surname="Patton">
              <organization>Cloudflare</organization>
            </author>
            <author fullname="Eric Rescorla" initials="E." surname="Rescorla">
              <organization>Mozilla</organization>
            </author>
            <author fullname="Christopher A. Wood" initials="C. A." surname="Wood">
              <organization>Cloudflare</organization>
            </author>
            <date day="10" month="July" year="2023"/>
            <abstract>
              <t>   There are many situations in which it is desirable to take
   measurements of data which people consider sensitive.  In these
   cases, the entity taking the measurement is usually not interested in
   people's individual responses but rather in aggregated data.
   Conventional methods require collecting individual responses and then
   aggregating them, thus representing a threat to user privacy and
   rendering many such measurements difficult and impractical.  This
   document describes a multi-party distributed aggregation protocol
   (DAP) for privacy preserving measurement (PPM) which can be used to
   collect aggregate data without revealing any individual user's data.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-ppm-dap-05"/>
        </reference>
      </references>
    </references>
    <?line 4539?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>The security considerations in <xref target="security"/> are based largely on the security
analysis of <xref target="DPRS23"/>. Thanks to Hannah Davis and Mike Rosulek, who lent their
time to developing definitions and security proofs.</t>
      <t>Thanks to Henry Corrigan-Gibbs, Armando Faz-Hernández, Simon Friedberger, Tim
Geoghegan, Brandon Pitman, Mariana Raykova, Jacob Rothstein, Shan Wang, Xiao
Wang, and Christopher Wood for useful feedback on and contributions to the
spec.</t>
    </section>
    <section numbered="false" anchor="test-vectors">
      <name>Test Vectors</name>
      <t>[TO BE REMOVED BY RFC EDITOR: Machine-readable test vectors can be found at
https://github.com/cfrg/draft-irtf-cfrg-vdaf/tree/main/poc/test_vec.]</t>
      <t>Test vectors cover the generation of input shares and the conversion of input
shares into output shares. Vectors specify the verification key, measurements,
aggregation parameter, and any parameters needed to construct the VDAF. (For
example, for <tt>Prio3Sum</tt>, the user specifies the number of bits for representing
each summand.)</t>
      <t>Byte strings are encoded in hexadecimal. To make the tests deterministic, the
random inputs of randomized algorithms were fixed to the byte sequence starting
with <tt>0</tt>, incrementing by <tt>1</tt>, and wrapping at <tt>256</tt>:</t>
      <artwork><![CDATA[
0, 1, 2, ..., 255, 0, 1, 2, ...
]]></artwork>
      <section numbered="false" anchor="testvec-prio3count">
        <name>Prio3Count</name>
        <ul empty="true">
          <li>
            <t>TODO Copy the machine readable vectors from the source repository
(https://github.com/cfrg/draft-irtf-cfrg-vdaf/tree/main/poc/test_vec) and
format them for humans.</t>
          </li>
        </ul>
      </section>
      <section numbered="false" anchor="testvec-prio3sum">
        <name>Prio3Sum</name>
        <ul empty="true">
          <li>
            <t>TODO Copy the machine readable vectors from the source repository
(https://github.com/cfrg/draft-irtf-cfrg-vdaf/tree/main/poc/test_vec) and
format them for humans.</t>
          </li>
        </ul>
      </section>
      <section numbered="false" anchor="testvec-prio3sumvec">
        <name>Prio3SumVec</name>
        <ul empty="true">
          <li>
            <t>TODO Copy the machine readable vectors from the source repository
(https://github.com/cfrg/draft-irtf-cfrg-vdaf/tree/main/poc/test_vec) and
format them for humans.</t>
          </li>
        </ul>
      </section>
      <section numbered="false" anchor="testvec-prio3histogram">
        <name>Prio3Histogram</name>
        <ul empty="true">
          <li>
            <t>TODO Copy the machine readable vectors from the source repository
(https://github.com/cfrg/draft-irtf-cfrg-vdaf/tree/main/poc/test_vec) and
format them for humans.</t>
          </li>
        </ul>
      </section>
      <section numbered="false" anchor="testvec-poplar1">
        <name>Poplar1</name>
        <ul empty="true">
          <li>
            <t>TODO Copy the machine readable vectors from the source repository
(https://github.com/cfrg/draft-irtf-cfrg-vdaf/tree/main/poc/test_vec) and
format them for humans.</t>
          </li>
        </ul>
      </section>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA+y963obR5Io+L+eIhv6zjHQAiCSutl02zOURMlsSyKHlOT2
aNREASiQZQEoTFWBFFvyPMj+2mfZfbGNW2ZGZhUoyu6e02d3+c20BaAqL5GR
cb8MBoOkzut5tms6b7Iyn+XpeJ6ZJ3lVl/l4XWdTs3d2VmZnaZ0XS/N0vZzg
P6pOko7HZXaBrz3Ze9pJpsVkmS5gmGmZzupBXtazwWRWng0upulssPUwmaR1
dlaUV7smX86KJMlX5a6py3VV72xtfbO1k6Rllu6ag+NXT5PLonx/Vhbr1a55
/PT4WfI+u4KvpvDrss7KZVYPnuAsSVLV6XJ6ms6LJcx8lVVJtUjL+vQ/10Wd
VbtmWSSrfNe8rYtJ31RFWZfZrIJ/XS3wH++SJF3X50W5m5hBYuCPd3CcT87T
cmqeD82jFGar6LeiPEuX+d8IDrCsvJoU9H22SPP5rinn43/NVxfD6kM42JP0
Ip+ax0XxvmWUgxPYnBpkml9k5Vm2rKfpRfavZ/jlcFIswhEfn5dwOsXqPCvN
UVrXxbJtffNiPZ3NAaZ6/Am+uqJ3budZPds0xdF5Pp/nq5U5mZwXq9UiXbbN
8awozubB+JV7/F/P6EcaOlkW5QLeuch2E3j66cHRyc7Wzi69aHHv5Ie9wV1z
gseZ4kEfZeViXdNEg0dpBWj4Q1qdG/jZ7H+oM3gK0HRwuK5X61pjJY45BUzb
NXvrM8Ats7O1fZ++rQC7swpxb9e8PDh5ReswR68fwSM7gI7wg17l3rM/Hx7t
bIerPCrz4jYsrswv0skV/DeDUS/y5Zm7JBnuoYbzySeVuchT86go5lm6NCeA
Upks0GEd/Q3gQgCungzN3nSaLt/n4fc/Ds2ztBxn4bf7Q/PndDaLvj0emkO4
uMVF9f4q/GVvaI6K+RUgQLHM02mxVpCC/W/zNlNAvnrXnNf1qtq9cydPh5Py
Dv585/7DBwiVR48eP3t2sP1NCJZ/z8pi8OOyuJxn07MMwFIUs8oAuTjJJiVc
Vtr7FK5CnRJMnq7n8yvzPF9mKaDw46PrwPIELiHc7vPG9h8VV/No+z8M4aKV
ZQ5IOniWj8dV+PNLgGQ+Hxdp+PXPQ3NQnad5AJHtbxpI8/j456NXh/63TdDa
/ubO9tdfe2jFSPQ8PzuvLzP8X/Mqm5wv8/9cZ5UB9GPEAhz6IUsvrswPeQ3U
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
jw4UZPLF2KIfqAbGGaB1P7FVNGKD2Y0LaQRm4eRGFTQY6X1XHuI3rTU0ki+u
odFWPuEirJ9AKKceasM49XOEcHacAN3+/1oG/ytrGXzxldAp8Lboxn5LPgen
9rTkWbdmfzgPepXfINVa5yTjLByiF+b/3dQfEb6lkJAeb89mbstOjh0U8cgt
GdD0ik6Bbs1oVknLkpqrhnJJy7yi4Lffn7S8Of84jHX7jQnI7SF4N89AdoYW
Scpt6Px+/d7uqGAqsOZgm+DbKPeWFtqaqtyt2ORasXfpO7PRK9Y3v9wsEdf+
fWH+rv37XP5zy19wZl/0Zpw+HbysYG5zh+lT+JQ9APcIQVIfu1aJVXmcPLIY
hHnmeXR6rNcOtqPzs9b14OQ22Vu/DDZ6c+1bDnHOrvxGeCfDBMuOvAh4IN59
0Gu83ngUxkMMLtZ121TBIeGj+ogo4pqKnqheAd4ykImWY12XG87tH3gYzYP4
nRff0ejfegQtID0V3G/MUamHZBu/o0yBvNpIBqH2wToA0OVlujAENtq3vM2i
JZUSceWrJA3ixhUO2oHtgUA1Dt7CZ4AqvcsGIvWEP8ewMMImtaYfjP73Lnrw
e6odtEvGX1Du4DfVO7jYXPDA5cI455aveKD8GGVTG3LKfp9cL9gsNCxXGFRt
9raVIDzmVZD/QZkCaOCzNv9zMfeyFMTxsucFoCM3oHOuWTGNVd4UL2+AcM5B
EWTUSjb6yc1eRfmWqc89CaXcX204MYq6SZuoq9YQlJZlc6+rZWCbMtjCA8kY
rlOWxYGqLcUVWCZ/HOTvHaU1nIDYw8IAbmchGqBBkjuAeF8PzqTkqqZzDXOf
Mhse60vfoWk18SXgZRd9MSezrrNUumi7588Z6xMxco7aeEJvpFEQ1hyUnm9a
1dG7V9axC9HYLqo2MVb3UGVL8QrWm3KYQiEFItDEy/6OeK/O+EQVLEKPAaEf
9rUkdV7UsNAfafPatLxLxb8ulzr5Fs+NXhzIi6STwaXm4WIi0dKhPnqiUQvu
U/zERfOJEwIoj/g9egVBgVtnU8UKQSGHX56i4nmehdyubca2727jCMfZL1z7
/U+4dku8NsDC0rKTALI2LCPISqQ0Pw6TQx9NztZjRGbqPOlqY0rwV4UFtrAB
wKpwVgUgOOiRnBeTdJ749kl30ANtI/ltsS3C9CwrXeM6jixyo48IoiP6NWGN
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
jAUpyCS3rqhDNaVtZFgZAptL2qC9ZWO1B1HjD4VfKuzNrUnavsxs6HIpfb3D
jXC11bWA1VaqFFczPDNMq1P7a5eg7jHWwpoD3LjEZSMKOzHRjDQswhRbXrJw
FHYdsiirsDX1RYyKsrGlZRKv33qZg5kVXnftPj1C+e2M5MdRQDvomgXjYXob
njBXvOdqnfKixaA51kEGYrC0CC0EBLfvgpfad0/mpEusbFfm2Nc8uKKqIYgN
BFcIH2FOg0KIZYqrInFyl8R/6lsToZ83AYv9DK8lrbVP9RP0NYx7A9lIie/4
S9F3cOYPyKPodS/ey8O3QeksQI06JTrY/RBiYp+Zx1BT08D6Z81u3Ncoi5fs
pM1HPprXrZ8X8xzW25zE2mkxh9GaF8z/gIfJN+J1DKydafaPj0+f7OPLrInA
AsLsT5WlvdUPxuyb570GUE4/wOvy77f5bn77uVc98ScMPPEgcy8Fav0H873d
l2VnoTIVrRw0tQN7qyoD/PiM0lsBp4XbubdhdzZdlG/Zh15wJPC7S1gi7BoI
cg9saoOkKz1pw3mCVyAFUM7SLSwVtP6Qz3OsIvdUNJ+KJVDF1N0jVjkiGsvo
XrVdmtKJgERhm/0jnUjj5Xqy97aUULUVfZzdM58RByCCj8K+jXKpbbEbZj3q
1sFKT6v1GDjhLGB5fQOi5HnwVS/syHWyHlMVRQ7Dw4ftvL6kC46qytHaaGTX
sjxqyIXume4iXXXn6WI8Tc2HXfPh7dY7M4D/YHdOLMiBQ8riej0xSeImgId9
2Sb2ptOWpYu8ec3Cb7jm25vXHCIrK8QDjz+upR4JwP77zYj69OmrwVOQt5dT
EPxD6Xcwm9WDmfxmW+6xNG0r4Yns6yTvQFnKZrN8QsVNdCymhGdO84q5y9Ni
XVK5UNubrM992SmJmaIbafGowoCedLUsFjk1iQIRGD5LS5Tu4TKz1fcQyZud
YSlbMMiu8r3eMPAWZJ2nz4+Qy3z8OJuvBvLlQJcqxGZr5oQVCYkhtgwY9ZM0
t/3POwhVC7kOFQiMqsNWsPBqduXr09oegVGwH6shv3Jxyk2yMpMjLSTD6lk0
Etat5SKpAsx8OWXyCQc3PgMt30XPGgMaZJ1LJvQFvIW/gvxIzRX19qS1bhn0
sbWjWamDMq2KS35kJxIcicKozqvu7Wk+4QhIzCWndSZGnTzAyGNEJUqyTZto
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

-->

</rfc>
