jiebi/TextFlow huggingface dataset:
Original text:
by refusing to emit output shares. Input validity proof forging.  Any aggregator can collude with a <del> malicious client to craft a proof share that will fool honest </del>  aggregators into accepting invalid input. 6.1.2.3. aggregating invalid inputs. This capability is no stronger than any aggregator's ability to <del> forge validity proof shares in collusion with a malicious client. </del>  Relaying messages between aggregators.  The leader can compromise availability by dropping messages. [TODO: Decide how to provide mutual authentication in leader-to- helper and collector-to-leader connections.  One option is to use client certificates for TLS; another is to have the leader sign its <del> messages directly, as in Prio v2.  For collector-to-leader connections, we may just have this be up to deployment.  (For instance, the collector might authenticate themselves by logging into a website that has some trust relationship with the leader.)] </del>  11. faster implementations?]] The table below lists parameters that meet these criteria at various <del> levels of security.  (Note that #1 is the field used in "Prio v2".) The "size" column indicates the number of bits required to represent elements of the field. </del>  [TODO: Choose new parameters for 2, 3, and 5 so that p is as close to 2^size as possible without going over. (4 is already close enough; 1

Reviewer comments:
Remove terms which are infrequently used (and in a few cases, remove the unnecessary references) Clean up a few terms which appear to be defined incorrectly.

Revised text:
by refusing to emit output shares. Input validity proof forging.  Any aggregator can collude with a  <ins> malicious client to craft a proof that will fool honest </ins> aggregators into accepting invalid input. 6.1.2.3. aggregating invalid inputs. This capability is no stronger than any aggregator's ability to  <ins> forge validity proof in collusion with a malicious client. </ins> Relaying messages between aggregators.  The leader can compromise availability by dropping messages. [TODO: Decide how to provide mutual authentication in leader-to- helper and collector-to-leader connections.  One option is to use client certificates for TLS; another is to have the leader sign its  <ins> messages directly.  For collector-to-leader connections, we may just have this be up to deployment.  (For instance, the collector might authenticate themselves by logging into a website that has some trust relationship with the leader.)] </ins> 11. faster implementations?]] The table below lists parameters that meet these criteria at various  <ins> levels of security.  The "size" column indicates the number of bits required to represent elements of the field. </ins> [TODO: Choose new parameters for 2, 3, and 5 so that p is as close to 2^size as possible without going over. (4 is already close enough; 1
Original text:
Each endpoint in the system must agree on the configuration for each task, which is defined using the Param structure: <del> "nonce": A unique sequence of bytes used to ensure that two </del>  otherwise identical "Param" instances will have distinct "TaskID"s.  It is RECOMMENDED that this be set to a random 16-byte string derived from a cryptographically secure pseudorandom number

Reviewer comments:
Apply to clean up some other whitespace stuff, too.
Because you'll also want a "jitter buffer" on the receiver side and that means something different. Instead of having a random value, why not just have time be to a nanosecond clock and then lexically sort between collisions?
Which will also help one remove duplicates.
Yeah, this is a bad name :)

Revised text:
Each endpoint in the system must agree on the configuration for each task, which is defined using the Param structure:  <ins> "uuid": A unique sequence of bytes used to ensure that two </ins> otherwise identical "Param" instances will have distinct "TaskID"s.  It is RECOMMENDED that this be set to a random 16-byte string derived from a cryptographically secure pseudorandom number
Original text:
The overall system architecture is shown in pa-topology. [[OPEN ISSUE: This shows two helpers, but the document only allows <del> one for now.  https://github.com/abetterinternet/prio-documents/ </del>  issues/117]] The main participants in the protocol are as follows: 10.1.  URIs <del> [1] https://github.com/abetterinternet/prio-documents/issues/102 </del>  <del> [2] https://github.com/abetterinternet/prio-documents/issues/22 </del> 

Reviewer comments:
The repo was renamed to "ppm-specification". This commit replaces various occurences of the old repo's name, and also updated URL to reflect the current name of the protocol.

Revised text:
The overall system architecture is shown in pa-topology. [[OPEN ISSUE: This shows two helpers, but the document only allows  <ins> one for now.  https://github.com/abetterinternet/ppm-specification/ </ins> issues/117]] The main participants in the protocol are as follows: 10.1.  URIs  <ins> [1] https://github.com/abetterinternet/ppm-specification/issues/102 </ins>  <ins> [2] https://github.com/abetterinternet/ppm-specification/issues/22 </ins>
Original text:
input share uploaded by the client.  At the end of the computation, each aggregator is in posession of either an "output share" that is ready to be aggregated or an indication that a valid output share <del> could not be recovered. </del>  To facilitiate this computation, the input shares generated by the client include information used by the aggregators during aggregation <del> in order to validate their recovered output shares.  For example, </del>  "prio3" includes a distributed zero-knowledge proof of the input's validity BBCGGI19 which the aggregators can jointly verify and reject the report if it cannot be verified.  However, they do not learn

Reviewer comments:
What PPM calls an "output share" is called an "aggregate share" in the VDAF draft. Furthermore, in the VDAF draft, an "output share" is what an aggregator recovers from running the MPC with its peers. This change fixes this ambiguity without changing the PPM protocol itself (modulo changing the info string for HPKE).
Squashed.
Thanks fellas!
Generally looks good. I would change the "agg" in the label if you can as it is confusing.LGTM, modulo typos

Revised text:
input share uploaded by the client.  At the end of the computation, each aggregator is in posession of either an "output share" that is ready to be aggregated or an indication that a valid output share  <ins> could not be computed. </ins> To facilitiate this computation, the input shares generated by the client include information used by the aggregators during aggregation  <ins> in order to validate their corresponding output shares.  For example, </ins> "prio3" includes a distributed zero-knowledge proof of the input's validity BBCGGI19 which the aggregators can jointly verify and reject the report if it cannot be verified.  However, they do not learn
Original text:
First the aggregator checks that the request's batch interval respects the boundaries defined by the PPM task's parameters. Namely, it checks that both "batch_interval.start" and <del> "batch_interval.end" are divisible by "min_batch_duration" and that "batch_interval.end - batch_interval.start >= min_batch_duration". Unless both these conditions are true, it aborts and alerts the peer with "invalid batch interval". </del>  Next, the aggregator checks that the request respects the generic privacy parameters of the PPM task.  Let "X" denote the set of

Reviewer comments:
While reviewing , NAME and I figured out a way to redefine so that invalid values cannot be represented[1]. The existing representation contains and , which means an interval could be defined with , which is invalid. Redefining as a start instant and a duration makes it impossible to represent invalid s (since is an unsigned integer). Additionally, this implicitly fixes a bug in the batch interval validation logic: we asserted that should be divisible by , but since is excluded from the , I think that was incorrect. Instead, should be divisible by . In any case, this is simpler with the new definition of : needs to be a multiple of . [1]: URL
Nice!

Revised text:
First the aggregator checks that the request's batch interval respects the boundaries defined by the PPM task's parameters. Namely, it checks that both "batch_interval.start" and  <ins> "batch_interval.duration" are divisible by "min_batch_duration" and that "batch_interval.duration >= min_batch_duration".  Unless both these conditions are true, it aborts and alerts the peer with "invalid batch interval". </ins> Next, the aggregator checks that the request respects the generic privacy parameters of the PPM task.  Let "X" denote the set of
Original text:
The following terms are used: <del> This document uses the protocol definition language of RFC8446. </del>  2. "HpkeConfig" is the key config of the aggregator receiving the input share. <del> "enc" is the encapsulated HPKE context, used by the aggregator to </del>  decrypt its input share. "payload" is the encrypted input share. where "pk" is the aggregator's public key, "task_id" is "Report.task_id" and "server_role" is a byte whose value is "0x01" if the aggregator is the leader and "0x00" if the aggregator is the <del> helper. "enc" is the encapsulated HPKE context and "context" is the HPKE context used by the client for encryption.  The payload is encrypted as </del>  where "input_share" is the aggregator's input share and "nonce" and "extensions" are the corresponding fields of "Report". "collector_hpke_config_id" is "collector_config.id" from the task parameters corresponding to "CollectReq.task_id". <del> "enc" is the encapsulated HPKE context, used by the collector to </del>  decrypt the aggregate share. "payload" is an encrypted "AggregateShare". 7.3. The following value [will be/has been] registered in the "IETF URN <del> Sub- namespace for Registered Protocol Parameter Identifiers" </del>  registry, following the template in RFC3553: Initial contents: The types and descriptions in the table in errors

Reviewer comments:
Here are a few small editorial changes: Refer to TLS's "presentation language", per section 3 of the RFC. The output from the HPKE setup function is an encapsulated key, not an encapsulated context. The term context is defined as "A context is an implementation-specific structure...", whereas is alternately described as "an encapsulated KEM shared secret", an "encapsulated key", or a "KEM encapsulated key". Remove stray whitespace from a hyphenated word.
One non-blocking comment.

Revised text:
The following terms are used:  <ins> This document uses the presentation language of RFC8446. </ins> 2. "HpkeConfig" is the key config of the aggregator receiving the input share.  <ins> "enc" is the HPKE encapsulated key, used by the aggregator to </ins> decrypt its input share. "payload" is the encrypted input share. where "pk" is the aggregator's public key, "task_id" is "Report.task_id" and "server_role" is a byte whose value is "0x01" if the aggregator is the leader and "0x00" if the aggregator is the  <ins> helper. "enc" is the HPKE encapsulated key and "context" is the HPKE context used by the client for encryption.  The payload is encrypted as </ins> where "input_share" is the aggregator's input share and "nonce" and "extensions" are the corresponding fields of "Report". "collector_hpke_config_id" is "collector_config.id" from the task parameters corresponding to "CollectReq.task_id".  <ins> "enc" is the HPKE encapsulated key, used by the collector to </ins> decrypt the aggregate share. "payload" is an encrypted "AggregateShare". 7.3. The following value [will be/has been] registered in the "IETF URN  <ins> Sub-namespace for Registered Protocol Parameter Identifiers" </ins> registry, following the template in RFC3553: Initial contents: The types and descriptions in the table in errors
Original text:
(see issue#57).  For example, how does a leader respond to a collect request if the helper drops out?]  4.4.1. Before an aggregator responds to a collect request or aggregate-share

Reviewer comments:
The info strings used in HPKE context construction used the prefix "pda", referring to the old "Private Data Aggregation" name of this protocol. This commit also adds text instructing the collector how to decrypt the aggregate shares it receives and to use the VDAF's unsharding algorithm to obtain aggregate results.
Question for the reviewers: VDAF defines labels like (). Should we include the draft version number in info strings like this? e.g. ?

Revised text:
(see issue#57).  For example, how does a leader respond to a collect request if the helper drops out?] <ins> The collector then decrypts each aggregate share "share" using the following procedure: where "sk" is the HPKE secret key, "task_id" is "AggregateReq.task_id" and "server_role" is the role of the server that send the aggregate share ("0x01" for the leader and "0x00" for the helper). "batch_interval" is the "Interval" from the "CollectReq".  The collector then unshards the aggregate shares into an aggregate result using the VDAF's "agg_shares_to_result" algorithm. </ins> 4.4.1. Before an aggregator responds to a collect request or aggregate-share
Original text:
When both aggregators' shares are successfully obtained, the leader responds to subsequent HTTP GET requests to the collect job's URI <del> with HTTP status 200 OK and a body consisting of a "CollectResult": </del>  "shares" is a vector of "EncryptedAggregateShare"s, as described in aggregate-share-request, except that for the leader's share, CollectReq pa-collect: "message/ppm-collect-req" <del> CollectResult pa-collect: "message/ppm-collect-result" </del>  The definition for each media type is in the following subsections.

Reviewer comments:
CollectResp is paired with CollectReq; naming things this way matches other {Req, Resp} message pairs.

Revised text:
When both aggregators' shares are successfully obtained, the leader responds to subsequent HTTP GET requests to the collect job's URI  <ins> with HTTP status 200 OK and a body consisting of a "CollectResp": </ins> "shares" is a vector of "EncryptedAggregateShare"s, as described in aggregate-share-request, except that for the leader's share, CollectReq pa-collect: "message/ppm-collect-req"  <ins> CollectResp pa-collect: "message/ppm-collect-resp" </ins> The definition for each media type is in the following subsections.
Original text:
the HTTP server responds with an HTTP error status as described in errors. <del> If a fatal error is encountered while processing an HTTP request, </del>  the HTTP client... [TODO: Figure out what behavior is called for here.  An HTTP request should be sent that conveys the error.] FAILED without sending a message to the helper.  Otherwise it interprets "out" as follows.  If this is the last round of VDAF preparation phase, then "out" is the leader's output share, in which <del> case the leader finishes.  Otherwise, it interpresets "out" as the </del>  tuple "(new_state, outbound)", where "new_state" is its new preparation state and "outbound" is its next VDAF messaage, and continues with "outbound" as its next VDAF message.  Either way, it the tag.  If this check fails, it MUST abort with error "invalidHmac". <del> Next, it first checks that the sequence of Transition messages corresponds to the ReportShare sequence of the AggregateInitReq.  If any message appears out of order or is missing, or a transition has an unrecognized nonce, then the leader MUST abort with error </del>  "unrecognizedMessage". Next, for each Transition, the leader proceeds as described in prep-

Reviewer comments:
While implementing upload today, I also noticed some inconsistencies between the handling of reports in the leader during the upload protocol and the helper

Revised text:
the HTTP server responds with an HTTP error status as described in errors.  <ins> If a fatal error is encountered while processing an HTTP response, </ins> the HTTP client... [TODO: Figure out what behavior is called for here.  An HTTP request should be sent that conveys the error.] FAILED without sending a message to the helper.  Otherwise it interprets "out" as follows.  If this is the last round of VDAF preparation phase, then "out" is the leader's output share, in which  <ins> case the leader finishes.  Otherwise, it interprets "out" as the </ins> tuple "(new_state, outbound)", where "new_state" is its new preparation state and "outbound" is its next VDAF messaage, and continues with "outbound" as its next VDAF message.  Either way, it the tag.  If this check fails, it MUST abort with error "invalidHmac".  <ins> Next, it checks that the sequence of Transition messages corresponds to the ReportShare sequence of the AggregateInitReq.  If any message appears out of order or is missing, or a transition has an unrecognized nonce, then the leader MUST abort with error </ins> "unrecognizedMessage". Next, for each Transition, the leader proceeds as described in prep-
Original text:
with which the batch interval of each collect request must be aligned.  (See batch-parameter-validation.) <del> A unique identifier for the VDAF being used for the task. </del>  In addition, in order to facilitate the aggregation and collect protocols, each of the aggregators is configured with following

Reviewer comments:
Extracted and slightly modified from .
(Build failure appears to be some GitHub API issue.)
Ah, this looks like we're hitting the patch for URL I'll check if the upstream template repository has a fix.
Thanks NAME
!

Revised text:
with which the batch interval of each collect request must be aligned.  (See batch-parameter-validation.)  <ins> A unique identifier for the VDAF instance used for the task, including the type of measurement associated with the task. </ins> In addition, in order to facilitate the aggregation and collect protocols, each of the aggregators is configured with following
Original text:
The aggregator keeps track of the number of times each report was aggregated.  If any input share in "X" was added to at least "max_batch_lifetime" previous batches, then the aggregator aborts <del> and alerts the peer with error "privacyBudgetExceeded". </del>  4.7.

Reviewer comments:
Adds definitions of error codes to section 3.1 for validation of batch intervals in or . Also adds an error code for leader to use when rejecting a report from too far in the future.
NAME I can't request review from you until you accept the invite to the ietf-wg-ppm organization but you should see this PR too!

Revised text:
The aggregator keeps track of the number of times each report was aggregated.  If any input share in "X" was added to at least "max_batch_lifetime" previous batches, then the aggregator aborts  <ins> and alerts the peer with error "batchLifetimeExceeded". </ins> 4.7.
Original text:
as well; see collect-flow.)  In addition, the leader SHOULD abort the upload protocol and alert the client with error "reportTooLate". <del> The leader MUST buffer reports while waiting to aggregate them.  The </del>  leader SHOULD NOT accept reports whose timestamps are too far in the future.  Implementors MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew.  If the leader

Reviewer comments:
Per NAME
NAME observes that we have an awkward MUST requirement on leaders buffering received reports: URL

Revised text:
as well; see collect-flow.)  In addition, the leader SHOULD abort the upload protocol and alert the client with error "reportTooLate".  <ins> Leaders can buffer reports while waiting to aggregate them.  The </ins> leader SHOULD NOT accept reports whose timestamps are too far in the future.  Implementors MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew.  If the leader
Original text:
in Base 64 with URL and filename safe alphabet with no padding, as specified in sections 5 and 3.2 of RFC4648.  If the aggregator does not recognize the task ID, then it responds with HTTP status code 404 <del> and an error of type "unrecognizedTask".  The aggregator responds to well-formed requests with HTTP status code 200 OK and an "HpkeConfig" value: </del>  [TODO: Allow aggregators to return HTTP status code 403 Forbidden in deployments that use authentication to avoid leaking information

Reviewer comments:
All of the following are currently used to refer to 200 responses: status 200 HTTP 200 OK HTTP status 200 HTTP status 200 OK Would be nice to pick one and use it consistently.
I didn't check if this change is complete, in the sense of making all the language in the doc consistent, but it's at least self-consistent. !

Revised text:
in Base 64 with URL and filename safe alphabet with no padding, as specified in sections 5 and 3.2 of RFC4648.  If the aggregator does not recognize the task ID, then it responds with HTTP status code 404  <ins> Not Found and an error of type "unrecognizedTask".  The aggregator responds to well-formed requests with HTTP status code 200 OK and an "HpkeConfig" value: </ins> [TODO: Allow aggregators to return HTTP status code 403 Forbidden in deployments that use authentication to avoid leaking information
Original text:
the reports in sub-batches of 10.  Each sub-batch takes two round- trips to process. <del> In order to allow the helpers to retain minimal state, the helper can attach a state parameter to its response, with the leader returning the state value in the next request, thus offloading the state to the leader.  This state value MUST be cryptographically protected as described in agg-init. </del> [OPEN ISSUE: Should there be an indication of whether a given aggregate request is a continuation of a previous sub-batch?] Implement some form of batch-to-report index, as well as inter- and intra-batch replay mitigation storage, which includes some way <del> of tracking batch report size with optional support for state offloading.  Some of this state may be used for replay attack mitigation.  The replay mitigation strategy is described in anti- replay. </del>  Beyond the minimal capabilities required of helpers, leaders are generally required to: Implement and store state for the form of inter- and intra-batch replay mitigation in anti-replay; and <del> Store helper state. </del> 5.1.3. Collectors statefully interact with aggregators to produce an schemes like Prio in which the input-validation protocol is only run once per report, each aggregator only needs to store its aggregate share for each possible batch interval, along with the number of <del> times the aggregate share was used in a batch.  (The helper may store its aggregate shares in its encrypted state, thereby offloading this state to the leader.)  This is due to the requirement that the batch interval respect the boundaries defined by the DAP parameters.  (See batch-parameter-validation.) </del>  6.

Reviewer comments:
This is a follow-up to , removing a few dangling references to the helper state blob.

Revised text:
the reports in sub-batches of 10.  Each sub-batch takes two round- trips to process.  [OPEN ISSUE: Should there be an indication of whether a given aggregate request is a continuation of a previous sub-batch?] Implement some form of batch-to-report index, as well as inter- and intra-batch replay mitigation storage, which includes some way  <ins> of tracking batch report size.  Some of this state may be used for replay attack mitigation.  The replay mitigation strategy is described in anti-replay. </ins> Beyond the minimal capabilities required of helpers, leaders are generally required to: Implement and store state for the form of inter- and intra-batch replay mitigation in anti-replay; and  5.1.3. Collectors statefully interact with aggregators to produce an schemes like Prio in which the input-validation protocol is only run once per report, each aggregator only needs to store its aggregate share for each possible batch interval, along with the number of  <ins> times the aggregate share was used in a batch.  This is due to the requirement that the batch interval respect the boundaries defined by the DAP parameters.  (See batch-parameter-validation.) </ins> 6.