<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.2 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-irtf-cfrg-vdaf-08" category="info" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.18.2 -->
  <front>
    <title abbrev="VDAF">Verifiable Distributed Aggregation Functions</title>
    <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-vdaf-08"/>
    <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="November" day="20"/>
    <area>IRTF</area>
    <workgroup>CFRG</workgroup>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <?line 186?>

<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 196?>

<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>
              <t>General patterns of communications among the various actors involved in
the system (clients, aggregation servers, and the collector of the
aggregate result);</t>
            </li>
            <li>
              <t>Capabilities of a malicious coalition of servers attempting to divulge
information about client measurements; and</t>
            </li>
            <li>
              <t>Conditions that are necessary to ensure that malicious clients cannot
corrupt the computation.</t>
            </li>
          </ol>
        </li>
        <li>
          <t>Providing cryptographers with design criteria that provide a clear
deployment roadmap for new constructions.</t>
        </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>
              <t>Each client shards its measurement into a sequence of additive shares and
distributes the shares among the aggregation servers.</t>
            </li>
            <li>
              <t>Next, each server adds up its shares locally, resulting in an additive
share of the aggregate.</t>
            </li>
            <li>
              <t>Finally, the aggregation servers send their aggregate shares to the data
collector, who combines them to obtain the aggregate result.</t>
            </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>08:</t>
        <ul spacing="normal">
          <li>
            <t>Poplar1: Bind the report nonce to the authenticator vector programmed into
the IDPF. (*)</t>
          </li>
          <li>
            <t>IdpfPoplar: Modify <tt>extend()</tt> by stealing each control bit from its
corresponding seed. This improves performance by reducing the number of AES
calls per level from 3 to 2. The cost is a slight reduction in the concrete
privacy bound. (*)</t>
          </li>
          <li>
            <t>Prio3: Add support for generating and verifying mutliple proofs per
measurement. This enables a trade-off between communication cost and runtime:
if more proofs are used, then a smaller field can be used without impacting
robustness. (*)</t>
          </li>
          <li>
            <t>Replace SHAKE128 with TurboSHAKE128. (*)</t>
          </li>
        </ul>
        <t>07:</t>
        <ul spacing="normal">
          <li>
            <t>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.</t>
          </li>
          <li>
            <t>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. (*)</t>
          </li>
          <li>
            <t>Define a new VDAF, called Prio3SumVec, that generalizes Prio3Sum to a vector
of summands.</t>
          </li>
          <li>
            <t>Prio3Histogram: Update the codepoint and use the parallel sum optimization
introduced by Prio3SumVec to reduce the proof size. (*)</t>
          </li>
          <li>
            <t>Daf, Vdaf: Rename interface methods to match verbiage in the draft.</t>
          </li>
          <li>
            <t>Daf: Align with Vdaf by adding a nonce to <tt>shard()</tt> and <tt>prep()</tt>.</t>
          </li>
          <li>
            <t>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.</t>
          </li>
          <li>
            <t>Prio3: Split sharding into two auxiliary functions, one for sharding with
joint randomness and another without. This change is intended to improve
readability.</t>
          </li>
          <li>
            <t>Fix bugs in the ping-pong interface discovered after implementing it.</t>
          </li>
        </ul>
        <t>06:</t>
        <ul spacing="normal">
          <li>
            <t>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.</t>
          </li>
          <li>
            <t>Prio3Histogram: Generalize the measurement type so that the histogram can be
used more easily with discrete domains. (*)</t>
          </li>
          <li>
            <t>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.)</t>
          </li>
          <li>
            <t>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).</t>
          </li>
        </ul>
        <t>05:</t>
        <ul spacing="normal">
          <li>
            <t>IdpfPoplar: Replace PrgSha3 with PrgFixedKeyAes128, 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 PRG is not suitable
for all applications. (*)</t>
          </li>
          <li>
            <t>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 PRG.</t>
          </li>
          <li>
            <t>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.</t>
          </li>
          <li>
            <t>Use little-endian byte-order for field element encoding. (*)</t>
          </li>
          <li>
            <t>Poplar1: Move the last step of sketch evaluation from <tt>prep_next()</tt> to
<tt>prep_shares_to_prep()</tt>.</t>
          </li>
        </ul>
        <t>04:</t>
        <ul spacing="normal">
          <li>
            <t>Align security considerations with the security analysis of <xref target="DPRS23"/>.</t>
          </li>
          <li>
            <t>Vdaf: Pass the nonce to the sharding algorithm.</t>
          </li>
          <li>
            <t>Vdaf: Rather than allow the application to choose the nonce length, have each
implementation of the Vdaf interface specify the expected nonce length. (*)</t>
          </li>
          <li>
            <t>Prg: 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.</t>
          </li>
          <li>
            <t>Replace PrgAes128 with PrgSha3, an implementation of the Prg 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"/>. (*)</t>
          </li>
          <li>
            <t>Prio3, Poplar1: Ensure each invocation of the Prg uses a distinct
customization string, as suggested by <xref target="DPRS23"/>. This is intended to make
domain separation clearer, thereby simplifying security analysis. (*)</t>
          </li>
          <li>
            <t>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. (*)</t>
          </li>
          <li>
            <t>Prio3: Bind nonce to joint randomness parts. This is intended to address
birthday attacks on robustness pointed out by <xref target="DPRS23"/>. (*)</t>
          </li>
          <li>
            <t>Poplar1: Use different Prg invocations for producing the correlated randomness
for inner and leaf nodes of the IDPF tree. This is intended to simplify
implementations. (*)</t>
          </li>
          <li>
            <t>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. (*)</t>
          </li>
          <li>
            <t>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. (*)</t>
          </li>
          <li>
            <t>Poplar1: Increase the maximum candidate prefix count in the encoding of the
aggregation parameter. (*)</t>
          </li>
          <li>
            <t>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. (*)</t>
          </li>
          <li>
            <t>Poplar1: Clarify that the aggregation parameter encoding is <bcp14>OPTIONAL</bcp14>.
Accordingly, update implementation considerations around cross-aggregation
state.</t>
          </li>
          <li>
            <t>IdpfPoplar: Add implementation considerations around branching on the values
of control bits.</t>
          </li>
          <li>
            <t>IdpfPoplar: When decoding the the control bits in the public share, assert
that the trailing bits of the final byte are all zero. (*)</t>
          </li>
        </ul>
        <t>03:</t>
        <ul spacing="normal">
          <li>
            <t>Define codepoints for (V)DAFs and use them for domain separation in Prio3 and
Poplar1. (*)</t>
          </li>
          <li>
            <t>Prio3: Align joint randomness computation with revised paper <xref target="BBCGGI19"/>.
This change mitigates an attack on robustness. (*)</t>
          </li>
          <li>
            <t>Prio3: Remove an intermediate PRG evaluation from query randomness generation.
(*)</t>
          </li>
          <li>
            <t>Add additional guidance for choosing FFT-friendly fields.</t>
          </li>
        </ul>
        <t>02:</t>
        <ul spacing="normal">
          <li>
            <t>Complete the initial specification of Poplar1.</t>
          </li>
          <li>
            <t>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.)</t>
          </li>
          <li>
            <t>Extend (V)DAF syntax to allow the unsharding step to take into account the
number of measurements aggregated.</t>
          </li>
          <li>
            <t>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.</t>
          </li>
          <li>
            <t>Prio3: Align aggregate result computation with updated FLP syntax.</t>
          </li>
          <li>
            <t>Prg: Add a method for statefully generating a vector of field elements.</t>
          </li>
          <li>
            <t>Field: Require that field elements are fully reduced before decoding. (*)</t>
          </li>
          <li>
            <t>Define new field Field255.</t>
          </li>
        </ul>
        <t>01:</t>
        <ul spacing="normal">
          <li>
            <t>Require that VDAFs specify serialization of aggregate shares.</t>
          </li>
          <li>
            <t>Define Distributed Aggregation Functions (DAFs).</t>
          </li>
          <li>
            <t>Prio3: Move proof verifier check from <tt>prep_next()</tt> to
<tt>prep_shares_to_prep()</tt>. (*)</t>
          </li>
          <li>
            <t>Remove public parameter and replace verification parameter with a
"verification key" and "Aggregator ID".</t>
          </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>8</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>
          <t><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>.</t>
        </li>
        <li>
          <t><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>.</t>
        </li>
        <li>
          <t><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>.</t>
        </li>
        <li>
          <t><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>.</t>
        </li>
        <li>
          <t><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>.</t>
        </li>
        <li>
          <t><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.</t>
        </li>
        <li>
          <t><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.</t>
        </li>
        <li>
          <t><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.</t>
        </li>
        <li>
          <t><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.</t>
        </li>
        <li>
          <t><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.</t>
        </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>
          <t>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".</t>
        </li>
        <li>
          <t>The Aggregators refine their input shares into "output shares".
          </t>
          <ul spacing="normal">
            <li>
              <t>Output shares are in one-to-one correspondence with the input shares.</t>
            </li>
            <li>
              <t>Just as each Aggregator receives one input share of each measurement, if
this process succeeds, then each aggregator holds one output share.</t>
            </li>
            <li>
              <t>In VDAFs, Aggregators will need to exchange information among themselves
as part of the validation process.</t>
            </li>
          </ul>
        </li>
        <li>
          <t>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.</t>
        </li>
        <li>
          <t>The Aggregators submit their aggregate shares to the Collector, who combines
them to obtain the aggregate result over the batch.</t>
        </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>
          <t>Sharding - Each Client generates input shares from its measurement and
distributes them among the Aggregators.</t>
        </li>
        <li>
          <t>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.</t>
        </li>
        <li>
          <t>Aggregation - Each Aggregator combines a sequence of output shares into its
aggregate share and sends the aggregate share to the Collector.</t>
        </li>
        <li>
          <t>Unsharding - The Collector combines the aggregate shares into the aggregate
result.</t>
        </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>
            <t><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>.</t>
          </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>
            <t><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.</t>
          </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>
            <t><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>.</t>
          </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>
            <t><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.</t>
          </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>
            <t><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.</t>
          </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>
          <t>Sharding - Computing input shares from an individual measurement</t>
        </li>
        <li>
          <t>Preparation - Conversion and verification of input shares to output shares
compatible with the aggregation function being computed</t>
        </li>
        <li>
          <t>Aggregation - Combining a sequence of output shares into an aggregate share</t>
        </li>
        <li>
          <t>Unsharding - Combining a sequence of aggregate shares into an aggregate
result</t>
        </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>
            <t><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>.</t>
          </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>
            <t><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.</t>
          </li>
          <li>
            <t><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.</t>
          </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>
            <t><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>.</t>
          </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>
            <t><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.</t>
          </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>
            <t><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.</t>
          </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>
            <t><tt>Vdaf.decode_public_share(encoded: bytes) -&gt; Vdaf.PublicShare</tt> decodes a
public share.</t>
          </li>
          <li>
            <t><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.</t>
          </li>
          <li>
            <t><tt>Vdaf.encode_prep_share(prep_share: Vdaf.PrepShare) -&gt; bytes</tt> encodes a prep
share.</t>
          </li>
          <li>
            <t><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.</t>
          </li>
          <li>
            <t><tt>Vdaf.encode_prep_msg(prep_msg: Vdaf.PrepMessage) -&gt; bytes</tt> encodes a prep
message.</t>
          </li>
          <li>
            <t><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.</t>
          </li>
          <li>
            <t><tt>Vdaf.decode_agg_param(encoded: bytes) -&gt; Vdaf.AggParam</tt> decodes an
aggregation parameter.</t>
          </li>
          <li>
            <t><tt>Vdaf.encode_agg_param(agg_param: Vdaf.AggParam) -&gt; bytes</tt> encodes an
aggregation parameter.</t>
          </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>
            <t>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.</t>
          </li>
          <li>
            <t>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.</t>
          </li>
          <li>
            <t>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.</t>
          </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>
            <t><tt>encode_ping_pong_message(message: Message) -&gt; bytes</tt> encodes a <tt>Message</tt> into
an opaque byte buffer.</t>
          </li>
          <li>
            <t><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.</t>
          </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>
            <t><tt>MODULUS: Unsigned</tt> is the prime modulus that defines the field.</t>
          </li>
          <li>
            <t><tt>ENCODED_SIZE: Unsigned</tt> is the number of bytes used to encode a field element
as a byte string.</t>
          </li>
        </ul>
        <t>A concrete <tt>Field</tt> also implements the following class methods:</t>
        <ul spacing="normal">
          <li>
            <t><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>.</t>
          </li>
          <li>
            <t><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>.</t>
          </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>
            <t><tt>elem.as_unsigned() -&gt; Unsigned</tt> returns the integer representation of
field element <tt>elem</tt>.</t>
          </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>
            <t><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>.</t>
          </li>
        </ul>
        <t>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>
        <t>Finally, <tt>Field</tt> implements the following methods for representing a value as
a sequence of field elements, each of which represents a bit of the input.</t>
        <figure anchor="field-bit-rep">
          <name>Derived class methods to encode integers into bit vector representation.</name>
          <artwork><![CDATA[
def encode_into_bit_vector(Field,
                           val: Unsigned,
                           bits: Unsigned) -> Vec[Field]:
    """
    Encode the bit representation of `val` with at most `bits` number
    of bits, as a vector of field elements.
    """
    if val >= 2 ** bits:
        # Sanity check we are able to represent `val` with `bits`
        # number of bits.
        raise ValueError("Number of bits is not enough to represent "
                         "the input integer.")
    encoded = []
    for l in range(bits):
        encoded.append(Field((val >> l) & 1))
    return encoded

def decode_from_bit_vector(Field, vec: Vec[Field]) -> Field:
    """
    Decode the field element from the bit representation, expressed
    as a vector of field elements `vec`.
    """
    bits = len(vec)
    if Field.MODULUS >> bits == 0:
        raise ValueError("Number of bits is too large to be "
                         "represented by field modulus.")
    decoded = Field(0)
    for (l, bit) in enumerate(vec):
        decoded += Field(1 << l) * bit
    return decoded
]]></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>
              <t><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>.</t>
            </li>
          </ul>
          <t>FFT-friendly fields also define the following parameter:</t>
          <ul spacing="normal">
            <li>
              <t><tt>GEN_ORDER: Unsigned</tt> is the order of a multiplicative subgroup generated by
<tt>Field.gen()</tt>.</t>
            </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>
            <t><tt>SEED_SIZE: Unsigned</tt> is the size (in bytes) of a seed.</t>
          </li>
          <li>
            <t><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).</t>
          </li>
          <li>
            <t><tt>xof.next(length: Unsigned)</tt> returns the next <tt>length</tt> bytes of output of
<tt>xof</tt>.</t>
          </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-turboshake128">
          <name>XofTurboShake128</name>
          <t>This section describes XofTurboShake128, an XOF based on the
TurboSHAKE128 <xref target="TurboSHAKE"/>. This
XOF is <bcp14>RECOMMENDED</bcp14> for all use cases within VDAFs. The length of the
domain separation string <tt>dst</tt> passed to XofTurboShake128 <bcp14>MUST NOT</bcp14>
exceed 255 bytes.</t>
          <figure>
            <name>Definition of XOF XofTurboShake128.</name>
            <artwork><![CDATA[
class XofTurboShake128(Xof):
    """XOF wrapper for TurboSHAKE128."""

    # Associated parameters
    SEED_SIZE = 16

    def __init__(self, seed, dst, binder):
        self.l = 0
        self.m = to_le_bytes(len(dst), 1) + dst + seed + binder

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

        # Function `TurboSHAKE128(M, D, L)` is as defined in
        # Section 2.2 of [TurboSHAKE].
        #
        # Implementation note: Rather than re-generate the output
        # stream each time `next()` is invoked, most implementations
        # of TurboSHAKE128 will expose an "absorb-then-squeeze" API that
        # allows stateful handling of the stream.
        stream = TurboSHAKE128(self.m, 1, self.l)
        return stream[-length:]
]]></artwork>
          </figure>
        </section>
        <section anchor="xof-fixed-key-aes128">
          <name>XofFixedKeyAes128</name>
          <t>While XofTurboShake128 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 TurboSHAKE128 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 = TurboSHAKE128(dst_length + dst + binder, 2, 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>
              <t>The document version (i.e.,<tt>VERSION</tt>);</t>
            </li>
            <li>
              <t>The "class" of the algorithm using the output (e.g., VDAF);</t>
            </li>
            <li>
              <t>A unique identifier for the algorithm; and</t>
            </li>
            <li>
              <t>Some indication of how the output is used (e.g., for deriving the measurement
shares in Prio3 <xref target="prio3"/>).</t>
            </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>
          <t>Each measurement is encoded as a vector over some finite field.</t>
        </li>
        <li>
          <t>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".</t>
        </li>
        <li>
          <t>The aggregate result is obtained by summing up the encoded measurement
vectors and computing some function of the sum.</t>
        </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>
            <t><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.</t>
          </li>
          <li>
            <t><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.</t>
          </li>
          <li>
            <t><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.</t>
          </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>
              <t><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>.</t>
            </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>
              <t><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>.</t>
            </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>
              <t><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.</t>
            </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 anchor="multiproofs">
          <name>Multiple proofs</name>
          <t>To improve soundness, the prover can construct multiple unique proofs for
its measurement such that the verifier will only accept the measurement once
all proofs have been verified. Notably, several proofs using a smaller
field can offer the same level of soundness as a single proof using a large field.</t>
          <t>To generate these proofs for a specific measurement, the prover calls
<tt>Flp.prove</tt> multiple times, each time using an independently generated prover
and joint randomness string. The verifier checks each proof independently,
each time with an independently generated query randomness string. It accepts
the measurement only if all the decision algorithm accepts on each proof.</t>
          <t>See <xref target="security-multiproof"/> below for discussions on choosing the right number
 of proofs.</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"/>). It also has an associated constant, <tt>PROOFS</tt>,  with a value within
 the range of <tt>[1, 256)</tt>, denoting the number of FLPs generated by the Client
 (<xref target="multiproofs"/>). The value of <tt>PROOFS</tt> is <tt>1</tt> unless explicitly specified.</t>
        <t>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>
              <t>Encode the Client's measurement for the FLP</t>
            </li>
            <li>
              <t>Shard the measurement into a sequence of measurement shares</t>
            </li>
            <li>
              <t>Derive the joint randomness from the measurement shares and nonce</t>
            </li>
            <li>
              <t>Run the FLP proof-generation algorithm using the derived joint randomness</t>
            </li>
            <li>
              <t>Shard the proof into a sequence of proof shares</t>
            </li>
            <li>
              <t>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</t>
            </li>
          </ol>
          <t>As described in <xref target="multiproofs"/>, the soundness of the FLP can be amplified
by generating and verifying multiple FLPs. (This in turn improves the
robustness of Prio3.) To support this, in Prio3:</t>
          <ul spacing="normal">
            <li>
              <t>In step 3, derive as much joint randomness as required by <tt>PROOFS</tt> proofs</t>
            </li>
            <li>
              <t>Repeat step 4 <tt>PROOFS</tt> times, each time with a unique joint randomness</t>
            </li>
          </ul>
          <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_proofs_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 and shard each proof into shares.
  prove_rands = Prio3.prove_rands(k_prove)
  leader_proofs_share = []
  for _ in range(Prio3.PROOFS):
      prove_rand, prove_rands = front(
          Prio3.Flp.PROVE_RAND_LEN, prove_rands)
      leader_proofs_share += Prio3.Flp.prove(meas, prove_rand, [])
  for j in range(Prio3.SHARES-1):
      leader_proofs_share = vec_sub(
          leader_proofs_share,
          Prio3.helper_proofs_share(j+1, k_helper_proofs_shares[j]),
      )

  # Each Aggregator's input share contains its measurement share
  # and share of proof(s).
  input_shares = []
  input_shares.append((
      leader_meas_share,
      leader_proofs_share,
      None,
  ))
  for j in range(Prio3.SHARES-1):
      input_shares.append((
          k_helper_meas_shares[j],
          k_helper_proofs_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>
                <t>Shard the encoded measurement into shares</t>
              </li>
              <li>
                <t>Generate and shard each proof into shares</t>
              </li>
              <li>
                <t>Encode each measurement and shares of each proof into an input share</t>
              </li>
            </ol>
            <t>Notice that only one pair of measurement and proof(s) share (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_proofs_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 and shard each proof into shares.
  prove_rands = Prio3.prove_rands(k_prove)
  joint_rands = Prio3.joint_rands(
      Prio3.joint_rand_seed(k_joint_rand_parts))
  leader_proofs_share = []
  for _ in range(Prio3.PROOFS):
      prove_rand, prove_rands = front(
          Prio3.Flp.PROVE_RAND_LEN, prove_rands)
      joint_rand, joint_rands = front(
          Prio3.Flp.JOINT_RAND_LEN, joint_rands)
      leader_proofs_share += Prio3.Flp.prove(meas,
                                             prove_rand, joint_rand)
  for j in range(Prio3.SHARES-1):
      leader_proofs_share = vec_sub(
          leader_proofs_share,
          Prio3.helper_proofs_share(j+1, k_helper_proofs_shares[j]),
      )

  # Each Aggregator's input share contains its measurement share,
  # share of proof(s), and blind. The public share contains the
  # Aggregators' joint randomness parts.
  input_shares = []
  input_shares.append((
      leader_meas_share,
      leader_proofs_share,
      k_leader_blind,
  ))
  for j in range(Prio3.SHARES-1):
      input_shares.append((
          k_helper_meas_shares[j],
          k_helper_proofs_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 randomnesses <tt>joint_rands</tt>, split it into multiple <tt>joint_rand</tt>,
and pass each <tt>joint_rand</tt> 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>
                <t>Compute a "joint randomness part" from each measurement share and blind</t>
              </li>
              <li>
                <t>Compute a "joint randomness seed" from the joint randomness parts</t>
              </li>
              <li>
                <t>Compute the joint randomness for each proof evaluation from the joint randomness seed</t>
              </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 share of proof(s) locally, then exchanges its share of
verifier(s) with the other Aggregators. The shares of verifier(s) are then
combined into the verifier message(s) 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 shares of
verifier(s).</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, proofs_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_rands = Prio3.joint_rands(k_corrected_joint_rand)

  # Query the measurement and proof share.
  query_rands = Prio3.query_rands(verify_key, nonce)
  verifiers_share = []
  for _ in range(Prio3.PROOFS):
      proof_share, proofs_share = front(
          Prio3.Flp.PROOF_LEN, proofs_share)
      query_rand, query_rands = front(
          Prio3.Flp.QUERY_RAND_LEN, query_rands)
      if Prio3.Flp.JOINT_RAND_LEN > 0:
          joint_rand, joint_rands = front(
              Prio3.Flp.JOINT_RAND_LEN, joint_rands)
      verifiers_share += Prio3.Flp.query(meas_share,
                                          proof_share,
                                          query_rand,
                                          joint_rand,
                                          Prio3.SHARES)

  prep_state = (out_share, k_corrected_joint_rand)
  prep_share = (verifiers_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.
  verifiers = Prio3.Flp.Field.zeros(
      Prio3.Flp.VERIFIER_LEN * Prio3.PROOFS)
  k_joint_rand_parts = []
  for (verifiers_share, k_joint_rand_part) in prep_shares:
      verifiers = vec_add(verifiers, verifiers_share)
      if Prio3.Flp.JOINT_RAND_LEN > 0:
          k_joint_rand_parts.append(k_joint_rand_part)

  # Verify that each proof is well-formed and the input is valid
  for _ in range(Prio3.PROOFS):
      verifier, verifiers = front(Prio3.Flp.VERIFIER_LEN, verifiers)
      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_proofs_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(Prio3.PROOFS) + byte(agg_id),
      Prio3.Flp.PROOF_LEN * Prio3.PROOFS,
  )

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

def prove_rands(Prio3, k_prove):
  return Prio3.Xof.expand_into_vec(
      Prio3.Flp.Field,
      k_prove,
      Prio3.domain_separation_tag(USAGE_PROVE_RANDOMNESS),
      byte(Prio3.PROOFS),
      Prio3.Flp.PROVE_RAND_LEN * Prio3.PROOFS,
  )

def query_rands(Prio3, verify_key, nonce):
  return Prio3.Xof.expand_into_vec(
      Prio3.Flp.Field,
      verify_key,
      Prio3.domain_separation_tag(USAGE_QUERY_RANDOMNESS),
      byte(Prio3.PROOFS) + nonce,
      Prio3.Flp.QUERY_RAND_LEN * Prio3.PROOFS,
  )

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_rands(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),
      byte(Prio3.PROOFS),
      Prio3.Flp.JOINT_RAND_LEN * Prio3.PROOFS,
  )
]]></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 share of proof(s). Otherwise, if the aggregator ID
is greater than <tt>0</tt>, then the measurement and shares of proof(s) 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 proofs_share[F * Prio3.Flp.PROOF_LEN * Prio3.PROOFS];
} 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_proofs_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 verifiers_share[F * Prio3.Flp.VERIFIER_LEN * Prio3.PROOFS];
} 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 verifiers_share[F * Prio3.Flp.VERIFIER_LEN * Prio3.PROOFS];
    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>
              <t><tt>Valid.encode(measurement: Measurement) -&gt; Vec[Field]</tt> returns a vector of
length <tt>MEAS_LEN</tt> representing a measurement.</t>
            </li>
            <li>
              <t><tt>Valid.truncate(meas: Vec[Field]) -&gt; Vec[Field]</tt> returns a vector of length
<tt>OUTPUT_LEN</tt> representing an aggregatable output.</t>
            </li>
            <li>
              <t><tt>Valid.decode(output: Vec[Field], num_measurements: Unsigned) -&gt; AggResult</tt>
returns an aggregate result.</t>
            </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>
              <t>Let <tt>H = len(Valid.GADGETS)</tt></t>
            </li>
            <li>
              <t>For each <tt>i</tt> in <tt>[H]</tt>:
              </t>
              <ul spacing="normal">
                <li>
                  <t>Let <tt>G_i = Valid.GADGETS[i]</tt></t>
                </li>
                <li>
                  <t>Let <tt>L_i = Valid.GADGETS[i].ARITY</tt></t>
                </li>
                <li>
                  <t>Let <tt>M_i = Valid.GADGET_CALLS[i]</tt></t>
                </li>
                <li>
                  <t>Let <tt>P_i = next_power_of_2(M_i+1)</tt></t>
                </li>
                <li>
                  <t>Let <tt>alpha_i = Field.gen()^(Field.GEN_ORDER / P_i)</tt></t>
                </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>
                <t>For each <tt>i</tt> in <tt>[H]</tt> create an empty table <tt>wire_i</tt>.</t>
              </li>
              <li>
                <t>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.</t>
              </li>
              <li>
                <t>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>.</t>
              </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>
                    <t>Let <tt>w = [seed_i[j-1], wire_i[j-1,0], ..., wire_i[j-1,M_i-1]]</tt>.</t>
                  </li>
                  <li>
                    <t>Let <tt>padded_w = w + Field.zeros(P_i - len(w))</tt>.</t>
                  </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>
                    <t>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>.</t>
                  </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>
                    <t>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>.)</t>
                  </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>
                <t>For every <tt>i</tt> in <tt>[H]</tt> create an empty table <tt>wire_i</tt>.</t>
              </li>
              <li>
                <t>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"/>.</t>
              </li>
              <li>
                <t>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.</t>
              </li>
              <li>
                <t>Compute the wire polynomials just as in the prover's step (4.).</t>
              </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>
                    <t>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.)</t>
                  </li>
                  <li>
                    <t>Let <tt>y_i = poly_gadget_i(t)</tt>.</t>
                  </li>
                  <li>
                    <t>For each <tt>j</tt> in <tt>[0,L_i)</tt> let <tt>x_i[j-1] = poly_wire_i[j-1](t)</tt>.</t>
                  </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>
                <t>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"/>.</t>
              </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>
                    <t>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.</t>
                  </li>
                  <li>
                    <t>If <tt>z != y_i</tt>, then return <tt>False</tt> and halt.</t>
                  </li>
                </ul>
              </li>
              <li>
                <t>Return <tt>True</tt> if <tt>v == 0</tt> and <tt>False</tt> otherwise.</t>
              </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 XofTurboShake128 (<xref target="xof-turboshake128"/>) 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 XofTurboShake128 (<xref target="xof-turboshake128"/>) 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

    return self.Field.encode_into_bit_vector(measurement,
                                             self.MEAS_LEN)

def truncate(self, meas):
    return [self.Field.decode_from_bit_vector(meas)]

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 XofTurboShake128 (<xref target="xof-turboshake128"/>) 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

        encoded += self.Field.encode_into_bit_vector(val, self.bits)
    return encoded

def truncate(self, meas):
    truncated = []
    for i in range(self.length):
        truncated.append(self.Field.decode_from_bit_vector(
            meas[i * self.bits: (i + 1) * self.bits]
        ))
    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 XofTurboShake128 (<xref target="xof-turboshake128"/>) 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>
          <t>Each Client splits its string into input shares and sends one share to each
Aggregator.</t>
        </li>
        <li>
          <t>The Aggregators agree on an initial set of candidate prefixes, say <tt>0</tt> and
<tt>1</tt>.</t>
        </li>
        <li>
          <t>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.</t>
        </li>
        <li>
          <t>The Aggregators send their aggregate shares to the Collector, who combines
them to recover the counts of each candidate prefix.</t>
        </li>
        <li>
          <t>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.</t>
        </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. The binder string
is used to derive the key in the underlying XofFixedKeyAes128 XOF that is used
for expanding seeds at each level. It <bcp14>MUST</bcp14> be chosen uniformly at random by
the Client (see <xref target="nonce-requirements"/>).  </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),
        nonce,
    )

    # 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,
                                            nonce,
                                            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, nonce)

    # 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 = [
        bytearray(xof.next(XofFixedKeyAes128.SEED_SIZE)),
        bytearray(xof.next(XofFixedKeyAes128.SEED_SIZE)),
    ]
    # Use the least significant bits as the control bit correction,
    # and then zero it out. This gives effectively 127 bits of
    # security, but reduces the number of AES calls needed by 1/3.
    t = [Field2(s[0][0] & 1), Field2(s[1][0] & 1)]
    s[0][0] &= 0xFE
    s[1][0] &= 0xFE
    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
XofTurboShake128 (<xref target="xof-turboshake128"/>). 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>
          <t>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.</t>
        </li>
        <li>
          <t>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.</t>
        </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>
          <t>Securely distributing the long-lived parameters, in particular the
verification key.</t>
        </li>
        <li>
          <t>Establishing secure channels:  </t>
          <ul spacing="normal">
            <li>
              <t>Confidential and authentic channels among Aggregators, and between the
Aggregators and the Collector; and</t>
            </li>
            <li>
              <t>Confidential and Aggregator-authenticated channels between Clients and
Aggregators.</t>
            </li>
          </ul>
        </li>
        <li>
          <t>Enforcing the non-collusion properties required of the specific VDAF in use.</t>
        </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>
            <t>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.</t>
          </li>
          <li>
            <t>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.</t>
          </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>As described in <xref target="xof"/>, our constructions rely on eXtendable
Output Functions (XOFs). In the security analyses of our protocols, these are
usually modeled as random oracles. XofTurboShake128 is designed to be
indifferentiable from a random oracle <xref target="MRH04"/>, making it a suitable choice
for most situations.</t>
        <t>The one exception is the Idpf implementation IdpfPoplar <xref target="idpf-poplar"/>.
Here, a random oracle is not needed to prove privacy, since the analysis of
<xref target="BBCGGI21"/>, Proposition 1, only requires a Pseudorandom Generator (PRG).
As observed in <xref target="GKWY20"/>, a PRG can be instantiated from a correlation-robust
hash function <tt>H</tt>. Informally, correlation robustness requires that for a random
<tt>r</tt>, <tt>H(xor(r, x))</tt> is computationally indistinguishable from a random function of <tt>x</tt>.
A PRG can therefore be constructed as</t>
        <artwork><![CDATA[
PRG(r) = H(xor(r, 1)) || H(xor(r, 2)) || ...`
]]></artwork>
        <t>since each individual hash function evaluation is indistinguishable from a random
function.</t>
        <t>Our construction at <xref target="xof-fixed-key-aes128"/> implements a correlation-robust
hash function using fixed-key AES. For security, it assumes that AES with a
fixed key can be modeled as a random permutation <xref target="GKWY20"/>. Additionally, we
use a different AES key for every client, which in the ideal cipher model leads
to better concrete security <xref target="GKWWY20"/>.</t>
        <t>We note that for robustness, the analysis of <xref target="BBCGGI21"/> still assumes a random
oracle to make the Idpf extractable. While XofFixedKeyAes128 has been shown
to be differentiable from a random oracle <xref target="GKWWY20"/>, there are no known
attacks exploiting this difference.
We also stress that even if the Idpf is not extractable, Poplar1 guarantees
that every client can contribute to at most one prefix among the ones being
evaluated by the helpers.</t>
      </section>
      <section anchor="security-multiproof">
        <name>Choosing the Number of Proofs to Use for Prio3</name>
        <ul empty="true">
          <li>
            <t>TODO Add guidance for choosing <tt>PROOFS</tt> (<xref target="multiproofs"/>) for Prio3.
 In particular when we go for a smaller field for a given circuit. See
<eref target="https://github.com/cfrg/draft-irtf-cfrg-vdaf/issues/177">this</eref> for details.</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 anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="RFC8446">
          <front>
            <title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
            <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
            <date month="August" year="2018"/>
            <abstract>
              <t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol. TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
              <t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961. This document also specifies new requirements for TLS 1.2 implementations.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8446"/>
          <seriesInfo name="DOI" value="10.17487/RFC8446"/>
        </reference>
        <reference anchor="TurboSHAKE">
          <front>
            <title>KangarooTwelve and TurboSHAKE</title>
            <author fullname="Benoît Viguier" initials="B." surname="Viguier">
              <organization>ABN AMRO Bank</organization>
            </author>
            <author fullname="David Wong" initials="D." surname="Wong">
              <organization>O(1) Labs</organization>
            </author>
            <author fullname="Gilles Van Assche" initials="G." surname="Van Assche">
              <organization>STMicroelectronics</organization>
            </author>
            <author fullname="Quynh Dang" initials="Q." surname="Dang">
              <organization>National Institute of Standards and Technology</organization>
            </author>
            <author fullname="Joan Daemen" initials="J." surname="Daemen">
              <organization>Radboud University</organization>
            </author>
            <date day="20" month="June" year="2023"/>
            <abstract>
              <t>   This document defines three eXtendable Output Functions (XOF), hash
   functions with output of arbitrary length, named TurboSHAKE128,
   TurboSHAKE256 and KangarooTwelve.

   All three functions provide efficient and secure hashing primitives,
   and the last is able to exploit the parallelism of the implementation
   in a scalable way.

   This document builds up on the definitions of the permutations and of
   the sponge construction in [FIPS 202], and is meant to serve as a
   stable reference and an implementation guide.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-kangarootwelve-11"/>
        </reference>
      </references>
      <references anchor="sec-informative-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 initials="C." surname="Guo">
              <organization/>
            </author>
            <author initials="J." surname="Katz">
              <organization/>
            </author>
            <author initials="X." surname="Wang">
              <organization/>
            </author>
            <author initials="C." surname="Weng">
              <organization/>
            </author>
            <author initials="Y." surname="Yu">
              <organization/>
            </author>
            <date year="2020"/>
          </front>
          <seriesInfo name="CRYPTO 2020" value=""/>
        </reference>
        <reference anchor="GKWY20" target="https://eprint.iacr.org/2019/074">
          <front>
            <title>Efficient and Secure Multiparty Computation from Fixed-Key Block Ciphers</title>
            <author initials="C." surname="Guo">
              <organization/>
            </author>
            <author initials="J." surname="Katz">
              <organization/>
            </author>
            <author initials="X." surname="Wang">
              <organization/>
            </author>
            <author initials="Y." surname="Yu">
              <organization/>
            </author>
            <date year="2020"/>
          </front>
          <seriesInfo name="S&amp;P 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="23" month="October" 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-08"/>
        </reference>
      </references>
    </references>
    <?line 4679?>

<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 Junye Chen, Henry Corrigan-Gibbs, Armando Faz-Hernández, Simon
Friedberger, Tim Geoghegan, Albert Liu, 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+y963rbRpYo+h9PUU1/e0K2SVqSr5E7mZF1sdWxLY0kO53x
uEWQBCXEJMEGQMmKnXmQ/Ws/yzkvdtatqlYBIC0n3bN7n3P0fd0xSaAuq1at
+6XX60VlWk6TbdN6m+TpJI2H08TspUWZp8NlmYzNzsVFnlzEZZrNzcFyPsJ/
FK0oHg7z5Apf29s5aEXjbDSPZzDMOI8nZS/Ny0lvNMkvelfjeNLbeBKN4jK5
yPKbbZPOJ1kUpYt825T5sii3Nja+3diK4jyJt83hydlBdJ3lHy7ybLnYNrsH
J8+jD8kNfDWGX+dlks+TsreHs0RRUcbz8Xk8zeYw801SRMUszsvzvy2zMim2
zTyLFum2eVdmo64psrzMk0kB/7qZ4T/eR1G8LC+zfDsyvcjAH+/gJB1dxvnY
vOybZzHMVtBvWX4Rz9NfCA6wrLQYZfR9MovT6bbJp8N/SxdX/eJjONhefJWO
zW6WfWgY5fAUNqcGGadXSX6RzMtxfJX82wV+2R9ls3DE3cscTidbXCa5OY7L
Mps3rW+aLceTKcBUjz/CVxf0zt00KSerpji+TKfTdLEwp6PLbLGYxfOmOZ5n
2cU0GL9wj//bBf1IQ0d44PkM3rpKtiN4fuf5n4+Otza36VWLfcd5mt2FqfP0
Kh7dwH+TIsmv0vmFQ8DEnJYwSFGmo8JcpbF5lmXTJJ6bUziuBFASh3MnSn89
QDbAg9O+2RmP4/mHNPz+h755HufDJPx2v2/+HE8mlW9P+uYILkV2VXy4CX/Z
6ZvjbHoDwM3maTzOlvTzGBa8bbY2tjZ5mzEcbLltLstyUWzfu5fG/VF+D3++
9/DxI4TKs2e7z58fbn4bguU/kjzr/TDPrqfJ+CIBsGTZpDBwFU+TUQ4XgfY+
BjQrY4LJwXI6vTEv03kSA3rsHq8Dyx4gONycy9r2n2U308r2X/QBifM8BQTo
PU+HwyL8+TVAMp0Oszj8+qe+OSwu4zSAyOa39BGON00KxA1A15Ofjs+O/G+r
oLX57b3NJ088tKpI9DK9uCyvE/x/c5aMLufp35ZJYQD9GLEAh14k8dWNeZGW
QEn+CYEj6KKBc7i/v29O/+X4Vsi0sfkYwbP7/Nnm4/oF27Zg6JqTbAi0t2uA
gMI1j6dE93ez2WJZMq3PJo03bw3IvgCGAKIOGR7X9vv6dO/Q/1Ld63jaj0ez
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
a9ROGyZzNv1Armq84gY3fiWKTvMVsg4y4LwYNN9L571xsgAaDDRIxdokgc2B
Ie4siYztE7UoF+bNRrFrq16JokJ8U9t7Gra5C/9h4awSUh5q7w6OsLmj47PD
o9c7L1FvaVIGqvnFoYgbs791lMN96lViO0rOjw31XdT2bjXkEIPjL1XCE0to
bPNU3pGiNsWPlxQmLVvEV8VR4V5p4oX2DlqSRO8B3pNLhl4SYjOhCCFUSdiP
DLf1lyR37G/j/ray8zqjK3MYFhYLLdDNmiVaXKLza6IQx0dcd6uQBlJjrtoA
JclxVyki0AIr+wRBSk55tiaxtEy5gg0qFERBQ67bILhgJocNAsOrn5IaefK8
pmRR5IpeqNducR12YLIJSCoHpl3pPAVSZfBQDg7OehMM0h8DPSOdEHEBC5zB
CFxAQmy7aO/FcGkblOZERQtVfGOfnHFOL2e/K/LL+YiyCmLT0vjSsmpEaE7g
0xortzyS36ljVYoiePkAHxmRp4CuXAt0UAxmp/QcjGcB9lagmOpIOpXvcxhx
miRBcFgXg+tpiw/69xm9khIwuWC72aqNeuVxOXcaJynN1rDHoZwjpslMyLxE
GEap+JgONeXBy2M7n7bhsz9AFqqubS0fhrNenbkAZw1sARLIiiqSjFlyxYLK
ugPjX5BvVLtZ9eze6s1iOqk313fKL9u21P6IKE6oIqV2gK7eEFvd4Su8Zmzv
4bDG4DGiRDwsC/NjyfB1AK15oBBIPAgNv/XwIV6eTXFEqpk4zsOq/VgsCE3S
PrK4EuLaV3Pcot4JRadosJPNhj1KTqhlCeNrrTTKE0v0SW6vZ4NsRGOlK4j5
8Y/QCSPGtYIHPiQ3LXq95e8zXFNMQruD0fBXHMHNhJ6AweHxHHiCNlys3luY
1qs3p2etLv/XvD6if5/s//ubw5P9Pfw3qNwvX7p/RPLE6YujNy/3/L/8m7tH
r17tv97jl+FbE3wVtV7t/NRinb5lGb8kAAYhRjmJSEOxdy7QX4BxMJGPOoV3
nu0e/1//a/MBkJ4/nBzsbm1SxCt/eLL5GKMlUW/k2ajaAn+E+3cTedmVpd1F
WsbTgnVxyrWSNLM/vkPIvN82fxqOFpsPvpcvcMPBlxZmwZcEs/o3tZcZiA1f
NUzjoBl8X4F0uN6dn4LPFu7qyz/96xSvS2/zyb9+H0XRjjMmNx/NdY7Ruywi
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
/b45mit4XVKri2srttj8LRhJcQ90dNgeHraGPHVp9KWWYUMz6pOmumHeefz4
K+vNXDUXnDmFsTFoV4IOTbuwWktjhRpUIBlkvhZNtLYGzepaMY01aHDwaGUR
mpofo1ltDorQMP1UVphLvFpt7lSPk1YMKxiAEWoKHIURrRQQB0+Nh1olKKup
8A2N839g5Zu3X1v6ZsVG/0+pfXNVLX5DxFs/58JvRlyCqvp7JajCj/VrR0Go
IYXof3dlGmJ3poHqpiUVhHMJNGsK/YjI57unuWgcjmJE4GEvmdIV7P70yYGC
TL4YW/SCamBcAFp3I1tFo2owu3UhjcAsHN2qggYjve/KQ/ymsYZG9NU1NJrK
J1yF9RMI5dRDTRinfq4gnB0nQLf/v5bB/85aBl99JXQKvC26sd+Qz8GpPQ15
1o3ZH86DXqS3SLXWOck4C4fohfl/t/VHhG8pJKTHm7OZm7KTqw6K6sgNGdD0
ik6BbsxoVknLkpqrhnJJy7yi4Lffn7S8Ov84jHX7jQnIzSF4t89AdoYWScqt
6fx+/d7uqGAqsOZgm+DbSu4tLbQxVbldsMm1YO/Sd2alV6xrfr5dIq79+8r8
Xfv3pfznhr/gzL7qzWr6dPCygrnNHaZP4VP2ANwjBEl97FolVuVx0orFIMwz
Tyunx3ptb7Nyfta6HpzcKnvr18FGb655yyHO2ZXfCu9kmGDZFS8CHoh3H3Rq
r9cehfEQg7Nl2TRVcEj4qD4iirimoieqV4C3DCSi5VjX5Ypz+wceRv0gfufF
dzT6tx5BA0jPBfdrcxTqIdnG7yhTIK/WkkGofbAOAHR5mS4MgY32DW+zaEml
RFz5KkmDuHWFg2ZgeyBQjYN38BmgSu+ygUg94c8xLIywSq3pBqP/vYse/J5q
B82S8VeUO/hN9Q6uVhc8cLkwzrnlKx4oP0Ze14acst8l1ws2Cw3LFQZVm71t
JQiPOQvyPyhTAA181uZ/KeZeloI4XvYyA3TkBnTONSumscKb4uUNEM45KIKM
WtFKP7nZKSjfMva5J6GU+6sNJ0ZRN2oSddUagtKybO51tQxsUwZbeCAawnVK
kmqgakNxBZbJd4P8veO4hBMQe1gYwO0sRD00SHIHEO/rwZmUXFV3rmHuU2LD
Y33pOzStRr4EvOyiK+Zk1nXmShdt9vw5Y30kRs5BE0/oDDQKwpqD0vN1qzp6
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
2UkyjpufqxRv4FaMJdFQu86TFU8XTIj8HSwNwn7HXnKHS9ohbTXRO1yOrhEs
Yq6X5UpoKTR8tihXl/XyTGIdGNMbRSQeZM5lnN/uPnn9/fe7r57uPpUglwhB
ykpIZfEYfGQ79IWw8jpBK8EXO72CFPfrr5o6T2nz//L22ZN/ffDgK8aQ4szC
UOPvkvTifPpumgusFIia3O+040gIpu6z6OnMPc1sYPfVk9dP9ZVJSCdo5Ry0
UM7riwKzjamxd/DK3rv9r3mTn8V1mCgjQUK6QMLFFNB5OcZkTMzaBuIShzOX
YnWOQavvgzO58Vio971nOhhKF2DoGorSLlmUTtEvowhCzhWljIgNmaJZBEqF
jaxxo7i2KSakCkDEtPeYYAIBbvVx2yFdceo025FXCrEfjdLHeQXIt+62NrXT
iq3x2RRsDWstuIBK/JoZG0AS6PLUvTNmwA4D2Jff+QOHJ/QT6CX/jm++hRf9
xr3wKTv/LjEMutwxvsGqY1ej7JKwqxvzf8mQhIb9RutFp4FtAcB3FZW6uNMI
xkFSHApZfKeZMY1LucUUFIM3xFkQQc7KkLNjxUVexJowPPviKQG9ScL+Iu0o
8xMk5OvuRKsoby9/vXI1uNs9ZtAj/FmstNhI3H1/JpcFHyUsKfPpT5P8J9J9
MZxCMQ2lcA+lVL2ULC01b8/Zbkahjd+R9tBs8Xas6lVB7y8Jow5LenLRUIpt
aO8K9Ixz6GIQ0QnOeQh3mnB8O2u09p4wZqtBWNt7ZkfLK7xwwJJXvHaTvNSn
KoZTyqOmUyoHs2+6McPKZVXv+OSuMOHs5iwlzPjr1nd+ajZk7vlGQ+7Yneig
J3uUXTdkt1rQEHCA9pCJRXQtbxcTtIq2l9fPYPOC32T0buFuNnr3Qi8LR5+B
3rw3JB00W/2xU5L41xKq3+AUdNeTwqDdnIb8uD0Hja6IzvBVxVX6Z8/1muu7
vRibt1kk39tttFar6pJnMrtU2s9LPGF/NBspnM6RlyVheTeXZaJ1kEn2rkSn
O6fsPZU33GUznCf7GwzzgXQVmdBGlT+WXLL5+M16eYFFllBA5UoQWvipNyZZ
yk9H6GAekFcU2UVcVN1gwR5Mduh2PixPMG4yqTc1Ri3tQ1Ve/v67AR3rR7Kz
VVxww+7w8uOqXDDCMDtj9UGtiHEOvFWKcbxPx9yuVe4HlVQsz7Jv8tdv4AC9
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
4qzc3vlX2aTxCj9s5EPaRi4eCPuIdvamtf8juc7hBNAawHEQQkOh+qsHUyIQ
/L1xzXGAQcb+V2zXNFRrjQO1ZG6aBjeSHJ0dS5gRhlk0wVtG3mN0iIxYAyWw
ZPG0kJ+Eotr0GqOn8QHvF4G/MbPtc/pl22VQmfjTbgOuOrq3ySfIYdNyccwj
345W7iD4McoWjnNHQHBRv7xZ9uV+lCXuCEZvrlsJjkT0JZcO0N0Z1RFQD6Hz
JcEqTKwVwTLN9ySAkVuFX/aHLlBxrJ+GVUuJW+AWxF3Av1M0MXBjEBeA5RnA
vmejGbJRTgaLXR4rH7NI7ob1+TlQyi9UlQ8u58ktLNnBePkJQVE9sVDTPSDn
/WlvP10hUNO97b438r7Ip+l27xv9huhr3+mwid+77p0Oo7E606ejdshoT1RT
eKevnw6Lczfn0XeCnzO2MbfOFJ01c3My8NT6nAmack3aLJ7SChGQE+lPzA3i
h5LiuxdUJVSv1IwWYdJ5A4SyEvFq5Tt/PwQWOqRwITIw4J8cMb8AcbSpZxVp
4zHz8DeAjfdTroJMr4LWijnmDQsVXwTQROdNkPlQMz7bfcyiCdnZMuVgSaHX
tZBHoytDWusctdbu8h0WOdK4RzF9X6LCiIssjlwghkTPBJaqYTPMQIHf38u/
iWZQx+Vev3mU7+Sff848Vs9vcNiHckkvXsExzVpsOQIHJ9BpGO8Bz8cH9dym
Xlyex8OR4AyL1Qmzje+JPTciZuMHqHymIxruc3sSeMOtaVDTQU/Vk1DSDB7D
S6hoDtbCCwbDTSnUScQ637Yei65eCDICGaZZqmlJH5JQ0iuAbP8zBRBK8Odf
wszpjP2jJAE3SuqBB5m+ySNGqKlHjjoH92Qm8Gl4FseOn+J1fYgcjSLAjEqx
kS84SeJ68eNwPwTlwBtd3QT64RW73e1/25u/99ZnMmpd4703PvK1jku/77Zn
Ntg5/lvd9H23/Mbnb3HD251163t+4x3fvlRuc7/D+Wnd7j+Ws97LsnW5+9BE
veUtGInySF0BtBH5YuHyQnMP7ZvYDWan68XZgXzXIwpIRxl5L+L4loYhY0TF
iNQJ7dBJAty83IZdoAstwUPi2NON7EDlx5xqcrRGM8qjClnk2GNtFUaKeNF1
zXZ0mcDnOa2NAt/gyOfzcj6GNR9Tu2N+EK0J/zTFlgnjZgJNrNpisYFwt0VQ
+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
riK+uUmKZf9/99n9D8BVZLO6CwMA

-->

</rfc>
