Draft: draft-pda-protocol

Commentary: by having the collector pass parameters to the aggregators for each round of verification and aggregation . Reframes the execution of a PA protocol in terms of clients pushing input shares to the aggregators and the collector pulling output shares from the aggregators . This is meant to satisfy the requirements discussed in . 
 Each aggregate request corresponds to a round of the input validation protocol . For Prio , ; for  , I think . In general , I 'd expect to be small and constant . Yes . This is indeed a problem in general . For Hits the latency is unavoidable ; for Prio we can avoid it because the aggregate requests can actually be made as reports are uploade . ( Note that this is one of the requirements outline in . and mention in the comments some ways we might deal with this . ) That sounds right to me . The collector 's state encodes whatever information it needs from previous request to figure out what the next request will be . I envision this being pretty application specific ... I 'm not sure it has intrinsic value to either Prio or Hits . This question reflects a requirement that we worked out on the design call : that right now the " batch " of reports that are used to respond to a collect request is not well - defined . As a first stab at this , we will timestamp reports and have the collect request specify a time range that defines the batch . See above . 
 Rebased . 
 TL;DR both aggregators need to maintain state to enforce privacy guarantees . Seems like there is an explicit state / communication trade - off to allow this Filing this issue based on the design meeting today . In the updated design in the leader is in a somewhat privileged position in that it receives reports / batches directly and is the primary entity that keeps track of state . For differential privacy guarantees , we want to bound the number of times any record / batch can contribute to an output to the collector . This requires some statefulness that the leader could help facilitate . However , if the leader is colluding with the collector the following attack is possible : issues a query to the leader : " aggregate the last day of data " protocol proceeds as normal and the collector receives the aggregate data + noise issues a similar query to the ( corrupt ) leader , asking for that same data again ignores its state that would otherwise say not to aggregate this data again and communicates to the helper the same data as in ( 2 ) collector receives the same data with newly sampled noise , and can leverage averaging attacks to diminish privacy This is all possible because keeping track of " budgets " is the sole responsibility of the leader in step ( 4 ) . To mitigate this we would need both helper and leader to maintain this information independently , so that neither aggregator has an advantage or can reduce user privacy on their own . To do this , the helper will be required to keep track of ( some ) state . Additionally , we can rely on the leader to keep some state on behalf of the helper in some way that maintains the integrity of the data and prevents mutation . I believe there is an explicit tradeoff here in terms of ( a ) statefulness of the helper and ( b ) communication cost with the leader to maintain the auxiliary state . On one extreme is the maximum statefulness in which all state is maintained by the helper ( i.e. the helper and leader keep similar privacy budget databases ) . On the other extreme is maximum statelessness which would entail something like the helper keeping track of a single counter which " versions " the helper 's database stored on the leader . The entire database would be communicated to the helper during the protocol , and a new version would be pushed to the leader for storage . How big would this database be ? This is a bit of an open question but it will scale proportionally to the number of partitions of the data we would support querying independently ( without impacting budget of other partitions ) . In the design outlined in we would partition based on : Some time window ( e.g. hour ) The collector 's identity Some application specific key which is specified by the client I could imagine this being large in practice though I do n't have exact numbers . One natural compromise design between these two extreme options would be to partition the auxiliary databases stored on the leader per one of these keys ( e.g. collector identity ) . This would entail the helper keeping c counters , one for each collector . Then the aux state transferred during each protocol is just the state for the relevant collector . You could presumably do this for any number of parameters that are available in the clear to both aggregators ( e.g. information to or already in ) . 
 After the design call I made two changes to that might help : client now includes with its report a timestamp for report creation time . The associated data for encryption of the helper 's helper 's share will include this timestamp . That means the helper can authenticate the creation time for reports generated by honest clients . PA parameters now include a " batch window " , which specifies the minimum time difference between the oldest and newest report in a batch . Moreover , collect requests specify the batch via a contiguous sequence of batch windows . I wonder if this is enough plumbing to allow the helper to prevent replays without needing more overhead than a counter . Suppose for simplicity that a helper is configured for only one PA task and only handles requests from a single leader . Its encrypted state ( held by the leader ) could keep track of the number of times a collect request has been made for the reports in a given window . It knows the set of reports that fall in that window , so it also knows how many times each report has been used . 
 Can you elaborate on exactly what the encrypted state is going to look like ? It seems like your suggestion is the " stateless extreme " option I outlined in the original post . My concern is that the state will need to be a map of { batch_identifier --counter } for all possible batch identifiers . A batch identifier could contain a time window for sure , but there may be other parameters that make this map large ( collector identity , etc . ) . For example , we probably want to support multiple collectors issuing queries ( with different data ) for batches in the same time window . 
 Yes , I 'm advocating for the stateless extreme . My assessement is that the communication overhead will be negligible compared to the cost of re - transmitting ( intermediate stages of ) the IDPF shares in some aggregate requests : IIUC the cost of the counters is bits , where where is the number of batches that are valid for a collect request at any given time . If multiple collectors are allowed to make requests for any window , then this increases to . Concretely , if the batch window is 1 hour , and the leader agrees to hang on to reports for at least 24 hours , then . ( Not sure what a realistic value of would be . ) Each aggregate query includes ( some intermediate stage of ) the encrypted IDPF shares of a subset of reports in a batch . The size of each IDPF share is bits , where is the number of bits of each input . That 's bits , summing over all the aggregate requests , where is the minimum number of reports per batch . Concretely , might be on the order of a million . Perhaps I 'm missing something ? 
 Sorry for the delay on this . Yeah I think this hinges on numcollectors and numbatches . For ad - tech consumers I think this could be in the thousands+ . I think num_batches may need to be larger than 24 too , if we wanted to support something like larger like weekly / monthly aggregations . But I agree this may not be a problem in practice depending on these params and I see the benefit in avoiding premature optimization . 
 As discussed on today 's design call , we 'll resolve this issue by allowing trade - off to be made by the helper implementation . In particular , we will neither specify how the helper 's state is encrypted nor " require " the helper to be stateless . ( I pushed a change to that reflects this resolution . ) 
 This looks good . This model supports a stateful helper and a " mostly stateless " helper that gets all its state from the cookie ( It does n't support sharding the cookie , but I think that 's fine for the time being . ) Closing this out ! 
 At the moment , the spec thinks of a PA task as a one - way data - processing pipeline with three phases : upload , in which clients send inputs to the leader ; verify , in which the leader and helper verify each input ; and collect , in which the leader and helper aggregate inputs and push the output to the collector . The upload and verify phases are currently specified ; our next task is to specify the collect phase . This pipeline model is a perfectly fine way of thinking about Prio . ( Although there are ways in which one might use Prio metrics that do n't quite fit into this model ; see . ) However , HH does n't fit into this model at all ( see ) . It 's apparently necessary to re - think the communication model for PA protocols . and I were kicking this around and wanted to share some thoughts . First off , let 's try to enumerate the relevant requirements for the PA framework . helper is stateless . ( i.e. , the leader and helper ) enforce the batch size ( ): As long as one of the aggregators is honest , the collector should be unable to see outputs aggregated over a small amount of inputs . should never learn more information about outputs than the collector . Moreover , it should be possible to design a PA protocol in which neither the aggregator sees the output in the clear . ( This is possible for Prio . In HH , the aggregators inevitably learn the set of candidate prefixes at each round , which leaks some information about the output . ) HH requires O(n ) space for the leader , where n is the number of inputs . However , it should be possible for the leader to implement Prio with O(1 ) space . aggregators verify and aggregate inputs over multiple rounds . In each round , the collector specifies the parameters that will be used . ( In HH , the parameters are the set of candidate prefixes . ) [ Needs discussion ] Not every PA protocol will verify inputs ( ) . We ca n't satisfy all of these requirements in the upload - verify - collect model . Instead , we might think of a PA task as two concurrent processes running asynchronously : Upload process : Clients push inputs to the leader via the upload start and upload finish requests . Collect process : Collector pulls outputs from the leader via a yet - to - be - specified collect request . The request carries the parameters the aggregators will use for verification and aggregation . In this communication model , the collector may attempt to pull the output for a PA task whenever it likes . A pull will only be successful if the aggregators have verified and aggregated enough inputs . If / when inputs are verified is up to the PA protocol , but must occur before the leader can respond to a collect request . ( In Prio , reports can verified as soon as they 're uploaded ; in HH , verification can only occur once all the reports have been uploaded and the collector has issued a collect request . ) The helper will keep a long - term symmetric key for encrypting the state that 's managed by the collector . This ensures privacy while allowing the helper to be stateless . At the end of aggregation , each of the aggregators holds a share of the output . Before responding to a collect request , the leader requests the helper 's output share . To ensure that the leader does n't see the output in the clear , the helper encrypts its share under the collector 's HPKE public key . Open questions collect requests be idempotent ? collect request may take a long time . ( For HH , the latency may be several minutes ! ) Is HTTP the right application ? does the helper learn the collector 's HPKE public key ? The collector needs to prove ownership of the corresponding secret key in some way . 
 Perhaps a slight adjustment to upload - verify - collect would be to split into and / like the v1 / v2 protocols . It would prevent overloading the term e.g. : Prio : upload -verify -aggregate -publish HH : upload -(verify -aggregate -verify - ... -aggregate ) -publish I 've been thinking about the protocol through the lens of map - reduce pipeline with network storage ( e.g. Spark and S3 ) , where computation is represented as a DAG . It looks the like HH computation would fit neatly into a batched pipeline , given a fixed number of verify - aggregate rounds . What is the benefit of idempotency in this context ? This is so the results of earlier rounds can be used as inputs into later rounds to improve performance ? One way to deal with the long latency time is to use a task queue e.g. rabbitmq to wait for responses . The collector would then poll the task queue for completion before moving onto the next step ( pushing the results to the leader for another round ? ) . Is this not solved as part of the upload phase ? Or does the upload phase only authenticate the leader with the helpers ? 
 This seems reasonable to me . The one downside I see is that the number of verify - aggregate rounds may not be fixed . For example , the collector might want to start with a set of candidate prefixes . By doing so , it can reduce the number of rounds significantly in applications where the search space can be constrained in some way . ( I 'd love to hear thoughts on this . ) Can you be more specific on how this fits into a map - reduce pipeline ? My guess is that you 'd have a map - reduce for each round . It seems to me like this is still possible . This question is about usability , not performance . Imagine the collector is some person on their laptop , interacting with the system . Should the protocol ensure that they can re - run a query multiple times and get back the same result ? Or is this up to the implementation ? Sorry , this is a bit confusing . The upload process involves the helper 's public key ( used by the clients ) ; the collector phase involves collector 's public key ( used by the helper ) . 
 Each verification / aggregation step would just map over the data , joining appropriately with the outputs of the previous step . The reduce step is done at the very end ( with the collect phase ) . Iterative algorithms work fine with map - reduce ( e.g. power iteration with thresholds for eigenvector computation ) . It 's trickier when the workflow involves multiple parties because you have to persist intermediate results to a shared location , but it 's certainly doable . Coordinating work is the challenge , a task queue or something similar in the collector / leader would abstract some of those details . It would be difficult to guarantee idempotency if differential privacy were applied server - side , something which has been mentioned before . 
 I think the difference being proposed in this issue is , rather than have the servers drive aggregation ( by running some map and reduce functions ) , it has the collector drive aggregation . This seems to have the benefit of turning aggregators into very dumb entities that hold reports and compute functions over them . ( One could still build the map - reduce pipeline that sends aggregate data to some sink this way by having the collector drive aggregation and write it to a sink . ) 
 At a high level , there 's still a comparable amount of coordination and delegation . Scheduling is nontrivial ( " A collect request may take a long time " ) and will probably involve some task management in the collector . For reference , here 's the cluster management model of Spark . I do n't think it 's too far fetched to imagine the collector as a driver program and stateless cloud functions as executors . ! This is ( mostly ? ) orthogonal to the data flow e.g. upload -verify -aggregate -publish . 
 Yep , they seem to match pretty nicely ! I need to think about this more , but in my mental model , the protocol looks very different if , say , the collector drives things instead of the being a dumb consumer of data output from the aggregators , even though the flow of data is mostly the same . 
 A few thoughts here . As a preliminary , I want to talk about the commercial relationships rather than the network relationships . First , let 's call the " Customer " the entity which is paying for the service and presumably ( 1 ) is deploying the clients and ( 2 ) is interested in the data . So , in the case where we are doing Fx telemetry ,  would be the Customer . The Customer contracts with 1 or more Operators who collectively run the service . In the simplest conceptual topology , there are two Operators , call them A and B , each of whom runs an Aggregator . One could also have a situation in which the Customer contracts with one Operator and then runs the second Aggregator themselves , but that seems like a case that is likely to be less widely used . In the former scenario , With that as background : think this is going to work best if the PA system presents as a single service to the common Customer , at least technically . By this I mean that once it 's set up , the Customer / Collecter should only have to talk to one system ( presumably operated by the same entity that operates the Leader ) . The Leader would in turn talk to the other aggregators . This does not preclude concealing the results from the Leader , but merely requires that the aggregated shares be encrypted so that the Leader can not see them . have been a bit vague about what the Leader / Collector interface is , but I think it 's most reasonable to think of it as a standard Web service API . This of course means that if you just want a dashboard a la Amplitude , someone will have to implement that , but the most flexible way to do so is as a system that talks to the Leader over that API . It 's been noted that there are times when things are long - running , but there are well - established mechanisms for Web services APIs to handle this kind of thing , such as by the Collector having a notification endpoint or polling . are multiple kinds of state to be stored . My expectation is that the Leader operates as effectively a query oracle , but that the Collector be responsible for the direction and order of queries . The Leader will be responsible for storing the reports and whatever memoized information is necessary between queries ( e.g. , suppose for query A you need to verify X , Y , Z and then for B you need to verify X , Y ,  , the Leader could memoize X and Y. ) . Some of this can be soft state and the Leader can recompute as needed . The Collector is responsible for storing its own context and for knowing what 's already been asked and what is to be asked next . The Helpers are stateless . Note that this does n't address the question of any limits on what queries can be made ( e.g. , for DP ) . Those have to be enforced at the Leader . 
 Two quick comments : Yes I think we want the computational model to be robust enough to handle dynamic # of rounds , although maybe it is sufficient to just have the " stopping point " of the protocol be dynamic to fail early when there is no point further expanding the domain . To ekr 's point on helpers being stateless and what queries can be made ( e.g. , for DP ) . Those have to be enforced at the Leader I wanted to point out that this choice affects the security guarantees of DP since we would n't be ensuring DP for repeated queries / data - stuffing in the 2 - pc model but by a single actor ( the leader ) . Within the MPC system we 'd only be guaranteeing per - query DP . cc who is starting to look at these problems on our side as well . 
 Uh , not sure how that got closed ! Re - opening . 
 Hi folks , PR tries to specify data collection in a way that satisfies the requirements enumerated here . Also , I believe this 
 As discussed on the 2021/7/14 call , all that 's left for this issue is to enumerate the design constraints discussed here in the spec . ( will file a PR . ) 
 enumerates the design constraints considered here . It 's time to close out this sucker . 
 ( moving a comment made in to an issue ) I have a high level concern with the architecture here , following up from our meeting on Wednesday related to heavy hitters . TL;DR evaluating a hierarchy at only a subset of levels ( which are specified at query time ) is not optimal for performance if the verification step does not have access to those specified levels . For heavy hitters , we are considering a model where records form a binary tree , where aggregates can be reported at different levels of the tree . There are a few possible ways this could go : For every record , verify and evaluate the entire binary tree ( i.e. bit - by - bit evaluation ) For every record , verify and evaluate only a subset of the tree ( at the limit , this can look more like Prio which only evaluates the last level of the tree ) 2a . The subset of the tree to evaluate is configured within a particular record at record - creation time 2b . The subset of the tree to evaluate is configured dynamically at collection / aggregation time For our use - case ( discussed in ( comment ) ) , we are interested in ( 2b ) , for a few reasons : ( 1 ) is potentially inefficient from both a performance and accuracy POV in that it requires more rounds , and additionally when used with differential privacy requires splitting a DP budget across all levels . Some prefixes might just not be interesting to the caller so we should n't waste privacy budget / compute on them . ( 2a ) is problematic in two dimensions . Embedding configuration in records may compromise user privacy if the configurations can be set by an adversary colluding with one of the aggregators ( e.g. you can leak  choose k ) bits of information if you allow any subset of k prefixes for an n - bit domain ) . Levels must be pre - specified at record - creation time , which is non - ideal if new information comes up at collection time which informs how aggregation should work ( e.g. realizing you have fewer records than expected so it is better to focus on querying only up to a given prefix ) . However , I think ( 2b ) runs into a few issues with this architecture that separates verification from collection , in that without knowing the specific levels to evaluate , we run the risk of spending unnecessary compute verifying levels that will never end up being used . The protocol is more efficient ( less computation , fewer rounds ) if we can verify multiple levels at once ( i.e. the levels the collector cares about ) . Possible solutions : a step where the collector and leader communicate prior to verification ( but keep verification and collection separate ) tightly couple " verify " and " collect " stages , so that verification can be done based on communication with the collector . In our setting , the " leader " and " collector " roles are somewhat merged which aligns with option ( 1 ) , but it seems like a good idea to make the general architecture robust to this use - case . cc who is working on our C++ implementation of IDPFs . 
 Thanks for the feedback I 've finally had a chance today to dig into the heavy hitters paper . I agree that the framework described in is n't going to be feasible for heavy hitters . I think your option ( 2b ) is the only way to go , as I explain below . For context , thinks of PA ( " Private Aggregation " ) protocols as having three distinct " phases " : Upload : Each client uploads its input shares to the aggregators . Verify : The aggregators verify each client 's input . Collect : Each aggregators add up their verified input shares and emits its output share to the collector . In order to fit heavy hitters into his framework , we could take your option ( 1 ) or ( 2a ) . However , these options are only feasible for very small inputs , say , , where is the length of each client input in bits . In order to make the protocol feasible for large inputs , heavy hitters involves multiple rounds of the Verify / Collect phases , where the output of the previous Collect phase is used to decide what to do in the next  phase . So that we 're all on the same page about why interaction is necessary , I 've included a brief overview of the protocol below [ 1 ] . ( Please correct me if I 've misunderstood anything ! ) Accounting for this interaction in the protocol spec should be fairly straightforward . The delta , I think , is that there needs to be a way to re - run the Verify / Collect phases on the same inputs , but using different parameters each time , i.e. , with different sets of prefixes specified by the collector . _ [ 1 ] Here 's a bird 's eye view of the protocol , as I understand it . ( I 'm ignoring DP for now . ) First , ( Upload ) each client generates IDPF shares of its -bit input and sends a share to each aggregator . After all clients have uploaded their IDPF key shares , the collector and aggregators verify and collect the heavy hitters as follows . Let . For each : ( Verify ) For each client upload : a. For each prefix in , each aggregator evaluates its IDPF share on input of . b. The aggregators verify ( in zero - knowledge ) that their IDPF outputs are well - formed , i.e. , that only one of the outputs is and the rest are . ( Collect ) a. For each verified IDPF output , each aggregator adds up its shares and sends the resulting " histogram share " to the collector . b. The collector adds the histogram shares together to get the histogram . This encodes the frequency of each prefix in among the client inputs .  The collector assembles , the next set of candidate prefixes . To do so , it collects the set of prefixes that appear at least times in the histogram . It lets be the set of strings obtained by appending or to each element of . d. Finally , the collector disseminates among the aggregators . What makes this feasible is that the size of each is at most the number of clients divided . 
 this sounds about right to me . Just a small nit but I wanted to point out that your ( Collect ) stage , multiple interactions with the collector are not strictly necessary . What you described is a zero - knowledge protocol but alternatively the aggregators could interact to learn the aggregates at each level and proceed down without interaction with the collector . We discussed this variant a few weeks ago , it trades off aggregator knowledge with protocol simplicity ( e.g. collectors do n't need to follow an interactive protocol ) . 
 Let me see if I understand you correctly . Concretely , the helper would send the leader its share of the aggregate at the end of each round . Next , the leader would use the aggregate shares to compute the next set of prefixes , then send this to the helper for the next round . If my understanding is right , then it seems to me that this is the same protocol as [ 1 ] , but with leader = = collector . What do you think ? Maybe I 'm missing something . I 'll do my best to read the design doc you shared by the end of the week . 
 Yes that 's right . I was outlining a " simpler " communication model where helpers communicated directly with each other but in this architecture it would go through the leader . 
 Prio v2 employs a linear secret sharing scheme in which all input shares are required in order to produce coherent outputs . This gives us robustness against malicious clients , but not malicious servers ( ) . We could provide robustness against a minority of malicious servers by running the protocol over multiple subsets of aggregators . If the outputs across all aggregator subsets do not agree , then participants know that there is at least one malicious server . If linear secret sharing is employed , then clients would have to generate input shares once for each subset . We could also use a threshold secret sharing scheme ( e.g. , ) , which would reduce work for clients . 
 This will be interesting :) 
 partially addresses this issue by deciding that multiple helpers will be used for resilience . Whether we can use  secret sharing to provide robustness against cheating servers is still an open question . Though IMO we should n't try to change the spec to allow for this . 
 This issue predates the VDAF abstraction and no longer applies ( directly ) to DAP . However , it 's an interesting consideration for a future variant of Prio3 ( or other VDAF ) . 
 We assume that all aggregators process the share of a client 's input , but what happens if one aggregator loses its share of the client input ? How do we accommodate one aggregator losing its view of a share , either maliciously or accidentally ? 
 consider two settings for ZKP systems on distributed data : one in which either the client or a subset of aggregators is malicious ( this is the setting in which Prio was analyzed ) ; and another in which the client may collude with a subset of aggregators . This issue corresponds to the latter setting . Security in this setting is addressed in Section 6.3 . The basic idea seems to be to run the input - validation protocol with every subset of servers . 
 We addressed this problem in Prio v2 by having each aggregator evaluate proofs independently . So during intake , when an aggregator receives a data share , it extracts the proof share and transmits it to the other aggregator . At aggregation time , an aggregator will not include a data share in a sum unless it can assemble the triple of ( data share , own proof share , peer proof share ) and verify the proof . If it ca n't do that because the peer proof is unavailable , the aggregator drops the share from the sum , but still sums everything else . In our design , the leader could be responsible for this . Clients would send encrypted data shares and proof shares to aggregators , and aggregators would then have to extract the proof share and send it to the leader . The leader could then work out the intersection of the sets of proof shares provided by all aggregators ( which is the set of data that can be summed in the aggregation ) and then only instruct aggregators to sum that set of shares . 
  , having all of the proof shares is a potential privacy issue , no ? If I have all of the proof shares , then I can assemble the entire proof polynomial , which gives me the output of each intermediate G - gate evaluation and not just the final output . ( Perhaps you mean " verification share " ? See ) This sounds like a good idea . 
 As of 2021/7/14 , our answer is as follows : all aggregators need to be online for the duration of the protocol . In order to recover in case an aggregator drops , the collector could spin up multiple tasks , each with different sets of aggregators . We briefly considered formalizing this in the protocol , but decided this was too complex . ( See . ) Another protocol - level option is , potentially , threshold secret sharing ( ) .
Paragraph (version A):
Batch size: The number of valid input shares accumulated by each
aggregator before computing the final output.
Paragraph (version B):
Batch: A set of reports that are aggregated into an output.
Paragraph (version B):
Batch size: The minimum size of a batch.
Paragraph (version B):
Batch window: The minimum time difference between the oldest and
newest report in a batch (in seconds).
Paragraph (version B):
Server: An aggregator or collector.
Paragraph (version A):
Each PA task in this document is divided into three sub-protocols as
follows.
Paragraph (version B):
Each PA task consists of two sub-protocols, _upload_ and _collect_,
which are executed concurrently.  Each sub-protocol consists of a
sequence of HTTP requests made from one entity to another.
Paragraph (version A):
The first field, "version" specifies the version of this document.
The second field, "id" is an opaque identifier used by the clients,
aggregators, and collector to uniquely identify the PA task at hand.
We will call it the _task id_ in the remainder.
Paragraph (version A):
The "batch_size" field encodes the _batch size_, the number of input
shares accumulated by each aggregator before emitting its output
share.  The "proto" field identifies the specific PA protocol in use.
The rest of the structure contains any protocol-specific parameters
that are required.
Paragraph (version A):
We call this the helper's _key configation_. The key configuration is
used to set up a base-mode HPKE context to use to derive symmetric
keys for protecting the shares sent to the helper.  The _config id_,
"HpkeConfig.id", is forwarded by the client to the helper, who uses
this value to decide if it knows how to decrypt a share it receives.
Paragraph (version A):
The client, aggregators, and collector are configured with a
specific PA task.
Paragraph (version A):
The client and leader can establish a leader-authenticated secure
channel.
Paragraph (version A):
The leader and each helper can establish a leader-authenticated
secure channel.
Paragraph (version A):
The aggregators agree on a set of PA tasks, as well as the PA
protocol and parameters used for each task.
Paragraph (version A):
Uploading a report involves two requests to the leader.  In the
_upload start request_, the client discovers the protocol-specific
parameters it needs to generate the report, as well as the endpoint
URL of each helper.  In the _upload finish request_, it uploads its
report to the leader.
Paragraph (version B):
The first field, "version" specifies the version of this document.
The second field, "id", is an opaque identifier used by the clients,
aggregators, and collector to uniquely identify the PA task at hand.
We will call it the _task id_ in the remainder.
Paragraph (version B):
"task": The PA task.
Paragraph (version B):
"helper_urls": The helpers' endpoint URLs.
Paragraph (version B):
"batch_size": The batch size, i.e., the minimum number of reports
that are aggregated into an output.
Paragraph (version B):
"batch_window": The batch window, i.e., the minimum time
difference between the oldest and newest report in a batch.
Paragraph (version B):
"proto": The PA protocol, e.g., Prio or Hits.  The rest of the
structure contains the protocol specific parameters.
Paragraph (version B):
We call this a _key configation_. The key configuration is used to
set up a base-mode HPKE context to use to derive symmetric keys for
protecting: (1) input shares sent from the client to the helper; or
(2) output shares sent from the helper to the collector.  The _config
id_, "HpkeConfig.id", is forwarded by the sender to the receiver to
help the receiver decide if it knows the decryption key.
Paragraph (version B):
The aggregators agree on a set of PA tasks, as well as the PA
parameters associated to each task.
Paragraph (version B):
Each client has selected a PA task for which it will upload a
report.
Paragraph (version B):
Each client and the leader can establish a leader-authenticated
secure channel.
Paragraph (version B):
The leader and each helper can establish a helper-authenticated
secure channel.
Paragraph (version B):
The collector and leader can establish a leader-authenticated
secure channel.
Paragraph (version B):
The collector has chosen an HPKE key pair.
Paragraph (version B):
Each helper has chosen a key for an AEAD scheme.
Paragraph (version B):
Uploading a report involves two requests to the leader.  In the
_upload start request_, the client discovers the protocol-specific
parameters it needs to generate the report.  In the _upload finish
request_, it uploads its report to the leader.
Paragraph (version A):
The message includes the URL of each helper and any protocol-specific
parameters the client needs to generate its report.  The leader's
response to malformed requests is specified in pa-error-common-
aborts.
Paragraph (version B):
The message includes the PA parameters the client will use to
generate its report.  It also includes a protocol-specific message,
e.g., PrioUploadStartResp, the semantics of which is up to the PA
protocol.
Paragraph (version B):
The leader's response to malformed requests is specified in pa-error-
common-aborts.
Paragraph (version A):
Note that the leader share is sent not encrypted.
Paragraph (version A):
After the client uploads a report to the leader, the leader and
helper verify in zero knowledge that the proof is well-formed.  The
exact procedure for doing so is protocol specific, but all protocols
have the same basic structure.  In particular, the protocol is
comprised of a sequence of HTTPS requests from the leader to the
helper.  At the end of this phase, the leader and helper will have
decided whether a set of client inputs are valid.  For each valid
input, they proceed as described in pa-collect.
Paragraph (version A):
The "enc" field is the helper's encapsulated HPKE context sent in the
report.  The remainder of the me structure is dedicated to the
protocol-specific helper share and request parameters used for the
current round.
Paragraph (version A):
where "sk" is the secret key corresponding to the HPKE config.  Next,
it computes the body of the "PAVerifyResp" according to the PA
protocol.
Paragraph (version B):
The collector interacts with the leader to produce the final
aggregate output.  This process consists of a sequence of _collect
requests_ issued to the leader.  Before a request can succeed, the
aggregators must have verified and aggregated enough reports and the
leader must have obtained the helper's encrypted output share (see
pa-aggregate).  In general, the procedure by which the aggregators
verify and aggregate reports depends on parameters carried by the
collect request.  This procedure is described below in pa-aggregate.
Paragraph (version B):
CreateRequest(): Creates a PACollectReq object, defined below,
that is sent to the leader to complete one iteration of the
protocol.  Along with any protocol-specific parameters, the
message specifies a time interval "[batch_start, batch_end)" that
determines the batch of reports to be aggregated.  It must be that
"batch_end - batch_start >= PAParam.batch_window" and
"batch_start" and "batch_end" are multiples of
"PAParam.batch_window".
Paragraph (version B):
Update(resp: PACollectResp): Consumes an opaque PACollectResp
object, defined below, that is received from the leader in
response to a PACollectReq.
Paragraph (version B):
Finished(): Returns a boolean indicating indicating whether or not
the collection procedure is complete.  This function returns true
when the collect iteration is complete.
Paragraph (version B):
Output(): Returns the aggregate output corresponding to the
protocol.
Paragraph (version B):
Each collect request involves one of the helpers specified by the PA
parameters.  If more than one helper is specified, the collector may
issue the requests in any order.
Paragraph (version B):
After the client uploads a report to the leader, the leader and
helper verify in zero knowledge that the input is valid.  The exact
procedure for doing so is protocol specific, but all protocols have
the same basic structure.  In particular, the protocol is comprised
of a sequence of _aggregate requests_ from the leader to the helper.
At the end of this procedure, the leader and helper will have have
aggregated a set of valid client inputs.
Paragraph (version B):
The "enc" field is the helper's encapsulated HPKE context sent in the
report.  (This field is marked optional because it is usually only
needed for the first aggregate request.  [TODO: Decide how to mark
the helper input share as optional as well.  This too is usually only
needed for the first request.]) The "time" field should match the
timestamp of the corresponding report.  The remainder of the
structure is dedicated to the protocol-specific helper share and
request parameters used for the current round.
Paragraph (version B):
where "sk" is its HPKE key and computes the body of the
"PAAggregateSubResp".  It then updates its state according to the PA
protocol.  After processing all of the sub-requests, the helper
encrypts its updated state and constructs its response to the
aggregate request.
Paragraph (version B):
The helper state is an optional parameter of an aggregate request
that the can helper use to carry state across requests.  At least
part of the state will usually need to be encrypted in order to
protect user privacy.  However, the details of precisely how the
state is encrypted and the information that it carries is up to the
helper implementation.
Paragraph (version B):
Once the aggregators have verified at least as many reports as
required for the PA task, the leader issues an _output share request_
to the helper.  The helper responds to this request by extracting its
output share from its state and encrypting it under the collector's
HPKE public key.
Paragraph (version B):
where "pk" is the HPKE public key encoded by the collector's HPKE key
configuration and "output_share" is its serialized output share.
Paragraph (version B):
The leader uses the helper's output share response to respond to the
collector's collect request (see pa-collect).