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

<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
input that would result in an incorrect 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 175?>

<section anchor="introduction">
      <name>Introduction</name>
      <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 input before
submitting to the aggregation server. The aggregation server then adds up the
noisy inputs, 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 input, it may be possible for a curious aggregator to make a
reasonable guess of the input'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 input 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
input is ever accessible to any party besides the client that submitted it. At
the same time, VDAFs are "verifiable" in the sense that malformed inputs that
would otherwise garble the output of the computation can be detected and removed
from the set of input measurements. We refer to this property as "robustness".</t>
      <t>In addition to these MPC-style security goals of privacy and robustness, VDAFs
can be composed with various mechanisms for differential privacy, thereby
providing the added assurance that the aggregate result itself does not leak
too much information about any one measurement.</t>
      <ul empty="true">
        <li>
          <t>TODO(issue #94) Provide guidance for local and central DP and point to it
here.</t>
        </li>
      </ul>
      <t>The cost of achieving these security properties is the need for multiple servers
to participate in the protocol, and the need to ensure they do not collude to
undermine the VDAF's privacy guarantees.  Recent implementation experience has
shown that practical challenges of coordinating multiple servers can be
overcome.  The Prio system <xref target="CGB17"/> (essentially a VDAF) has been deployed in
systems supporting hundreds of millions of users: The Mozilla Origin Telemetry
project <xref target="OriginTelemetry"/> and the Exposure Notification Private Analytics
collaboration among the Internet Security Research Group (ISRG), Google, Apple,
and others <xref target="ENPA"/>.</t>
      <t>The VDAF abstraction laid out in <xref target="vdaf"/> represents a class of multi-party
protocols for privacy-preserving measurement proposed in the literature. These
protocols vary in their operational and security requirements, sometimes in
subtle but consequential ways. This document therefore has two important goals:</t>
      <ol spacing="normal" type="1"><li>
          <t>Providing higher-level protocols like <xref target="DAP"/> with
a simple, uniform interface for accessing privacy-preserving measurement
schemes, documenting relevant operational and security requirements, and
specifying constraints for safe usage:  </t>
          <ol spacing="normal" type="1"><li>General patterns of communications among the various actors involved in
the system (clients, aggregation servers, and the collector of the
aggregate result);</li>
            <li>Capabilities of a malicious coalition of servers attempting to divulge
information about client measurements; and</li>
            <li>Conditions that are necessary to ensure that malicious clients cannot
corrupt the computation.</li>
          </ol>
        </li>
        <li>Providing cryptographers with design criteria that provide a clear
deployment roadmap for new constructions.</li>
      </ol>
      <t>This document also specifies two concrete VDAF schemes, each based on a protocol
from the literature.</t>
      <ul spacing="normal">
        <li>
          <t>The aforementioned Prio system <xref target="CGB17"/> allows for the privacy-preserving
computation of a variety aggregate statistics. The basic idea underlying Prio
is fairly simple:
          </t>
          <ol spacing="normal" type="1"><li>Each client shards its measurement into a sequence of additive shares and
distributes the shares among the aggregation servers.</li>
            <li>Next, each server adds up its shares locally, resulting in an additive
share of the aggregate.</li>
            <li>Finally, the aggregation servers send their aggregate shares to the data
collector, who combines them to obtain the aggregate result.</li>
          </ol>
          <t>
The difficult part of this system is ensuring that the servers hold shares of
a valid input, e.g., the input 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 inputs 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 input. 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 input.  </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>06:</t>
        <ul spacing="normal">
          <li>Vdaf: Define a wrapper interface for preparation that is suitable for the
"ping-pong" topology in which two Aggregators exchange messages over a
request/response protocol, like HTTP, and take turns executing the
computation until input from the peer is required.</li>
          <li>Prio3Histogram: Generalize the measurement type so that the histogram can be
used more easily with discrete domains. (*)</li>
          <li>Daf, Vdaf: Change the aggregation parameter validation algorithm to take the
set of previous parameters rather than a list. (The order of the parameters
is irrelevant.)</li>
          <li>Daf, Vdaf, Idpf: Add parameter <tt>RAND_SIZE</tt> that specifies the number of
random bytes consumed by the randomized algorithm (<tt>shard()</tt> for Daf and Vdaf
and <tt>gen()</tt> for Idpf).</li>
        </ul>
        <t>05:</t>
        <ul spacing="normal">
          <li>IdpfPoplar: Replace 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. (*)</li>
          <li>Idpf: Add a binder string to the key-generation and evaluation algorithms.
This is used to plumb the nonce generated by the Client to the PRG.</li>
          <li>Plumb random coins through the interface of randomized algorithms.
Specifically, add a random input to (V)DAF sharding algorithm and IDPF
key-generation algorithm and require implementations to specify the length of
the random input. Accordingly, update Prio3, Poplar1, and IdpfPoplar to match
the new interface. This change is intended to improve coverage of test
vectors.</li>
          <li>Use little-endian byte-order for field element encoding. (*)</li>
          <li>Poplar1: Move the last step of sketch evaluation from <tt>prep_next()</tt> to
<tt>prep_shares_to_prep()</tt>.</li>
        </ul>
        <t>04:</t>
        <ul spacing="normal">
          <li>Align security considerations with the security analysis of <xref target="DPRS23"/>.</li>
          <li>Vdaf: Pass the nonce to the sharding algorithm.</li>
          <li>Vdaf: Rather than allow the application to choose the nonce length, have each
implementation of the Vdaf interface specify the expected nonce length. (*)</li>
          <li>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.</li>
          <li>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"/>. (*)</li>
          <li>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. (*)</li>
          <li>Prio3: Replace "joint randomness hints" sent in each input share with "joint
randomness parts" sent in the public share. This reduces communication
overhead when the number of shares exceeds two. (*)</li>
          <li>Prio3: Bind nonce to joint randomness parts. This is intended to address
birthday attacks on robustness pointed out by <xref target="DPRS23"/>. (*)</li>
          <li>Poplar1: Use different Prg invocations for producing the correlated randomness
for inner and leaf nodes of the IDPF tree. This is intended to simplify
implementations. (*)</li>
          <li>Poplar1: Don't bind the candidate prefixes to the verifier randomness. This is
intended to improve performance, while not impacting security. According to
the analysis of <xref target="DPRS23"/>, it is necessary to restrict Poplar1 usage such
that no report is aggregated more than once at a given level of the IDPF tree;
otherwise, attacks on privacy may be possible. In light of this restriction,
there is no added benefit of binding to the prefixes themselves. (*)</li>
          <li>Poplar1: During preparation, assert that all candidate prefixes are unique
and appear in order. Uniqueness is required to avoid erroneously rejecting a
valid report; the ordering constraint ensures the uniqueness check can be
performed efficiently. (*)</li>
          <li>Poplar1: Increase the maximum candidate prefix count in the encoding of the
aggregation parameter. (*)</li>
          <li>Poplar1: Bind the nonce to the correlated randomness derivation. This is
intended to provide defense-in-depth by ensuring the Aggregators reject the
report if the nonce does not match what the Client used for sharding. (*)</li>
          <li>Poplar1: Clarify that the aggregation parameter encoding is <bcp14>OPTIONAL</bcp14>.
Accordingly, update implementation considerations around cross-aggregation
state.</li>
          <li>IdpfPoplar: Add implementation considerations around branching on the values
of control bits.</li>
          <li>IdpfPoplar: When decoding the the control bits in the public share, assert
that the trailing bits of the final byte are all zero. (*)</li>
        </ul>
        <t>03:</t>
        <ul spacing="normal">
          <li>Define codepoints for (V)DAFs and use them for domain separation in Prio3 and
Poplar1. (*)</li>
          <li>Prio3: Align joint randomness computation with revised paper <xref target="BBCGGI19"/>.
This change mitigates an attack on robustness. (*)</li>
          <li>Prio3: Remove an intermediate PRG evaluation from query randomness generation.
(*)</li>
          <li>Add additional guidance for choosing FFT-friendly fields.</li>
        </ul>
        <t>02:</t>
        <ul spacing="normal">
          <li>Complete the initial specification of Poplar1.</li>
          <li>Extend (V)DAF syntax to include a "public share" output by the Client and
distributed to all of the Aggregators. This is to accommodate "extractable"
IDPFs as required for Poplar1. (See <xref target="BBCGGI21"/>, Section 4.3 for details.)</li>
          <li>Extend (V)DAF syntax to allow the unsharding step to take into account the
number of measurements aggregated.</li>
          <li>Extend FLP syntax by adding a method for decoding the aggregate result from a
vector of field elements. The new method takes into account the number of
measurements.</li>
          <li>Prio3: Align aggregate result computation with updated FLP syntax.</li>
          <li>Prg: Add a method for statefully generating a vector of field elements.</li>
          <li>Field: Require that field elements are fully reduced before decoding. (*)</li>
          <li>Define new field Field255.</li>
        </ul>
        <t>01:</t>
        <ul spacing="normal">
          <li>Require that VDAFs specify serialization of aggregate shares.</li>
          <li>Define Distributed Aggregation Functions (DAFs).</li>
          <li>Prio3: Move proof verifier check from <tt>prep_next()</tt> to
<tt>prep_shares_to_prep()</tt>. (*)</li>
          <li>Remove public parameter and replace verification parameter with a
"verification key" and "Aggregator ID".</li>
        </ul>
      </section>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

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

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

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

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

    agg_share_0     agg_share_1         agg_share_[SHARES-1]
      |               |                   |
      V               V                   V
    +-----------------------------------------------+
    | agg_shares_to_result                          |
    +-----------------------------------------------+
      |
      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: Vec[Daf.Measurement]):
    out_shares = [ [] for j in range(Daf.SHARES) ]
    for measurement in measurements:
        # 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.measurement_to_input_shares(measurement, rand)

        # Each Aggregator prepares its input share for aggregation.
        for j in range(Daf.SHARES):
            out_shares[j].append(
                Daf.prep(j, agg_param, 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.out_shares_to_agg_share(agg_param,
                                                  out_shares[j])
        agg_shares.append(agg_share_j)

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

<t>The remainder of this section defines the VDAF interface. The attributes are
listed in <xref target="vdaf-param"/> are defined by each concrete VDAF.</t>
      <table anchor="vdaf-param">
        <name>Constants and types defined by each concrete VDAF.</name>
        <thead>
          <tr>
            <th align="left">Parameter</th>
            <th align="left">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">
              <tt>ID</tt></td>
            <td align="left">Algorithm identifier for this VDAF</td>
          </tr>
          <tr>
            <td align="left">
              <tt>VERIFY_KEY_SIZE</tt></td>
            <td align="left">Size (in bytes) of the verification key (<xref target="sec-vdaf-prepare"/>)</td>
          </tr>
          <tr>
            <td align="left">
              <tt>RAND_SIZE</tt></td>
            <td align="left">Size of the random byte string passed to sharding algorithm</td>
          </tr>
          <tr>
            <td align="left">
              <tt>NONCE_SIZE</tt></td>
            <td align="left">Size (in bytes) of the nonce</td>
          </tr>
          <tr>
            <td align="left">
              <tt>ROUNDS</tt></td>
            <td align="left">Number of rounds of communication during the Preparation stage (<xref target="sec-vdaf-prepare"/>)</td>
          </tr>
          <tr>
            <td align="left">
              <tt>SHARES</tt></td>
            <td align="left">Number of input shares into which each measurement is sharded (<xref target="sec-vdaf-shard"/>)</td>
          </tr>
          <tr>
            <td align="left">
              <tt>Measurement</tt></td>
            <td align="left">Type of each measurement</td>
          </tr>
          <tr>
            <td align="left">
              <tt>AggParam</tt></td>
            <td align="left">Type of aggregation parameter</td>
          </tr>
          <tr>
            <td align="left">
              <tt>Prep</tt></td>
            <td align="left">State of each Aggregator during Preparation (<xref target="sec-vdaf-prepare"/>)</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>AggResult</tt></td>
            <td align="left">Type of the aggregate result</td>
          </tr>
        </tbody>
      </table>
      <t>Similarly to DAFs (see {[sec-daf}}), any output of a VDAF method that must be
transmitted from one party to another is treated as an opaque byte string. All
other quantities are given a concrete type.</t>
      <ul empty="true">
        <li>
          <t>OPEN ISSUE It might be cleaner to define a type for each value, then have that
type implement an encoding where necessary. See issue#58.</t>
        </li>
      </ul>
      <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>Prg</tt> used by
the VDAF. (See <xref target="prg"/>.)</t>
      <section anchor="sec-vdaf-shard">
        <name>Sharding</name>
        <t>Sharding transforms a measurement into input shares as it does in DAFs
(cf. <xref target="sec-daf-shard"/>); in addition, it takes a nonce as input and
produces a public share:</t>
        <ul spacing="normal">
          <li>
            <tt>Vdaf.measurement_to_input_shares(measurement: Measurement, nonce:
Bytes[Vdaf.NONCE_SIZE], rand: Bytes[Vdaf.RAND_SIZE]) -&gt; tuple[Bytes,
Vec[Bytes]]</tt> is the randomized sharding algorithm run by each Client. Input
<tt>rand</tt> consists of the random bytes consumed by the algorithm. It consumes
the measurement and the nonce and produces a public share, distributed to each
of Aggregators, and the corresponding sequence of input shares, one for each
Aggregator. Depending on the VDAF, the input shares may encode additional
information used to verify the recovered output shares (e.g., the "proof
shares" in Prio3 <xref target="prio3"/>). The length of the output vector <bcp14>MUST</bcp14> be <tt>SHARES</tt>.</li>
        </ul>
        <t>In order to ensure privacy of the measurement, the Client <bcp14>MUST</bcp14> generate the
random bytes and nonce using a CSPRNG. (See <xref target="security"/> for details.)</t>
      </section>
      <section anchor="sec-vdaf-prepare">
        <name>Preparation</name>
        <t>To recover and verify output shares, the Aggregators interact with one another
over <tt>ROUNDS</tt> rounds. Prior to each round, each Aggregator constructs an
outbound message. Next, the sequence of outbound messages is combined into a
single message, called a "preparation message". (Each of the outbound messages
are called "preparation-message shares".) 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 preparation message. Its output in the last
round is its output share and its output in each of the preceding rounds is a
preparation-message 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 inputs 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_next |  | prep_next |       | prep_next |   |
    +-----------+  +-----------+       +-----------+   |
      |              |              ...  |             |
      V              V                   V             | x ROUNDS
    +----------------------------------------------+   |
    | prep_shares_to_prep                          |   |
    +----------------------------------------------+   |
                     |                                 |
      +--------------+-------------------+             |
      |              |              ...  |             |
      V              V                   V             /
     ...            ...                 ...
      |              |                   |
      V              V                   V
    +-----------+  +-----------+       +-----------+
    | prep_next |  | prep_next |       | prep_next |
    +-----------+  +-----------+       +-----------+
      |              |              ...  |
      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
class 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: Bytes,
input_share: Bytes) -&gt; Prep</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.  </t>
            <t>
It is up to the high level protocol in which the VDAF is used to arrange for
the distribution of the verification key prior to generating and processing
reports. (See <xref target="security"/> for details.)  </t>
            <t>
Protocols using the VDAF <bcp14>MUST</bcp14> ensure that the Aggregator's identifier is equal
to the integer in range <tt>[0, SHARES)</tt> that matches the index of <tt>input_share</tt>
in the sequence of input shares output by the Client.  </t>
            <t>
Protocols <bcp14>MUST</bcp14> ensure that public share consumed by each of the Aggregators is
identical. This is security critical for VDAFs such as Poplar1.</t>
          </li>
          <li>
            <tt>Vdaf.prep_next(prep: Prep, inbound: Optional[Bytes]) -&gt; Union[Tuple[Prep,
Bytes], OutShare]</tt> is the deterministic preparation-state update algorithm run
by each Aggregator. It updates the Aggregator's preparation state (<tt>prep</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 or, if this is the first round,
<tt>None</tt>.</li>
          <li>
            <tt>Vdaf.prep_shares_to_prep(agg_param: AggParam, prep_shares: Vec[Bytes]) -&gt;
Bytes</tt> is the deterministic preparation-message pre-processing algorithm. It
combines the preparation-message shares generated by the Aggregators in the
previous round into the preparation message consumed by each in the next
round.</li>
        </ul>
        <t>In effect, each Aggregator moves through a linear state machine with <tt>ROUNDS+1</tt>
states.  The Aggregator enters the first state on using the initialization
algorithm, and the update algorithm advances the Aggregator to the next state.
Thus, in addition to defining the number of rounds (<tt>ROUNDS</tt>), a VDAF instance
defines the state of the Aggregator after each round.</t>
        <ul empty="true">
          <li>
            <t>TODO Consider how to bake this "linear state machine" condition into the
syntax. Given that Python 3 is used as our pseudocode, it's easier to specify
the preparation state using a class.</t>
          </li>
        </ul>
        <t>The preparation-state update accomplishes two tasks: recovery of output shares
from the input shares and ensuring that the recovered output shares are valid.
The abstraction boundary is drawn so that an Aggregator only recovers an output
share if it is deemed valid (at least, based on the Aggregator's view of the
protocol). Another way to draw this boundary would be to have the Aggregators
recover output shares first, then verify that they are valid. However, this
would allow the possibility of misusing the API by, say, aggregating an invalid
output share. Moreover, in protocols like Prio+ <xref target="AGJOP21"/> based on oblivious
transfer, it is necessary for the Aggregators to interact in order to recover
aggregatable output shares at all.</t>
        <t>Note that it is possible for a VDAF to specify <tt>ROUNDS == 0</tt>, in which case each
Aggregator runs the preparation-state update algorithm once and immediately
recovers its output share without interacting with the other Aggregators.
However, most, if not all, constructions will require some amount of interaction
in order to ensure validity of the output shares (while also maintaining
privacy).</t>
        <ul empty="true">
          <li>
            <t>OPEN ISSUE accommodating 0-round VDAFs may require syntax changes if, for
example, public keys are required. On the other hand, we could consider
defining this class of schemes as a different primitive. See issue#77.</t>
          </li>
        </ul>
      </section>
      <section anchor="sec-vdaf-validity-scopes">
        <name>Validity of Aggregation Parameters</name>
        <t>Similar to DAFs (see <xref target="sec-daf-validity-scopes"/>), VDAFs <bcp14>MAY</bcp14> impose
restrictions for input shares and aggregation parameters. Protocols using a VDAF
<bcp14>MUST</bcp14> ensure that for each input share and aggregation parameter <tt>agg_param</tt>, the
preparation phase (including <tt>Vdaf.prep_init</tt>, <tt>Vdaf.prep_next</tt>, and
<tt>Vdaf.prep_shares_to_prep</tt>; see <xref target="sec-vdaf-prepare"/>) is only called if
<tt>Vdaf.is_valid(agg_param, previous_agg_params)</tt> returns True, where
<tt>previous_agg_params</tt> contains all aggregation parameters that have previously
been used with the same input share.</t>
        <t>VDAFs <bcp14>MUST</bcp14> implement the following function:</t>
        <ul spacing="normal">
          <li>
            <tt>Vdaf.is_valid(agg_param: AggParam, previous_agg_params: set[AggParam]) -&gt;
Bool</tt>: Checks if the <tt>agg_param</tt> is compatible with all elements of
<tt>previous_agg_params</tt>.</li>
        </ul>
      </section>
      <section anchor="sec-vdaf-aggregate">
        <name>Aggregation</name>
        <t>VDAF Aggregation is identical to DAF Aggregation (cf. <xref target="sec-daf-aggregate"/>):</t>
        <ul spacing="normal">
          <li>
            <tt>Vdaf.out_shares_to_agg_share(agg_param: AggParam, out_shares: Vec[OutShare])
-&gt; agg_share: Bytes</tt> is the deterministic aggregation algorithm. It is run by
each Aggregator over the output shares it has computed over a batch of
measurement inputs.</li>
        </ul>
        <t>The data flow for this stage is illustrated in <xref target="aggregate-flow"/>. Here again,
we have the aggregation algorithm in a "one-shot" form, where all shares for a
batch are provided at the same time. VDAFs typically also support a "streaming"
form, where shares are processed one at a time.</t>
      </section>
      <section anchor="sec-vdaf-unshard">
        <name>Unsharding</name>
        <t>VDAF Unsharding is identical to DAF Unsharding (cf. <xref target="sec-daf-unshard"/>):</t>
        <ul spacing="normal">
          <li>
            <tt>Vdaf.agg_shares_to_result(agg_param: AggParam,
agg_shares: Vec[Bytes], num_measurements: Unsigned) -&gt; AggResult</tt> is
run by the Collector in order to compute the aggregate result from
the Aggregators' shares. The length of <tt>agg_shares</tt> <bcp14>MUST</bcp14> be <tt>SHARES</tt>.
<tt>num_measurements</tt> is the number of measurements that contributed to
each of the aggregate shares. This algorithm is deterministic.</li>
        </ul>
        <t>The data flow for this stage is illustrated in <xref target="unshard-flow"/>.</t>
      </section>
      <section anchor="vdaf-execution">
        <name>Execution of a VDAF</name>
        <t>Secure execution of a VDAF involves simulating the following procedure.</t>
        <figure anchor="run-vdaf">
          <name>Execution of a VDAF.</name>
          <artwork><![CDATA[
def run_vdaf(Vdaf,
             verify_key: Bytes[Vdaf.VERIFY_KEY_SIZE],
             agg_param: Vdaf.AggParam,
             nonces: Vec[Bytes[Vdaf.NONCE_SIZE]],
             measurements: Vec[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.measurement_to_input_shares(measurement, nonce, rand)

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

        # Aggregators recover their output shares.
        inbound = None
        for i in range(Vdaf.ROUNDS+1):
            outbound = []
            for j in range(Vdaf.SHARES):
                out = Vdaf.prep_next(prep_states[j], inbound)
                if i < Vdaf.ROUNDS:
                    (prep_states[j], out) = out
                outbound.append(out)
            # This is where we would send messages over the
            # network in a distributed VDAF computation.
            if i < Vdaf.ROUNDS:
                inbound = Vdaf.prep_shares_to_prep(agg_param,
                                                   outbound)

        # The final outputs of prepare phase are the output shares.
        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.out_shares_to_agg_share(agg_param,
                                                   out_shares_j)
        agg_shares.append(agg_share_j)

    # Collector unshards the aggregate.
    num_measurements = len(measurements)
    agg_result = Vdaf.agg_shares_to_result(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 the
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 with at least one
round of preparation.</t>
        <t>The state machine of each Aggregator for VDAF preparation 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>, indicating that the report was rejected and
cannot be processed any further, and <tt>Finished(out_share)</tt>, indicating that
the Aggregator has recovered an output share <tt>out_share</tt>.</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>The first state transition, from <tt>Start</tt> to <tt>Continued</tt> or <tt>Rejected</tt>, is
induced by the following transition rule. No messages are sent or received
during this transition.</t>
        <sourcecode type="transition"><![CDATA[
def ping_pong_start(Vdaf,
                    vdaf_verify_key: bytes[Vdaf.VERIFY_KEY_SIZE],
                    is_leader: bool,
                    agg_param: Vdaf.AggParam,
                    nonce: bytes[Vdaf.NONCE_SIZE],
                    public_share: bytes,
                    host_input_share: bytes) -> State:
    try:
        prep_state = Vdaf.prep_init(
            vdaf_verify_key,
            0 if is_leader else 1,
            agg_param,
            nonce,
            public_share,
            host_input_share,
        )
        return Continue(prep_state)
    except:
        return Rejected()
]]></sourcecode>
        <t>If the state is <tt>Rejected</tt>, then processing halts. Otherwise, if the state is
<tt>Continued</tt>, then processing continues using the following transition rule until
a terminal state is reached.</t>
        <t>Let us call the initiating party the "Leader" and the responding party the
"Helper". The high-level idea is that the Leader and Helper will take turns
running the computation locally until input from their peer is required:</t>
        <ul spacing="normal">
          <li>For a 1-round VDAF (e.g., Prio3 (<xref target="prio3"/>)), the Leader sends its prep share
to the Helper, who computes the prep message locally, computes its output
share, then sends the prep message to the Leader. Preparation requires just
one round trip between the Leader and the Helper.</li>
          <li>For a 2-round VDAF (e.g., Poplar1 (<xref target="poplar1"/>)), the Leader sends its
first-round prep share to the Helper, who replies with the first-round prep
message and its second-round prep share. In the next request, the Leader
computes its second-round prep share locally, computes its output share, and
sends the second-round prep message to the Helper. Finally, the Helper
computes its own output share.</li>
          <li>In general, each request includes the Leader's prep share for the previous
round and/or the prep message for the current round; correspondingly, each
response consists of the prep message for the current round and the Helper's
prep share for the next round.</li>
        </ul>
        <t>The Aggregators proceed in this ping-ponging fashion until a step of the
computation fails, indicating the report is invalid and should be rejected, or
preparation is completed. All told there there are <tt>ceil((Vdaf.ROUNDS+1)/2)</tt>
requests sent.</t>
        <t>Each message in the ping-pong protocol is structured as follows (expressed in
TLS syntax <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>The Leader computes each state transition according to the following algorithm:</t>
        <sourcecode type="transition"><![CDATA[
def ping_pong_req(Vdaf,
                  agg_param: Vdaf.AggParam,
                  state: State,
                  inbound: Optional[Message],
                  ) -> (State, Optional[Message]):
    if inbound == None:
        prep_msg = None
        peer_prep_share = None
    elif inbound.type == 1: # continue
        prep_msg = inbound.prep_msg
        peer_prep_share = inbound.prep_share
    elif inbound.type == 2: # finish
        prep_msg = inbound.prep_msg
        peer_prep_share = None
    else:
        return (Rejected(), None)

    return Vdaf.ping_pong_transition(
        agg_param,
        prep_msg,
        peer_prep_share,
        state.prep_state,
    )
]]></sourcecode>
        <t>(The auxiliary function <tt>ping_pong_transition()</tt> is defined at the end of this
section.) The input <tt>inbound</tt> denotes the last message received from the Helper. This
parameter is optional since initially there is no inbound message.</t>
        <t>Likewise, the Helper computes each state transition according to the following
algorithm:</t>
        <sourcecode type="transition"><![CDATA[
def ping_pong_resp(Vdaf,
                   agg_param: Vdaf.AggParam,
                   state: State,
                   inbound: Message,
                   ) -> (State, Optional[bytes]):
    if inbound.type == 0: # initialize
        prep_msg = None
        peer_prep_share = inbound.prep_share
    elif inbound.type == 1: # continue
        prep_msg = inbound.prep_msg
        peer_prep_share = inbound.prep_share
    else: # finish
        prep_msg = inbound.prep_msg
        peer_prep_share = None

    return Vdaf.ping_pong_transition(
        agg_param,
        prep_msg,
        peer_prep_share,
        state.prep_state,
    )
]]></sourcecode>
        <t>At the start of each request/response cycle, the Leader runs:</t>
        <artwork><![CDATA[
(state, outbound) = Vdaf.ping_pong_req(agg_param, state, inbound)
]]></artwork>
        <t>with <tt>state == Continued(leader_prep_state)</tt> and, if <tt>outbound != None</tt>, sends
<tt>outbound</tt> to the Helper. For the initial request, <tt>inbound == None</tt>. To
respond to the Leader, the Helper runs</t>
        <artwork><![CDATA[
(state, outbound) = Vdaf.ping_pong_resp(agg_param, state, inbound)
]]></artwork>
        <t>with <tt>state == Continued(helper_prep_state)</tt>, where <tt>inbound</tt> is the message it
received from the Leader, and sends <tt>outbound</tt> to the Leader.</t>
        <t>If <tt>state == Finished(out_share)</tt> at the end of a request/response cycle, then
processing is complete. 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>
        <t>The core state transition logic is the same for both Aggregators:</t>
        <artwork><![CDATA[
def ping_pong_transition(Vdaf,
                         agg_param: Vdaf.AggParam,
                         prep_msg: Optional[bytes],
                         peer_prep_share: Optional[bytes],
                         host_prep_state: Vdaf.Prep,
                         ) -> (State, Optional[Message]):
    try:
        # If `prep_msg == None` then this is the start of the
        # first round. Otherwise, `prep_msg` is the prep message
        # from the end of the previous round.
        out = Vdaf.prep_next(host_prep_state, prep_msg)
        if type(out) == Vdaf.OutShare:
            return (Finished(out), None)
        (host_prep_state, host_prep_share) = out

        if peer_prep_share != None:
            prep_shares = [peer_prep_share, host_prep_share]
            if is_leader:
                prep_shares.reverse()
            prep_msg = Vdaf.prep_shares_to_prep(
                agg_param,
                prep_shares,
            )
            out = Vdaf.prep_next(host_prep_state, prep_msg)
            if type(out) == Vdaf.OutShare:
                outbound = Message.finish(prep_msg)
                return (Finished(out), outbound)
            (host_prep_state, host_prep_share) = out
            outbound = Message.continue(prep_msg, host_prep_share)
        else:
            outbound = Message.initialize(host_prep_share)
        return (Continued(host_prep_state), outbound)
    except:
        return (Rejected(), None)
]]></artwork>
      </section>
      <section anchor="star-topology-any-number-of-aggregators">
        <name>Star Topology (Any Number of Aggregators)</name>
        <t>The ping-pong topology of the previous section is only suitable for VDAFs
involving exactly two Aggregators. If more Aggregators are required, the star
topology described in this section can be used instead.</t>
        <ul empty="true">
          <li>
            <t>TODO Describe the Leader-emulated broadcast channel architecture that was
originally envisioned for DAP. (As of DAP-05 we are going with the ping pong
architecture described in the previous section.)</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="prelim">
      <name>Preliminaries</name>
      <t>This section describes the primitives that are common to the VDAFs specified in
this document.</t>
      <section anchor="field">
        <name>Finite Fields</name>
        <t>Both Prio3 and Poplar1 use finite fields of prime order. Finite field
elements are represented by a class <tt>Field</tt> with the following associated
parameters:</t>
        <ul spacing="normal">
          <li>
            <tt>MODULUS: Unsigned</tt> is the prime modulus that defines the field.</li>
          <li>
            <tt>ENCODED_SIZE: Unsigned</tt> is the number of bytes used to encode a field element
as a byte string.</li>
        </ul>
        <t>A concrete <tt>Field</tt> also implements the following class methods:</t>
        <ul spacing="normal">
          <li>
            <tt>Field.zeros(length: Unsigned) -&gt; output: Vec[Field]</tt> returns a vector of
zeros. The length of <tt>output</tt> <bcp14>MUST</bcp14> be <tt>length</tt>.</li>
          <li>
            <tt>Field.rand_vec(length: Unsigned) -&gt; output: Vec[Field]</tt> returns a vector of
random field elements. The length of <tt>output</tt> <bcp14>MUST</bcp14> be <tt>length</tt>.</li>
        </ul>
        <t>A field element is an instance of a concrete <tt>Field</tt>. The concrete class defines
the usual arithmetic operations on field elements. In addition, it defines the
following instance method for converting a field element to an unsigned integer:</t>
        <ul spacing="normal">
          <li>
            <tt>elem.as_unsigned() -&gt; Unsigned</tt> returns the integer representation of
field element <tt>elem</tt>.</li>
        </ul>
        <t>Likewise, each concrete <tt>Field</tt> implements a constructor for converting an
unsigned integer into a field element:</t>
        <ul spacing="normal">
          <li>
            <tt>Field(integer: Unsigned)</tt> returns <tt>integer</tt> represented as a field element.
The value of <tt>integer</tt> <bcp14>MUST</bcp14> be less than <tt>Field.MODULUS</tt>.</li>
        </ul>
        <t>Finally, each concrete <tt>Field</tt> has two derived class methods, one for encoding
a vector of field elements as a byte string and another for decoding a vector of
field elements.</t>
        <figure anchor="field-derived-methods">
          <name>Derived class methods for finite fields.</name>
          <artwork><![CDATA[
def encode_vec(Field, data: Vec[Field]) -> Bytes:
    encoded = Bytes()
    for x in data:
        encoded += to_le_bytes(x.as_unsigned(), Field.ENCODED_SIZE)
    return encoded

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

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

def vec_add(left: Vec[Field], right: Vec[Field]):
    """Add the right operand to the left and return the result."""
    return list(map(lambda x: x[0] + x[1], zip(left, right)))
]]></artwork>
          </figure>
        </section>
        <section anchor="field-fft-friendly">
          <name>FFT-Friendly Fields</name>
          <t>Some VDAFs require fields that are suitable for efficient computation of the
discrete Fourier transform, as this allows for fast polynomial interpolation.
(One example is Prio3 (<xref target="prio3"/>) when instantiated with the generic FLP of
<xref target="flp-generic-construction"/>.) Specifically, a field is said to be
"FFT-friendly" if, in addition to satisfying the interface described in
<xref target="field"/>, it implements the following method:</t>
          <ul spacing="normal">
            <li>
              <tt>Field.gen() -&gt; Field</tt> returns the generator of a large subgroup of the
multiplicative group. To be FFT-friendly, the order of this subgroup <bcp14>MUST</bcp14> be a
power of 2. In addition, the size of the subgroup dictates how large
interpolated polynomials can be. It is <bcp14>RECOMMENDED</bcp14> that a generator is chosen
with order at least <tt>2^20</tt>.</li>
          </ul>
          <t>FFT-friendly fields also define the following parameter:</t>
          <ul spacing="normal">
            <li>
              <tt>GEN_ORDER: Unsigned</tt> is the order of a multiplicative subgroup generated by
<tt>Field.gen()</tt>.</li>
          </ul>
        </section>
        <section anchor="parameters">
          <name>Parameters</name>
          <t>The tables below define finite fields used in the remainder of this document.</t>
          <table anchor="fields">
            <name>Parameters for the finite fields used in this document.</name>
            <thead>
              <tr>
                <th align="left">Parameter</th>
                <th align="left">Field64</th>
                <th align="left">Field128</th>
                <th align="left">Field255</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">MODULUS</td>
                <td align="left">2^32 * 4294967295 + 1</td>
                <td align="left">2^66 * 4611686018427387897 + 1</td>
                <td align="left">2^255 - 19</td>
              </tr>
              <tr>
                <td align="left">ENCODED_SIZE</td>
                <td align="left">8</td>
                <td align="left">16</td>
                <td align="left">32</td>
              </tr>
              <tr>
                <td align="left">Generator</td>
                <td align="left">7^4294967295</td>
                <td align="left">7^4611686018427387897</td>
                <td align="left">n/a</td>
              </tr>
              <tr>
                <td align="left">GEN_ORDER</td>
                <td align="left">2^32</td>
                <td align="left">2^66</td>
                <td align="left">n/a</td>
              </tr>
            </tbody>
          </table>
        </section>
      </section>
      <section anchor="prg">
        <name>Pseudorandom Generators</name>
        <t>A pseudorandom generator (PRG) is used to expand a short, (pseudo)random seed
into a long string of pseudorandom bits. A PRG suitable for this document
implements the interface specified in this section.</t>
        <t>PRGs are defined by a class <tt>Prg</tt> with the following associated parameter:</t>
        <ul spacing="normal">
          <li>
            <tt>SEED_SIZE: Unsigned</tt> is the size (in bytes) of a seed.</li>
        </ul>
        <t>A concrete <tt>Prg</tt> implements the following class method:</t>
        <ul spacing="normal">
          <li>
            <tt>Prg(seed: Bytes[Prg.SEED_SIZE], dst: Bytes, binder: Bytes)</tt> constructs an
instance of <tt>Prg</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 PRG).</li>
          <li>
            <tt>prg.next(length: Unsigned)</tt> returns the next <tt>length</tt> bytes of output of PRG.
If the seed was securely generated, the output can be treated as pseudorandom.</li>
        </ul>
        <t>Each <tt>Prg</tt> has two derived class methods. The first is used to derive a fresh
seed from an existing one. The second is used to compute a sequence of
pseudorandom field elements. For each method, 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 PRG).</t>
        <figure anchor="prg-derived-methods">
          <name>Derived class methods for PRGs.</name>
          <artwork><![CDATA[
def derive_seed(Prg,
                seed: Bytes[Prg.SEED_SIZE],
                dst: Bytes,
                binder: Bytes):
    """Derive a new seed."""
    prg = Prg(seed, dst, binder)
    return prg.next(Prg.SEED_SIZE)

def next_vec(self, Field, length: Unsigned):
    """Output the next `length` pseudorandom 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(Prg,
                    Field,
                    seed: Bytes[Prg.SEED_SIZE],
                    dst: Bytes,
                    binder: Bytes,
                    length: Unsigned):
    """
    Expand the input `seed` into vector of `length` field elements.
    """
    prg = Prg(seed, dst, binder)
    return prg.next_vec(Field, length)
]]></artwork>
        </figure>
        <section anchor="prg-sha3">
          <name>PrgSha3</name>
          <t>This section describes PrgSha3, a PRG based on the Keccak permutation of SHA-3
<xref target="FIPS202"/>. Keccak is used in the cSHAKE128 mode of operation <xref target="SP800-185"/>.
This Prg is <bcp14>RECOMMENDED</bcp14> for all use cases within VDAFs.</t>
          <figure>
            <name>Definition of PRG PrgSha3.</name>
            <artwork><![CDATA[
class PrgSha3(Prg):
    """PRG based on SHA-3 (cSHAKE128)."""

    # Associated parameters
    SEED_SIZE = 16

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

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

        # Function `cSHAKE128(x, l, n, s)` is as defined in
        # [SP800-185, Section 3.3].
        #
        # Implementation note: Rather than re-generate the output
        # stream each time `next()` is invoked, most implementations
        # of SHA-3 will expose an "absorb-then-squeeze" API that
        # allows stateful handling of the stream.
        stream = cSHAKE128(self.x, self.l, b'', self.s)
        return stream[-length:]
]]></artwork>
          </figure>
        </section>
        <section anchor="prg-fixed-key-aes128">
          <name>PrgFixedKeyAes128</name>
          <t>While PrgSha3 as described above can be securely used in all cases where a Prg
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 Prg used inside the Idpf <xref target="idpf"/> implementation in Poplar1
<xref target="idpf-poplar"/>. It is <bcp14>NOT RECOMMENDED</bcp14> to use this Prg anywhere else.
See Security Considerations <xref target="security"/> for a more detailed discussion.</t>
          <artwork><![CDATA[
class PrgFixedKeyAes128(Prg):
    """
    PRG based on a circular collision-resistant hash function from
    fixed-key AES.
    """

    # Associated parameters
    SEED_SIZE = 16

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

        # Use SHA-3 to derive a key from the binder string and domain
        # separation tag. Note that the AES key does not need to be
        # kept secret from any party. However, when used with
        # IdpfPoplar, we require the binder to be a random nonce.
        #
        # Implementation note: This step can be cached across PRG
        # evaluations with many different seeds.
        self.fixed_key = cSHAKE128(binder, 16, b'', dst)
        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 PRG 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>PRGs are used to map a seed to a finite domain, e.g., a fresh seed or a vector
of field elements. To ensure domain separation, the derivation is needs to be
bound to some distinguished domain separation tag. The domain separation tag
encodes the following values:</t>
          <ol spacing="normal" type="1"><li>The document version (i.e.,<tt>VERSION</tt>);</li>
            <li>The "class" of the algorithm using the output (e.g., VDAF);</li>
            <li>A unique identifier for the algorithm; and</li>
            <li>Some indication of how the output is used (e.g., for deriving the measurement
shares in Prio3 <xref target="prio3"/>).</li>
          </ol>
          <t>The following algorithm is used in the remainder of this document in order to
format the domain separation tag:</t>
          <artwork><![CDATA[
def format_dst(algo_class: Unsigned,
               algo: Unsigned,
               usage: Unsigned) -> Bytes:
    """Format PRG domain separation tag for use within a (V)DAF."""
    return concat([
        to_be_bytes(VERSION, 1),
        to_be_bytes(algo_class, 1),
        to_be_bytes(algo, 4),
        to_be_bytes(usage, 2),
    ])
]]></artwork>
          <t>It is also sometimes necessary to bind the output to some ephemeral value that
multiple parties need to agree on. We call this input the "binder string".</t>
        </section>
      </section>
    </section>
    <section anchor="prio3">
      <name>Prio3</name>
      <t>This section describes Prio3, a VDAF for Prio <xref target="CGB17"/>. Prio is suitable for
a wide variety of aggregation functions, including (but not limited to) sum,
mean, standard deviation, estimation of quantiles (e.g., median), and linear
regression. In fact, the scheme described in this section is compatible with any
aggregation function that has the following structure:</t>
      <ul spacing="normal">
        <li>Each measurement is encoded as a vector over some finite field.</li>
        <li>Input validity is determined by an arithmetic circuit evaluated over the
encoded input. (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 input is said to be "valid"; otherwise, if the output is
non-zero, then the input is said to be "invalid".</li>
        <li>The aggregate result is obtained by summing up the encoded input vectors and
computing some function of the sum.</li>
      </ul>
      <t>At a high level, Prio3 distributes this computation as follows. Each Client
first shards its measurement by first encoding it, then splitting the vector into
secret shares and sending a share to each Aggregator. Next, in the preparation
phase, the Aggregators carry out a multi-party computation to determine if their
shares correspond to a valid input (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 input 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 inputs. 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 input's validity and distributes shares of the
proof to the Aggregators. Each Aggregator then performs some a computation on
its input 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 input. (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>INPUT_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 input and proof</td>
            </tr>
            <tr>
              <td align="left">
                <tt>Measurement</tt></td>
              <td align="left">Type of the measurement</td>
            </tr>
            <tr>
              <td align="left">
                <tt>AggResult</tt></td>
              <td align="left">Type of the aggregate result</td>
            </tr>
            <tr>
              <td align="left">
                <tt>Field</tt></td>
              <td align="left">As defined in (<xref target="field"/>)</td>
            </tr>
          </tbody>
        </table>
        <t>An FLP specifies the following algorithms for generating and verifying proofs of
validity (encoding is described below in <xref target="flp-encode"/>):</t>
        <ul spacing="normal">
          <li>
            <tt>Flp.prove(input: 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 input, the "prover randomness"
<tt>prove_rand</tt>, and the "joint randomness" <tt>joint_rand</tt>. The prover randomness is
used only by the prover, but the joint randomness is shared by both the prover
and verifier.</li>
          <li>
            <tt>Flp.query(input: 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
input and proof. The result of the query (i.e., the output of this function)
is called the "verifier message". In addition to the input 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 input and proof shares were generated.</li>
          <li>
            <tt>Flp.decide(verifier: Vec[Field]) -&gt; Bool</tt> is the deterministic decision
algorithm run by the verifier. It takes as input the verifier message and
outputs a boolean indicating if the input from which it was generated is
valid.</li>
        </ul>
        <t>Our application requires that the FLP is "fully linear" in the sense defined in
<xref target="BBCGGI19"/>. As a practical matter, what this property implies is that, when
run on a share of the input 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 input's
validity. Therefore, to decide if an input 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 of the input and proof 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 input, 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, inp: 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(inp, prove_rand, joint_rand)

    # Shard the input and the proof.
    input_shares = additive_secret_share(inp, num_shares, Flp.Field)
    proof_shares = additive_secret_share(proof, num_shares, Flp.Field)

    # Verifier queries the input shares and proof shares.
    verifier_shares = [
        Flp.query(
            input_share,
            proof_share,
            query_rand,
            joint_rand,
            num_shares,
        )
        for input_share, proof_share in zip(input_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 input is valid.
    return Flp.decide(verifier)
]]></artwork>
        </figure>
        <t>The proof system is constructed so that, if <tt>inp</tt> is a valid input, then
<tt>run_flp(Flp, inp, 1)</tt> always returns <tt>True</tt>. On the other hand, if <tt>inp</tt> is
invalid, then as long as <tt>joint_rand</tt> and <tt>query_rand</tt> are generated uniform
randomly, the output is <tt>False</tt> with overwhelming probability.</t>
        <t>We remark that <xref target="BBCGGI19"/> defines a much larger class of fully linear proof
systems than we consider here. In particular, what is called an "FLP" here is
called a 1.5-round, public-coin, interactive oracle proof system in their paper.</t>
        <section anchor="flp-encode">
          <name>Encoding the Input</name>
          <t>The type of measurement being aggregated is defined by the FLP. Hence, the FLP
also specifies a method of encoding raw measurements as a vector of field
elements:</t>
          <ul spacing="normal">
            <li>
              <tt>Flp.encode(measurement: Measurement) -&gt; Vec[Field]</tt> encodes a raw measurement
as a vector of field elements. The return value <bcp14>MUST</bcp14> be of length <tt>INPUT_LEN</tt>.</li>
          </ul>
          <t>For some FLPs, the encoded input 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 input to
the length of the aggregated output:</t>
          <ul spacing="normal">
            <li>
              <tt>Flp.truncate(input: Vec[Field]) -&gt; Vec[Field]</tt> maps an encoded input (e.g.,
the bit-encoding of the input) to an aggregatable output (e.g., the singleton
vector containing the input). The length of the input <bcp14>MUST</bcp14> be <tt>INPUT_LEN</tt> and
the length of the output <bcp14>MUST</bcp14> be <tt>OUTPUT_LEN</tt>.</li>
          </ul>
          <t>Once the aggregate shares have been computed and combined together, their sum
can be converted into the aggregate result. This could be a projection from
the FLP's field to the integers, or it could include additional
post-processing.</t>
          <ul spacing="normal">
            <li>
              <tt>Flp.decode(output: Vec[Field], num_measurements: Unsigned) -&gt; AggResult</tt>
maps a sum of aggregate shares to an aggregate result. The length of the
input <bcp14>MUST</bcp14> be <tt>OUTPUT_LEN</tt>. <tt>num_measurements</tt> is the number of measurements
that contributed to the aggregated output.</li>
          </ul>
          <t>We remark that, taken together, these three functionalities correspond roughly
to the notion of "Affine-aggregatable encodings (AFEs)" from <xref target="CGB17"/>.</t>
        </section>
      </section>
      <section anchor="prio3-construction">
        <name>Construction</name>
        <t>This section specifies <tt>Prio3</tt>, an implementation of the <tt>Vdaf</tt> interface
(<xref target="vdaf"/>). It has two generic parameters: an <tt>Flp</tt> (<xref target="flp"/>) and a <tt>Prg</tt>
(<xref target="prg"/>). 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>Prg.SEED_SIZE</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>RAND_SIZE</tt></td>
              <td align="left">
                <tt>Prg.SEED_SIZE * (1 + 2 * (SHARES - 1)) if Flp.JOINT_RAND_LEN == 0 else Prg.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>Prep</tt></td>
              <td align="left">
                <tt>Tuple[Vec[Flp.Field], Optional[Bytes], Bytes]</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>OutShare</tt></td>
              <td align="left">
                <tt>Vec[Flp.Field]</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>AggResult</tt></td>
              <td align="left">
                <tt>Flp.AggResult</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_MEASUREMENT_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
input in a way that allows the Aggregators to reconstruct it from their input
shares. (This idea is based on the Fiat-Shamir heuristic and is described in
Section 6.2.3 of <xref target="BBCGGI19"/>.)</t>
          <t>The sharding algorithm involves the following steps:</t>
          <ol spacing="normal" type="1"><li>Encode the Client's raw measurement as an input for the FLP</li>
            <li>Shard the measurement into a sequence of measurement shares</li>
            <li>Derive the joint randomness from the measurement shares and nonce</li>
            <li>Run the FLP proof-generation algorithm using the derived joint randomness</li>
            <li>Shard the proof into a sequence of proof shares</li>
            <li>Return the public share, consisting of the joint randomness parts, and the
input shares, each consisting of the measurement share, proof share, and
blind of one of the Aggregators</li>
          </ol>
          <t>The algorithm is specified below. Notice that only one set of input and proof
shares (called the "leader" shares below) are vectors of field elements. The
other shares (called the "helper" shares) are represented instead by PRG seeds,
which are expanded into vectors of field elements.</t>
          <t>The definitions of constants and a few auxiliary functions are defined in
<xref target="prio3-auxiliary"/>.</t>
          <figure anchor="prio3-eval-input">
            <name>Input-distribution algorithm for Prio3.</name>
            <artwork><![CDATA[
def measurement_to_input_shares(Prio3, measurement, nonce, rand):
    l = Prio3.Prg.SEED_SIZE
    use_joint_rand = Prio3.Flp.JOINT_RAND_LEN > 0

    # Split the random input into the various seeds we'll need.
    if len(rand) != Prio3.RAND_SIZE:
        raise ERR_INPUT # unexpected length for random input
    seeds = [rand[i:i+l] for i in range(0,Prio3.RAND_SIZE,l)]
    if use_joint_rand:
        k_helper_seeds, seeds = front((Prio3.SHARES-1) * 3, seeds)
        k_helper_meas_shares = [
            k_helper_seeds[i]
            for i in range(0, (Prio3.SHARES-1) * 3, 3)
        ]
        k_helper_proof_shares = [
            k_helper_seeds[i]
            for i in range(1, (Prio3.SHARES-1) * 3, 3)
        ]
        k_helper_blinds = [
            k_helper_seeds[i]
            for i in range(2, (Prio3.SHARES-1) * 3, 3)
        ]
        (k_leader_blind,), seeds = front(1, seeds)
    else:
        k_helper_seeds, seeds = front((Prio3.SHARES-1) * 2, seeds)
        k_helper_meas_shares = [
            k_helper_seeds[i]
            for i in range(0, (Prio3.SHARES-1) * 2, 2)
        ]
        k_helper_proof_shares = [
            k_helper_seeds[i]
            for i in range(1, (Prio3.SHARES-1) * 2, 2)
        ]
        k_helper_blinds = [None] * (Prio3.SHARES-1)
        k_leader_blind = None
    (k_prove,), seeds = front(1, seeds)

    # Finish measurement shares and joint randomness parts.
    inp = Prio3.Flp.encode(measurement)
    leader_meas_share = inp
    k_joint_rand_parts = []
    for j in range(Prio3.SHARES-1):
        helper_meas_share = Prio3.Prg.expand_into_vec(
            Prio3.Flp.Field,
            k_helper_meas_shares[j],
            Prio3.domain_separation_tag(USAGE_MEASUREMENT_SHARE),
            byte(j+1),
            Prio3.Flp.INPUT_LEN
        )
        leader_meas_share = vec_sub(leader_meas_share,
                                    helper_meas_share)
        if use_joint_rand:
            encoded = Prio3.Flp.Field.encode_vec(helper_meas_share)
            k_joint_rand_part = Prio3.Prg.derive_seed(
                k_helper_blinds[j],
                Prio3.domain_separation_tag(USAGE_JOINT_RAND_PART),
                byte(j+1) + nonce + encoded,
            )
            k_joint_rand_parts.append(k_joint_rand_part)

    # Finish joint randomness.
    if use_joint_rand:
        encoded = Prio3.Flp.Field.encode_vec(leader_meas_share)
        k_joint_rand_part = Prio3.Prg.derive_seed(
            k_leader_blind,
            Prio3.domain_separation_tag(USAGE_JOINT_RAND_PART),
            byte(0) + nonce + encoded,
        )
        k_joint_rand_parts.insert(0, k_joint_rand_part)
        joint_rand = Prio3.Prg.expand_into_vec(
            Prio3.Flp.Field,
            Prio3.joint_rand(k_joint_rand_parts),
            Prio3.domain_separation_tag(USAGE_JOINT_RANDOMNESS),
            b'',
            Prio3.Flp.JOINT_RAND_LEN,
        )
    else:
        joint_rand = []

    # Finish the proof shares.
    prove_rand = Prio3.Prg.expand_into_vec(
        Prio3.Flp.Field,
        k_prove,
        Prio3.domain_separation_tag(USAGE_PROVE_RANDOMNESS),
        b'',
        Prio3.Flp.PROVE_RAND_LEN,
    )
    proof = Prio3.Flp.prove(inp, prove_rand, joint_rand)
    leader_proof_share = proof
    for j in range(Prio3.SHARES-1):
        helper_proof_share = Prio3.Prg.expand_into_vec(
            Prio3.Flp.Field,
            k_helper_proof_shares[j],
            Prio3.domain_separation_tag(USAGE_PROOF_SHARE),
            byte(j+1),
            Prio3.Flp.PROOF_LEN,
        )
        leader_proof_share = vec_sub(leader_proof_share,
                                     helper_proof_share)

    # Each Aggregator's input share contains its measurement share,
    # proof share, and blind. The public share contains the
    # Aggregators' joint randomness parts.
    input_shares = []
    input_shares.append(Prio3.encode_leader_share(
        leader_meas_share,
        leader_proof_share,
        k_leader_blind,
    ))
    for j in range(Prio3.SHARES-1):
        input_shares.append(Prio3.encode_helper_share(
            k_helper_meas_shares[j],
            k_helper_proof_shares[j],
            k_helper_blinds[j],
        ))
    public_share = Prio3.encode_public_share(k_joint_rand_parts)
    return (public_share, input_shares)
]]></artwork>
          </figure>
        </section>
        <section anchor="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 input and
proof share locally, then exchanges its verifier share with the other
Aggregators. The verifier shares are then combined into the verifier message,
which is used to decide whether to accept.</t>
          <t>In addition, the Aggregators must ensure that they have all used the same joint
randomness for the query-generation algorithm. The joint randomness is generated
by a PRG seed. Each Aggregator derives a "part" of this seed from its input
share and the "blind" generated by the Client. The seed is derived by hashing
together the parts, so before running the query-generation algorithm, it must
first gather the parts derived by the other Aggregators.</t>
          <t>In order to avoid extra round of communication, the Client sends each Aggregator
a "hint" consisting of the other Aggregators' parts of the joint randomness
seed. This leaves open the possibility that the Client cheated by, say, forcing
the Aggregators to use joint randomness that biases the proof check procedure
some way in its favor. To mitigate this, the Aggregators also check that they
have all computed the same joint randomness seed before accepting their output
shares. To do so, they exchange their parts of the joint randomness along with
their verifier shares.</t>
          <t>The definitions of constants and a few auxiliary functions are defined in
<xref target="prio3-auxiliary"/>.</t>
          <figure anchor="prio3-prep-state">
            <name>Preparation state for Prio3.</name>
            <artwork><![CDATA[
def prep_init(Prio3, verify_key, agg_id, _agg_param,
              nonce, public_share, input_share):
    k_joint_rand_parts = Prio3.decode_public_share(public_share)
    (meas_share, proof_share, k_blind) = \
        Prio3.decode_leader_share(input_share) if agg_id == 0 else \
        Prio3.decode_helper_share(agg_id, input_share)
    out_share = Prio3.Flp.truncate(meas_share)

    # Compute joint randomness.
    joint_rand = []
    k_corrected_joint_rand, k_joint_rand_part = None, None
    if Prio3.Flp.JOINT_RAND_LEN > 0:
        encoded = Prio3.Flp.Field.encode_vec(meas_share)
        k_joint_rand_part = Prio3.Prg.derive_seed(k_blind,
            Prio3.domain_separation_tag(USAGE_JOINT_RAND_PART),
            byte(agg_id) + nonce + encoded)
        k_joint_rand_parts[agg_id] = k_joint_rand_part
        k_corrected_joint_rand = Prio3.joint_rand(k_joint_rand_parts)
        joint_rand = Prio3.Prg.expand_into_vec(
            Prio3.Flp.Field,
            k_corrected_joint_rand,
            Prio3.domain_separation_tag(USAGE_JOINT_RANDOMNESS),
            b'',
            Prio3.Flp.JOINT_RAND_LEN,
        )

    # Query the measurement and proof share.
    query_rand = Prio3.Prg.expand_into_vec(
        Prio3.Flp.Field,
        verify_key,
        Prio3.domain_separation_tag(USAGE_QUERY_RANDOMNESS),
        nonce,
        Prio3.Flp.QUERY_RAND_LEN,
    )
    verifier_share = Prio3.Flp.query(meas_share,
                                     proof_share,
                                     query_rand,
                                     joint_rand,
                                     Prio3.SHARES)

    prep_msg = Prio3.encode_prep_share(verifier_share,
                                       k_joint_rand_part)
    return (out_share, k_corrected_joint_rand, prep_msg)

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

    if inbound is None:
        return (prep, prep_msg)

    k_joint_rand_check = Prio3.decode_prep_msg(inbound)
    if k_joint_rand_check != k_corrected_joint_rand:
        raise ERR_VERIFY # joint randomness check failed

    return out_share

def prep_shares_to_prep(Prio3, _agg_param, prep_shares):
    verifier = Prio3.Flp.Field.zeros(Prio3.Flp.VERIFIER_LEN)
    k_joint_rand_parts = []
    for encoded in prep_shares:
        (verifier_share, k_joint_rand_part) = \
            Prio3.decode_prep_share(encoded)

        verifier = vec_add(verifier, verifier_share)

        if Prio3.Flp.JOINT_RAND_LEN > 0:
            k_joint_rand_parts.append(k_joint_rand_part)

    if not Prio3.Flp.decide(verifier):
        raise ERR_VERIFY # proof verifier check failed

    k_joint_rand_check = None
    if Prio3.Flp.JOINT_RAND_LEN > 0:
        k_joint_rand_check = Prio3.joint_rand(k_joint_rand_parts)
    return Prio3.encode_prep_msg(k_joint_rand_check)
]]></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 out_shares_to_agg_share(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 Prio3.Flp.Field.encode_vec(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 agg_shares_to_result(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, Prio3.Flp.Field.decode_vec(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 method is called by the sharding and preparation algorithms to
derive the joint randomness.</t>
          <artwork><![CDATA[
def joint_rand(Prio3, k_joint_rand_parts):
    return Prio3.Prg.derive_seed(
        zeros(Prio3.Prg.SEED_SIZE),
        Prio3.domain_separation_tag(USAGE_JOINT_RAND_SEED),
        concat(k_joint_rand_parts),
    )
]]></artwork>
          <section anchor="message-serialization">
            <name>Message Serialization</name>
            <t>The following methods are used for encoding and decoding the leader's (i.e.,
the Aggregator with ID <tt>0</tt>) VDAF input share. The leader's share consists of
the full-length measurement and proof shares.</t>
            <artwork><![CDATA[
def encode_leader_share(Prio3,
                        meas_share,
                        proof_share,
                        k_blind):
    encoded = Bytes()
    encoded += Prio3.Flp.Field.encode_vec(meas_share)
    encoded += Prio3.Flp.Field.encode_vec(proof_share)
    if Prio3.Flp.JOINT_RAND_LEN > 0:
        encoded += k_blind
    return encoded

def decode_leader_share(Prio3, encoded):
    l = Prio3.Flp.Field.ENCODED_SIZE * Prio3.Flp.INPUT_LEN
    encoded_meas_share, encoded = encoded[:l], encoded[l:]
    meas_share = Prio3.Flp.Field.decode_vec(encoded_meas_share)
    l = Prio3.Flp.Field.ENCODED_SIZE * Prio3.Flp.PROOF_LEN
    encoded_proof_share, encoded = encoded[:l], encoded[l:]
    proof_share = Prio3.Flp.Field.decode_vec(encoded_proof_share)
    l = Prio3.Prg.SEED_SIZE
    if Prio3.Flp.JOINT_RAND_LEN == 0:
        if len(encoded) != 0:
            raise ERR_DECODE
        return (meas_share, proof_share, None)
    k_blind, encoded = encoded[:l], encoded[l:]
    if len(encoded) != 0:
        raise ERR_DECODE
    return (meas_share, proof_share, k_blind)
]]></artwork>
            <t>Next, the methods below are used for encoding and decoding the helpers' (i.e.,
non-leader) VDAF input shares. Each consists of PRG seeds that are expanded
into the measurement and proof shares.</t>
            <artwork><![CDATA[
def encode_helper_share(Prio3,
                        k_meas_share,
                        k_proof_share,
                        k_blind):
    encoded = Bytes()
    encoded += k_meas_share
    encoded += k_proof_share
    if Prio3.Flp.JOINT_RAND_LEN > 0:
        encoded += k_blind
    return encoded

def decode_helper_share(Prio3, agg_id, encoded):
    c_meas_share = Prio3.domain_separation_tag(USAGE_MEASUREMENT_SHARE)
    c_proof_share = Prio3.domain_separation_tag(USAGE_PROOF_SHARE)
    l = Prio3.Prg.SEED_SIZE
    k_meas_share, encoded = encoded[:l], encoded[l:]
    meas_share = Prio3.Prg.expand_into_vec(Prio3.Flp.Field,
                                           k_meas_share,
                                           c_meas_share,
                                           byte(agg_id),
                                           Prio3.Flp.INPUT_LEN)
    k_proof_share, encoded = encoded[:l], encoded[l:]
    proof_share = Prio3.Prg.expand_into_vec(Prio3.Flp.Field,
                                            k_proof_share,
                                            c_proof_share,
                                            byte(agg_id),
                                            Prio3.Flp.PROOF_LEN)
    if Prio3.Flp.JOINT_RAND_LEN == 0:
        if len(encoded) != 0:
            raise ERR_DECODE
        return (meas_share, proof_share, None)
    k_blind, encoded = encoded[:l], encoded[l:]
    if len(encoded) != 0:
        raise ERR_DECODE
    return (meas_share, proof_share, k_blind)
]]></artwork>
            <t>Next, the methods below are used for encoding and decoding the VDAF public share.</t>
            <artwork><![CDATA[
def encode_public_share(Prio3,
                        k_joint_rand_parts):
    encoded = Bytes()
    if Prio3.Flp.JOINT_RAND_LEN > 0:
        encoded += concat(k_joint_rand_parts)
    return encoded

def decode_public_share(Prio3, encoded):
    l = Prio3.Prg.SEED_SIZE
    if Prio3.Flp.JOINT_RAND_LEN == 0:
        if len(encoded) != 0:
            raise ERR_DECODE
        return None
    k_joint_rand_parts = []
    for i in range(Prio3.SHARES):
        k_joint_rand_part, encoded = encoded[:l], encoded[l:]
        k_joint_rand_parts.append(k_joint_rand_part)
    if len(encoded) != 0:
        raise ERR_DECODE
    return k_joint_rand_parts
]]></artwork>
            <t>Finally, the methods below are used for encoding and decoding the values
transmitted during VDAF preparation.</t>
            <artwork><![CDATA[
def encode_prep_share(Prio3, verifier, k_joint_rand):
    encoded = Bytes()
    encoded += Prio3.Flp.Field.encode_vec(verifier)
    if Prio3.Flp.JOINT_RAND_LEN > 0:
        encoded += k_joint_rand
    return encoded

def decode_prep_share(Prio3, encoded):
    l = Prio3.Flp.Field.ENCODED_SIZE * Prio3.Flp.VERIFIER_LEN
    encoded_verifier, encoded = encoded[:l], encoded[l:]
    verifier = Prio3.Flp.Field.decode_vec(encoded_verifier)
    if Prio3.Flp.JOINT_RAND_LEN == 0:
        if len(encoded) != 0:
            raise ERR_DECODE
        return (verifier, None)
    l = Prio3.Prg.SEED_SIZE
    k_joint_rand, encoded = encoded[:l], encoded[l:]
    if len(encoded) != 0:
        raise ERR_DECODE
    return (verifier, k_joint_rand)

def encode_prep_msg(Prio3, k_joint_rand_check):
    encoded = Bytes()
    if Prio3.Flp.JOINT_RAND_LEN > 0:
        encoded += k_joint_rand_check
    return encoded

def decode_prep_msg(Prio3, encoded):
    if Prio3.Flp.JOINT_RAND_LEN == 0:
        if len(encoded) != 0:
            raise ERR_DECODE
        return None
    l = Prio3.Prg.SEED_SIZE
    k_joint_rand_check, encoded = encoded[:l], encoded[l:]
    if len(encoded) != 0:
        raise ERR_DECODE
    return k_joint_rand_check
]]></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 input: If the circuit output is zero, then the input
is deemed valid; otherwise, if the circuit output is non-zero, then the input is
deemed invalid. Thus the goal of the proof system is merely to allow the
verifier to evaluate the validity circuit over the input. For our application
(<xref target="prio3"/>), this computation is distributed among multiple Aggregators, each of
which has only a share of the input.</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 an input <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 input 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 input 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 input 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 <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 input 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(inp, r) = r * Range2(inp[0]) + ... + r^N * Range2(inp[N-1])
]]></artwork>
            <t>(Note that this is a special case of <xref target="BBCGGI19"/>, Theorem 5.2.) Here <tt>inp</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>inp</tt> is valid (i.e., each <tt>inp[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>inp[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.) For example, the following circuit is allowed, where
<tt>Mul</tt> and <tt>Range2</tt> are the gadgets defined above (the input has length <tt>N+1</tt>):</t>
            <artwork><![CDATA[
C(inp, r) = r * Range2(inp[0]) + ... + r^N * Range2(inp[N-1]) + \
            2^0 * inp[0]       + ... + 2^(N-1) * inp[N-1]     - \
            Mul(inp[N], inp[N])
]]></artwork>
            <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>INPUT_LEN</tt></td>
                <td align="left">Length of the input</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>A concrete <tt>Valid</tt> provides the following methods for encoding a measurement as
an input vector, truncating an input vector to the length of an aggregatable
output, and converting an aggregated output to an aggregate result:</t>
          <ul spacing="normal">
            <li>
              <tt>Valid.encode(measurement: Measurement) -&gt; Vec[Field]</tt> returns a vector of
length <tt>INPUT_LEN</tt> representing a measurement.</li>
            <li>
              <tt>Valid.truncate(input: Vec[Field]) -&gt; Vec[Field]</tt> returns a vector of length
<tt>OUTPUT_LEN</tt> representing an aggregatable output.</li>
            <li>
              <tt>Valid.decode(output: Vec[Field], num_measurements: Unsigned) -&gt; AggResult</tt>
returns an aggregate result.</li>
          </ul>
          <t>Finally, the following class methods are derived for each concrete <tt>Valid</tt>:</t>
          <figure>
            <name>Derived methods for validity circuits.</name>
            <artwork><![CDATA[
def prove_rand_len(Valid):
    """Length of the prover randomness."""
    return sum(map(lambda g: g.ARITY, Valid.GADGETS))

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

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

def verifier_len(Valid):
    """Length of the verifier message."""
    length = 1
    for g in Valid.GADGETS:
        length += g.ARITY + 1
    return length
]]></artwork>
          </figure>
        </section>
        <section anchor="flp-generic-construction">
          <name>Construction</name>
          <t>This section specifies <tt>FlpGeneric</tt>, an implementation of the <tt>Flp</tt> interface
(<xref target="flp"/>). It has as a generic parameter a validity circuit <tt>Valid</tt> implementing
the interface defined in <xref target="flp-generic-valid"/>.</t>
          <ul empty="true">
            <li>
              <t>NOTE A reference implementation can be found in
https://github.com/cfrg/draft-irtf-cfrg-vdaf/blob/main/poc/flp_generic.py.</t>
            </li>
          </ul>
          <t>The FLP parameters for <tt>FlpGeneric</tt> are defined in <xref target="flp-generic-param"/>. The
required methods for generating the proof, generating the verifier, and deciding
validity are specified in the remaining subsections.</t>
          <t>In the remainder, we let <tt>[n]</tt> denote the set <tt>{1, ..., n}</tt> for positive integer
<tt>n</tt>. We also define the following constants:</t>
          <ul spacing="normal">
            <li>Let <tt>H = len(Valid.GADGETS)</tt></li>
            <li>
              <t>For each <tt>i</tt> in <tt>[H]</tt>:
              </t>
              <ul spacing="normal">
                <li>Let <tt>G_i = Valid.GADGETS[i]</tt></li>
                <li>Let <tt>L_i = Valid.GADGETS[i].ARITY</tt></li>
                <li>Let <tt>M_i = Valid.GADGET_CALLS[i]</tt></li>
                <li>Let <tt>P_i = next_power_of_2(M_i+1)</tt></li>
                <li>Let <tt>alpha_i = Field.gen()^(Field.GEN_ORDER / P_i)</tt></li>
              </ul>
            </li>
          </ul>
          <table anchor="flp-generic-param">
            <name>FLP Parameters of FlpGeneric.</name>
            <thead>
              <tr>
                <th align="left">Parameter</th>
                <th align="left">Value</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">
                  <tt>PROVE_RAND_LEN</tt></td>
                <td align="left">
                  <tt>Valid.prove_rand_len()</tt> (see <xref target="flp-generic-valid"/>)</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>QUERY_RAND_LEN</tt></td>
                <td align="left">
                  <tt>Valid.query_rand_len()</tt> (see <xref target="flp-generic-valid"/>)</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>JOINT_RAND_LEN</tt></td>
                <td align="left">
                  <tt>Valid.JOINT_RAND_LEN</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>INPUT_LEN</tt></td>
                <td align="left">
                  <tt>Valid.INPUT_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 <tt>inp</tt>, <tt>prove_rand</tt>, and <tt>joint_rand</tt>, the proof is computed as
follows:</t>
            <ol spacing="normal" type="1"><li>For each <tt>i</tt> in <tt>[H]</tt> create an empty table <tt>wire_i</tt>.</li>
              <li>Partition the prover randomness <tt>prove_rand</tt> into sub-vectors <tt>seed_1, ...,
seed_H</tt> where <tt>len(seed_i) == L_i</tt> for all <tt>i</tt> in <tt>[H]</tt>. Let us call these
the "wire seeds" of each gadget.</li>
              <li>Evaluate <tt>Valid</tt> on input of <tt>inp</tt> and <tt>joint_rand</tt>, recording the inputs of
each gadget in the corresponding table. Specifically, for every <tt>i</tt> in <tt>[H]</tt>,
set <tt>wire_i[j-1,k-1]</tt> to the value on the <tt>j</tt>th wire into the <tt>k</tt>th call to
gadget <tt>G_i</tt>.</li>
              <li>
                <t>Compute the "wire polynomials". That is, for every <tt>i</tt> in <tt>[H]</tt> and <tt>j</tt> in
<tt>[L_i]</tt>, construct <tt>poly_wire_i[j-1]</tt>, the <tt>j</tt>th wire polynomial for the
<tt>i</tt>th gadget, as follows:  </t>
                <ul spacing="normal">
                  <li>Let <tt>w = [seed_i[j-1], wire_i[j-1,0], ..., wire_i[j-1,M_i-1]]</tt>.</li>
                  <li>Let <tt>padded_w = w + Field.zeros(P_i - len(w))</tt>.</li>
                </ul>
                <ul empty="true">
                  <li>
                    <t>NOTE We pad <tt>w</tt> to the nearest power of 2 so that we can use FFT for
interpolating the wire polynomials. Perhaps there is some clever math for
picking <tt>wire_inp</tt> in a way that avoids having to pad.</t>
                  </li>
                </ul>
                <ul spacing="normal">
                  <li>Let <tt>poly_wire_i[j-1]</tt> be the lowest degree polynomial for which
<tt>poly_wire_i[j-1](alpha_i^k) == padded_w[k]</tt> for all <tt>k</tt> in <tt>[P_i]</tt>.</li>
                </ul>
              </li>
              <li>
                <t>Compute the "gadget polynomials". That is, for every <tt>i</tt> in <tt>[H]</tt>:  </t>
                <ul spacing="normal">
                  <li>Let <tt>poly_gadget_i = G_i(poly_wire_i[0], ..., poly_wire_i[L_i-1])</tt>. That
is, evaluate the circuit <tt>G_i</tt> on the wire polynomials for the <tt>i</tt>th
gadget. (Arithmetic is in the ring of polynomials over <tt>Field</tt>.)</li>
                </ul>
              </li>
            </ol>
            <t>The proof is the vector <tt>proof = seed_1 + coeff_1 + ... + seed_H + coeff_H</tt>,
where <tt>coeff_i</tt> is the vector of coefficients of <tt>poly_gadget_i</tt> for each <tt>i</tt> in
<tt>[H]</tt>.</t>
          </section>
          <section anchor="flp-generic-construction-query">
            <name>Query Generation</name>
            <t>On input of <tt>inp</tt>, <tt>proof</tt>, <tt>query_rand</tt>, and <tt>joint_rand</tt>, the verifier message
is generated as follows:</t>
            <ol spacing="normal" type="1"><li>For every <tt>i</tt> in <tt>[H]</tt> create an empty table <tt>wire_i</tt>.</li>
              <li>Partition <tt>proof</tt> into the sub-vectors <tt>seed_1</tt>, <tt>coeff_1</tt>, ..., <tt>seed_H</tt>,
<tt>coeff_H</tt> defined in <xref target="flp-generic-construction-prove"/>.</li>
              <li>Evaluate <tt>Valid</tt> on input of <tt>inp</tt> and <tt>joint_rand</tt>, recording the inputs of
each gadget in the corresponding table. This step is similar to the prover's
step (3.) except the verifier does not evaluate the gadgets. Instead, it
computes the output of the <tt>k</tt>th call to <tt>G_i</tt> by evaluating
<tt>poly_gadget_i(alpha_i^k)</tt>. Let <tt>v</tt> denote the output of the circuit
evaluation.</li>
              <li>Compute the wire polynomials just as in the prover's step (4.).</li>
              <li>
                <t>Compute the tests for well-formedness of the gadget polynomials. That is, for
every <tt>i</tt> in <tt>[H]</tt>:  </t>
                <ul spacing="normal">
                  <li>Let <tt>t = query_rand[i]</tt>. Check if <tt>t^(P_i) == 1</tt>: If so, then raise
ERR_ABORT and halt. (This prevents the verifier from inadvertently leaking
a gadget output in the verifier message.)</li>
                  <li>Let <tt>y_i = poly_gadget_i(t)</tt>.</li>
                  <li>For each <tt>j</tt> in <tt>[0,L_i)</tt> let <tt>x_i[j-1] = poly_wire_i[j-1](t)</tt>.</li>
                </ul>
              </li>
            </ol>
            <t>The verifier message is the vector <tt>verifier = [v] + x_1 + [y_1] + ... + x_H +
[y_H]</tt>.</t>
          </section>
          <section anchor="decision">
            <name>Decision</name>
            <t>On input of vector <tt>verifier</tt>, the verifier decides if the input is valid as
follows:</t>
            <ol spacing="normal" type="1"><li>Parse <tt>verifier</tt> into <tt>v</tt>, <tt>x_1</tt>, <tt>y_1</tt>, ..., <tt>x_H</tt>, <tt>y_H</tt> as defined in
<xref target="flp-generic-construction-query"/>.</li>
              <li>
                <t>Check for well-formedness of the gadget polynomials. For every <tt>i</tt> in <tt>[H]</tt>:  </t>
                <ul spacing="normal">
                  <li>Let <tt>z = G_i(x_i)</tt>. That is, evaluate the circuit <tt>G_i</tt> on <tt>x_i</tt> and set
<tt>z</tt> to the output.</li>
                  <li>If <tt>z != y_i</tt>, then return <tt>False</tt> and halt.</li>
                </ul>
              </li>
              <li>Return <tt>True</tt> if <tt>v == 0</tt> and <tt>False</tt> otherwise.</li>
            </ol>
          </section>
          <section anchor="encoding">
            <name>Encoding</name>
            <t>The FLP encoding and truncation methods invoke <tt>Valid.encode</tt>,
<tt>Valid.truncate</tt>, and <tt>Valid.decode</tt> in the natural way.</t>
          </section>
        </section>
      </section>
      <section anchor="prio3-instantiations">
        <name>Instantiations</name>
        <t>This section specifies instantiations of Prio3 for various measurement types.
Each uses <tt>FlpGeneric</tt> as the FLP (<xref target="flp-generic"/>) and is determined by a
validity circuit (<xref target="flp-generic-valid"/>) and a PRG (<xref target="prg"/>). 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 PrgSha3 (<xref target="prg-sha3"/>) as its PRG. 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 Mul(x, y):
    return x * y
]]></artwork>
          <t>The validity circuit is defined as</t>
          <artwork><![CDATA[
def Count(inp: Vec[Field64]):
    return Mul(inp[0], inp[0]) - inp[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>INPUT_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 PrgSha3 (<xref target="prg-sha3"/>) as its PRG. 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(Sum, measurement: Integer):
    if 0 > measurement or measurement >= 2 ** Sum.INPUT_LEN:
        raise ERR_INPUT

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

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

def decode(Sum, 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 Range2(x):
    return x^2 - x
]]></artwork>
          <t>The validity circuit is defined as</t>
          <artwork><![CDATA[
def Sum(inp: Vec[Field128], joint_rand: Vec[Field128]):
    out = Field128(0)
    r = joint_rand[0]
    for x in inp:
        out += r * Range2(x)
        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>INPUT_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="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 PrgSha3 (<xref target="prg-sha3"/>) as its PRG. Its validity
circuit, denoted <tt>Histogram</tt>, uses <tt>Field128</tt> (<xref target="fields"/>) as its finite field.
Let <tt>length</tt> be the number of histogram buckets. The measurement is encoded as a
one-hot vector representing the bucket into which the measurement falls:</t>
          <artwork><![CDATA[
def encode(Histogram, measurement: Integer):
    encoded = [Field128(0)] * length
    encoded[measurement] = Field128(1)
    return encoded

def truncate(Histogram, inp: Vec[Field128]):
    return inp

def decode(Histogram, output: Vec[Field128], _num_measurements):
    return [bucket_count.as_unsigned() for bucket_count in output]
]]></artwork>
          <t>The validity circuit uses <tt>Range2</tt> (see <xref target="prio3sum"/>) as its single gadget. It
checks for one-hotness in two steps, as follows:</t>
          <artwork><![CDATA[
def Histogram(inp: Vec[Field128],
              joint_rand: Vec[Field128],
              num_shares: Unsigned):
    # Check that each bucket is one or zero.
    range_check = Field128(0)
    r = joint_rand[0]
    for x in inp:
        range_check += r * Range2(x)
        r *= joint_rand[0]

    # Check that the buckets sum to 1.
    sum_check = -Field128(1) * Field128(num_shares).inv()
    for b in inp:
        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 input 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>[Range2]</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>GADGET_CALLS</tt></td>
                <td align="left">
                  <tt>[length]</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>INPUT_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 inputs are prefixed by
each candidate prefix.</t>
      <t>This functionality is the core component of the Poplar protocol <xref target="BBCGGI21"/>,
which was designed to compute the heavy hitters over a set of input strings. At
a high level, the protocol works as follows.</t>
      <ol spacing="normal" type="1"><li>Each Client splits its input string into input shares and sends one share to
each Aggregator.</li>
        <li>The Aggregators agree on an initial set of candidate prefixes, say <tt>0</tt> and
<tt>1</tt>.</li>
        <li>The Aggregators evaluate the VDAF on each set of input shares and aggregate
the recovered output shares. The aggregation parameter is the set of
candidate prefixes.</li>
        <li>The Aggregators send their aggregate shares to the Collector, who combines
them to recover the counts of each candidate prefix.</li>
        <li>Let <tt>H</tt> denote the set of prefixes that occurred at least <tt>t</tt> times. If the
prefixes all have length <tt>BITS</tt>, then <tt>H</tt> is the set of <tt>t</tt>-heavy-hitters.
Otherwise compute the next set of candidate prefixes, e.g., for each <tt>p</tt> in
<tt>H</tt>, add <tt>p || 0</tt> and <tt>p || 1</tt> to the set. Repeat step 3 with the new set of
candidate prefixes.</li>
      </ol>
      <t>Poplar1 is constructed from an "Incremental Distributed Point Function (IDPF)",
a primitive described by <xref target="BBCGGI21"/> that generalizes the notion of a
Distributed Point Function (DPF) <xref target="GI14"/>. Briefly, a DPF is used to distribute
the computation of a "point function", a function that evaluates to zero on
every input except at a programmable "point". The computation is distributed in
such a way that no one party knows either the point or what it evaluates to.</t>
      <t>An IDPF generalizes this "point" to a path on a full binary tree from the root
to one of the leaves. It is evaluated on an "index" representing a unique node
of the tree. If the node is on the programmed path, then the function evaluates
to a non-zero value; otherwise it evaluates to zero. This structure allows an
IDPF to provide the functionality required for the above protocol: To compute
the hit count for an index, just evaluate each set of IDPF shares at that index
and add up the results.</t>
      <t>Consider the sub-tree constructed from a set of input strings and a target
threshold <tt>t</tt> by including all indices that prefix at least <tt>t</tt> of the input
strings. We shall refer to this structure as the "prefix tree" for the batch of
inputs and target threshold. To compute the <tt>t</tt>-heavy hitters for a set of
inputs, the Aggregators and Collector first compute the prefix tree, then
extract the heavy hitters from the leaves of this tree. (Note that the prefix
tree may leak more information about the set than the heavy hitters themselves;
see <xref target="agg-param-privacy"/> for details.)</t>
      <t>Poplar1 composes an IDPF with the "secure sketching" protocol of <xref target="BBCGGI21"/>.
This protocol ensures that evaluating a set of input shares on a unique set of
candidate prefixes results in shares of a "one-hot" vector, i.e., a vector that
is zero everywhere except for one element, which is equal to one.</t>
      <t>The remainder of this section is structured as follows. IDPFs are defined in
<xref target="idpf"/>; a concrete instantiation is given <xref target="idpf-poplar"/>. The Poplar1 VDAF is
defined in <xref target="poplar1-construction"/> in terms of a generic IDPF. Finally, a
concrete instantiation of Poplar1 is specified in <xref target="poplar1-inst"/>;
test vectors can be found in <xref target="test-vectors"/>.</t>
      <section anchor="idpf">
        <name>Incremental Distributed Point Functions (IDPFs)</name>
        <t>An IDPF is defined over a domain of size <tt>2^BITS</tt>, where <tt>BITS</tt> is constant
defined by the IDPF. Indexes into the IDPF tree are encoded as integers in range
<tt>[0, 2^BITS)</tt>. The Client specifies an index <tt>alpha</tt> and a vector of
values <tt>beta</tt>, one for each "level" <tt>L</tt> in range <tt>[0, BITS)</tt>. The key generation
algorithm generates one IDPF "key" for each Aggregator. When evaluated at level
<tt>L</tt> and index <tt>0 &lt;= prefix &lt; 2^L</tt>, each IDPF key returns an additive share of
<tt>beta[L]</tt> if <tt>prefix</tt> is the <tt>L</tt>-bit prefix of <tt>alpha</tt> and shares of zero
otherwise.</t>
        <t>An index <tt>x</tt> is defined to be a prefix of another index <tt>y</tt> as follows. Let
<tt>LSB(x, N)</tt> denote the least significant <tt>N</tt> bits of positive integer <tt>x</tt>. By
definition, a positive integer <tt>0 &lt;= x &lt; 2^L</tt> is said to be the length-<tt>L</tt>
prefix of positive integer <tt>0 &lt;= y &lt; 2^BITS</tt> if <tt>LSB(x, L)</tt> is equal to the most
significant <tt>L</tt> bits of <tt>LSB(y, BITS)</tt>, For example, 6 (110 in binary) is the
length-3 prefix of 25 (11001), but 7 (111) is not.</t>
        <t>Each of the programmed points <tt>beta</tt> is a vector of elements of some finite
field. We distinguish two types of fields: One for inner nodes (denoted
<tt>Idpf.FieldInner</tt>), and one for leaf nodes (<tt>Idpf.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>Idpf.Vec</tt> as shorthand for the type
<tt>Union[Vec[Vec[Idpf.FieldInner]], Vec[Vec[Idpf.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>
            <tt>Idpf.gen(alpha: Unsigned, beta_inner: Vec[Vec[Idpf.FieldInner]], beta_leaf:
Vec[Idpf.FieldLeaf], binder: Bytes, rand: Bytes["Idpf.RAND_SIZE"]) -&gt; Tuple[
Bytes, Vec[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.</li>
          <li>
            <t><tt>Idpf.eval(agg_id: Unsigned, public_share: Bytes, key: Bytes, level:
Unsigned, prefixes: Tuple[Unsigned, ...], binder: Bytes) -&gt; Idpf.Vec</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 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>Vec[Vec[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>Vec[Vec[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 PRG'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>
          </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>Prg</tt>
(<xref target="prg"/>). 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>Prg.SEED_SIZE</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>RAND_SIZE</tt></td>
              <td align="left">
                <tt>Prg.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>Prep</tt></td>
              <td align="left">
                <tt>Tuple[Bytes, Unsigned, Idpf.Vec]</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>OutShare</tt></td>
              <td align="left">
                <tt>Idpf.Vec</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>AggResult</tt></td>
              <td align="left">
                <tt>Vec[Unsigned]</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 input is 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. Function <tt>encode_input_shares</tt> is defined in <xref target="poplar1-auxiliary"/>.</t>
          <figure anchor="poplar1-mes2inp">
            <name>The sharding algorithm for Poplar1.</name>
            <artwork><![CDATA[
def measurement_to_input_shares(Poplar1, measurement, nonce, rand):
    l = Poplar1.Prg.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)

    prg = Poplar1.Prg(
        k_shard,
        Poplar1.domain_separation_tag(USAGE_SHARD_RAND),
        b'',
    )

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

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

    # Generate correlated randomness used by the Aggregators to
    # compute a sketch over their output shares. PRG seeds are
    # used to encode shares of the `(a, b, c)` triples.
    # (See [BBCGGI21, Appendix C.4].)
    corr_offsets = vec_add(
        Poplar1.Prg.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.Prg.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.Prg.expand_into_vec(
            Poplar1.Idpf.FieldLeaf,
            corr_seed[0],
            Poplar1.domain_separation_tag(USAGE_CORR_LEAF),
            byte(0) + nonce,
            3,
        ),
        Poplar1.Prg.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 = prg.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.
    return (public_share,
            Poplar1.encode_input_shares(
                keys, corr_seed, corr_inner, corr_leaf))
]]></artwork>
          </figure>
        </section>
        <section anchor="preparation-1">
          <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>
          <t>The algorithms below make use of the auxiliary function <tt>decode_input_share()</tt>
defined in <xref target="poplar1-auxiliary"/>.</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) = \
        Poplar1.decode_input_share(input_share)
    Field = Poplar1.Idpf.current_field(level)

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

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

    # Get shares of the correlated randomness for computing the
    # Aggregator's share of the sketch for the given level of the IDPF
    # tree.
    if level < Poplar1.Idpf.BITS - 1:
        corr_prg = Poplar1.Prg(
            corr_seed,
            Poplar1.domain_separation_tag(USAGE_CORR_INNER),
            byte(agg_id) + nonce,
        )
        # Fast-forward the PRG state to the current level.
        corr_prg.next_vec(Field, 3 * level)
    else:
        corr_prg = Poplar1.Prg(
            corr_seed,
            Poplar1.domain_separation_tag(USAGE_CORR_LEAF),
            byte(agg_id) + nonce,
        )
    (a_share, b_share, c_share) = corr_prg.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_prg = Poplar1.Prg(
        verify_key,
        Poplar1.domain_separation_tag(USAGE_VERIFY_RAND),
        nonce + to_be_bytes(level, 2),
    )
    verify_rand = verify_rand_prg.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 = sketch_share \
                + [A_share, B_share, Field(agg_id)] \
                + out_share
    return (b'ready', level, prep_mem)

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

    # Aggregators exchange masked input values (step (3.)
    # of [BBCGGI21, Appendix C.4]).
    if step == b'ready' and opt_sketch == None:
        sketch_share, prep_mem = prep_mem[:3], prep_mem[3:]
        return ((b'sketch round 1', level, prep_mem),
                Field.encode_vec(sketch_share))

    # Aggregators exchange evaluated shares (step (4.)).
    elif step == b'sketch round 1' and opt_sketch != None:
        prev_sketch = Field.decode_vec(opt_sketch)
        if len(prev_sketch) == 0:
            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),
                Field.encode_vec(sketch_share))

    elif step == b'sketch round 2' and opt_sketch != None:
        if len(opt_sketch) == 0:
            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(Field.decode_vec(prep_shares[0]),
                     Field.decode_vec(prep_shares[1]))
    if len(sketch) == 3:
        return Field.encode_vec(sketch)
    elif len(sketch) == 1:
        if sketch == Field.zeros(1):
            # In order to reduce communication overhead, let the
            # empty string denote a successful sketch verification.
            return b''
        else:
            raise ERR_VERIFY # sketch verification failed
    else:
        return 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-1">
          <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 out_shares_to_agg_share(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 Field.encode_vec(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 agg_shares_to_result(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, Field.decode_vec(agg_share))
    return list(map(lambda x: x.as_unsigned(), agg))
]]></artwork>
          </figure>
        </section>
        <section anchor="poplar1-auxiliary">
          <name>Auxiliary Functions</name>
          <section anchor="message-serialization-1">
            <name>Message Serialization</name>
            <t>This section defines methods for serializing input shares, as required by the
<tt>Vdaf</tt> interface. Optional serialization of the aggregation parameter is also
specified below.</t>
            <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>
            <artwork><![CDATA[
def encode_input_shares(Poplar1, keys,
                        corr_seed, corr_inner, corr_leaf):
    input_shares = []
    for (key, seed, inner, leaf) in zip(keys,
                                        corr_seed,
                                        corr_inner,
                                        corr_leaf):
        encoded = Bytes()
        encoded += key
        encoded += seed
        encoded += Poplar1.Idpf.FieldInner.encode_vec(inner)
        encoded += Poplar1.Idpf.FieldLeaf.encode_vec(leaf)
        input_shares.append(encoded)
    return input_shares

def decode_input_share(Poplar1, encoded):
    l = Poplar1.Idpf.KEY_SIZE
    key, encoded = encoded[:l], encoded[l:]
    l = Poplar1.Prg.SEED_SIZE
    corr_seed, encoded = encoded[:l], encoded[l:]
    l = Poplar1.Idpf.FieldInner.ENCODED_SIZE \
        * 2 * (Poplar1.Idpf.BITS - 1)
    encoded_corr_inner, encoded = encoded[:l], encoded[l:]
    corr_inner = Poplar1.Idpf.FieldInner.decode_vec(
        encoded_corr_inner)
    l = Poplar1.Idpf.FieldLeaf.ENCODED_SIZE * 2
    encoded_corr_leaf, encoded = encoded[:l], encoded[l:]
    corr_leaf = Poplar1.Idpf.FieldLeaf.decode_vec(
        encoded_corr_leaf)
    if len(encoded) != 0:
        raise ERR_INPUT
    return (key, corr_seed, corr_inner, corr_leaf)

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>
          </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 PRG for deriving the output shares, as well as a variety
of other artifacts used internally. For performance reasons, we instantiate
this object using PrgFixedKeyAes128 (<xref target="prg-fixed-key-aes128"/>). See
<xref target="prg-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>Prg.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[:PrgFixedKeyAes128.SEED_SIZE],
        rand[PrgFixedKeyAes128.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):
    prg = PrgFixedKeyAes128(seed, format_dst(1, 0, 0), binder)
    s = [
        prg.next(PrgFixedKeyAes128.SEED_SIZE),
        prg.next(PrgFixedKeyAes128.SEED_SIZE),
    ]
    b = prg.next(1)[0]
    t = [Field2(b & 1), Field2((b >> 1) & 1)]
    return (s, t)

def convert(IdpfPoplar, level, seed, binder):
    prg = PrgFixedKeyAes128(seed, format_dst(1, 0, 1), binder)
    next_seed = prg.next(PrgFixedKeyAes128.SEED_SIZE)
    Field = IdpfPoplar.current_field(level)
    w = prg.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 = PrgFixedKeyAes128.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
PrgSha3 (<xref target="prg-sha3"/>). This VDAF is suitable for any positive value of <tt>BITS</tt>.
Test vectors can be found in <xref target="test-vectors"/>.</t>
      </section>
    </section>
    <section anchor="security">
      <name>Security Considerations</name>
      <t>VDAFs have two essential security goals:</t>
      <ol spacing="normal" type="1"><li>Privacy: An attacker that controls the network, the Collector, and a subset
of Clients and Aggregators learns nothing about the measurements of honest
Clients beyond what it can deduce from the aggregate result.</li>
        <li>Robustness: An attacker that controls the network and a subset of Clients
cannot cause the Collector to compute anything other than the aggregate of
the measurements of honest Clients.</li>
      </ol>
      <t>Formal definitions of privacy and robustness can be found in <xref target="DPRS23"/>. A VDAF
is the core cryptographic primitive of a protocol that achieves the above
privacy and robustness goals. It is not sufficient on its own, however. The
application will need to assure a few security properties, for example:</t>
      <ul spacing="normal">
        <li>Securely distributing the long-lived parameters, in particular the
verification key.</li>
        <li>
          <t>Establishing secure channels:  </t>
          <ul spacing="normal">
            <li>Confidential and authentic channels among Aggregators, and between the
Aggregators and the Collector; and</li>
            <li>Confidential and Aggregator-authenticated channels between Clients and
Aggregators.</li>
          </ul>
        </li>
        <li>Enforcing the non-collusion properties required of the specific VDAF in use.</li>
      </ul>
      <t>In such an environment, a VDAF provides the high-level privacy property
described above: The Collector learns only the aggregate measurement, and
nothing about individual measurements aside from what can be inferred from the
aggregate result.  The Aggregators learn neither individual measurements nor the
aggregate result.  The Collector is assured that the aggregate statistic
accurately reflects the inputs as long as the Aggregators correctly executed
their role in the VDAF.</t>
      <t>On their own, VDAFs do not mitigate Sybil attacks <xref target="Dou02"/>. In this attack, the
adversary observes a subset of input shares transmitted by a Client it is
interested in. It allows the input shares to be processed, but corrupts and
picks bogus measurements for the remaining Clients.  Applications can guard
against these risks by adding additional controls on report submission,
such as Client authentication and rate limits.</t>
      <t>VDAFs do not inherently provide differential privacy <xref target="Dwo06"/>.  The VDAF approach
to private measurement can be viewed as complementary to differential privacy,
relying on non-collusion instead of statistical noise to protect the privacy of
the inputs.  It is possible that a future VDAF could incorporate differential
privacy features, e.g., by injecting noise before the sharding stage and
removing it after unsharding.</t>
      <section anchor="requirements-for-the-verification-key">
        <name>Requirements for the Verification Key</name>
        <t>The Aggregators are responsible for exchanging the verification key in advance
of executing the VDAF. Any procedure is acceptable as long as the following
conditions are met:</t>
        <ol spacing="normal" type="1"><li>To ensure robustness of the computation, the Aggregators <bcp14>MUST NOT</bcp14> reveal the
verification key to the Clients. Otherwise, a malicious Client might be able
to exploit knowledge of this key to craft an invalid report that would be
accepted by the Aggregators.</li>
          <li>To ensure privacy of the measurements, the Aggregators <bcp14>MUST</bcp14> commit to the
verification key prior to processing reports generated by Clients. Otherwise,
a malicious Aggregator may be able to craft a verification key that, for a
given report, causes an honest Aggregator to leak information about the
measurement during preparation.</li>
        </ol>
        <t>Meeting these conditions is required in order to leverage security analysis in
the framework of <xref target="DPRS23"/>. Their definition of robustness allows the attacker,
playing the role of a cohort of malicious Clients, to submit arbitrary reports
to the Aggregators and eavesdrop on their communications as they process them.
Security in this model is achievable as long as the verification key is kept
secret from the attacker.</t>
        <t>The privacy definition of <xref target="DPRS23"/> considers an active attacker that controls
the network and a subset of Aggregators; in addition, the attacker is allowed to
choose the verification key used by each honest Aggregator over the course of
the experiment. Security is achievable in this model as long as the key is
picked at the start of the experiment, prior to any reports being generated.
(The model also requires nonces to be generated at random; see
<xref target="nonce-requirements"/> below.)</t>
        <t>Meeting these requirements is relatively straightforward. For example, the
Aggregators may designate one of their peers to generate the verification key
and distribute it to the others. To assure Clients of key commitment, the
Clients and (honest) Aggregators could bind reports to a shared context string
derived from the key. For instance, the "task ID" of DAP <xref target="DAP"/> could be set to
the hash of the verification key; then as long as honest Aggregators only
consume reports for the task indicated by the Client, forging a new key after
the fact would reduce to finding collisions in the underlying hash function.
(Keeping the key secret from the Clients would require the hash function to be
one-way.) However, since rotating the key implies rotating the task ID, this
scheme would not allow key rotation over the lifetime of a task.</t>
      </section>
      <section anchor="nonce-requirements">
        <name>Requirements for the Nonce</name>
        <t>The sharding and preparation steps of VDAF execution depend on a nonce
associated with the Client's report. To ensure privacy of the underlying
measurement, the Client <bcp14>MUST</bcp14> generate this nonce using a CSPRNG. This is
required in order to leverage security analysis for the privacy definition of
<xref target="DPRS23"/>, which assumes the nonce is chosen at random prior to generating the
report.</t>
        <t>Other security considerations may require the nonce to be non-repeating. For
example, to achieve differential privacy it is necessary to avoid "over
exposing" a measurement by including it too many times in a single batch or
across multiple batches. It is <bcp14>RECOMMENDED</bcp14> that the nonce generated by the
Client be used by the Aggregators for replay protection.</t>
      </section>
      <section anchor="requirements-for-the-aggregation-parameters">
        <name>Requirements for the Aggregation Parameters</name>
        <t>As described in <xref target="sec-daf-validity-scopes"/> and <xref target="sec-vdaf-validity-scopes"/>
respectively, DAFs and VDAFs may impose restrictions on the re-use of input
shares. This is to ensure that correlated randomness provided by the Client
through the input share is not used more than once, which might compromise
confidentiality of the Client's measurements.</t>
        <t>Protocols that make use of VDAFs therefore <bcp14>MUST</bcp14> call <tt>Vdaf.is_valid</tt>
on the set of all aggregation parameters used for a Client's input share, and
only proceed with the preparation and aggregation phases if that function call
returns <tt>True</tt>.</t>
        <section anchor="agg-param-privacy">
          <name>Additional Privacy Considerations</name>
          <t>Aggregating a batch of reports multiple times, each time with a different
aggregation parameter, could result in information leakage beyond what is used
by the application.</t>
          <t>For example, when Poplar1 is used for heavy hitters, the Aggregators learn not
only the heavy hitters themselves, but also the prefix tree (as defined in
<xref target="poplar1"/>) computed along the way. Indeed, this leakage is inherent to any
construction that uses an IDPF (<xref target="idpf"/>) in the same way. Depending on the
distribution of the measurements, the prefix tree can leak a significant amount
of information about unpopular inputs. For instance, it is possible (though
perhaps unlikely) for a large set of non-heavy-hitter values to share a common
prefix, which would be leaked by a prefix tree with a sufficiently small
threshold.</t>
          <t>The only known, general-purpose approach to mitigating this leakage is via
differential privacy.</t>
          <ul empty="true">
            <li>
              <t>TODO(issue #94) Describe (or point to some description of) the central DP
mechanism for Poplar described in <xref target="BBCGGI21"/>.</t>
            </li>
          </ul>
        </section>
      </section>
      <section anchor="prg-vs-ro">
        <name>Pseudorandom Generators and Random Oracles</name>
        <t>The objects we describe in <xref target="prg"/> share a common interface, which we have
called Prg. However, these are not necessarily all modeled as cryptographic
Pseudorandom Generators in the security analyses of our protocols. Instead, most
of them are modeled as random oracles. For these use cases, we want to be
conservative in our assumptions, and hence prescribe PrgSha3 as the only
<bcp14>RECOMMENDED</bcp14> Prg instantiation.</t>
        <t>The one exception is the PRG used in the Idpf implementation IdpfPoplar
<xref target="idpf-poplar"/>. Here, a random oracle is not needed to prove security, and
hence a construction based on fixed-key AES <xref target="prg-fixed-key-aes128"/> can be
used. However, as PrgFixedKeyAes128 has been shown to be differentiable from
a random oracle <xref target="GKWWY20"/>, it is <bcp14>NOT RECOMMENDED</bcp14> to use it anywhere else.</t>
        <ul empty="true">
          <li>
            <t>OPEN ISSUE: We may want to drop the common interface for PRGs and random
oracles. See issue #159.</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>A codepoint for each (V)DAF in this document is defined in the table below. Note
that <tt>0xFFFF0000</tt> through <tt>0xFFFFFFFF</tt> are reserved for private use.</t>
      <table anchor="codepoints">
        <name>Unique identifiers for (V)DAFs.</name>
        <thead>
          <tr>
            <th align="left">Value</th>
            <th align="left">Scheme</th>
            <th align="left">Type</th>
            <th align="left">Reference</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">
              <tt>0x00000000</tt></td>
            <td align="left">Prio3Count</td>
            <td align="left">VDAF</td>
            <td align="left">
              <xref target="prio3count"/></td>
          </tr>
          <tr>
            <td align="left">
              <tt>0x00000001</tt></td>
            <td align="left">Prio3Sum</td>
            <td align="left">VDAF</td>
            <td align="left">
              <xref target="prio3sum"/></td>
          </tr>
          <tr>
            <td align="left">
              <tt>0x00000002</tt></td>
            <td align="left">Prio3Histogram</td>
            <td align="left">VDAF</td>
            <td align="left">
              <xref target="prio3histogram"/></td>
          </tr>
          <tr>
            <td align="left">
              <tt>0x00000003</tt> to <tt>0x00000FFF</tt></td>
            <td align="left">reserved for Prio3</td>
            <td align="left">VDAF</td>
            <td align="left">n/a</td>
          </tr>
          <tr>
            <td align="left">
              <tt>0x00001000</tt></td>
            <td align="left">Poplar1</td>
            <td align="left">VDAF</td>
            <td align="left">
              <xref target="poplar1-inst"/></td>
          </tr>
          <tr>
            <td align="left">
              <tt>0xFFFF0000</tt> to <tt>0xFFFFFFFF</tt></td>
            <td align="left">reserved</td>
            <td align="left">n/a</td>
            <td align="left">n/a</td>
          </tr>
        </tbody>
      </table>
      <ul empty="true">
        <li>
          <t>TODO Add IANA considerations for the codepoints summarized in <xref target="codepoints"/>.</t>
        </li>
      </ul>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <reference anchor="SP800-185">
          <front>
            <title>SHA-3 Derived Functions: cSHAKE, KMAC, TupleHash and ParallelHash</title>
            <author>
              <organization/>
            </author>
            <date year="2016" month="December"/>
          </front>
          <seriesInfo name="NIST Special Publication 800-185" value=""/>
        </reference>
        <reference anchor="FIPS202">
          <front>
            <title>SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions</title>
            <author>
              <organization/>
            </author>
            <date year="2015" month="August"/>
          </front>
          <seriesInfo name="NIST FIPS PUB 202" value=""/>
        </reference>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification.  These words are often capitalized.  This document defines these words as they should be interpreted in IETF documents.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications.  This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="RFC8446">
          <front>
            <title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
            <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
            <date month="August" year="2018"/>
            <abstract>
              <t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol. TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
              <t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961. This document also specifies new requirements for TLS 1.2 implementations.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8446"/>
          <seriesInfo name="DOI" value="10.17487/RFC8446"/>
        </reference>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="AGJOP21" target="https://ia.cr/2021/576">
          <front>
            <title>Prio+: Privacy Preserving Aggregate Statistics via Boolean Shares</title>
            <author initials="S." surname="Addanki">
              <organization/>
            </author>
            <author initials="K." surname="Garbe">
              <organization/>
            </author>
            <author initials="E." surname="Jaffe">
              <organization/>
            </author>
            <author initials="R." surname="Ostrovsky">
              <organization/>
            </author>
            <author initials="A." surname="Polychroniadou">
              <organization/>
            </author>
            <date year="2021"/>
          </front>
        </reference>
        <reference anchor="BBCGGI19" target="https://ia.cr/2019/188">
          <front>
            <title>Zero-Knowledge Proofs on Secret-Shared Data via Fully Linear PCPs</title>
            <author initials="D." surname="Boneh">
              <organization/>
            </author>
            <author initials="E." surname="Boyle">
              <organization/>
            </author>
            <author initials="H." surname="Corrigan-Gibbs">
              <organization/>
            </author>
            <author initials="N." surname="Gilboa">
              <organization/>
            </author>
            <author initials="Y." surname="Ishai">
              <organization/>
            </author>
            <date year="2019"/>
          </front>
          <seriesInfo name="CRYPTO 2019" value=""/>
        </reference>
        <reference anchor="BBCGGI21" target="https://ia.cr/2021/017">
          <front>
            <title>Lightweight Techniques for Private Heavy Hitters</title>
            <author initials="D." surname="Boneh">
              <organization/>
            </author>
            <author initials="E." surname="Boyle">
              <organization/>
            </author>
            <author initials="H." surname="Corrigan-Gibbs">
              <organization/>
            </author>
            <author initials="N." surname="Gilboa">
              <organization/>
            </author>
            <author initials="Y." surname="Ishai">
              <organization/>
            </author>
            <date year="2021"/>
          </front>
          <seriesInfo name="IEEE S&amp;P 2021" value=""/>
        </reference>
        <reference anchor="CGB17" target="https://dl.acm.org/doi/10.5555/3154630.3154652">
          <front>
            <title>Prio: Private, Robust, and Scalable Computation of Aggregate Statistics</title>
            <author initials="H." surname="Corrigan-Gibbs">
              <organization/>
            </author>
            <author initials="D." surname="Boneh">
              <organization/>
            </author>
            <date year="2017"/>
          </front>
          <seriesInfo name="NSDI 2017" value=""/>
        </reference>
        <reference anchor="Dou02" target="https://doi.org/10.1007/3-540-45748-8_24">
          <front>
            <title>The Sybil Attack</title>
            <author initials="J." surname="Douceur">
              <organization/>
            </author>
            <date year="2002"/>
          </front>
          <seriesInfo name="IPTPS 2002" value=""/>
        </reference>
        <reference anchor="DPRS23" target="https://ia.cr/2023/130">
          <front>
            <title>Verifiable Distributed Aggregation Functions</title>
            <author initials="H." surname="Davis">
              <organization/>
            </author>
            <author initials="C." surname="Patton">
              <organization/>
            </author>
            <author initials="M." surname="Rosulek">
              <organization/>
            </author>
            <author initials="P." surname="Schoppmann">
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="Dwo06" target="https://link.springer.com/chapter/10.1007/11787006_1">
          <front>
            <title>Differential Privacy</title>
            <author initials="C." surname="Dwork">
              <organization/>
            </author>
            <date year="2006"/>
          </front>
          <seriesInfo name="ICALP 2006" value=""/>
        </reference>
        <reference anchor="EPK14" target="https://dl.acm.org/doi/10.1145/2660267.2660348">
          <front>
            <title>RAPPOR: Randomized Aggregatable Privacy-Preserving Ordinal Response</title>
            <author initials="Ú." surname="Erlingsson">
              <organization/>
            </author>
            <author initials="V." surname="Pihur">
              <organization/>
            </author>
            <author initials="A." surname="Korolova">
              <organization/>
            </author>
            <date year="2014"/>
          </front>
          <seriesInfo name="CCS 2014" value=""/>
        </reference>
        <reference anchor="ENPA" target="https://covid19-static.cdn-apple.com/applications/covid19/current/static/contact-tracing/pdf/ENPA_White_Paper.pdf">
          <front>
            <title>Exposure Notification Privacy-preserving Analytics (ENPA) White Paper</title>
            <author>
              <organization/>
            </author>
            <date year="2021"/>
          </front>
        </reference>
        <reference anchor="GI14" target="https://link.springer.com/chapter/10.1007/978-3-642-55220-5_35">
          <front>
            <title>Distributed Point Functions and Their Applications</title>
            <author initials="N." surname="Gilboa">
              <organization/>
            </author>
            <author initials="Y." surname="Ishai">
              <organization/>
            </author>
            <date year="2014"/>
          </front>
          <seriesInfo name="EUROCRYPT 2014" value=""/>
        </reference>
        <reference anchor="GKWWY20" target="https://link.springer.com/chapter/10.1007/978-3-030-56880-1_28">
          <front>
            <title>Better concrete security for half-gates garbling (in the multi-instance setting)</title>
            <author>
              <organization/>
            </author>
            <date year="2020"/>
          </front>
          <seriesInfo name="CRYPTO 2020" value=""/>
        </reference>
        <reference anchor="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="13" month="March" 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-04"/>
        </reference>
      </references>
    </references>
    <?line 4019?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>The security considerations in <xref target="security"/> are based largely on the security
analysis of <xref target="DPRS23"/>. Thanks to Hannah Davis and Mike Rosulek, who lent their
time to developing definitions and security proofs.</t>
      <t>Thanks to Henry Corrigan-Gibbs, Armando Faz-Hernández, Simon Friedberger, Tim
Geoghegan, Brandon Pitman, Mariana Raykova, Jacob Rothstein, 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>
      <ul empty="true">
        <li>
          <t>NOTE Machine-readable test vectors can be found at
https://github.com/cfrg/draft-irtf-cfrg-vdaf/tree/main/poc/test_vec.</t>
        </li>
      </ul>
      <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>
        <artwork><![CDATA[
verify_key: "000102030405060708090a0b0c0d0e0f"
upload_0:
  measurement: 1
  nonce: "000102030405060708090a0b0c0d0e0f"
  public_share: >-
  input_share_0: >-
    3ead59ec98fe1c4f70171b7a5f0b5c731ae0c48b62f687b98e981a811540934d76db
    271df5a3a6e97105856c18576573
  input_share_1: >-
    000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
  round_0:
    prep_share_0: >-
      4c151ee49ef43488213d8945b7aff36fc979166c714bd4b07676eea77634a432
    prep_share_1: >-
      b5eae11b600bcb77827a46303c1e0f073ebc46fcdc9c3fe9aeeb4a5f09e9c163
    prep_message: >-
  out_share_0:
    - 3ead59ec98fe1c4f
  out_share_1:
    - c452a6136601e3b0
agg_share_0: >-
  3ead59ec98fe1c4f
agg_share_1: >-
  c452a6136601e3b0
agg_result: 1
]]></artwork>
      </section>
      <section numbered="false" anchor="testvec-prio3sum">
        <name>Prio3Sum</name>
        <artwork><![CDATA[
bits: 8
verify_key: "000102030405060708090a0b0c0d0e0f"
upload_0:
  measurement: 100
  nonce: "000102030405060708090a0b0c0d0e0f"
  public_share: >-
    d6ba304b5e6fb668b98629cbaa51b5e780000a045a98af5f34a4d71abb6b7885
  input_share_0: >-
    c61ac8678ff4456241ff7d9f2182d8b4d007ae72f80d4e7fba171b7f17cfa14aedfd
    10de4bb9180493872144743b8ac975d273e07b0a347f5f9af84a1573bcaa610f093d
    013ead7503e6ac003975ae0d840333d65e7f62c70d271360bd404b17d4116ba46a3e
    71edbddd6abc15c8aaedb1b8931350544a138497d10eaf77733800be917b08d87ed5
    38e3812cd447335f46fb984e2779b3324bc602c31fe4745c34c7c5251f13dc402760
    ce65c9a16fce5f171b98a1f3c33d8e44ea7ad1f02ab5fe7acc05187f160ef5692369
    a105f9a6339249936563891682f8ffa5690a479f9876c49a753e3e982c7186f74a19
    16ad2ad2b2f926fc47e6c9d1bdd5584e46d3b5d72f8f5a81b2a3fe181670bc75aafa
    c4c56c189c913b3b32cb6d21b246738301568c7d5c323a7b0aaa28747364b1d1b42f
    f9a01a13b40c1af75d7e965ec20e18ca729419dcb88b0428b329447ff0ab30337525
    a58e2a28ea47579fa7b44d490c3d050ad253e8633fe972c689259a7807d7d149b231
    69a26879be85183a23c00b58060fb09672a8d1197e30065d403d8578110ce5d9608f
    cc2479f61a94e83d66e1493f77963700f4660aa8d16a51b47920c1e7b9b39ede9dc1
    c4acad858bc1c66d2b813e2955a4a57106c7905cffd73cea619a58d339bd3e582280
    9d154d0f9343f49d14c755cecbb770f38b18cdc6928bba24f5f5409527de57bb249e
    fb5f673c18bd0481d87876e80b59a8805ff95d4d826162c511b54c91d62824c5af0d
    c0ec1bf8debfec0e5ba26682ba7179ec7e68806170fb04821f6625063d6b1a12a6a8
    423a6ee4b4561759978de0adce61db70a131840d3d52c1dd6c0e709c9c91236c15da
    49b468ffbc4ebf0505756aced52055d811753e463e2f0fdceb0bcbfa303132333435
    363738393a3b3c3d3e3f
  input_share_1: >-
    000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021
    22232425262728292a2b2c2d2e2f
  round_0:
    prep_share_0: >-
      5879339d691b9230058dd5b6fdcf804306454c963883a700ed8251ead70e6a6ddf
      5c02433a304d03f0280080a6eab201d6ba304b5e6fb668b98629cbaa51b5e7
    prep_share_1: >-
      a986cc6296e46dcfde722a4902307fbcba25e7e7175787207014a8a1972756b0af
      e901f95ba76723b68531c445e83d7680000a045a98af5f34a4d71abb6b7885
    prep_message: >-
      f6011479e21b4ef3146e0b849423e360
  out_share_0:
    - 6de9984430d882b37f9eb596feeee52e
  out_share_1:
    - f81667bbcf277d4c64614a6901111ad1
agg_share_0: >-
  6de9984430d882b37f9eb596feeee52e
agg_share_1: >-
  f81667bbcf277d4c64614a6901111ad1
agg_result: 100
]]></artwork>
      </section>
      <section numbered="false" anchor="testvec-prio3histogram">
        <name>Prio3Histogram</name>
        <artwork><![CDATA[
length: 4
verify_key: "000102030405060708090a0b0c0d0e0f"
upload_0:
  measurement: 2
  nonce: "000102030405060708090a0b0c0d0e0f"
  public_share: >-
    1a84cd1f7c84b403ef8471cc15158c84b21b5733b6f53176ed5b8d8174a288e9
  input_share_0: >-
    fb788fb4dd1ada7c27fa1c6bd2f3ba3de3ea9c976900e67a80152e8d81603d516d08
    98cddce70a38bc5e6228b1bc4b67b0c779b2b93e73b4da90cab872f0f51ccf5b5bbc
    e30773cb5b0227b1c52cb2de52087f365317fa8bb1e6c15c809096b02104cc2a4680
    88ec6c8ad9dd1289a98e750ee469d1c78fbc1796d9b7d225f7b9410596d0bf27a093
    14d240d91f8bd194d24fff76524c5044d0939b53ceb724b49d417fe853d707617baa
    0c75e2d107bfa90725d50bbd691ed65e0e93f946091dff046e2cdf2fef9a4586a3f0
    d4b69177b290d3e7cbea8f5d70dfc5376537f1952339366a834e97363f8e5a9fb0ab
    08ea5902d19e64aa4bef980fb007928cc319fbd2e7254df43c5b803bf0b9656b9484
    aa1f4354166af16282ba51722a5768ce718c895f7a0ed3b4cad2c23fe954d62d564f
    23f30388da09f1641be3efccff94303132333435363738393a3b3c3d3e3f
  input_share_1: >-
    000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021
    22232425262728292a2b2c2d2e2f
  round_0:
    prep_share_0: >-
      960cec2ab69f328cc5e790b8a65852d2bac43ed54fb150d487415d2795383f406f
      d58ffe957f8ee525b8f2407d3ce5d71a84cd1f7c84b403ef8471cc15158c84
    prep_share_1: >-
      6bf313d54960cd731e186f4759a7ad2d71916f8a508640739726528e260a458f22
      a5cf556e866033059eb5e147c974a8b21b5733b6f53176ed5b8d8174a288e9
    prep_message: >-
      6af47a4b7d91c14993d2a4d40c8d62d7
  out_share_0:
    - fb788fb4dd1ada7c27fa1c6bd2f3ba3d
    - e3ea9c976900e67a80152e8d81603d51
    - 6d0898cddce70a38bc5e6228b1bc4b67
    - b0c779b2b93e73b4da90cab872f0f51c
  out_share_1:
    - 0687704b22e52583bc05e3942d0c45c2
    - 1e15636896ff198563ead1727e9fc2ae
    - 95f767322318f5c727a19dd74e43b498
    - 5138864d46c18c4b096f35478d0f0ae3
agg_share_0: >-
  fb788fb4dd1ada7c27fa1c6bd2f3ba3de3ea9c976900e67a80152e8d81603d516d0898
  cddce70a38bc5e6228b1bc4b67b0c779b2b93e73b4da90cab872f0f51c
agg_share_1: >-
  0687704b22e52583bc05e3942d0c45c21e15636896ff198563ead1727e9fc2ae95f767
  322318f5c727a19dd74e43b4985138864d46c18c4b096f35478d0f0ae3
agg_result: [0, 0, 1, 0]
]]></artwork>
      </section>
      <section numbered="false" anchor="testvec-poplar1">
        <name>Poplar1</name>
        <section numbered="false" anchor="sharding-1">
          <name>Sharding</name>
          <artwork><![CDATA[
bits: 4
upload_0:
  measurement: 13
  nonce: "000102030405060708090a0b0c0d0e0f"
  public_share: >-
    cd54d2e61e2c14720170a3d0748e06e0e4c840af1d8e0138ed00fb1de353014616a6
    6a90d9354b159ab14f61f09acb60f5d3c1e2377edf5240b0fb106993aeff889dc28d
    c4f4a46b28bf94d09eae4d50600400ef9f73f2cad7894ab244d99bf5f3c05ab13163
    8160e01a201b4ac7e1b18f537d53eccea86864da5d27da48d2bca05bd663abd34490
    7e7337ea6211566c41178170957627d356f228061c4c72eca34a3dcacf9cc85721db
    a1810817f24f1c
  input_share_0: >-
    000102030405060708090a0b0c0d0e0f202122232425262728292a2b2c2d2e2f4b0b
    a3a61241315702f3cde47fd8b5f4e0db66ed4ff3002ac48fd1fa1b2728e2a014b567
    123ae545640b8719bd593ba44157b33f386d83b8f39e10db848e890073eaf40fc1b6
    eb4b01d14199c7e0e21a84f33805453858c2c9860fd9a328331729b22e6fc4fa38f2
    771ae81091410b3e
  input_share_1: >-
    101112131415161718191a1b1c1d1e1f303132333435363738393a3b3c3d3e3f64d7
    572ab3849f73e2ff3ea5657411e5217df4b7b12d19328d71c8dd4e70badc909776eb
    a6558717ac481ebacce4656d7aaeb7c37c251d5683c7eb83b5a3524801518da879a9
    d5e5a22e68d8a3decf69fa10e0ca6aad9f3f539afe6fbd19c924386334e2d237f5d2
    390805243ee3cc3e
]]></artwork>
        </section>
        <section numbered="false" anchor="preparation-aggregation-and-unsharding">
          <name>Preparation, Aggregation, and Unsharding</name>
          <artwork><![CDATA[
verify_key: "000102030405060708090a0b0c0d0e0f"
agg_param: (0, (0, 1))
upload_0:
  round_0:
    prep_share_0: >-
      4195a4c56e1260647413dc5fa0f1822844fb8750eea70573
    prep_share_1: >-
      7e530646b6adb0632367eb0b0eb39d1a79ec88f7bbc98f50
    prep_message: >-
      bfe8aa0b25c010c8977ac76baea42043bde71048aa7195c3
  round_1:
    prep_share_0: >-
      24a5193d7d5bf285
    prep_share_1: >-
      dd5ae6c281a40d7a
    prep_message: >-
  out_share_0:
    - e457b2981c956b15
    - 79813da9034552cd
  out_share_1:
    - 1da84d67e26a94ea
    - 897ec256fbbaad32
agg_share_0: >-
  e457b2981c956b1579813da9034552cd
agg_share_1: >-
  1da84d67e26a94ea897ec256fbbaad32
agg_result: [0, 1]
]]></artwork>
          <artwork><![CDATA[
verify_key: "000102030405060708090a0b0c0d0e0f"
agg_param: (1, (0, 1, 2, 3))
upload_0:
  round_0:
    prep_share_0: >-
      dda737bbd51e94c5a8ecd1b3276a402446ddcc2d21bbf6b7
    prep_share_1: >-
      74baf93771f3714c3b40466cb9cf19f180f48934c1f1db3d
    prep_message: >-
      506231f347120612e22c1820e2395a15c6d15662e2acd2f5
  round_1:
    prep_share_0: >-
      a30e360c7d7e51fc
    prep_share_1: >-
      5ef1c9f38181ae03
    prep_message: >-
  out_share_0:
    - 078e84648c4ae70c
    - ac7a8371234c4540
    - 69b3af8cdff3b459
    - 91579ac64d319d58
  out_share_1:
    - fa717b9b72b518f3
    - 55857c8edbb3babf
    - 984c50731f0c4ba6
    - 71a86539b1ce62a7
agg_share_0: >-
  078e84648c4ae70cac7a8371234c454069b3af8cdff3b45991579ac64d319d58
agg_share_1: >-
  fa717b9b72b518f355857c8edbb3babf984c50731f0c4ba671a86539b1ce62a7
agg_result: [0, 0, 0, 1]
]]></artwork>
          <artwork><![CDATA[
verify_key: "000102030405060708090a0b0c0d0e0f"
agg_param: (2, (0, 2, 4, 6))
upload_0:
  round_0:
    prep_share_0: >-
      675359765228af1fe557ab25196a1ad1399ad4c7c4affc66
    prep_share_1: >-
      c87431627147a136eac6fba1d3f4e6bcb57a9b2449f8fe21
    prep_message: >-
      2fc88ad8c36f5056ce1ea7c7ed5e018eee1470ec0da8fb88
  round_1:
    prep_share_0: >-
      621b1271c1ec7b4a
    prep_share_1: >-
      9fe4ed8e3d1384b5
    prep_message: >-
  out_share_0:
    - a05be48631d9376b
    - 66cac23e03c7ca6d
    - 882152745673ba29
    - 1d096863ef00faf5
  out_share_1:
    - 61a41b79cd26c894
    - 9b353dc1fb383592
    - 79dead8ba88c45d6
    - e5f6979c0fff050a
agg_share_0: >-
  a05be48631d9376b66cac23e03c7ca6d882152745673ba291d096863ef00faf5
agg_share_1: >-
  61a41b79cd26c8949b353dc1fb38359279dead8ba88c45d6e5f6979c0fff050a
agg_result: [0, 0, 0, 1]
]]></artwork>
          <artwork><![CDATA[
verify_key: "000102030405060708090a0b0c0d0e0f"
agg_param: (3, (1, 3, 5, 7, 9, 13, 15))
upload_0:
  round_0:
    prep_share_0: >-
      5d26d73b85e6c726830478fe973d8b4687dffaf324399a3e62962ab71a41841a12
      93b70acb36828229dd8ee4fb0d437c2270472054dcef8fba9eb43fb3bb18387cf1
      38d5e13f9a4207d7026e112fe3e51e9d88688e4cb3105308ec5a2cdd4364
    prep_share_1: >-
      9a8537c1e41bd3d693b03ec522278178bda4454014ba800f4bea45d9c500b51330
      0a144b10fc37e3e5cfdda0f698519ae6301c8d0b41f623c19b125d6fe35c76143e
      6ec8752a598cec3b5316a1782eac1584b8be9e15f93ad4ecd70c4061d77d
    prep_message: >-
      f7ab0efd69029bfd16b5b6c3ba640cbf4484403439f31a4ead807090e041392e55
      9dcb55db32ba650fad6c85f2a6941609a163ad5f1de6b37b3ac79c229f752ea32f
      a79d576af3cef3125684b2a71192342141272d62ac4b27f5c3676c3e1b62
  round_1:
    prep_share_0: >-
      537a1a1fcdbbb4042dac5afb5c995abef6ffcbf2cb8375a357fd6b4697c84a47
    prep_share_1: >-
      9a85e5e032444bfbd253a504a366a5410900340d347c8a5ca80294b96837b538
    prep_message: >-
  out_share_0:
    - 0f33eec522414e75f7094646ee1ca7c22baba5bac4a02ce4ab1e812e21a34211
    - 013454e2f0b4046dac7287eac25ae1c398c30e2f1797507b546eaa36bc67a454
    - e56e12917baff2b8eb367a2d9fca0fad3dfd86e24f320589202f23ce34816834
    - af5d42b895abad21f05f3e73924b4d45533d5f9c63542c71a3343e1bd97fa61b
    - 5a3348a91fc4111a88528cba84c009228b6a5817b6b541c077edfd801489ec38
    - 0a511695baad2eb33150a7e13950e35a19abd5bf1bef81533f0229c9c45f0164
    - 7dc5f3900c63255f1418d3af04abb642fc4f92b3cc25325bcc15e11caabf8038
  out_share_1:
    - decc113addbeb18a08f6b9b911e3583dd4545a453b5fd31b54e17ed1de5cbd6e
    - eccbab1d0f4bfb92538d78153da51e3c673cf1d0e868af84ab9155c943985b2b
    - 0891ed6e84500d4714c985d26035f052c202791db0cdfa76dfd0dc31cb7e974b
    - 3ea2bd476a5452de0fa0c18c6db4b2baacc2a0639cabd38e5ccbc1e426805964
    - 93ccb756e03beee577ad73457b3ff6dd7495a7e8494abe3f8812027feb761347
    - e4aee96a4552d14cceaf581ec6af1ca5e6542a40e4107eacc0fdd6363ba0fe1b
    - 703a0c6ff39cdaa0ebe72c50fb5449bd03b06d4c33dacda433ea1ee355407f47
agg_share_0: >-
  0f33eec522414e75f7094646ee1ca7c22baba5bac4a02ce4ab1e812e21a34211013454
  e2f0b4046dac7287eac25ae1c398c30e2f1797507b546eaa36bc67a454e56e12917baf
  f2b8eb367a2d9fca0fad3dfd86e24f320589202f23ce34816834af5d42b895abad21f0
  5f3e73924b4d45533d5f9c63542c71a3343e1bd97fa61b5a3348a91fc4111a88528cba
  84c009228b6a5817b6b541c077edfd801489ec380a511695baad2eb33150a7e13950e3
  5a19abd5bf1bef81533f0229c9c45f01647dc5f3900c63255f1418d3af04abb642fc4f
  92b3cc25325bcc15e11caabf8038
agg_share_1: >-
  decc113addbeb18a08f6b9b911e3583dd4545a453b5fd31b54e17ed1de5cbd6eeccbab
  1d0f4bfb92538d78153da51e3c673cf1d0e868af84ab9155c943985b2b0891ed6e8450
  0d4714c985d26035f052c202791db0cdfa76dfd0dc31cb7e974b3ea2bd476a5452de0f
  a0c18c6db4b2baacc2a0639cabd38e5ccbc1e42680596493ccb756e03beee577ad7345
  7b3ff6dd7495a7e8494abe3f8812027feb761347e4aee96a4552d14cceaf581ec6af1c
  a5e6542a40e4107eacc0fdd6363ba0fe1b703a0c6ff39cdaa0ebe72c50fb5449bd03b0
  6d4c33dacda433ea1ee355407f47
agg_result: [0, 0, 0, 0, 0, 1, 0]
]]></artwork>
        </section>
      </section>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA+y923bbSJYg+o6vQNFrxmSZpCX5mnJldsuy7FSlbakl2Tk5
bpcIkqCENEmwAFCyys7+kPN0vuWcH5t9i4gdAZCSnFXV3WuNVnc5SQJx2bFj
3y+9Xi+qsmqabset92mRTbJkOE3jF1lZFdlwWaXjeOfsrEjPkirL5/HL5XyE
/1G2omQ4LNILfO3FzstWNM5H82QGw4yLZFL1sqKa9EaT4qx3MU4mvY3H0Sip
0rO8uNqOs/kkj6JsUWzHVbEsq62Nje82tqKkSJPteP/o5GV0mRefzop8udiO
d18evYo+pVfw1Rh+nVdpMU+r3gucJYrKKpmPT5NpPoeZr9IyKmdJUZ3+dZlX
abkdz/NokW3HH6p81I3LvKiKdFLCf13N8D8+RlGyrM7zYjuKe1EMf7yDo2x0
nhTj+HU/fp7AbCX9lhdnyTz7G8EBlpWVo5y+T2dJNt2Oi+nwX7PFRb/87A/2
IrnIxvFunn9qGGX/GDanBhlnF2lxls6rcXKR/usZftkf5TN/xN3zAk4nX5yn
RXyYVFU+b1rfNF+OJ1OAqR5/hK8u6J17WVpNVk1xeJ5Np9liER+PzvPFYpbM
m+Z4lednU2/80j7+r2f0Iw0dzfNiBu9cpNsRPH18+HRjo7f59NE2vWqw7/jH
nd6D+AXg4AUgnUU0WDT88tNeN/7pzc5uNz5ZLqbpj0l5HsPJw/6LZDpNp/hF
i4YbA5oB1NNROhsCgLY2Nh/T9yUMnJaIetvx2/3jk/h4kY6yZBofLofTbMTo
LQvDVb7cPzze2thqWuMxIl2C6HiYFrNlRe/2niclrNuubO9zlcJTcJl6B8tq
saz03XEL3VmewQ3AZT5qXiauIz589xwe2YJLAz9oWO68+vPB4damv8rDIsvv
weIAksnoCv5NYdSLbH5mr3KKe6gAi7JRGV9kSfw8z6dpMo+PAfFTWaC9G/TX
g2sLh3Hcj3fG42T+KfO//6kfv0qKYep/u9eP/5xMJsG3R/34AMhLflF+uvJ/
2enHh/n0CtA0n2fJOF8qSMH+N3mbCVyRajs+r6pFuX3/fpb0R8V9/Pn+oyeP
ESrPn+++erW/+Z0Plv+dFnnvp3l+OU3HZymAJc8nZQynfpyOCiAptPcxXNgq
IZi8XE6nV/HrbJ4mcNF2D9eB5QWQCqBB57XtP8+vpsH2f+wDOSiKDK5S71U2
HJb+z28Bktl0mCf+17/04/3yPMk8iGx+V0Oa3aNfDk8O3G+roLX53f3Np08d
tEIkep2dnVeXKf5vfJKOzufZX5dpGQP6MWIBDv2YJhdX8Y9ZBTT5vyBwBF00
cPb39vbi4/95eCNk2th8guDZffV880n9gm0bMHTjo3wId7hL1/54lEyJg+7m
s4WQhjifNN68NSC7BgweRC0yPKlTkOMX++6XcK/jaT8ZzfpA1O+P8+z+5kb/
Efzdf7D56OHjBxt9+vfRFsLgRb4MSeHJOWzlaphN452qSkaf1mzmz30cYJQu
C2+9QM9q53N4AtTO/lRbcJ7RamGlmxsbT+4/6D16uNF7+OjJw6e9p6dbD2mp
h0fHWw/8td5OsFl3KMjNg7PY7WsubL9+0we8KJfT9JP//WE/ZKorUfDB/c0H
G7Sny3zjsb+lFxmQ1QIkBWJhTOnXLB0W+QKFKv8A6pxxf3fn9aH7KVzaNJt/
6peLAnhJWiBvvw+S0gKuvz2Szc0nT5/A66ebuPC9w582H/oLP9o5PDw4AiYA
tyWfZX9T50AHJHvpKa51UIyzOWzzKC0XcELpmn3+//9PP94rYJlnZRmeyHs4
qOxckFCznJ/yIp/mF4l/mx7WSevusfvh+su0ufnw0f2tx483th4/6eO/Dx4S
vd17e7jjw2Tv8wJQpUjjt3kFiCrCiIHEQvFvAMMVMe02jtKJfz7PgKQcJou0
aHnLX0HeRjlIo5vf9UokQqP+aDzvJYsFy2n38b9k8tI8eX+0LBDN7vMb8PUc
bnvVq4pkBCu6vxhP7uNSTmklp7SSPnyJGwUW/DDEWnf7DvNsroQiop5AVLIi
3lHrWHPWt2KU9dPce3d0QMxy9Zlej+7fPXnae9B7/HCr9+jR1tZG79HpA5Ie
X/3088+/bG14u3+eIqOMAYIobqSwGIBtVl0RTz1PppMe8ocyPgM5CjE4bmfz
uAIyO1tOq6wHmwO5c4TvVRX83FGQKevX/dUyr1Hhn5Lqb/6X/6sf/5zMz2pv
/5yGXwJYfwnEsY3Vwof89q0A3XgAoHz89ClI46dbdGkOgBdm85N0ms7SCpRI
D634x9j+2mpaZ7iWSQY6YP65V+bLYpT2QH8t+7P8b6D4JHSLKxCJP2UVYPwM
qA5cgfJ+ZSaAL0HrIMS9n9Pk/fNqNsWF3nmfjDeJWN/xmSUKBNP0Mx44yAOr
6Pcdjex3FPxB8IaRz5M5f28R+7HM9I2QfgDE4NGTDWKgIO70er04GZZ4u0G7
PjnPyhgAs5zBQuNxWo7g8gKG3oafxm20D5QdEI+iSTLLprR9RukF6OpX8aLI
QT/PpyxcjkhuQvRPrMhUOmUlBwU5XgLORbM0QZqJSyv7SDnKVA0FojwuODub
w8KqPE7nRGCr8wQFtTKe5jgDPFfFoPiUVQRHbGfEDSDJhanSz3BL8VbiRTTD
x+fwdFlNr7pwNqCzZ+MlnKJeEBoz4nmKI5RpOo+HV0Dfrsygcq9HMHMB+lRF
n0rQvAFhZiBQEsRiUGzzS/wp4tdK3McYKMeoirNJnMSzBMhkli8BKkU8Q4PE
fJKdLVGJGU0zPLJyOZyheD6G2UF3RC0UIRBf5svpOAa+AseAqwHNL5uPQODE
sR3c+YE+o8UsG49BWo/uoBGmyMdLOl9EkjReDkE7EMzGvRgzDSzxE8Auq2iG
cQpQWkyTCnVYOmwFMng1miIS90oQoQHW5+k8hx+Sbnx5nlZo7FiQph6fwzDV
eVzB7RnT1nHGYXoOohl8gBUwCgGKlFdllc7okGlQQhM4GMBqgAySU7p+iFPT
ZNGFY73EI+vCaKD6pPPYqtuwUQIcvHmRTJeE+nAasn7iXepZBjJiaYnkvoSd
w+pZXQBovswRrxIkB133O0BIMWAeAhAOkAsgKHv25sh5hj6dQA58N6l4/8FI
M9LhLmGz+M4nUIABotnoPMbrV8qRZUWk30H0XaI9Y5aXeDRVOqdrk8A4VzjM
2RLWFU+W1ZIu2kU6zRdyjISyarB+zLYWEGx4xXdjNEEBgtDkyzI5AzgAzVue
nSM8GDUvEFlKuLYZGjsA+ijTAW3KCYfTWReOEPYAa+LNMLRx3SguJcXonGhI
fAZvzw38ANjjjNYURfsAGbqTWbVkWaPL3FbhpJB5AGuGlgKgXRliNtz9dEz3
xlyVyJGobpz2z/pdA+O8YDJYPxdcK4GXAA1zXMKRRxMkvaI0LtIccARkg4sU
EGaBjBYEgLHd1TiDnZaA1oDXQAUMumvUiRqpKKxtyuQMmRjAaQUZi0ew5nE6
RbMkHSsif2puufdkbUhz1MzbAOBvcK/wEXYKYCjyZHSeEk2rkM3AF3CpgCwA
2YuX8zFPGBfLYQF4AzO2xoplRjJs3H5x2GnFX76QivTbb6h0ARrBQZWLNPkE
6wC0RWaZ+MSdIBXLlY70yNMrc1OFZwg8cTHjFIagi8+Hi+jjIKc5Et5UgBSc
FnMOD24hgSUoDxF4cEvKdHoVoZRdIO6N+7FHLbK5PeVp9imNWZuC/ZOm9dtv
gHyJXAZkKPBOGc1zGDSeFPkMr286nfaQBhD2MOsmZAQKlozHRKvpSFAQZ44x
BDGpAAxnXoJHyw80sEsisE1sFB6f8/jLBSESLuqKJyjZcjJMRwmsGxeA62O4
eWukLQAzQCEYf+SNXSZlxFsdd/FlBCZc0GyGAMbHqgJAXy7h1QxIQAGHlM+J
gDO8mRq8aEaBJmDjvYVBrpgdL6b5Fa1fLhyIObCLyXIKJDIpgOimcD8PgJUg
qb2cKybz4pCQHe4tiHuGcMZoGAWZja8KojigOhJ3ZK4gojB5PIdvkIH2LWXF
VXdxOcAU8YhyFjFaySxfzqsWjs7gSiKRDeg0YAu4MDoHgt4MyDuiYl6WGcII
uXQSo6KCcoY5WWS6OTF3GE9B9GyZloaj8KB3S4Y/XQDQzOBi4zkR+cgLc4Ys
DWUsOY3l9ymOVQDxoaEvQTDHlRGMCKlgaHvOMmVOlva+Rw6jdIZnhEABiFfO
lEleI5BEAdSIZLgXonXoqIqHyZSULSMJGHoDJx0BNk5B2Omz7MNizVkO/8PA
WtT1dk0ZhPZkQldg5aQIppGWiUfKeth+c7jbAXU3J4YNEt8iIQLji6SARIgZ
KFLOIyBMFfM/4pck3lkCb271FTBD4jnm1oxTEOqEUnh0qo/MstLKALC31CoE
t9IHItEHWJo4S+cgt0zh8BNGHCfBE3SAmGVwW3hyhDEAHd9HTxOAs1QPIMEy
p0SnATK3Ix9ItRDJfKssSSqWGsNdIZFhviTXEV2ZeQ9lgOVYKySOroHisaN0
CaSRoJ3bqyxi+3U6BIv7llzwzue5COywcdIjkhEwE76UcPeQ9TCqgEJGIqK7
QzyAk/2zCpWMqFnJgDvYurDn1zJ4hZKXrATUDJQ6SeJBck3fRqxC5CiYX+IV
JqtFqm6hgYIGuTA6VmJIK0FRbwYC+DiyaCcQ5N37Wt7PyDInaaGlBqaNAP5W
QXZ4gGrZYvkOSElmZOWKFES4Sr2yupoq6wviiqCeveKxG0oAFcnSyRqA8hox
k4uE6eIMqEoyz8oZ67BanjDDEk0r0iHRc7iJBiNhjQiIEnaZMGMTYaMmJQCh
TqcTuIJw2POc9NZPUZUDHUZBWKsG5tYzy1AgBLD8EJ8cvDhoZzBhGt/57mEH
HWHEuFCkpyXgFqY5sBQCxQjewysKxJPYHJntiG/AWLgloYMj1hTkRsr2SgVo
OasMFUJG1znwAtYDkfQtpvbKwLYcsavSkNixwGBH0Op9Cpc+J/DwvcXLEpE4
OcvmjJ54nndLRyvMvQP8io/SEUlvKE4gwBieTvYGWRykjXMUn0TKRmkdQQUI
APIacm5WQXMyWhPhCXcn1yBCvRPwieV3snznhjt8+UJup99+i9uAg1YsSWjx
HVwFDIAaAMkfdDWttlsuF6R1wMznsPMiHdOSZujSz43OBcvYplnfsMkrDm1o
iKa/ojngy5fA9gaLMuBfY7iGU7PW6gjPApCyEPQkOuvZCY4NkhyJ8ha/wvCP
uI0REp2uhBp0yTScdiOcn0hPiaLv28MdkPwZC4k5GAsWTjZNsjFSJMShL18w
GAXWX6TEnFFvSRzvUQw48o1S17B0xGwiCoKnIB2gNg4/i2FKDQck40qeA4bF
ajusUy6bvSxF+tdlJnQPQ1cA8hnyOzzn5bACZAKuRsYDeFAoDajmZAnTRjsi
Oii/E85UlzniNmAHihBE+TCMYLMvRIBwJjuDd3pT1OkVOyYJ+MuXf3mxc/j9
fu9FX8J80mrSWyxmvXGyALgiUWSzNKjVrLEs5xmZe0hxniRCXoSZwXTrQcsW
Zub1XbsrfAgEw/QCd3FDEKLgRoORwEziIEIP8CRDNMBFlckkZXMExVbECJdX
IqBoiwXc2RlsSzwUCp0NO0jQZIBndZFPL/hysi2d+Rtf8bYIvN0mucJROGeC
EHlFRgrZQ+eZWfJuskiGKKFmTIu0oXAER54Z6ceQI9zabGE0O5ATl9MzO0+d
r4iQoTnzMwtenN8YWYwMR6ZQPG9Efd8Wq5fG4EDiCOTbTI9GyeWiCiWJfoi1
o+JqUeVnRbIgqkDcme2/8BNexyzx7CJ074HSsKeAqCjdlyJPxrNkQfgwTy8F
R9jWWfZDkzjcn1wwCoGN18u6d7SYKmr5kEKEEJD2YjmxRxGNKPojK9J4cQnh
czRjNzMIMhMzAjOPDO9TFIdib0KYmqLY1GAdYiUe1pqNSLlha8yUrgwuAcYD
GEySrEAzC11zdFbAcezhJo3pGUPoStIufbsICq8xU60RKW4spYEMX1LwkUUl
J72LdGt+t/etSSDnlbxNP1cCdLFAGOMDLkgGIhkHBXC+QWwHIyudrIiXQU/X
bDcy0Uv0TE9ZumtaDwrSYyH2Cti8ALGjoHkqEmyXy47mQ8Sl2RCkFtr9DJ/O
h1UiPKbBSs9iBAqf2QgFRuRkvO6sVGonXT+Wz0TUNGs9z0Gkl7XlkygmRJlm
Y2MfYMOm1e1xMFItq/SMvRqJuQyjGGSqs1Q0ccEad1GSRgeQ4QzoKMvKc14i
iopJ+Ym2t48sHC2ID5DXKAUUJ3jQFfGI9zXJ+V5YrQelLbQtTgr4JLEQCf/O
Ljx2xOVKyhyS2AAkaIGiC56Dsx5k4gQx5P3LFxN1BmujFTj3CpIhEo9QVgAu
iAQVkf8MDrOk2/4mJ8M1Cp+ITBTcE6dIYPp25K1NGNlseaxoSIxoTB71xZQo
GjEzYD1GxxhUg945Bmv1zjlYy1pbs/kKgwUQYTTn/ZhSAGmqLjYiCZ7gMKt6
eD/R2DSJUfQFkjuYDxzrIi08uDcZRWUYhMvoDoi/pqb8GQvJCBi6ddThZkiD
ZTpFxK0gsjdjKrJ0ghhZBARGiKuMgYDRGHVSi0WAoYyVAs3KIGZ/+YIhDOY8
E4VQziHXAmworloyHbxmLxBuFHWwRkCRzY8Mo3CD0ML7VzTNwHgAQTIqJAZ/
5ALDYDSTULXAxIDCnSJcjmbROZH1Z8TKiDjTothYG4nslYQG6ST7bNV2Ou27
YhtknmCBGfA9pF6rrFeIi2RfuLIkB9k+KYtzuwBjeuHjx0MFJMrGdOmuX5yj
DXQDNgPqIGTBuyWbYvw3il5pgDwRFEjExGcJPFzc82RRiumyrGiX0/QzEJEF
6kkoUIlRimRlokkcpCwzwviixaIwhPYpdiO4HfXYHoYo6TlXEsLwdEEBqgDR
SF2nfvxcLOesb3sSC71pxY6SAl0JOcgzon3Lxr4qUjNr1Z/RrHGWkv4RsymZ
b6eTCTNEX/LW5BGfc82Lxk7TjM09Ykex7Gvcj18EVutIb6FrDT0ENLRPyxKd
Xg2qIpKcIltIgACbBiqk8qwXoo8W/19FFuHKDfxxhWQDEw0WWOWCpkJDwlCJ
r93IOPfSuY+JZT6pLhN2LhdLJKuU2wCAZPMf2RHmF1mRz8kSE5/kkWjqcnB6
cV3f3MoXbgxXAKWBFTbWSMVcKBMrS2jFahNrRqKFkYsNv4xq9hEcjo2GyBfJ
T2c9F8MUj8/ZEcnQdHC49zbePz5+t4fx+Dh4NsGLKaZq9GESDUDJ9TI3Tq4Y
pzCeetIdUChOpjAgSq3JnH3W9evF+gQ5u+HI4OxZBUAaAIsT+0CBmQrkXTSC
kYUxung5v4EMckaC2Aa6gkh1kaWXQFhw1UjxhiBAT2LzA4X0kD0VFkRAegav
sbHBHBvrfvMq+UxE0TzEJoloxVN2rAV6QmZqOKNsaoKVibeSwk9QTWXbZ74s
fLLwTMlRLqynOjdUSz/8LNJ0NXhaQO89TzD48sXo4fBSOgcIiwRFJEc0dBP7
IBfS7hfO6s6deJdpz+v8LIra//7HDjqPyDlDRhv+kc58WKTJJ6RgvGlQ1TPS
f69YDWSam14QtMhsAeNjPC3IXe8B+JgtgiBF7yjojwsSZbWxgimvCsug+JGM
41VF7wLO0VoAmvUWwMhAGsgX+TQ/u1JEBjB8x7rPSkdbZ0hZyGxIagoMhPQt
Lav7hcS7KomUOMuPJyeHImWhBw5ux9w4GUTiC1Q+INuZ8ftYfXORphTWYAg+
yaF0/D9iehGo0rNtY/6AK1Gj6tXVAhmD0yLOzWvGvhmbEBJ2mGLoF+vlWckq
8jifkQQc4/Hi9C+SSVfOZNccsK9W4UHMUpSciKWIXWJ6BiJ8dU6EjGFCMBBh
0h6+fRl2naAUxOJXAmAtgSK3KZCmsMQhVS+w0psVxuzU99fbjffHC1j1znis
ljg42nn74vR4/3/vDcQn40wFyKGMnwnPnMKhQSZA9MZ7sUSHy5CZaeFipd1W
2wNSsdudAZOTZMLEB1ZDguc4HoA0YX7G5XUQ7x8R3uNHvrzb8VEK/47w6p8d
nycP+Izgw8vsczr+Kb3aScvNraeoXU3wm96n9ArOdEyoDzPt7B334Hdt3NDk
gBEOJGmOiMUQDbKhCPZnpEkB+yeJA6E8Q06UenoSnMY+StYpxV6x0PM2r5Sz
BE01h0evcDhk2eZ2ii6ErEpzV4dw7tRQUCa+IBKp6OawWSOUmTAJtwp3GmR3
oH3B/xHWI0udwgHz8nJS96xwJ+e6K+46ngrWz3eQXhOEGIFmgthSYFiLqN6G
NgFYmjCD1uLHBSS0QRlS4gDzuP2+QzYqRCMSwi1u4TYR4jBQCADvGSOJ+f4S
0ovEzsqmLdZ5CNEdPhvNYgc0floArnS5QKHfKPTCX5jYOZzl4INqdC7j4elb
sKzDL4tdI7IGnLFZB2gtDHRBhhdWx9+VZI+rpmkPJVMkZ3Axe0wbEKPgDoME
k/Kmgb+NctyAwytZ+DYo9uycjqcJxRmAXImKwqcUVq8xiW7JADnN6Tz9XOG1
pevAX7FKeVrlp/gRfsSb/JBu8s4UbZyrWKplgPaBBJ0yZUYy1JcvnC1D3hPD
DA9RTHRIK8hZRxL1ypEmpiZq1Y9mBC3/PM/LVI3MWNGV8LaETjNwvAkZxlkU
3mvUQtccuZL1mOocirNtuAtwlnELtRa53S22Q7K91oR3b9OArRFI7XiljCZA
z3dxbQaPyMVLrAvAaiSDZ9bs0fIISatr6QF+L5xJXOSoYy1QZ0QXA4XIlMLj
LZgw7LLMRxnRDTpOp0+gfg+D8T2m81C0nMm2peZI2rtkrmsEMTyhIEy0HJc5
jynllS/g0hwfXDdWdY0BDWTSBG2Q/l0ueDEwDl1nXtAuKZGyKviWPtub7i1a
X34QNJDq02qYFyfkrykQrzIR1DhFosrY0mEJXl4kI3RFsSBmCDSbiIhVuhvB
4q9/NRQyaaK0He+xH4PsMejrGdUgChPhQtGQnYGUjmJZA3ZRZG25PDvjuFJg
Dnp2w1U0GcPIKxishoTs08DgMgk2YO1PjC81GhBszYkCrV/Jy8/wwygIEO7g
hrTQmk0WTdkz4jCbmujE+DUrzdCLFGTsXiSpiuO46UXZX0GhR6XvWkMEBDJ9
niZjp3C74Byxs4EgnaKLGy5zbT/P8cZZOlbbFK2tGcLAMWFwFPuGGSiS4+QK
3WTJ6BNlDLvwEI6HSNnFHJxcjRkgW7GxIXLlDNoYRzPalF20EsqbdPPdqkWm
ydBAS1cDjhwjlcapjbwjYakq0rR5bwYnavS2bFjzi3x+t7Kky9nlxCLnvBis
/MOa3FLt9Jp6Ki6sZLyuBBCj9AY/JxxDbDBWERZmi8RfGjkZRTGiGKg9jhix
XWSjyiqs5OWlCHIajOKtkF6hOSMrlXWKtRe20iIaocFEoq/ZQx6CHN2wNiqq
q5HGGFSCEEsMigSaj2YLY5Iwy0XzF2+W7UrzXMKFhiCQTTK2vGTzsZJX3akA
fS7T6UXaeKjsAFKKLbGZtKisqbvppCkrgPwfomGgtpwU1gbYj9/Rr3QxlGpJ
F+oiz0BiKgpgtqCLTdGM96uEiiMTYwshH8Ez8crAkL6fXoVkm5XQXMCMRp+c
2il4hbY39IVl5FVpAMM+umoT4Wqz5HM2W85q+8aQW0e7jKjnvPGN2mnDZM/N
FfLkqsYrHuPGL0TRab5CxlwHnBcj9XrZvDdOF0CDgQYpB1/q2RwY4rJug+0T
tSgbW0bSNQeHKkWF+CY5l0QabNjmLvzDwlkQx+Zr7xaOsLmDw5P9g7c7r1Fv
aVIGAoklEHETtv6OCrhPvcDNVHHCja/vorZ3oyGHGJF3rqKpWULDC45BIBSi
j+6VsjbFz+cUmyVbxFf5rN0rTbzQ3EFDkug9wHtKBqWXhNhMyFmJKglbteG2
/i0tLPvbeECagVi1YBEpMSnmMCwsllqgmzVLtLhEa2VFIY6PuMZkWQOpMVdt
gJLI+4sMEWiBOcKev9Qqz8YkllUZ58KiQkEU1Oe6DYILBpEabzRe/YzUyKNX
NSWLvGh6oU67xXWYgckmIPGjGN+tgyNJlcFDefnypDfByMAx0DPSCREXsFQC
jMAJn+LXzOYZxWgZ/7gVFQ1U8Q2uGWP1crYCI7+cjyiUMYlbGl9aRo3wzQl8
WmPlJEDyO7WsSlEEJx/gIyOyGNOVa4EOihF0FBOM3jVgbyWKqZakUyEQixHH
aer5qbsY0UdbfNh/wOiVVoDJJdvNVm3UKY/LudU4SWk2hj2OHxkxTWZC5iRC
32fmPExqypevD818mJM5Zp0W3qzOc9Hs9LWtBeFyGo01F+Csni1AomdQRZIx
K06BDNbtGf+8IOfazaqnC4U3i+mk3lzfKr9s21L7I6I4odo2BvMJBCs3hEO9
xK/wmrG9hyMsvMeIEvGwLMyPJXHIAlSZeZkyIZB4EBp+69EjvDyb26zIqpnY
62TUfkw4R5O0C2cK4mr6ao4b5CeTr0yDnWw2CywP5IRaljBua6WxOxb6JLfX
sUE2orHS5Xkg3SN0wohxLe+BT+lVi15vufsM1xQj3+9gCN4Fh40xoSdgcEwe
u8HQhosV1cq49ebd8Umry//Gbw/ov4/2/u3d/tHeC/xvULlfv7b/EckTxz8e
vHv9wv2Xe3P34M2bvbcv+GX4Nva+ilpvdn5psU7fMoxfsg48h2dBItJQ7J0L
9BegVy5yATDwzvPdw//v/918CKTnD0cvd7c2KfiGPzzdfIKRG6g38myUvskf
4f5dRU52ZWl3kVXJtGRdnAK8Jbb9jx8QMh+34z8NR4vNhz/IF7hh70sDM+9L
gln9m9rLDMSGrxqmsdD0vg8g7a935xfvs4G7+vJP/zLF69LbfPovP0RRtGON
yc1Hc1lgIBGLCFdAWubxAyB86BEiQ4HLH4brwQ5LsRbQSYjxCx7HBJp4kgDk
STUoTEAS+5Ha7GyfAOOggNE8gmtRitNYRCETseNcNR028SwpYh4EivGUjSog
SRHTTuYR2gwWEke6w25lzjFDaynuYvAcHTEDtjORoMWmmjC82jhjy5SiyyIy
E4sHgdSWhPNWUB5Esl2QBMTJJnN2IO4c7+7vo+SD/JZCfxE9EYKRgTKgpIFy
rGfgkNFpaQA1GN6lSA0zsyz67qBD+zyb5kPMVDC/Dt7vHR0DIgwImLTtd3Mu
mUA7582NjeHMORhocRNJhUUhMikp2Ba9iPF+VUq6K6M6XOHB40EtdNY5ktW4
NhekHkjkxWukEWWHoCJ4tWAnhzIdpeJKtSEgCP+Ck6hA/EMLIYztNsip/ZQI
OEwpxxCkw1KSp4jkI8Lxiij1ivT7MEQDo+d4R1EiyStL9FX4GiNMZFeQhMgV
BE3sq3CGIRePqXITkiLTLSjciwOzgWqZwTPW1mE8mp4dc3hf0Enej1Fckwyg
R09h2mPGGooXCOIJiBsPUL0o29N0vh0bFOnEvR9iuSZAnckJjeJ6USRUBwJf
YX8mi0TaCTRgEjCIiZIihsCvA+LB6LQ8Ren8drNp/6kJDLQzrp0PX2nDZVw/
F7mtTNaIlTwG8N7AnSOpnIZMqKRvfszMDXg8+LDR3Xr0uCNLwJjxpGqTOXI7
fp+OPtDsH1cthJ9P5569megr2isdQgEtyfopEgYa+sPGx/jr17jf7+M//BXA
geft9DY/ynIA5edVm6HnoNJFCZFXtzO/4rW1zaeu+34AgtoUldUBPD9gswW7
WsTDRtFTnKwF4l8Bt+7C1liYJaDmLBdO0cWfB7wUHMtKm3rTQHN4l20Y6MM2
P/2R1vtBdvHRgPpzXsDOJnDaBNduXOANk0+r4A26N+U4/q+DIzpOHGBgnOw0
AMZszmPLVsj4lRCtz9RCmS/iBTZRVsZhRWsDwXGYnhIKtwF3NOjDw9ArHaGw
VxDAk6kIpMPsTHsuy2cU984IqfCQgrQJG+Otv7Sf/pGn6aDkagRkvK1IA93S
hKJomDm2IbG8pWwaQwtTu7vp32l3ddfs32OD09+5QdQIThf5ZVqc5pPTrXZI
vdwYGrfKGYallpUJo4flgDifrIoNtgFIFBEIjAbno9twmfMyTAzwKUd7slbS
tneXVC24HKB/isKiT2LCeh4KA1hfDFaN77j3Pg5En12tL4pOwzs0IZrOv24j
lx32SykXY/O64ngN0FuXC2MmZeGRh+jKzSMfFCeVxn7itZmKwjHn7H07W2aw
XYrYQo7O/IKUpQOJ4Yui//iP/zB5R+7vXs/7uxeFv/3wVZlU4o34a+2xr40D
0S/1x8zfX/Qvqx/7erPH3q9/7AZruxfudBN3ei987GvjaPB9ZL+9h2817hRn
+UG/fS/6asxaX826avu7x4ewazPl4NEfXMVVf+JVf7WJV4ES2ec6UDb9/aPP
LwA4A+priKn+8b3tbTJMayhfHy2SZ/adx7dUL+wEBhi6SF+24zuSc9ObkFkP
i+F93zqQPBwqykM/UJoC2wJbv3HiPkbH9mKJB+1xaJmpyVIvpsHVKNw1x3gp
VE5QwYwoJR3JwbZgEjB9ZQJl44DFnVKSsW22kCwQdY4g5XckXi4VKkyJe7mU
XgjKbqi3u9pcK4lytaD5ObG6lnKyly1JcKW6Z1alZgc8hpIgQXRbo3IJNnOY
PD66dIJOwdOTmCQ0YCHTKxPgsWvC3FvsNmr1JUVRu5eEVeMLtniQjEkyYEsU
f9lMn5Dqj/GB/lZoNm6vV+U9LnlTcCTsmJZrQ5r0BGasP6MSB2sOQEGpVRS4
HYINNk/PeqeTTQTfvdQDYFIUaUCnJyEQqiAO50WRaUJtyCwMkJqsmB7ucdKF
rWFgIoK9lFuT7CjOXFlYUqrsvlTHwspq8Xz2AiDodEJvkZixjO4zI6WKb2pI
TkBCQ52i1QrsrS2JgcZIbHzDKB0209KsUkwEUT15uQmb5BJVa1Mnd5sTJtlp
fl3KpMsVoXWjjUTNT541zgE2mRNER2Ly16LWjWsoEusiqtOlMmJNR+iO2ZLn
puB0WHR4mmwupkBkAaLcZSovgbG2w9xGs3MkgaqoYaQqzvIEMtG1VSbRwQ0/
C/pVlF9DlR7nqliTtyaGGRpzJO1r/XSUbUAVTNjQZqvmlA6DaxQ3BDU719l0
wQYZ8eJr5IZpd+vZ56b+nQEzJd7oCSJSuXJbEqTtrEYcLOICFSQ/jVMN8TKr
+5OVERft6YRMoz4lT0dgRo/I0i9gAqj2c4YVmhj70NtsYepDTxcxYEbJwSfi
OjNFgbsRb8Sr22XF7JTtTRSSnFx5IS2YPIUxKH6ZOUQSJ05xzTFWOEZEXuFV
t9cuRllYhrEsje+MrGTqSrVBlUJsX56xGVlSzCXzTdK0FYTW15xiO4gyD7qg
D3GH2ioMNIyUR0H7JNmHrWrRWO8CI+ykiKE5F4E4kEM0OiGdNjC22BOU56RK
R1Q7kQm8YMCCijm5taWRUWKEI1NEkFTGok3j3ZqlKjQnKEBBeS/zSTaW4oiI
nLNlxRZwLCeM36PFCG25hn06YwWN69MolKS8CrsmaikB9Lya5UvK0VF+JZsA
9eUO5jNF0fMrKhXKKIsBOKlNmTbwsRSJpBH+WpmF/cy1SOVXSibnjX17oOBS
UK1MSPWcpEqQiaMxqWucN1QvXdW3ACI7cWXLqgzTyCT6+anMoQhkqYFL2DTx
XhNAB5YJ4VsSWGO63GUceHXYQI7Jp346A7vfVcYV5Yi66AXMuFmWpXF4uMoU
Ol3BrN2zXltmnynTcMsY2EHnjkK/u5flIECr53jGTeOGhIet3yD4UFniub8Y
6/BhqRi2WKYzLLmUqiKWmqOzURYeQgv5qLTQd67WrHT1C+o1LiO3TC4MYKvX
Me01cLRmYibAbJagNPEMRXi6baNkHg1TNncKQDzxIa36NYq8IpJKZo5qMzcE
8KG7TiIgVVIf4MSeF1NOCHJOes2ysNHLGDlwJg6BYxOc0WMpU7iyOfvSR32y
uISVQMIwFaly4ap76KMj57yLTOo1yLZiJqxFJnPkxdwTeEWixUTBqdIomnDS
pJOomAup61OuDwDUNNzTFfzj44RmW4ibQGIihINVIxQ0nWuCgkj4foUVX9Yn
gMBpeHI4w8qpl768bFVMT+bG9bxzcTo9ul9abFDqRk2AZ6+A/oU0VCllYvGL
EnzVyVNdd1KycG/INXV5Ow88iGBqee5Npl2s3YTUqz3jahJSibdrdYQIvsqZ
lXvgZNeqrfpDpNUVRtAJU0Zc0KiEuh+HMkhVB6wQUKZy1ZhieQlfjEl2TOfE
NOK+TnCONGsljDQ8octZem7NOv1YJZxYHzZBkwwqLpvXzsnmD5L7JPn7K3Vm
YwxnK9UL466EXX/D39fo67ZvlAo/3/oPhowH+y8G2pa24yBLwhTF/vDBASQx
yybeiR9s9YZZhaXNpL+AmO77MQ15/OPO0d7xwAz51oan1S0i7M8ODRDEhxBt
UQOjIVUeKQ55jPm4IqMox6dJXVxgGClH+tezthiW8eCNm28AQ1LsRoMxpF87
iVXHEw/g8tGpD3jjZsgV9PFGQx4sK2rLFgzJl0WTxlut8ojIzMAbsslAcINR
v5KdE1tc0taMkXNX3xs2RNqLihHaVE9H3b8+Gj5P6Orrh7nwRu67EG0ETSlC
t0T3UZ8DqQoQMQFpFGQPhqRrsSBCUVGhAaDrk7hu1AQcV+enmbFRWl9CxTOx
xBvH+8D1mU4j0gwlmjqGm4h0xMmcusKUKwnWzEXg5Ygm8qJ2KDUBGRY50qiY
Q75IgB96znEX/DrUBVQiWZeJB9HBILYatESfBHEma+I3MDFrztbXsak2QGtG
4kLoQNOKbZG3hIUcfuCnbLw6QdRElLB1yWa6yIZQ7ZJrTEGf+khKGBCjQZM5
vI9FyisTs6WCQjgmhGQLUUMsMSTsTST1oiuU0FYAQ2oKbMZSztLuLjKhvsIa
x81hZYqXffniAtdJRL1zx0mdX+4AU+vhrSMKx04DU4bGNCHwTGVIfn0BFO1Q
tL/dsGCdr/g2VKzzLM/EowfqFQwApSfEvzqI5CCMjmD5yWJZYN1Q9tu+SCb9
NaO06cN2/EYbqpH4Y+09wvsPOILlFBygUWG31A8S6uACSz4OTAlelUBumAXK
hZYNouXKECwGlBFKEAQDfH3A6ROli8rQwTgkavvlDBQzIoT1vfZOf2RTEorE
qrqj2O24Znq8KNPlOJf5JKRaBsBch93jw6O3rzpk9JFViG04VEUk845EZz/I
vhuG0qv6W1FcN2wmymHBOWzNiNMl65u9ILHnufECprS9XrzuNo5JhI0+Oa/Z
e83HRP/5Pf2x9y6squochO/p35rXb/0fuw2/xmtQtolbfvNMNfdq48ev1z1L
3lv6yId8avTBb5rB7eQrLzX4qJ/9Gg7UPO57/9n3/rPv9bMK1qcb/sdN/+MH
RpPe5sfrVuTg46/I+Z/fx95n+UjPemEQsR8r4H8262GsRRGKqI/nKD5xPlJy
oqYrqonWJIWaTUE0zZotSN9zkgOw+usILf+SMaPfQAkNeJBWRh0bkuJs8MgB
ZYlq+zhZUsQByWKMNy/HpvtSnid4YVwRJ8Fwno7MFT7NlU50XTiTOehKalqi
6mttliBvW05EGQww2mk21vFB+A3JE9uxkfa73k0ycXWRh4A6lMqJ9JkpHlBR
dXaqPusVW1K1JmIk4RJ6ZKxLtwGlb5ZEnsKo1Q0w424pwo1SAK+RdDHqk0yU
qrCLNYLoYKiaOSc6UT4hL77ZCF4kLxCx10WTwyVHSlnFAq8mXqwS64FUZ1XB
cHz/OhJORtmeNqRtnH6OOGjVnt/AaPorgwaaMtFYaHuP7jsxqmvzzKErxuTu
0YU83CtHOahBcJ92lZZU1grNvNn5hQqaY93DtCBPr0qeLiVT3q2TXCONp1hS
NWkpjCeSB51CDfqWZevLt3LceGDvzKDr7tbAdhQTZ0Y2iejHrDwlILTta11b
wOrUfld2XBThSbFMJaY2GjQ8SvIZgqbkwLrG3fPWSO8wQ0yvIuoxsLTtLqxD
Ue0ceyfhyRCYnJriExhjTHX0pb5Nj6LUd7GNRvEP5hGSblHwzfPpAIuFpZhk
L7G2CuKxmG61pReBoOKIJX2rBjXGXo2xDk2tHrqC4HMoiGd15d5AK4yOfHhD
uYZaEzIis3P3dLjLlVca2ugoKtoikmiLmt7uziC3khpKbrh1jhVtPBL3MMeR
GjL+UeJE7evbJnK3kbxr7FN6ADtlWdmI4lr4jikMG68wwmrxNxBCalLIKkkE
v/9e/TV9Dr/7XgvYuRPGUBxTnzfps/+ME8lON2qvbwavb657fbP2+lbw+ta6
17dc/J8X2tjwWX1fm/N5MOfzdXM+bxa4GyMoPTFU/YWf6buafnGv4XPtGVFl
YKlbgJ+yjvAzpU3o737HXP+ondtLKAjnPlvUV98prcCK4ZZaeKK4poKhP6kf
D54P4szW5qy85ObAlKKirVCeRhcnV6MZAdOnWAdiQSbxjawkytuBkaEtDA0s
z/OK4s5mJpskQbviSoqbkFOHXP3jOFH5Fxgb2Y/fYJ1uYmPojsNIF1ubFyYs
0Y44o7JhekYVsChBdymLn1QjhgaOon2/0MQ8x7bNL40XX0rb8tRtWzu2Y2rY
5JWqY0M+fY/PoIW/yqUCROjkM4Gn0yuTiG1pL6aanQQhUDZyiNraFmdhhCCz
mND+yuGhVxgSA9pNV95kHxa9wabe8D2vptd+aPwFlUV4B8Wu2dJPeS1Q1OYU
UKNltJVTPEoqKQnos1KbNrxSvLewVopw5RoA3JfSjigCQg/zfvrx8ZILh1Hw
HK6Jqh9QbQxXSFfXIva96yBHKEekEyOkyAFchJ1JJaGIOoaMTeiuFhGwwaUp
aKPKHvjGepZN2Yub6ToIK7y4HDkJrLdcpRVizJMw3uARntlJFJa2kETB8kaj
OBEpOuSlvHFiiqYaQRaNct9QURwxUPpalypK7oWuNpZzEIOgAvxdz7ar0gjd
mgcNJjgQJMPFWyloRZEKDgbBujDWvmjEn5pPyq3JJ4qlL2L9l5CFvpkR/SO5
4y3tjlYuaMLqhkm8dX3bXKFNFmfm+RisFsP9E3LsWyiKx7x3az0vpYBQ423Q
Pa0Z4ZBR/xD/27u9Y6waALzyalivy6ySuKW8+9BzLug2AT+oOi+a3LUlQMLu
siOV+KRLbNhaEQYy3aW5Ag1bKJoroVKRuLXdy/oddN8VfGMz0t96+YQtEbVq
8f+C7jJsgFhVi3L7/v0z2Pty2Adic59GvTzDge/j4F7Jn/vkYSvvb37HfKEh
8IoiKHu2yidAn7rjIa9yRb4lQtDwsnS2nFoepwg0CSZj7in1pz/0etFxhjne
L4ssHQ+RVxfb8T7ubP6J93dpzg4LdjMBpfZP6M0eg4jCWYfDrIqw62kKR8RK
d0GNmAM9mAPn2ag1TJGbjbm6KcbFjDA+VSVQRBhURwq6rYjOXQUooG3IhhJt
TACtr9f7gXKNQFtGRnAKgGtjTW4vpUnxH+RRmge5P5/jID/CZ5Wz7WNn29d5
yvj7+EP84SOh5a/Wvobz98W8FjM9o6BNz2rtT2cXcscLpnMOyett3mqIm0bU
mTfwksJWbNq950Xs2Mfa2srb1cZdEFe/j//dg+Z1vsxZ6MTsRCEQFBqJwbt0
rapXWLztGKuPZNtbpzvMD79+7GNFGABALR/O2sN/VQZw3+ztAwQG68iO6rux
9JX30yRlq5pPMkgYnmcDXHU0nkF2h54O/66DhmPGv8KLN7IOdWuAuv7PA3in
PntpDkGtx0LSyXfC5sLQQhM+iI+HkhjsCmsd6K86AY+Vja8XYrtqsbeBQLge
npxtuJrPG04O5Ax1BMPE63zChAyZuCDVEplJvk2rIUU3KWs829bOEREZrY2R
OB+2sZ5Bs0GbndzaE+An44hTgxcRubIoVJ/ERrZLU+yxKPXDdA4yfku3yPEc
IqYAapSMMeUe9WHjlLHsgjRxjn1zNM+6V1TzdFYYIxNDgDEmmGzIrY0xCW+e
TktSTEHxn5JlglVa85vN2RumkSs6zeZaUkNbppOImb4lSe5JeZ0Y0o2kexy1
3SjDmdk1YduPeJERqg91n1rK4Ta7ESvGpiFuvQogCV4Sqd8xiR6uMSe7VC9I
syd9qZLOarYSF/H2jNyqXhaC3yzGq1tufVzzyHZNlZPFMokKDXgBl9K70ySg
4fshjOlUuHe0ZHVIXG1Drsp7SVa54GyV1yiV0FdefTFGIOkeInG0ts3gmgyK
SGVQNN44lz/hctpWNP/qR3uugiVd/vee6GdvOAXrS9xfUtoeQ9s2bKobHeqC
v8qox/YYZ6Poxz/ml1gwid2j2udNE1DiamS7P2CAsmBXo7Dh6eOTZIRJNkiv
vaSbqB6reNdmzXDRzx1bodL2htRzUzatLCqiOojYm1uKiqKPwKSe+xX0pTuc
VOcKrSDNSQ+sU3HH0DDRYWXady2Jgcr0FaUEq/sFAEMHK7VxUqLCLVIYRI42
VL6WRbBLvqRMGvCtTRvQoomkUgQ5AKsGa04ACEQdo+vuz9koIqEYNnO1ARNt
0yhgDpcmCVA1Q8T8pwg7iKJU78OX7H3KO83h880OJra6iJ03cmWo0dbrWxgD
sHGKd04ppVyJNT5LiuFUe+Yim/dAOhpZxZFmS76aaifYtubGTuwKsNLXxt7Y
6apVRMpY6rZGZZUk1FSyazHUHOdle61tEacmvxd92Hn154PDrc2PXc2RXYBv
rYUeK2gr+q65jD+XeSCUTXVyQWu6VWcQ3bBVk4kQvbBx12h+9b2mfoj1e26Q
EaYl4N+a1IR60gH+rUk8qKcU8Azr0wpo1/Tq+72j/Ze/nP6094tE+0usfzuT
MkcdV+LGrwWKKIBm5QsdjQRIUk8f4BX9jhQCHvPtwdvdPT3oyqVyaXFeyMG7
ty+OBxo0Lj2isGnQXn5rPHbFzOvXf922vUSMcLZvSMbwJmPLvZnKy6bgqVZl
VDTkSvgvNEvd9NYhRY54qHVMnNTMo/RMAZsG2TpgeZkWDTvQVK0hkcJ/o9HW
zqkS7s5+U67Ee6P5HGezDAje9MowiLhdYhbsB3GuECFEt54s3HF6U5dZFX2M
blTxkSyDLqUAw7lqWQU6wcGvxSiJ+yrvihIi/tNzBprC/t//l4n7JxZgpTEV
SW9eoZkusKQ7Lno7svZArmd/6urZnwLBaHOzPmr/0VRvjg0irVaL/n1J2fwN
lfFhpIB8WwGMT5km6HuDiarPFQJOx2XV3uDegf39F7KiDi0+2q98pUKa6WEj
oZUrIaGTa0GQp+qwOBvwEKLT08UxhdoXxRnZuxuSKhRxU2mYdD9EsrrOGknW
KeokAUulXPv2aCKaYU+Tzmek+9uMxMwGeArLsIGeaOBU8fk65pN9jwTGGxoc
gxQKmsrlUNBIjrd9lBwL/euaFAsY5oZJFtekWOxLMc8bJFisS6+4Pu3BMegg
CcJvTNGQAhHFOqLTpj+wCve7EyBq9QIQfxsyw9BawfUatbwfe6U4zE1S7alX
iPmmkDI+0qIK8BjcSz9RjfLA5d/5pkQNnaokcaUqSyk4JK9UGA1mrAQUjOAh
QmKbXZn4Vc5/sdfeLxChWzI0BrZ7cgKI8bkBm9NWr8Lgg7rmz/o5E0iKjmFm
GtFAViJk4a9PEC5slg19262JNpYk4p4x6ocq6BhDYD9+m34WwAXqrPdcKcGh
Q2E9yOgjqcQkj3RNdC4mBSn4yM8tgOye8tXXZuA+zDyEHqAnD9hSaJ3Y9pkX
m1M4F0Y7BLcwhDXZI8/EbEVZAwQ/TFD33HL0kNg5qMAut7uhEwpdLHjSWWVe
4dASrLWJYPVe9ExlDevnwuCCLbJG7IkZ8RhZ3Rsic+uXdGAE5uinRCFEccCo
iGglkE0Bclu4z9jPEsk/k2Oiq98ogrcsIZklFCwUrTXQ9GsVzYzRODnD6oS5
CEIuj0DCtDCgSnpZ4WHyjqypqax7vVbGe/yOcI9bRXusT0SKw0euC/cIPnJK
UnO0x42DQG8aA0qNPNBOjKsIPsa1R66byUx1gwjQxk17X/37LUDgD/1NALEv
yo6JoHytfYwbHvm9M34DcG6DH8HQn2NmQt+UmxhCyTkO8WPD7GpH35YNqTbb
MOb6P/NiWKB3xTz1F/9553I/ckMGMwR/Jhr9utXdej2/m47c+Mp8+0z/GOKZ
a3LuxfXbB5vi+l0cGu7NC0IjJVmLBYYPi3jvu1E45YNEMR1B3o93OHQbO3nV
3UV1QZETcWzeXSQJMqQuU78ZdqJ7TqlQ/pKFehVz2D5i7CuByyjisCcpyqEU
VMs42iw7n35KrzzNMjD/fuRYAy8DM/LimVx6DquxK5XY26VoHpoEtXr+jpav
qJMYjUK97UxHrmbN1g9bN6INgZZkGyN3GoWrsW4XC5GqlwLJ+PjLuGYRh4Ha
AwfoQecmqZ7wCoPcPK4ELRjQmWPbKslMHmXVy2YZiDauAxraA3pm0AW9BAH3
5QtGeVwYa2UV5rO2B/rcBh3TyMrPcLUqqp/jqvTGtpfL2fFF8bIGFnek3kUw
3TTjxhKacVBA08tmNfZEI0CrCppil7CqjfbNhT6OhVEOdeM6NlsIHkWmr2l5
A6U3rmV82rVem3IbN6Tc4lZ+R9JtHCbd0jnU1NibpN3qndW24qGYNh5p7crT
4QkjxlxEdOrK5rhQW1Wl2DTrk2AX3d5SUUHqnof/tU3EBsPnSHPejg8WbMPR
LXDezeGrDydkaKPHjbkOKJvNQ7wpwTJdZT0yFcUNhIrsZ/x0/ZLUrwZeVySc
HQnINPm5acbOg6pkpbz+olF0PYXV1ItDR/+yKJy6jSkbmThRZcuoSBtjSahG
1zrT4NJsb5pEGi97ijcX/JVGU9ZUpgu/iBM3iv1EBMZltoE02TAalq4sEHis
g7dA3gYhuvhS9cqcYfNg2EPJoMsNUMSsFL7rKfbk2VQ59MLVNlxt2KlT5CAq
hs/X2k3EFmJKIzaBsHZhlb0HT1YsPvtzqcpcF4qwEyUuHB4Fsp3E2Pgvkb6g
QJWw47EElIh17t7mIKJfTXMENVg6l+xxc5I8DFldDUX15YPIwtIZjGtXMhlf
oCsjvHaGvkpJDOJHWPq7qz0J1l9m5p+HLua2MTt2ui6cip0nkQ5HKI1vNVhF
QtlazkJJTryTgxcHGNFDSQcU64hyDvasJXRvNYG5hccpqzanDkNJD9f4FfmS
iGjb/n+Gi2JNs2UhBZDQ/o03/26p4valXyq6AwNcEjooRmISV20xilXU0tUQ
KamZF4bUwEUT6nBVixeKyI1aE+2pcY/rTy6cdZU5nnL8kD71aXXJsKxMsBcR
GQwDRV9gkVzOMZ2Q43E8YyfVWJDx66pANpH0x3Ga4qViYtg2FeC7MbceESXF
o//YMsjk2hupp4PElp2/WIUNERGWxghgF2xTLOBncdp6dMHm2gXprDpoJ/V6
rF8pQOnIPSDQl1K73eTbcJqnrXI9y0p3T3cO94GqgHCaXHW9qCZyLtLwkc9Z
bIxpzNK8iBwuZgjkLwkaAvHLwjIHAYQIHvvdJzQAZ7zqbNcmA7f1J+iQQgGY
zfWkyNgAk6hyOmD527wSOaihYr4QA3d5DAmMv/8+3hh0nVRLWaBkDle4ZpMo
byB0WJ9bNpNu5dOryOJpzRaO9DhfVi7eEV35xu7OGOdld1gswDxjYrrIzgEE
Xec9obwoHTTJUWfJjJpUk6hpgyujrO61CmPnAlcaAGqactsA9FpjBRKU0MXX
1QkjHxIvuHOjx7zwvc3Ktmvk7t0S1Qk765Ia8YOrlS0CLmgMJvCN6/P344O5
gtc5dcm4NOKOyReDkRT3QBeRaf9hys9Tv0dXpRk2NKOOazqW4smTW1a/uWgu
fyNhLkGQy5dV9XJQjWSQuco40dqKOKsr1zRWxMHBo5UlcWquo+ZYJq8kDtNP
ZW85x6vV5p73OGlgPMEqOr4iMSBBIlopLw6exQ5qYfBTQxkeGue/YR2e97ct
xLNio/9dKvFchKV4iHjr52wI04gLYoW/B4EpbqzfOgpC/33q5NgU/SB0u6Ia
dDbNJ6iAHsVBSA+a10QgdF3abLwTB14iaLFJTWUrgX/5YuFHpl+M3vqRSnOc
AdJ3I1PcIzCr3by+h2cejm5U2IOvhGv3Q9yosbRHdOvSHk1VHS78sg6EkOqh
JnxUPwfoaMbxkHF9dtr/LbHwTyqxcOu7oTPzTVGQvYY8FE5Jakj/bsxasVEM
ZXaDDHCdKo2zcDSk70y8qWvCf0shID3enGTNJnKNjDVXRThwPS+b3rg2Mdtl
vrZp0q4eqYNH8rdswT+V3m9l5/fmY69OrfbDB78xt/o2sY7iF7pBjrW10Uha
coPh37zMEhbZgxykDbRVnjEttDHtmlWi7+OVXrFu/OuNcmtvl4vMsLjJk955
3OSFMPvbe0cBzKQ30yfvQLSeq4rtZIEZwB2DsbN+H6PJ1DuELDgEY8arZ7+b
IdQpmkFudJIyjHeW1rYvewZ4WPt+p/Y2WmDiP8VqnfUZ8K82IkyLlyNfVk0r
otkMtPFR76E71ofB/B5EEzaUYHa9iw+0vV/8d6XcP4srOibPJhKaXgveizfZ
qTvU643f35J/b0Hj4R7F2FNJGNVYwpQZZn3MOFtXIKMjvgrmeqJvq4MgrwYM
mjvZrIV81x5b7W0W66ioiBWXbQMHfOMGJRSaL4TSE7CIwgf4DJhK77LpRj3h
7ptfeeFmCse3Hr1d3t+79MLvqblwA7H2W4sufFPVhYvVZRds9pH1hLm6C8p5
UdSVHKvhd8njgs1F/eKIpnkARxFYg4oX/XLiJc5QigVa9Yyh/1xsvCzVcFvI
8xwwnRvWWXet2MNKZ3+XN0DU5ogIsmRFK33n8U5JWZ+JS9rxZdbfTPQ1Cq5R
k+Cq1uBVt2Ubr62oYPo8mPIHkenA4kcCN5R4YAl718skPEwqOAExgvnx7tYs
1EMrJDcUcQ4eRw9XBBphwUpOm8CoP7Z/iTtHlt4VwzErK3OlV3ruPuvnc2Z5
FkbIpFRjBp2BxjtYqFfCvsF+DpDlDt2RChCPTatVk5OrG62yTXgB6004XiGX
2hTGQBq5OWWv1sxExTN83wDhHDbbYdWc7UCq4W7UBHBRuHwXZUPOo4k/8MRX
SuDML9GHEZmcYTxoGq0no5FKBlQgNkFN3l8tQPJe+EQt1rAWo3lRf+KYDoNH
/AF9h6C/LdOxEnVAH4dfXqLeeZ4SU2UMADrWNGPTd/dwhKP0Vy5Q/ydcu6F2
K2BhiN+xB+4m2HImJofNoScnYxszYj+1trSlO/nkkErSKpaL3JoUgEKh33Ka
j5Jp5Hpc3aeiWSKImRJgdB3StLCd8ThKyY4+IIgO6NeIFXbzM69qYABBvhwq
WRs4IskydEkdGwRkaFseAV5zOIS7t5hcOlkW6Etg4j1oOKf6PFHgTJbuEOL/
DALe4oEdSsyghzBO7xCLbJzki3yan13F7QM0YJ9c5vqyd7i6rrpltqkh+W+9
+i/csH2gxBp0eG1JZFvkrAmtBdkUcqyF62dpL5i2SuICGauNuTIw+0YIOKT/
aVnd5zyxUvCHgG9ohauY8+PJyaGQAB1k4FCuy0m7cvxIogb2Ng0w3tM79xLQ
DNPcbFCG6l9oh4yLJfbFfpv79YVYbixsP4/IZqdTcrB5W4iJ+4LsLgi8UwTe
KZHhJvOLIRbwy6k2xQxvbIqRv6w8xYoTWOBvmAMwGx+6odlG/iTGdNgcY9r4
ih93OjRxp/U/pAKnXjjq0IajEoFhMbsqrpy87chk3ZbgTRJA01/BBilmBlox
CBlpvLmigqD/dYM9YbXhINyg+9XJ4iKXGtTVfICe4Siu7fB5g9ttkz888Wmu
Rn4teyDenidTjJU8QCqGtY67xnVj3o7UTaq/PpLfysa+MsFtAuGyyqZREvuU
mTwayMlTDKR5naJ4QO44FTxUcVEKysfHBK3XdFgtG0Ck0k3tU1Hrx3S6gKeY
WWCQqnR5z8ZpwoKYkH0ejkbjd9gtXlH0Djr3IlAMbDyRbuBKbAvb3uPWxAxo
Il+wSFbK8aHGBU2G/JcUabCpPNwm77RW5EWigmV9rqizEzNd0CmvnMs5i0W+
rMuVsuCue8Rp3yaSWM7ZdQL2RpDpeE19T462Uv2vyxJHQ5cJ7xI09YVtnxiA
3C2+78Cz1QSepnI3K0AEsxOvkGFqcrkHLvhxmqWl866Gr5KLjLdvgjVBVgaM
qw0vwrRJwGQ2p5fI0YMO9CvGWXtQ5pg40NSdU32s4NAEzH62KX8Zrgsl5qBd
0R/rTa1lgzG76wXheKN3NZraeB7j4DWxikbWq6GZbZesg1+f+bnluANJHreC
RJgrf/2gARJSAHzDyr2MWj8MUtJKVXkLZPU9ZPXkdU/Kc0pEJyKRcDMvCR3T
xGSC2nUgMFqZlIqdcXwa1QF1VZaFundBLokCxYeC9lKq7rSDBC2f0k7ZQCEl
IgcgyUzbgaX4/lZnEMnhsvxtaoPYfGQpj2c2qkL/0Q+GAUbLggMVmSNgdv1n
rBrISm908vrYBPN8+XIsmucDhMsfjl7uPn348DF7PpGnYc/p+IvONUnbG50u
4awwy036OCERvL1FH9pbjx51ot/iN7xkrE7zLIqkmgaOpn6gminPItPLK27L
b338vkNPxxz15ZZgOLGUgXEK+p82+v2tvzzY6m3+8My9aJba9NqsPKu9dOOB
edM3G/a3Zw4gz1heOHHk01IAutyhmE0xWlIQJA94ve4ht1b0BaRaKfjeRh6l
xW2zcNj0ez2jQHbdKKqSoNnmwepviJEXBUVjoGe3SyCMArhDfwxKAKfuAPXP
6dQNSGiGo26CXm4xpWl084L5as1M3qNGWlgx7xbOy4j0O2dV+yvTmrDadtJq
lx4VG7P8zGK8RRaHRU6ib5DGzaq6q5blfmBnppOs+ReRnNsUZbz8nE0zikE1
BRQHjSvqDHQhoiRITQTRWcxp/Y5umSuQHMCL2A1GJXAYymp7RdoQasO20QAc
uTg6jF0TVMVsyZGlTdzT21boM0hrSjFwvVMW993w3375o1tc/nKxWu29lTp6
3f13BEBuceNDzfd+yKkj4a23l2UDL4vjA99ABG5zNf8pJAGu6t+VAPzXudSS
M8yWb2M0rtmfRlejaeqpEhjNLeIH++u7zntqDQ4eW1P+KnnBur1pJZxUIxaL
75XBl20Pp0rfpyb2pIwPrJv+DwxaSh8FiT+yvwxq4r2IrMZAatWQQcC/0FSK
zX1IoPY1O480ICxuAYpy8e2wOKcZPViYsDxHOyXky8qiVVQnmmYbrmp+HWCi
xJLNxC2myY4b0PdkHQbNI53Z7KRwNCdK9kEXyH9Q4aqWppRPPHGek1tUPLsp
wyoVu1HZnmEBGaXzUTyDqysTkT0CTbQUCMm3XdtzjCW4hnMd0XlGOFKNNUzz
s2xkDkWKURfxMK+0d6ZUxfkaicFqc6hPIm5krPRIyHZI2te94xOZ27xKNj6H
uLJOk7G64u9Gkqdn97wTI7Y62ixHxEYbnVtpSZ6OYbmjUy49y58d0t4vrTvr
AcwVU3UY/BxGLzKkHh0UAKprD8rZQtEMCfyvzWE+MoIJpvYDZ4xkqa+tFS7N
Q/U51Rd0xSWYSK8g5G1/CKV+Qhjnl8Woj5BJhfP4kVba9lwPB1JD9wvM5ynT
dkNsGXPolRFDtWHXxJGo9/0f/Wm/9VRvebIylYmJMiq5KPnNw+PfCoxwMUn6
4RtjxjWrGnlmexRcagPZIXzVaMWAytaxciCzU8U//d3Utr3CidCglxGfxgqh
QEaUt3FnfqXqKPsuxxPPIlSZd0IaYeIMTPKNbWdhCwhEHNmMPCn9nIyqutey
j1SQ+J22w9X4IxHByK4kaO+gYh6U45IiUOBKurzeFyYawgkNPe65leqYCxP/
kBSj86xKyQLGfPsyKWEsUJLO2PJKdUGw8r+UsH2xc9gH0JLVEv67t/EIgzBw
N2e5l+tnHbDYRk1Pc23jCqrziOb6aYbelwIN3l+wUg98/k2q47mi7Lpzh81w
K50QQsl6cyNHSdEHVeU38qr8su/6JTfnfInNOXFu6tIJUz9HQYF9H7qJ5rL0
+3lKWGI2Szn1oG8GpF8jm0nEOICWRsxOl9LFnMU3oLkHytDvDFhlmY+oi4vT
sKV6z5uDF+9evzt2aRKKQeJqZvl4OV0KcHQCOS2Mixnsvd09eLHHkd8NAznh
j2t5mkopprapdDSVPcLlpSREXXgaFB1XoMjsk8S8VYWK4oZCRfRe/29pkZdt
zsoIkkOk5SeF4tPDH10GXGKqnlJOEQ1Sy+/g91VuB/8mJR94eoxWP4Whfu8K
pDqqB7pbrWjHf5cCWPxCy0kN5jy+/ZZhLEhBsR/Lkhrfkb0kxVwvbGpjuhTO
a6vdD2okK/xSgRl2TVIhe8JlUi+wXQ4lbvob4dJKSwGrqVfDKIDP9JPy1Pza
lhosBmMNrFnB5EI39rqZ5hpkitcz0rADz/TkV3Y3KKuwNXG5yhLcpbc0j8L1
S9iwP7PC67bZp0Mot52B/DjwaAddM288FG3xhLlqKNfskRcNBk2xsBkQg7lB
aCEguH3reWvePUYDIaMD8kbarHdFVcVkKeceKYQPMKdGITjAVMoTcDin1ITX
tyZAP6eyMSWia0lr7VL+k76GYRl1fgMlGvpSJFec+TPyKHrdSUTy8L3vATlB
ID4lOtj+7GNil5lHX1NTL6ZXhom4BHwaLll+1sXO3Pp5Ma/j7xsmMZZAjGeW
QTrx/4CH/4DWQCdMYWGdeO/o6PTFHr7M2gQswA8lVwkaG11vzG78ulMDyuln
eF3++0O2nd177ZQI/An1MQcy+5KnTH2OfzD7MuzMV6KClaOWaW5VGQM/PqNY
ecBp4Xb2bdidCR3nW/a54x0J/G4jDgm7eoLcPUFrE2/4ognnCV6eFEBBh3cw
I9ga6l+alqASJOaYes2WTzTW9g2vX5rCioBEYet9a6xI44w5VE5QVVgy9ZVM
iR7rR8gmxAGI4KOFB2fDuEJrNmHWo24drPS0XA6BE048lteNC2wT4V0/v3nB
8XJIxVLYh0w9JWRep7/jqEQW5KgklMY2UQx6F2DcenuWLNrTZDYcJ/Hn7fjz
h42PcQ/+wa5AmFKHQ8riOtgE02wCeNjtNrEzHjcsXeTNNQu/4ZrvrV6zj6xs
j+w5/HFtlWeqydY6RH358qSHLXfnYxD8fem3N5lUvYn8hsG0tu+TLXghsq+V
vD1lKbX94Ee1Ns9YL5y5y8t8WVBVINPGocv9ICltgVzztHhUYUBPuprnM7Qa
U/kP+Cwh2O2DeWqKbCCS1ztSUbiv1w/RtcXAqBGQdV6+PkQu8+XLZLroyZc9
XZEE+1LEx6ZlMnFKw4BRP0ky03exhVA1kGtRHZCgCFQJCy8nV64MlfSV8lQl
XAqpIb9xDZpVsjKTIy0kw+pZNBLWreUiqfvFfDlh8gkHNzwr8uXCWeRAg6wy
yX24gLfwV7TIoxChtyctvQqvf5YZzUgdCYat5Jf8yFYgOBKFUT2f7NvjbMTh
0Zg9QuukKAtz8gAjhxGlKMkmsPcIOMWbN3tvgUkKeqqNo92bsk9gPC7+T8u3
sf6Drb9sbZBEpDZqkJ30Fml645+D1c34KF7tvT09OHqxd9SgU1l4JSGg7e51
fTZYpz5Zjre+oyq1MHOhu4e5Mpj4LUv0tVTFPxr6nimVOGhH9pUx6fHD2P+T
7ze3nsbNf/LA1qNHcUPTslX9ytb0MWt4AFs+ieBgJsWokviP8cOt7x5+9/jJ
1nePgKhu0vePH+P3jzc3Hz99vLH59OHWkwdPnzz97ol9AJfaize/o05SWs6C
X5t3+TXefLxi++YBWI39AMO+sqhIvz75i1qoegu+b1ioemB+P/GGNRingNCw
GALCutV6w1p2Y9mLKhBkAtBWYZlGKmY58SGVhRP91wKC7T1nv6Fiu9BPuFvb
Pjx61dGlWtPPC2n4e54XwCXb/GJH3ixTELZF7cKO8EbXQEuNnmGYoS67E8Pw
PgPzlh8F5NeR7HoDKWPViiIYswzb/1mDDzVCWmvuCUnK8d5qM01Zb3GXEAwC
8wvNeiO7C88Jz2NlJ9toCD737TpAShmXlSnbDKCcU1g/qzCDoBtKHNf7QFl5
j5tT4UTd5l5S7C3lGTAWTnqaUSldpnisOJpWuibKskwlyAXHthwpn4hAi6TV
bodc2/YZR4E51Q94gDghuT6bVE8lem46ueFwpqgCpXckztiJdmO/xSdiNFuX
APf75Kmo2ZV87k2RnsYMJAY5V98Q/guGRAHZBNrjnjFlyO7Abkr34jQWZtVC
Tl8RE1/JR7bWDiBd0ciNp64qP4viEojC5xEty3SkTT9j5RJyNktfTY4Vbmxf
rOsNR941Do1TL12eKq6s6+BRx4G/Kwbc/vxtXziC0ikusg2grrvA1tzD2rPq
XtZ+8++p1WtemFOap5dMOozGAugJyrwhBXTpzW33FGqLxt7qRNfCH8jiUabT
iZhLunEN4e1yDhikdbT3zl1V6bJ2TrPsGSyaZiXh8zSfnG61PUNDB1l93RDC
9QHR+AFfd+I/mUWuMW3gnnjrDWagjnrxf34fz3zrx5/WGT9uYsJgIxhxw1Nk
eATkRgTCP4Z740+3wa/rcKyGZ82PrD5++nePeXzlghRxjQM2pzr7okWN0Eao
x7otEmvrHI/vFHB45va2IpQGrOYN6zg+Tx6w3IONBx+s9nTJs6hvopTiVX79
KR2Nkk/YXnqmdOzjH3d6D0CBfLl/eLy1sYUFz+TBzNcCRvDkT3sowM/Qm4O8
xNj8Mfb98OnGRm/z6SNMQqbFwVJC/YqKnk2n5BTDoG9OVoHxyVgg9I2hIRtB
5HQH7W2JFh637bI6dJnp0TvxToNkxNY+i6lwwpuP+Xm8FaeUc3d6KjSnfvDu
ttENnsL7G/5XeNeJb9xz0of6GSMrYEA3JREBnq7RSaTM0Grae98bZqSiWV7a
KF8Lj/ZnGLYbg95ccpBv4uJ8s7l694M9u25sUxj6Dz66+Jc7OmzHCIR88hj+
ux0fJcLeEsyf6un2fi4ty4zA9eqY5WIZunhAgOBFIuv7hKDHmq9O+mTXkhrE
YC4nuQFJy7HAyzxuJcMyL4Y9jCPqlSABpH9LW1QVmPKW3QBiM6L4gslySpVU
pyL1s8sdV+lgIKv+3t0DpuSfu3IwgCh378qHshbcwK9/6MlBfzT0wZICI42K
aGYugKYCL7PP6fin9GonLfEaMj2Y4Je9T+lVL6Gv4fGfiSkZskHHbmxFyTC/
SI0QZ0UVc83xbsq95MwaHCTKuOubowRs2qtHIRgNyMT0JaYarxozSjjewdn8
nK2NSmKb6233Fe/sHesixyywzfNLqQ6Nln107bt+gkh5TAhENmYs3B8vJkCm
Mvjnt98CvMINiL8+4kd6nJqHxJCtRG8PTnxLUU5ErDKELplfMcgwKKYfoapx
bEqVmHrq4h6tVSQRiHBhElg1WjyXZWkzsB1F9BHAp430r0cgQX3MitESK++O
QG2jSI0eSNUZwRulc2XVlwqHsQ93xxb/eXSVLsipbRGAVFZd23cAdb74WlnA
5VoFkcfVDkNWEzUJ8hRG7QXBARDhcERbnMY0PRzqAMJP6YLq0cAFNxrKFSfu
qvrlZE22RW81GQUsY5yj8s3GTq7WT/NhjC5Lr5SofQuSzAICJunJbR9RdnKc
jIocsenolRohRUdwYoppV6AK4WZceWg8NVUpiw6KEAVT0T2ayIvvAgoIPYSj
7gR8MKVjJavLt/LCfDIp04pGacCZ/4EYaB4FFeVUIiVWPH7Pafj8N5zmo0+n
3PXme/Fx+uF/c15sbaj7MHOnW3tWrYGeQBti5zq8dy+5C4CXFqBOC6RITW8q
Gggf4Qfan/OibUHe9XzSGR5Rp9MJCjN6f9bLq+Bhn/4Ycjg0HCVV21th5wMf
1Db/c4+389Edu1osHz79t6IJhrLhH2r8ZATvWfNQdZkmn8gOp2hdAUyN69YX
+XBZMqmzo1iSB4z2w6uffv75l62Nj2gd4m8f9rekJTKNHZsUJLyZ3JGL/4ha
wCquuHk1kVQj3yIZ1lfKiBToHeVCnA5FsKoVX7TS5pbzM2XfnbuT74A44T2j
ApMMLGvY28EGdiAY0NejbHGOWQFNgJzm3fg8A/ShJz9sP/0oY314uu3OFW7f
LOHDwSvOx/vhHDAH8Qr/neadjzVJB3+URfp0oqtH7PifTJwm1/F7wWa9Y0el
TxKm5M+ZNh4TbVdWU93Vlo2ZsUTRkLmZGUA35hR8MS7xY8SAWT+Maq508mNJ
kfiarZENRcSDbK4ycgppYhxxKCz68FAGGrPtakmxvM2GS0a7xp8iDogIjbAU
v4NRb5vmXamrhmHWVBycjFCD93tHx/sHbwedZ+bJFgkVLVs+2BbgcjUwxFAl
dQtQ6OPXdxpazhnzvh3nGeX1w9PkDDbZ4HzrTI03172Njk8mYuMsANWsQ5WP
Q1yz1RXrncxrkRO6+vHNPFq6JnTE7df5mJtORSWD8KOnwO3aOOspgdfveej9
4UNrfl5i8PRqFgiX+SWvDUlN49oIjiijioqdxO33HSr958cWmHvtCFt+OjRc
QvAGeIViavoBt9f1z3Tjhyt+XXKP8i35+aOp/8KBilTqPMcQQ2xa4Tqr4A3L
xNwjaGQuWrrADhdFMpXoNtL7xHeacnm9tN7Huh//nJqCLZlpH46jtzxxstXn
+GNCvDuMeGuMMfCz7c7E9fqyHBB299XzzSeoXNBn8oM7bxJoSJeotVxgdDM3
3dBFGG2sRjd27SXayEVQUnWaUAcGnXWxPOOcstewbw/QnfQiM+X/gB7N7J38
6xJ1MHQKyzWkhi5zadfIfZ8iWASWPkDNBD3zk2RkWtRTV5E1gelNjRPmV1HT
xmLpHhHSOluOgbxNe0FhSTKyS/hdomNosTwq4YX2PPapDAgese3/ouqji/dt
ruNbSbzIKsPWTQMCDoEwExPWYAg82iFq77YIo90+ESAFxVjhEdvHo1gH0wrB
4lWze0qGu6vbX5pOs0HYKAZrcRBz12RWGfOoF4gStwgOrWfcVsYromQniaha
VO8mo0mRjxbCGZdcK6iPSRPDKjGwBlTFBgbUjpNSshQ8baAbF4phBw8hBJ2q
kuY4JgSdUDsYxuE6epqiRK7argQO6XgjV+Ojr0umR1Ktrblw+vBKXFgmmBWe
MJWHFtOssgVQLkzHAWArojSq3jWlZFEmrrxPrY/jW9CQuiovwhD7iIobh41h
McylwJZmy8qEjvS4qpTeM+nQgvRy3lkRycJclRqWpbhuC59JOwmvC3H/Gs53
xBisJ7X1/pO4tSjyfEJSiL2IKxrACgCisFwmHDi1caUyRLxwqToUVAhy5X/N
K3h564WV52O/8lSIu32h90TUrYmAuoIk8+Z6uUgtKRnHc6VK97YyMv7Rpm5z
RIkWi+mViYAHYRqlXO7TpGpIsfIxj0xwmytTK51aP6WEulgBDO2dKBoEvSP8
NcMtEk8ydemZUXUpc5OI5CC5B8RN5iY/0+YGMWPTIXH9aMd6ayvjNrgkLFpM
8ysnmn35svf2cAf2U14ByGaG/3xKrekxcmwGlTOGKb4kr9Cww2U2NVXM0tE5
CaxUkrvIuWwiRc09f7776tX+5ncwHetzIG1RzN4ck7VgzwWZS70ikaO8pDLG
+LidL6LYDspzG4tRjwv5kkraxOaecTBDjgXLJw6qQB6kFYwOqMWCb/CUlK3C
W5KUPsB9WLs0Z0TlfJ7yEamza71cYgbXa27oeIjXMG6/fH3YacmuEGcNsCJA
Qg0sBjmGQQLZSxYl5ZAJv/aq5postiDefy5NCrk+lPTqkdWZAINz7OxJqyZ2
bqM+rcSSRArCtr8ZLMpUXudK1wyLusCvJJPGQk8SYMC1nXD5PHIZeUIOxYCi
JHei4kMb1jonaNG6zCFEXjiQaDFhGKlQfZWhg+N4wUcoR1niacSUzE9ki71Y
VRzXkkbP/E75+rxAHBpFUIxHwFTXstaUhsz7OlvO7MEfkqCD5dUMH5cTnkif
WFgbIE/Vk59NX5lV+BkfE3pS8DGAPop20TC6qJYSZyuQJpy5zIXn2bJeXMbb
hFfR9eb6fUnEnbqZWGOJX0xwWpaUSWubUabyyt2AozG3zbj3p/CtSCw9tjKb
maD+su4CkMxy08pS54me2AEtgwwYqO0+j309DT6Q9VtJPcLkXMtP/K9ake1+
rdEBSTQglSJWl1JO24/Wnkd2Aap3Hs/gFQNUtSxcxLtZBImfkbeUXWpTbOSo
9DM3TVQdLsSTFwoGJNuMgJBG3CD1PKegXFlMPvElGttqvekahk3Xd0pOgCPT
PTkgxzq31kX8WT+TDejT1xg5HkhQZcQUwnSGJQ+OzfWcLqTXurlqpkpixReS
gwYI1s4hE0w0QyOosBXTJNeFZtrWY/UV0rEB+mgiQm/SLQ1Cf/Hvq2QZcxaJ
/1cL6r0ugBcjVQeHRwfv906p4dDrvbcDmOG1TXt0F1K8JPMUDRGVl4vaGPXl
taBWw5C/Ri4YS1yMwbSUf3u3d/TLmqWAiAES9+9diSETPOefD/bfnqyZ89c8
wxKQv2NOqnCiQEDc2VvD/tvDdyc8vRyyvwajrmnFqM3Iwj9hXgWNdPDuxBsq
HKmp+W3zSIAWBy/XrImPzSJePKCK0/t7R+ad8AW7ZVN5xtND6GhdEgauy5E3
Gl918xrwgqgio4yuQSMLUh3q4voLNY2Z3pEsDXelsIuFC+ogWHEiSMcEZJsb
61J+mDszzWDO7sccKwJA0Qc7zFJ9+tNgZOXQJX15DCZdSRO3fEIChuVObac1
63gCDtK1BMeevCSuTBd9QtU2nYOfi0U/UEyl/z1dk9r30s5SJ2E3NrKkpZuo
lsxr9+j6CmLmCt0gjBkoTWcV00fFM2nwJW3VSBcaZgduCwMnO7TCe96KB25P
kq9dG4+NNkuOBwDO69E6bqjSREO420RSNNIHGFBTiL49E7oiK84kn/hf0bP1
Y4Kxmw+K2z2aNpCeVbx+eDAKjX/dgbk92E5axo3UogFaMlpw3xnYci090i8h
v16UL2sbRi1CjMtK06iXTjYkPC0v68kIRsEaJPYlVhurSMNPtO06ZEjxwAF+
YHGLQB7F3nM13ELBj9Noa+jkwDhwpzTAyHtLMdDjQyEFIekUefQSnayW4Dqc
YgGubWaoJ2pjw97mO4uvoqXag1Hj4e9XTbCr8QM2P5rmYgl1JEipkoKtdCwW
U1VBXfrlcDcOx1Ho6LjXfRQdLAuve1C9tZFoNK0J6URsjG8ZgwmI0mWqI/u0
pk5tjlCIwQ7o2LB1Ri0uMDCFxs5I/APBvroyJh5TVJ6DV7BoPAcTWbl5BTqm
626dBVvkDRMCGfRSbkaCEVFG4aJW626Z8irAJBL7CztoFbxqZ4d1pzD1DwsH
EGca5nLMojFZnkTYXlCxua5TIfBk6ajF1k1P102u3Id+OY+ugYYti260Gbdi
KVuFutVQEgdnEbUrsu0Ua9tjNoEHxdeAEV+1XGaRf82CbOXzRHc4V7c5UEEi
X8j0tMraHefaQf4Nl7STkhvQRiaHXFvGx2JHV8ugQqIDIddeCVkgSmjURPfZ
CLAE3aF4abQaZzI92D7qTFh164iuiItFgFBHEytO3cL9zDUIMsYX2yLdBIaU
kgYSrXBlztFWhLZDNHtJ+XeW0arc61GvZgGc5UslQWb2niqltuuVM0Q0LcZU
10NOyp5gZHohGmEPvWnKVLJKPXDmsm2/My/Asw0EnPrACtUGcr6WmbNn2zEe
LGFh3nHVdPArXyfqSMi+kZpWv+erkvyeY4ir3/P1PttP8JAB4swxVu/omyUB
nHlUK7BqEVWLpXZUrCA3Du5RMLBu1Arjs6hA6UB4e6TPIs3lAN11m+u41V03
iBD3FcPIit8bbEBYGv1ANxOu8fu+JNLwe6ruoIt3sgJlEEvX0Hsm2I3/gztf
/3sH+aAfjtuq/d6FOFFEnFqDnjeWfsz6dLwHJCj8o+tHaUl8SP9j20/Pydka
ZB6u2kJX7QCiHzY+dly9Gv9HXG3wuAu6U9OYshfmq27wVh0LmGOWvjBkeGZf
h540SHgdr4slUJHmJpZzq5yeWF1fhIGsdFQf0/FyEWYyKnK04EwIn0gim4kG
IdnCgBYsPnaJIX62wNJJscSCwwdzZ66k1AFvgkj838LBkpLTihNfsOZ+a55E
rnkkRlmh1B2xXG4LKFif/+AliDSpJAYjKQI+MJ2Jqj1Mhhm6YICk/8zuj+IT
8xDP62UKcaGLGARVKZFjvSla4GQwi8wlpaEupVUJOlZQbCLVxbllRMx0Cg8m
aMDJtUxUZWS+jzf7j7jlS1f6T/VGOUbskS0VhdcLdHYlo2l43HN2WsOs3HsH
Ywj3jFkBAcZxHuQtMKYEKYIg5hbPn5+SeGiML2MtCggfRMyLf0ypJbkRRDlO
yao7ialglk9cYECRXAb+E6/UW1AA0Nk6eM26AS1Wg1d94AMl2EQKJuGMUdw4
ZVBUzmQLUuxULQFWGwP73J2PnAHoHOvWDR1Su89IlyDULdlfHNgjKUZL4jhF
jotH5+nok+0fyowILRasUhmJUTJTkkmVFu5JDB+KhhhKS6NQ65i5rvtCmrep
uFYuZy2SQxklSHGzQVqIYTRlRAqAqdHGUeHx4MNGN976iwThNgYgAVn4FKYb
ShiDLdLGpuZhVjkZmidqc08+XJYJh/M0PfJWwPox+jHeISCwbdf28+NldGMO
bePbaNJ5vPp3UVa5BREyLEsrJFs6obUGCvoEsqn6/Ij+nJOCMG207bKTDK1E
FsVlkAaLXg27Z8mCVuGjGcesRTFNBGDs2VundZKOlAxstDJz1BsJyxRJVZHp
QA5RJHpvl52wCKPbv63CqCznbD6og0Xmt68oEznaBijI3bMHi4RAASeM4hyt
MjahK0NCjyo/S6tzcVtmhOSRyQThAoSpattbC3KJJWxH+jORH+TXVOUKCWbc
LQW1rZ2KkAnL/BUx6UI4glAAa9VKptEiL6ueq9ru2XyQ3tUrZHZrnbADU6Cz
qAOkGVFw2zqC0oLPxwS97eCArP2v8YRYO9VraqiGqn+OJHMAMcq4fMMzMBek
xru7ZKia+2dLaWgYxKpDLzI/fqvAYIrpVSQzAeEUSaq1M8GL3fOuhLk8Zdze
eblXdloBSTRtqZ1ubWJhfb9pEBjr+OOAQgzIvB2m4smtoDauA+dJjdrc9Zjo
3H5lS0uYkAtV7TamkpXoNm1LdEZH2pJTVYqIin2d0UB42KqGyqjBNWIjWIT7
1xama7aoOA7jJeWkFfHSeuEwFFEIUO56Xbl1SCzbdaRZPbGIphLJHNpCAZHL
ocCaeXmZRm7mCaeUuT1iOzJjjgziT1Z5d+Ov8XuSC27+1+j0vb5sU7MvOOga
i97QgVd9YHCT9cQDUuX18+E48R/j9mZ8L8bSUG1pJtwDfaCDUn7dBEHtdLjr
6o2Gga/4E4gNtCDXg3ZgF7T5+Prd1DZGre/UezjOrYbhcXh13jiAI4MPWyDs
PHrcucmIjU5RXA+Cr/b9NeOYNhn2YYQZ9Yu43b6wjYX3Dnx3sgQC9CE0Udkm
Fs+5YQZnX3yU8zKV/vV6/BGuXVmjD9jAp/b9unG4yoQlOkZj5j7nfgUuoruk
N+NNLjIi96uHltvefIdX3Wna2LvjnVd7p2/2do7fHe292YO7Qiilq1F9jTcd
IPh5durXnjSr2Qqfd7fw4M3bvWOvuDnWUmsYXwyAjc8/DJ93hr/G5x+tXs8p
0gB/D1/jx2ueP9w5Ogmff1I7YKLOdU/+Ugq1uuNFLfhY2EYUHaWU2SJcnHii
71ySMEd8ihGlwd9sPcKRsgYrjydHp3Vq4W76Gd1ooS9NEkiQnefcKJ0lkyBe
WuLeOEy6bHZZ096wZa7Ym9ASfplc8TYlQix014hbRSQWlFZV12Max9jF4zZ7
iKXnsldW5SUIDz2A9SxDG8iyYPdjMh/7QQ2grpkU08f9rT71CPU8ddJ5wjF7
5Z2RgHk/8AKTuyX3b48r7Dtg3S1D7Z+UUuPCMul6aLvAHD1rc/YyajiKVtXR
8n5m0ODrUg1q9bmEIyuzMKW14yBH4r5CdFwTb+HSE03UfDilvyE2BzRsRduj
aX5XhJcNUKY/sfTiVcpkbZNo8SptsAaaOLX525VJD8apgaSrV2U6I8ewGG5R
hIXT5VWFxow2Xqqji8qlUBqqb5CNxIdErnscSkIIA3edyf5o6xiFqbQql99o
1A6JoyurUHPIKhtIm4bkksRmyE6t4YW0LyGyhvUWMbG2GznjD1exMjrs6mUw
eIJqf76kn8ST9LKxzLYv3NsAZ/soCcrG76WOE9sWaT9AW1IB1SNdRv0u4ZE4
v6ZUdQppuCdG0m9A40895xg/2CCM/mAqZgALwBwk1hI4DtBQR+NdkABvgm58
md4FLjGnSpD4vpSKpwVijXie0QrPTRXjyeABEy/ncD7Uisdo00hy9CLoZZ73
+/gD/kJV4acf68Xlg3m7085Hsz4fKm5Fn06lBR/jjZ0IyNG8avNx9FnK7YE8
/sf4gTzTqQ+Bh9bko6rP8yHzG2PVy+Q3z/zAzfqxPn/gqfsdC9j8tgUQAfqd
U2/daur2J2knxnN3O+EJbnrH5XeiuvXZb/2nnT3qU/+pZ3/tAtzZo771ERXZ
YBT1jj4z3T4WjpPkxXXnKBSLu52tkhaaOa/1intUse434aXKIt3JUmPYRcRb
cMTklMb2e1786uAZQMGhXw1zPKIeFl/0jswtvqH0YhNOfvg1qLfII3BBgFNX
EOC0Ss7aK3SyoFwNZuW3f7232WkaGJdmbdoN/vEm2LruD8Fva/pJqr/apr2O
IKvoP/651i0BXPuqDcya4RnoAUJ4h6nLsNY2E1yh2lHd7LgCFbHTUKLVHFh8
j0UK+Fe2vq77YR3VTfXQ2i/h5QxvoZUWVp3GjU6ihh+asnzTKQRM5JYXZT3k
Ceoba2G+Zv1lH8TbtKiQLTSA27zXIO/9PhrCP7ph62ddNt77m8GJjSQhoO7e
XUVJfLk1BJzP1D1QfPgYYKTT9HSAkRcTdgPwrQSdYV/Bk+ugEpqaFFQ8iLg5
/eg00/1b9kGBZO7ZG4ST4Yu2JbcLUvpetDz8+ZYczR/m78rStJjzDTxN2Q1v
y81sHlHTvW2EX8DPVkaerfyr79kS2CDt8q6fUGnjSsMqFGr2OzUTAtsPJENE
WTbccGKzwPKOzqxw9zphS4cgioikvzXchEEtdF5gxsGFq6WG7poT0LeyTt5V
vNtNMPvaBRsB21+wh7vrxLGbIfg6SUE2xAcXXD5Zo/6tiaDrkLu2frjr7V+X
rEYjB1a66Uk8BxucKZKqZ9OJfcOc717girWuRsn6zqwUBEDZihzlTjYyVSSj
DEpjWLMs4jSWeelxiQRjnyU7V5gPzHVaTIyqS1ZGK1tDmrLE7pkIfX7DD9N0
LTka0pZPGqI6JRls7qI0anGeNqZfTF1eawRKRbg8J98/RTCMMPO9H0W1Nkna
zE3Zv0EU+ZUULOFi3GMXJM7JQNqAK6bi1dkDvNemJDIbyxhRZqGx49XTy41p
HxPaAWdbqkqDqYtiDyxy2eVkSKRL01pdNoaM6qkJ5WOb8fCKakKic8TEUjAq
siG3xCpGmAKCsew26mc1BCi8H8EsxYLOEn9EPa8LG9XoQkdo6s7FyUWejQH1
qiLhVvRss1RVSDzHCCfTB/geASxhgwDLuuG5Nv9dWecKA3fEp0Z3GGgunlS+
kKQHLstMsabOpyQLG52nciIA0+SKavuNCOh1TwzWo6nhEA04zKh8tJPxKKaP
ycYYkJqyKsjZAwQf0WQC8CuodCN2fD7jQuRZWb8ZFE/Ho9mLEdmLYeOq/Muh
10d4JajCl1GQJStM3XNLquACY4W6Ll8/m/ljolfXgB9Wk0v77IgfDwjLP9HI
TU3ZcRZj0uYEX67vmZydnWLU8yn+B7meQ5FIbN4ruZDw5kY7jMiBaZ3p6Q/M
7tpKmPCSA2BoIhgdGNCVvvWG9oQUvTbKAqMtqoCPFYN4goOBix6MXsvNR0+6
t+GQWhcWCW1X+ts06+ChlsSwpEAwtMUrqDbonWKx6zq7XTZZ62W4pYL/+zT7
T/8wLZ5Pp0GVX6fAf+C3PsJ6az+q15pAb7e4Xg//x1kBVmDEfwG9X5D83yhv
OXSRBllEjPFe/tbv0fEVHbuFmh9GiCggMKlrmNhPJ9OKfpCio28TJ0Pd1ni6
Oi9q5d+qhKmVf6swaOWf1sbkyImrzMqzmmqD3zMN9WFzw6kabq6vDuUulWsV
nTRrk95U9FE6VxEDxC+QtFO5Z+FftxqXbDLpIjIkV4aithNAiZWb1ehwNKNa
V22jLNOELFNeaJu1mgkbXv3D9yvW3eT05bBMuLc1wYUHm1Bfi0gD3sJHAZVl
GXSd40cDXiVL6McE0CpTLeQ8nBbnvtUFYDo38va4HAM9s4NAiJMNyOZJGQ75
9YkweluW4xOkWyXhyXHejGU3A+A6HwAMj1k3boowf28tfjD1thurY0cjEt9e
HFlzF27AcwVF64QI70596NBugo/2qK2QbYPqDCHcb6jBWPLe1MQBAO24EHCv
c+/eBbJFbRGknASuxZGawhwUU1JL9VZh5ZEKCsV3lHSflaeUuNj2Lx11JXQX
0Vw+0508nbebHiIhOQCOKbPQK0egQdpQVbX5xmKkYfQqQkxBKbKmFymiy5FN
vgkJrQmYbICWCK6CQdONx6rwsIQRmSy8HhZCVuCxVIuoFG6VL28DqXKPCrDs
0zcgVS7DxJkznaqQKfKpqJGewBAM+51aUAOSN4rr9t0QwWGkLfjRHJ7G1nXm
wHc2jwG01dykNbjTClN0wqq9bFqBXZVrT4vKubCNjbKcxDAiz7jCI7Ycc+zy
+tRR293TUXN2UMM5rxZD3AD1vCWHEt+IDO6ss7mayUMGHw26tXmEB/lHvQI5
JCeLxqltJkCP/9Pemy+3cWZ5ov/nU+TQEWPABuncsKnajpAt2da0LTssVdV0
aFRCriJKJMBGgqJYdj3MfZb7YvM753xrZgIkbVV33Iir6RoTQOa3nn3FQ6e6
JL8OVHbqRB4obzaA38ZU8a0xVeg0I2ub6FmWdT6zTb8asnlwPgyFghqbHHeI
6tQyU6VaTcltPM6BtzrJpttvQmX92nxnNbaN6WUVxnIDZ779VtWBHjQBOZDp
cDAFjwOM7FH/Hg+6yl2A87uxPkQT6sS+O++qDhMHXc22+csn4Y+qYM8LLJQq
ohjvQf+YncYvbnVhKXlaOwngYs/5tFWB6B3joxjxnz0JV9FqLAWzHQ6rEwLV
CMZxRgZVrmXHIdnXFxeqsd8xhdW9xCF/mNzmQYpyH93vXuqetoAJjFjTDWe4
jMbet58/yKJzv7c8xye99mAz0+df6k24YK5+DVSH5EMHbKw73Zhbu1i3JW/4
2cHYJzWQ67h0jlP99erRxWvz9asL1V9pIDpskDL3pxg/fNXGx+2t2rOK3nPZ
QyEAR9fdu+tjIc7H4IBkScdvK5HJ+iZJXe2oNlb7ePKUjqWnRB80EJO6ofVD
MTne93SOr2pwRXeuRiOr0EipBr53UkqlVuY9KaEYpdtPNSWkdh6CIX3Kp4tA
O8TOBuKrtBonDD8wnsyHUUDPTn4HBXx3r+DBd/cLyXggFXTn7v/mzPivpmgD
B2b8Lj5lK4diUB8WGqrGGUL7+8bj3In17z4S/Rwy+x41g9/x737QNvCv/L0v
ut6IB704wKA0BftYVP5jn+590XToX/n7X/3dRzzETu+WXv5/rvURuJYkMjuR
a30u4nmD7+QiB7SlYR7we0j5YY3nLuo+sJGD8up/rwBlrLJ3WdHXw3F44wPm
Whrh3rA7PP8RI/YfA/j+VALgXp+p3wXj0sgz4M4xl+s9RZ1U1xwHJ9BvbQYD
wG+9CG5MBvsJ3BV/BIXPlun7vajhLuhOZOht7A+obq77x9OD7GHdE+iO+JwG
NKD7H9lHZxZ2Z5Y7HJfEXP/kv559HADToAfc5HgZsnWJ/+VjU+/+FPcCVGeR
Ppj+t1Dl+96zbPC/4LYHTlWZ/cLH4XfS2Oz05+vdFRVApiIAUrFRF2U+GEGs
Gj55JRncKlQqenTjNzALnHbf3Pq1qN9S9GCnFvQpRSO/X9c3//ynbloa6q+U
KXvtF8Y0camQeepNy8ZmUYz1g7py5SX0blU082V3zf3uYO6iOj3CguCr8Kef
AUzPXrz481Ns5lNVG/GWSmlT1C9uTYa7NWUBVSu50yvnxDHrV3Sy6x3VhWFP
yuWamrAVbP1uav6eG+3KaKHb9Y77ozGXI7MBl/X+SioXqgLg4Q1VfqS3VTda
vCbtnqmS1w6ypBTpJj/PJCwvqOaolLTblIArjKbOpMxt4CJ1Bry4xZztWmJn
b3Zr5WDtLW6nw3JzBhMMqE6ByiFQQ0VqT8g9nS5zDEm1t65Cavq0ZU7M+6Jz
GjB00D4xnl92RPUPbHXjrJx9s1TDssBu39mWuBI9q6PJ7brc2zkLvsIPFOi9
uQ1L7vhJ1VfzzafS3FGu1RR/v6ZuvvTEuw2kEIklNyUu2dvwlX8P7ZYPDU9P
VCEAqmPyzsa4d9fkdxz8ShUPVW6Vblk3r+dbvsfj5/v9Vfvoiy/eYvzr4gxH
8UXZ7N5+Ue3yZn+63u2bU/p8SlXfvtjv6voLsjd8cbUtuwD/zfkOO//rdluF
V0RiuC+ujUX2uv3h3CGaUXcB6SmZS91YglSCitycyVn49D1Wz13l1Hlo8L3Z
cjm+tarSzDXdzwWxuLwmBqNp1he3qhYnY42OSv/2l+9UldqfNCHxKJ0lORwT
7mS2CdnolI2ZdDoYSxjv+3XuV6sPDvcvDlXRTanIb4rY2zrDQw1/A56sphZS
PP9Q4+D+SEfaBwdqNFU52Sk/qltk9k5iTUlQO8J+cuKSc4ixx4hnVDtf7VbL
2H6TRP8EpD3A1m/GIdUC19xeXnqu3N27z/Qad0LNVQ0YsAlBRapfyHEbQ301
AB8vrq8YyaSV6OVWiIzpb9HdyeobqWvNxRwnus0rB8PTLIHTUJpzJ3RzGSKv
arlqw6fF7akOHO9Vc25lVYF7u6YDrkon092GbT8TdvPecGMDXsdGue6osRCb
oO18LxksBrturD6snM4b3eQeLjMamOum89hubE9grsKLAUxuT7Hb5hWoqJyn
15AX01Mdqauaq5i66Tq9Z02rYV1KigBq9c3ow3hlewqBRtZBUZf5dWsadpoK
e6fELJyuFypJgzerWxZycWQWljCyLe0efh6enZ3h/zff6QS31+PwSxa9vOfH
5gXna/uKSGOj59u9MGzFmWkT9X9eSztX7JKWJOkuOQcdeX0sWhxGzQ1Jbe7B
2u+NUdi9n43D76W1pqKmAkf8NHVApILqDNcAkv2pwLYuJuZ22QBSQFZo91zU
6G7YU81GLNiNGc7vJrROOSku7MWV2oiTGtoTjhxqMA5dSqSSSfgpmlxtx0FM
qWzF6KoKrjs/YisjF5rHDvE0TpYzDqyxwgAxqskg3cTVY5mlKj7bJScK5OoP
52sqSZ1rSco2yoWwpEUx3XW13xlFRIeT707pEtqTYNRyg033SJ+YjJVwepaM
Q0VetyzLN4qe8SWqJBagjm1aIn1mS+k8kzMlxhFer9tzvM43v/puNVHCj4ZX
c/Ys9kvHHlUcNRD6rovfm9MArf70bV69BY7q7z4VOX9LM+hezCfyzIl0zibC
dXFxTS09uXi96TtjCubnw3ScqTwRk7cbCGaSnUshUqsfoJzhjxFweRK+Asqu
VBtqSm3iN/0uVrkqvXQa63AnIitkd9HdDCLGsQ8YkGkrl/iMJslYWhPonk1W
wOGEF8PohcQZyUKJePUHquHVShX0vRe3UdWg1/VpAjHt4nazvQRIPTKEjUJl
R7QUqZD6Wch/f8n/+VuCL+kPIVLS/seM4R7W6odVqGntSr0qY/AOmeUSQTYb
hwYeRKuQD0c+cocht2CaZLmZ2Zz29UOIPAnUvCsmKzanj5q4d8Af7A6S6CWU
0HTiUcmNOFkpDRGXRSoNlMlQ94sVcFcQKY2Zrgvq59kK3g8ti6WbwGt+pAYw
Kp5POtXN/Hh9MbqoG7CDHT1Ht0QfcT/8WV/IgExSipbFQDG8hxUGX4kc3m4t
JDCv+jKkmT8wrMs3PgQcJ9ZuxcdBeZDlB00/AiV8qQNRLGbVWcBKAi9NB6mx
oti57o+ho8uC7WAfLNOjURiI26RElef2uo//UAs5KETc6h0vjavkMXfxJAXu
KMCWMMEyS5I36RsR3m+ovdzZWE1Cn179/TSevIMcsAKWbrZWYr42ounq7yuQ
c3rYfPMO33ALD60Sq0Uo0zWbQeTEVeiflo1e2IWTOIr/rX5ccQXQQGqQ0u6a
9QdF08tew4hVfnF1nvPlQKah7gb08UfawFk4UoQ9UPW2aZq21sohCTGc4mnY
mm4tN6ELEF0P85bXlMRM+ZBD2tmpte/8859/YqVeZ0oraV26sDPFgTK83ZGo
Edj8a866VLvTtT9VUVUDGirvnW9ItYvhja5Ib7UUyXbrs+pdgHnUIfG1soOu
ui5VIq3bnlJdZNi/SAGQ61bd8fnaY3TOEk7Owp/tepw7p4Rhxg7DhqGatIFq
yaMa1jkaFPjbnmuiu1nEICR4pq0v1xvCXd2qyradCxzY65xLL+eXSRKxB0co
64xICMwEQg2p+6zlmpENtBrXQ/kqB4N7oJQECRflvjciqpIVAnRx8+7Cdpl/
RFY3MljsSTKR5OoLoweCCJRcsFH1YsXE6lotQ+gewA13YFBhtsTieVGq043O
cYYspbJ9SJy7AgHY7Nes2ciLrE1uRBtzeifpfjmc+swp4tuAUgFEW9Up14YC
mwbyuW1RxNVyId+xacXPxQ76OyKptr64OOV2pDolnd62rXJNXrh0kTFWKpV2
3htz0i+rL63e72F45ZjVp9bSO2zJcWmFILq0VOkU8qekMmOo4lcqN+tdcbqD
ZmwZhhpBUMcqas4jhtRB7qFYmW90Nk0gN06jjomKQlaFlUdaVWNC0K8SrSsd
+AU7bFszcUr8KRBdQKK5/WMdq1tVLJwvURtsrvbrSxUUrNt97siMngftJZGo
luyLnHlW73aUM8Bo056D+tY7zYa9LpCONK5nYeXHF8B1joISqFfPV6biLE0h
pM3LMyC1ec3mZq7auwvI7nUWPu50qbUtI1WjFVcsMAr4RQ61hht9Ep9Zg4Gr
riosiZIEQn273I4jnijXDhMC9VqgjmX0oq41PSbeJyDRkVg1vEFb4+UJplAx
78fcQSzwzjq0DWc6m3LVAgEfNtOr4zCyIFe42pE0uIPE+QsFEST0pWfO2P3t
uf/j8yF7hrExWL7PVoaemq+FcmyRLBREsE1fNwknNzBgJbzVTjWWUyVuPXFF
JD9fgwxWsmDTLuaEQyROmQKeuCTP0om8oCJkoRJP1YZZcfpAGlLwQfVqdsvg
+I3vhHQrsZDhlX569feu/jfmKHnfcsOqsjWobqE99tPMjMSIAxGpaN0E7hxk
4XH0zEY3EIN06fW349mUvk6oI8YEqvUT+N3tXjJ2kufGutys90FyMIjUEcl1
tYIuRYT6ry2YxoCrVSxymega8MoNoqgQ93Vur9++BQvqd1+ehL9I857sbApY
6rWftThg6LKie9T99oaEhUCUJIYxDTGqjJBanrX6M3wQhdZUl6R+3bft+efx
avwxEAs/+Cmtyd8iPCYvq6/0CMnfRs+l0Kx+nX8+7YxAmhY/8HoiD2r0NYE1
B/VmNncRWBmblraXMeyeb9el1lcCKBS18REd0SAmqkCOOAq3oVUjjDWAhgg8
EV5siGQZ3JbXUuCbr9idk5NHyBi50X0pnXsMHJwfoJs1FPqS5GHIZLYI/jfU
hPz29OX1O6gU3377MhydfJu3++BbgDxJXC8poIiEpZOxW7CpQxWdjuO1becF
zfMEQ542GGlTXdyekHrktTriR0+bZm+e0VKRzWf9RlvRfNmI8e+QNHRM6vKb
MzsGkaBvTeNFrIwz1nYbrG0DJ2dmdsYHwWP2OO9qsh+qEXRamY+0TtOpgXZJ
v4VPeGRuJBMe/jfQXeW+7ZG4lch3j5989/SlbtbzGxgxCdV0JJo+HJhVv/rm
m8c//PCCGrI8NwKENKl2lSCb1MavOp3teNYfBtrgHZjV6Z828OpQcz7zqh89
s+q97FW592f1Ww79xoxyqAPowIL9bjx4Vb3mLtckMvqvcljYynxFXShdlArZ
/K1x7j7oJe1gunnTGuItRHIa5VPn/shQTYzXgItNldSOkHD15Ol3vzx92u32
zsTTtB0PTxxTv5h0T6y3S2+A6YeIk/yIpsFd7VQpoFReb6A/uzA/q7QcMMb4
VEH3K7cziSmPBSUyLGufQHDOJ87LW5G91unq2tujKUln8YHe8Q/ZadDJSq6h
CKvHvzx7+R9DB2v7uYvhLnDa5ViBXiCa7XbjYRJFFgHuu+zTKB2N6oefdhrD
BMbLqruFOm09O79pC5FtktjpqGna0qvYHUrCVuP0OhweaMMonUF5Yw9uf6t9
G04D1iAc6F7bbb7qTHDmTP+A1qQDM6t5sQCP6vlTDzYkddfwkTpimvUN9L3s
xDA7gil7w9yMW6Ph61CvLig+cqvF6eLEbyhskH9XUZEnJyc+7VbGTyfnGY+4
EYTt9eXoMr8aXeSXRZWHbx+Fb88YrSYibZwp0jZWEaS2ktHdk/OzR+Y2A5hJ
dOEaynq4z96gYusxFTBSdQz6SAc5ejsJ375h2/c4VI3kvfn8PQrLdkLof8Zo
ZD96cwXdYfcGa0q486Ae0zyo5v78S3149NCZ0H1u7qAbFMad7RMY85ZN6Zk7
d92tado/gNgcAJsXvR0/OrrmoeWpOgSKOT5RcOpSwJ6n21Qb6HQzPSh/Hu5p
+u3F1XfyxtHGptyZ1OtrKj1KTVtTbh7d62s66C1WpN/MpG2crnDryhM9+VuC
R5//9PIpxMb7Be+BCT8weK+42BYmeO8LLOKNWsTZlVbguemXX+zFPc9OicrO
VtxWq4Fpsepeu67Z6jcT73xro9FVdsaaa5WYU6c1eEG5LHAONl81kXvyc0WD
3hDLxJ292vg+Nnbt/xorLXTzT7GJXG1b8Ujo5tyrzYoDFhwJo0updcgNc0/2
7H3P3tou5Vrh52818V6tRSx89f3rlWCceve7N2u87b35av165T7yw+AjgqLe
gz/2HhQC1h3wZ36uS8fw9ufx2HuQlXV+WPIucJWj8d9G8uG7p8/f/PTLk6e/
hF+EGBFvDvWyHW5lO9jqclgdk4aiXtF+bkgr2+xwvvEqVOEvA0g4Fl3Brwvo
jNVhZPcZq68oqbF6P/SVudA+7f0woLw5j3o/6LORPMnuqJZp3mcrbuLOyh3G
Y0T3GanbddaM5P0woLc5j3o/SGvOHi3SHIiomq3fRRzA0jTNeKhMOlnKv7Nl
pQ9zn1OGqn9SW3gdFUmW3Um4suC2Evq1stkWq07omu0X3wYq3EC6SA4ShRCy
HXtdN2F9eUVBgCylsk/6zZoUILz5MwWJ8uIHJTlvfSpq+ro41S6UFdUUeKNI
IKE5f/5+JRbQcEX3y1+tuaYYyI4QSfL4uEvV7mrlyeYG2GEo1nWOW+DaBVxc
3LFsyA6emtBRxVS3+oi32n7eP1ZyEu1MDh8/3oq+4ZtOdFaK7sfOb0iOhR9H
xzI1V3lz96XOZK8P3QnWMH382Oy+6QZqmKIMnoefhjNWAXOH3zgRinJcVoNu
T5xQs+FFquOhL2j81StcE5lSbX/VFY33xm7htQJMZ72Ozq78RDzWmh6QFU+c
IJlHgcsTbijtVMCER5+EzmkZM6/zHfgKHntN23eGucorStuj0W4gZ3o1ucBx
Tpmh3ozH+jUlPv2VSr3jAG7MnVDUA7m1mZMRFCXG6CuJGxyFQDZbbFUNxYIb
DsFKJd2LAK7Vu/P8qlWxM2uJz6N0GcK5y1xaLarxrtblOxpJAQ57gfzOuFRp
vqWAGJ5wS5vonEf30rRdh7wU7V5bRzo3J/YVoZK9IUaKff/tHeOzPvFX7147
eP1OgdbPBEYDENrz498DRh/1dybDsCgBVBi5SzUw4375AwONDr1UO6QZvVQD
I6ETemm87F6lcYUyfKuhdODN6LE1QK1NFLWOD3dHkaBz4UtOIJHQehFsJfhT
txESagvYLrd10/Bf4q0Rsmt++H5FTSiYAssX61VnSC4ybxwTEtPnnerKWgnk
HgIh1Ir1SZ3n+7E+FoJc1qfp8kTtjP6wktJBNthVSgO3T4VPXDRL7NO6h/FE
tT5LjQeYH61e3cdKgd1KsUEm/yt9J4f1oAFJ4Z//vcxNVOV9faWKb64vcmM/
FCHh05Z5Gz0ySs/G1Bahvtr7F2UyTDwUU84Np1X4mtHRGJTvCnMT3CxuTbga
lD1DrTQAO6RKiRer95765s+gnft0RiYIrk+8epTg79SiJTdors9GHUx2Nu6P
QUFPKvrEBkRtHFd8n0D69FEWeZxEUjl+i1OkrmERHKNFUQX7vxFLHEvMNCeQ
tTq1izOBFUmjfODHX//0y0sGsvP8Yq996SpUrBOnqxJ284osx+LwvKjzd+p+
8C/3A/P0qfXMTWNvL7dM5P3b3Y8t97fS799XOkThB1IfRW//oJiXHsPlZzLM
y4E1dGmwUzvg1fvXnLxD9PfV7ZvYTegBEQ7wnUMqn6jETp8Adoft0jjJo2p1
Rp5OtlNxIF35HxSLwubNYEKwAPAT2j6TqFuHPH0g2kRffb/yXVd0oEdIk1By
RZoEmh4IxsNU2QfdfyiO/oGu0IH843yarlmIIeRtLb/8w8h0xjYvEwHiMc//
+DIEbK005ItJcvUtVqqCdhnkA6fJ/Orl7hq/EQ695xIAiv6qd2yGhY4wVI4b
ayzzKoloZw3Wr61eFBr2rvZ9KGAkHaeGZpKum2FlwhFzrDWntNdbXgcT2pzC
Qv1arGvv68MGUv85LifH5VXFLrvjsNZuSnV7Ju6167ZjYdXJJXQWIw/WSNvP
N6rbk4TaiU9wIEBgdMBaIP1yqNodp3++laBEknadqL9AnB++bRRwT4RZc3fX
wPrLAfNqa/RRgfhWKh61H9fsSl+94Qs7Y9qoW7Thi28wwR505VrXWNZ5EfaO
1q0OpeS1U7giaSqPpESge2sm7jGQuEfOHjaxuT1vuSKP7fWlxnfXm3WmgMks
iOHg593bF+d5qu7mtMXffGnSog23Rqb01pjLted6otg24J13DOBXYEWi8yxb
MTjQ360znOug53EDrYea0chHPdE70TlOE5WGkZicCB2k1Vr3GLulJ+GtX66X
fNS3RxJrHFe3OxhvityUjodwlr32x9aRVpGKtJLEGvnLTtm9UFUbxFQtEkGZ
oGHzFswRaG7qabukIyDSIVkvvm1f8ux0IsuO7/8S5/UP7qYFhnT2AJOttdHd
33Z7LIKGjX2vcFCvVwfn6YbOyDvxoTfCg2bW+OAbh+2td74zYPyN7npnwDaq
PcmriangZeI2B+Ji/HcOzTNgWB3GP/2Odej5ptQeWjD8O80nQbdeXF8KQHNo
fZ+scf4UFSwj+FOqtXK4tGIogYR6atlIwIdwNkj1bBV5/7TC5G8FCMl4NdHm
TPoo0cKbIG/bbblm1dPgSI/qmfV+JPKHY/GJX5ws7kP9yL92iDS0Nt1UbdDa
CPzcLX0OZNxbXZBGNlyb3wRJCGGVRykfWT3GNIMa0nTqoY2wvUnoxYs8k4ux
9Zii8Cvv/rY77+NXX4ZJ+NlnIUayLpChMkf8Y9CpP+XUvrswsDDyxhr3Ck/p
mnX0GN/JaOSt6KvwYhz+zzAeHy4haEJV+ABA09UsmmR/GdrBI9tLYHQxCQsO
Oqg315dsBxnZl+nfjfdqHP7bv2Ex5lc9/OdkMP0sLNz1vVI/vnbLZcn6dJTQ
mwPNEWyjIDwG7nSWt2+uFXUZjY/lnZJGobNDjNLjljHeblQ6OZt1D3B1FWx9
kLHHxxi7ic33GbvkMT+ctePAOowdGPva7ffd+UnNS3VwlIsU3+pLJ+XTvkmM
X4PCh5BrYF3Zq6cRPveCxD/Ym8e3QyPZm5OdPoyTP5SLH+Tgst4eSz7IvYlq
DTDwQ5xbiNzg+h/EtQ9x7KPPP4BbG/7zYJ59lF/3WcZDeDVRE49Tfw/c3L7F
Owd5n5MOBgVrfWldJF5DakqUI3/If16Trgn2V9wqk6BqDSQKzLmeb4iZUzib
RIqTDmMeDYrr8h3RiK0YX0znGonxl18pT+Rr/iukwI8PNCvXluM6JZDDJA/E
z8RXr6pUfFn6P2oVQQIVXOJAW9HW6856A53XRaKMM5ylgL5ttuSs2k9bHvpU
hpYyTtd10HD2Ndl9RHDvKWys+bWd6FSXfDMjwRLVaf3LhRkDOb9HpAnYVCRy
i3Fs2X2Zq7eXe0w9whWT1nt6vt33hBgNrIWGDSokxmmDHaU35CvoSzVmn0dl
G0cKccj+a5BvE4lqHnrljPPa5RPxPWQMZzl9zuSzPfzusX/n1V5Iq/C1O2SC
V3KIbxgWfbmA6YP7s2S60iyvj/BdARydXzVyklMhZTrAIwqvcdI92wdK2uAO
XXL10vx8w0UNyX7fdlzW+l7NMQyx9sAnxQcZfa+/Mg5O9YKykcByeJ8oWyuT
BSYiGhbb0LHVSFtV5h+mdd4fkSDckR4iSfTX7FJKMhgBg2JZLT6ZtZ46YExW
ff3Jnsz4bL15P7ICcNFbsx0PKy4CR5Zy1hgTVnm787LaOk9+RhqFHXhQUOpk
ZZkKa/UVp4IrN7IlTyap2qMlpqIed50ySfLrVqcIVNqazXVTb1WZ2AfKaQ8U
0x4opR0U0oSKDT4+IKNpwt5f+6CIduzxAQkt6T1pHz8moA08PiCVEZrrV5z9
PlAoe4BMZuiRSGbhz9uri3wXk51f/jps2lePgtBJufJ+jvc+b98pUUtV9eDa
dgEV3NRBDTpH4+tnBCPaZOzW7qB3rNi1ulidkj1ARmhNsMJF+G9fhjxIv8SX
RK5I98fcS+0/KTHjugJvowoWJNJJQIm3gk+lGuW6lZIf17yPm/CS6pIpDzmZ
M9UA5HYwXgIZW/2kpSJdMkjK6ylNs9xyj7FLCGyOVUTOmHB4vy23FyYjNomp
DoSg/03uFabzis6d1/n7W0g0ewGA9xxSrvauajTIOZ6Fj/e4F0q1Dimo6MKE
D8rEVFWudUsVSYiBc7Xt1QUxS/6fM7IQKq8ehDjahLjVpv6iCTGwJ38WJL3L
gHDKeVmqLMl6zyXqZEfdA6cujG1+y4ZQVXkeGtZZkPZH9RyEDM5bkWg7p2V3
YIRkHW2oSkHaNCfdUckVqb0Gp8YRwlNwHENvB2dB1l8tnR69ud71GmhqcDct
NMnyttXFLFu12Eu3dqWA37WK5TkAulMVCPF9L45925jFCh/bluX1js7B1Ghc
gcRxcumZKjhLyzAvUWgGF2fyaIHyrNKE3jHRYKcM16cKrlkc+Em7T/2ii1Jd
5SB01GdvzyZOuNKViWQkL3deQdW4Cn/7zfhq+UNsPMMtyYO/gFNTfh9FbaS2
cvKmvrnjYgNNbDuFwTgUAtB98kzrpADxJ069pJ+5AItukBmOnj35+dvxySQg
y/X6UlIIbIJzceuRDbkjU9BAxczgRpUinQfHpqKZMNx3z+KMki++3q3rhmtB
hviFNsJtL6iYqxlECsf63UDz8ISz4w0tPKEh9AclrSqUZJBmh+J2E9RON2QV
NkQBjUSoiItJ1WUZ+0SXWD9YuRdXTdXH3NDIzZaJEtW/veUq2qaiC5NDXjNH
OuZc68tdI2VobkK6i87pYla1Is58xOCULbXhDVO9i/WGK6kSWTMFdHbb7Z4K
PbGMLrwAqPSeMUj0T1vSmUnhCRseTroJjteb9X9e0/VWpuAdTaTxkH8QXUDT
ez5G9kzsz52SzeZuzJYD3owp1cGmBKcidPd4RM/Q0WGqpKg28OSbgA9OSluR
vOpNKpzSZPloSUNKX2ge9Sh8aZgfw9z5WlkuVAFesc1MJO7KLwqoSASvQdN4
ZUvhlwKm+FWlmxCLXYRw+BtdSkiH+PE99tF5kOuqmIM9VeShMnEYlqUdopcF
gTnVZuKLvCCnQrUuNY0VKuJTWDcNPzB8/a/MGXxpyL8CVYpGDUnrPzFHXOR7
qWCtBR1iPLzc0Cz3zDl48dpoCm0kDxVHIORQhpr0BD0au9v52R3WWaAAZgDq
vsvL/YCoYxBJsMbkcQvwewWC9MAB3xxVjKXAMynUtt5wCX8pm11IhXlhRLqf
QGde4q1tTZVCdbUr6ozMHP8UxPl9XlI6v1NEieLVNB9QVXDZrcigaJjJCcRv
uqsWenBJVVlPrGjm1DIi+n6mKqXqn+sN6SStR1O9humeZMNkSRENdV191qXB
n1RoU46PaLoyhpyYjHLJaje50VxkSxWXl1gukd4VJVf2FO0a1NUDdTHqUOih
CrozWXbmbrWK4kJ35ZXXpENtO3mFwa+/rqurhuo55jar2YtbohHfgqlSoA89
eyq6kco+NDqTNNOkovZOrK5So3r1TPyqrirxk9ZHvTBUUnYeHFgPmVOt7NBp
GqJnpFewq2DvhjDdI3KJg77uI3i0Inm0EAg+4SO0DNBxaSmlQzpHsgGDrNyr
5G9KylP6m+h/WhKiqpmdyg5yNs+IGmvzh/5aeCc3JrVWWdelzwabQDlGaKax
KppldBet1GouYWtuMoW2VQWkZ1e4KoC+VDNoU1vx8YQ1pxNVc9V1x7hzUtGe
tyb63XYfNwHpohfxxk7w8ImdwFGNwr96lT+FE2D2gCbnUDjZRkR6saKc/4bd
/7BSNcB4fFqLWyHAK4lJ2+V9vvrhtcQtyjhGIMdUrIur4Uk2d07NUgZC98CN
b3xsTlkG8+uH5M6A+UaqMqnHb1fdcrnY74uvKZ7q+djTTIQtklbMiVZU5+T5
iiIJWkml8DNtaSGQZm8F6DiAf8LlVruP8XHqk2Tky9du3RMdDfHDKrCbODDM
LQ+jAB9npzbyw3jlkTx2FWxbsHR3Mz/YzfCLtxrIJn5BlVk4iuOIwFHkzLG6
vECtNHUOO5nyw1E8lpqDc/oYj1UFN131xFY3MKKiKq7FOCEV8WwciKneq510
4osJVHjJX2u3hDvbz6VZjQ4haR+FPykkW2+AICyygvQoX1CwegbSI1EKz+j3
1Vg8ZhozAQiNfsd59gd8vRpDFPjpehccpK6jLjkdi2WJkrhyrn0o5RR3KtyF
IkSdCVlI6Kzc6RGxVczZEjJSFZRQQ5oMFd/y2Ylj/nHr6MckRjj1YXgwt36V
nKkqzqKaNJjIDzW2sDadV/9sE+w9NntTqzZLcop/qSUgl2s/nnPpZiUzcluk
1Z83WNgrMmjS/zqX9Pr1JOz/RHfy+jUXc5YSr1RySe65DZQa5oKWPdVupWj3
3ju/nY05pKktIanVOjN2t1bNB3wDpqHNkl4vG6e0cyZz1tkCdAHov+H1PBrY
mNkzP0YrI7fDwOYnhKUVDcL97KQMq/rw6oQfZms0dXU7kWI0L6+B568wnHqD
RuU/X782hNoptkmQceqzILdG3OgZaw9huJK0XTeCxo7EHXVb1Y+Da9DjVJ9p
y19rahWK7hQatrA/100vDQMV/iq7VmqRsElbVFK9/OOfX7yk8nRhL9TB5a62
71Cu28eSMq90OTad7VXrIIzUVT9c6GJxXeMSTqztcPvcsVMa4CCGrFoNu+Dh
dng1d4sxzd/MuwkonHeUtP1IXbH95ezsrAspDAoWLxWND/3CsxNqdLWvuXSn
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
DiHu9ZX0FYtnvn+ybwyRx/fbLdClvurYVJQcpgZLk7sGo2G4RLl+172yDgly
SMKgV+f4Q87yJmEmD1/l5TueJvL8MPJgxxnTOTfn9d9s6bp/C0fGeQcAXFuI
9b73D+vzcD4Ov/giXBzbgMw10d3NhhqgKFgcuHqfdmn4VAc3gAyJgwyJpitS
XoXZvF2WN5ZPK2SD0upkcJbMmSVTs7gvHZzMfejACXvjDB7wG32i9yQGBlYO
rIl/HjubcAUEso8zRtg1AjEM0DnBHN7ePNeCRFEofqZW89VXXYAL/2d4+Ufp
jS6tT0m+rvrDGXmQ91+auiFSnqyTHqkKberiGlzdxSt9elOrogS9MgcT7Wsm
MivgC5nqes115tg44RTBgxCsqTIvSa3mba0K/G/InmSkUv5kqwLqxM7Ar0ob
fBW+/OnJT1KPmAXQUpdOfrt+zzHOdmkrqq633dlCPRS4R/OokCydpW+qETjh
cwOFCaR8gi0OQ/qlNrYFXsESU5oAZ2tWowdsVX9oKWmyk1X3DDKsY1Ffc+mP
SV2u6/0thdxJKUvSAijGTiWz8KrYaCDailJMuG3WDpo5NjShe7XXQ9WtqWR3
weFzEmoH+eZbaj7x7/Xt47qNk4VursUtKahYyGnO33Nxhxd1HcjP79vT3VZV
aaG62NbGqqvqludbKCH90i337BFzvDuMV7blWG8VrzoLc7VuTU31oFeR5diD
XiGUQ2UTehVQDvWt7RU1kQeT6XSoN8snPYg7XLvEg2xOITVwaawKuHWdOMX2
AYVqT1Q1DBW35dQ3YZPnlmI5ORiYCmSItZhrEWMldFq7bSWPYzwVj2T7g1Cp
q1xhY+VU8XFU9YNlBjmAstURlMboETTGJLKCskrEeMwZyKQT7/b8gWOMlSTm
hrGNuPprp6azPmHSdKHmm+GlvKVfDYtxjHwf6uLcYrJSqzRcffftKOG6YFor
plQ7l55y8r1bDNKp+KgL9nnJxeAk/I5pPutcLoH8MQFPXiQx72K7eesyJjs/
86bOmHcJjk4+pm7wLbaYmx3m4VJC7mQmDdmZ5mNlIivDwHrP4rnnyebs4kc9
smeR2EkO4mePPPpIPavSG9RcZt6zcnt1qyTlcr+7MH32klE0VubHhLI+jWoj
3PjNzXZXdWwZnXybztUMZNs4TxzPtanJSx2OFDhBeulfu0xOqid3FbYuEyr+
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
AUWIcfOmH158TWLQj/gPy0Q0gKTSkNREbVO9HrC6m48xWNBAAUc+cFoKhezY
AlJs/XK7v9HTYb7b5bdn4cpFVWxHxe20qmsmq/5QQ5QU84gi/mXHlNjijKRM
bFaRkHPAt4HpzNs5I9UhlCuu26PheCw+OB6cFD287ZxS4JwSVxXfb6+uOOGB
q+zLuv/zum79bFwa/Iz60PknEFCuIVebU0CjvPgT8oIBAq83UqtXbs0/cW1L
3vOpUzYETm23veEBqUTYTvehdvuy2jwZ7sUaBF/fkjk0v76ACqzi1aSGmYmU
UjmQTijXaNXpicM2zgDU5cV5nuqoKfCDVLXBWbe6sbcXLufHFtk2ddzO9yx4
+dCm22TNut6RKUcrubkWZVv1C3ZMK2lVusfNNgSckg7MiTrq7bfb/IK6lcZn
oJjcb/5R+Ji6NuwprnGnqmYJ+W2V2r0nV08nZU135uS2OVwTHruTCnwSm+QW
goDGQXBKvZoZnorttSjZbmoZDXC+3WDnNJoeqqhvt2Qy5NpvXM8Ld8o6jYkv
7JpMz3h3v2yL65ari99zg96GnN3QajAtQSMVrqs7qXuOKRVXLhuUQD7O9fEX
KDrb4Z3rObGFb0kEvvCiu3TT0VKIws7scACCnvz8y4skpUimxwyfgXJPlBQ1
We5ur/amvhnGvBQwZa+FCdHkkyKjYf1eZVvh4t7XwYE1MGTpTlVccs9mLlFI
Ge3zBvTmfHtD1I+NREFu+ydKqhLlQ3GfvJaLuOVhU99Y6MXaQDH3a3K3NbaN
NXffZQSpL25t81BN5smCdXrBFnebcMuEz6ZcKbXcSyN/V99y69anLaH1uuW7
Vb1KtC/7ESm4nxFSNtLcEXfm1dw1T4b5JVnSvAam9KRuG6jtAt2esx64/Ymp
0fCU9sVTp+IvNefSK9BTOXjanVI27NVRJJ8e4OHimg1o9gpsHK2uYiWpfaUi
iJxlLi0mW+qETbR78369226kl0Yuz6kynq0JIDwVgU+DmZqQeq/r5l0Mh5Ij
aBFREZntRrlpLNZ5HTxozz4hojQ6rID643lYmbPVhMnMjaolKJ1FG7AgpxRz
0CNAYa+gKS8OwC1Nqg/NuJFid4cGtHslgz8jSGWLnNqXqBgBN/QN8hLASs0s
qZpmQy/r1qHSobeVuJS87dXiVEwbL0ouIfQiSSDcbS+MlZjuDxf800YlFzJ+
Cw+qtkwDiLDwml7cFusLRYVbok/b6ygxgZa0H/5J2tbmFYlHZLLZghjv3kvV
W0OY3YxVcqNs2ktyWClXpSoDS4awNuDoaZFYoBUTceIyn84pmHG42ieAjaQ7
Nldc7/kUrq8UplytaenF9u1161+brlFomskZMt5pEEsQ9PY631W44XzN7Z64
4Ntu3b5rnTRv3c4D8GE4FVBP5aHiIC7XLSHjJBDEavWmHbxn0xhRaDp98hUx
V/EuZ72hJk5UyVQjIWhn0/B3RFQ0BuK2brbRjG6L4VCalF7hHfLY4eB0K2y3
oqzClvfr+kYaPok3ig2mUpJ2aK5JQCRc2Tp9wkPnVedMbAyA48XNltQVXsR2
X6vuKnrl4LcW3LF6YU4Qy9o1yWnC4aCa7Imk87bEoM9CKw6bNuUu0/C+ps7p
HRK2z96eTeju1huKtxcP27rVNTSEMOpC0Fj421rJ7pfb91JYWcnXtlWhCLe/
CHX1QewvLn+CqivhNx7L2DHVuCIpUcuiqhCXJuhdJicdZN5TSgGlIajkYfUw
4zgkqFvBjepaQh1AWeorkXY7VMSETAfGwi+rAt8VwfOlKUfsiA+mfKhJnO/2
925tyRHSn8g4LCyztx/lMDJY6NQmzqnuEaQS8mIqpJHSxAWJNxc8nnS8vdji
at5ttjcXdfW2NvkOavxyh1sT/UbCdRRyMkhpBzcNJgc12JXkrHMaFmp7IuKB
s6C87PXe8Sr0jgJjipCqKBtdqyy1NQ2CeG0Dh8XLd87LqSeuktP5/u1pDNwE
jkNEtZxGk1AXmV/qQEtJciX9OhNgUPJTuMnzVm+goVxaM9CGKAh+rGsNxFye
08Di2pFcXF8JiR3svzPiZg4KfNuyysh0pCHhkXUFTryyMvZLZn9+iW4Hth2e
o/WQSQB181YjGTNVlr7LLQWH0t9dOCUY2Arxx1HvoDjviJCqywz6fdeY/NfQ
BdsKIpRyHq13fjJ/q9D2VgMIfbg8C4y6uVb8+XJb1ReC+aQRDGF+n64Qulzt
AxzoDqzbamzqEFT0oIZ7//zs+ZpMMIaVXLK9hhW64JhC55zNQNcsM+BaXRgr
IkF5vt0qpa+3P91tiK0qfRjWrYVUm23NjSitASoX9V+3Wr1/sP6hd45ZTpbF
EeuuBmexAS12hoklAGSQ0Jhf1AR5Bv/PgtFLNofxbBft1ma0cTVXLR1ZgmG6
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

-->

</rfc>
