-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prio3: Consider using a smaller field and re-running the proof verification multiple times #177
Comments
Summarizing some offline discussions: Running verification multiple times to improve soundness should work straightforwardly if there is no joint randomness. Once the report is fixed, the only coin that the soundness probabilities are evaluated over is the query randomness, and checking the polynomials at multiple points gives us independent events, so the protocol's overall soundness error would look something like the product of the soundness error from each query run. However, once we re-introduce joint randomness, the joint randomness values would be constant across each proof verification re-run, and thus the probability of repeated FLP verification detecting a dishonest submission is correlated. There's now another coin involved, and repeatedly running proof verification doesn't re-flip it. Thus, the soundness error you get from running proof verification repeatedly would be dominated by the terms that come from the joint randomness, and the overall soundness would not get exponentially better with more verifications. The query randomness values are used in polynomial identity tests that show that gadget input and output values are consistent, while the joint randomness values are used by validity circuits to compress intermediate values from multiple gadgets into a single field element. (typically, by computing a random linear combination of polynomials that are each zero for valid inputs) Concretely, a dishonest verifier could choose an invalid measurement, honestly evaluate all the gadgets in the validity circuit, and adversarially choose joint randomness blinds such that the circuit output is zero through cancellation. If they wanted to attack Prio3Sum, they could submit a measurement with, say, 2 in every "bit", and search until they find a joint randomness value that satisfies We could achieve reasonable soundness with smaller fields if we re-ran the validity circuit (and thus proof generation) multiple times with different joint randomness values, but this would cancel out the client-to-aggregator communication benefits of using a smaller field. For each circuit that currently uses joint randomness, we could imagine dropping the compression step, and having validity circuits output a vector of field elements. This would increase both client-to-aggregator and aggregator-to-aggregator communication, but the tradeoff for using smaller fields might be worth it with moderately-sized circuits (i.e., only a few gadget evaluations). Those are the only tricks I can think of at the moment to get around this. Of course, they'd need further analysis. |
@divergentdave Can we construct a new joint randomness for each verification using the iteration of the check as input? (Or just iteratively rehashing the joint randomness.) IIUC that should make no difference to an honest client while for a cheating client the |
Yeah, deriving additional joint randomness values would not be an issue. The issue is what you do with the resulting values, because there's a soundness versus report size tradeoff. If you re-run proof generation multiple times and send a new set of proof shares for each joint randomness, then the shorter field elements and repeated proof shares cancel out, so that the report size is about the same as when you started. If you somehow sum up proof shares from each run to compress them, i.e. by checking a circuit that evaluates a sub-circuit at multiple points, then that leaves a lone 1/|F| term in the soundness error. |
@divergentdave we notice that, for some use cases, e.g. Here is our proposal. ProposalThe basic idea is similar to what you said above, i.e., to construct multiple independent proofs, using distinct set of prover randomness and joint randomness and accept the inputs only after all proofs are validated. Here we explain this idea by describing the changes from section 7.2 in draft-irtf-cfrg-vdaf-06.
|
Soundness ErrorAdversaries have to find |
Communication CostHere are some preliminary results to compare clients/aggregators communication costs.
|
Computation timeWe benchmark the Rust implementation, with the following setup
|
@cjpatton @divergentdave what do you think? |
Thanks, I think this is a promising idea! I hadn't considered the effect on measurement size previously, and as you point out, it's the more important component here. It looks like we can get pretty significant report size wins with this, so I think it would be worth the extra complexity and bookkeeping. Concatenating and splitting proof and verifier messages as you show makes sense to me. Currently we specify which field each Prio3 instance uses. We would need to provide more guidance on soundness error, and either give users some choices for combinations of field size and number of proofs, or give formulas and thresholds for choosing such combinations. When considering lowering the field size, it's worth noting we have a lower bound constraint from the FFT interpolation we do. With We'll also need to satisfy ourselves that the security analysis hangs together, and that the repeated proofs don't introduce soundness or zero-knowledge issues. I'll defer to Chris on what's needed there. |
I also support this idea. It seems useful to provide users a trade-off between communication cost and CPU time. As far as the security implementations of this change: Privacy: I don't think privacy is impacted. The only thing to keep in mind is that using a smaller field increases the chance that proof generation fails: https://github.com/cfrg/draft-irtf-cfrg-vdaf/blob/main/poc/flp_generic.py#L242. But I don't think this is a big deal. Robustness: As you point out, we can achieve the same soundness error for the FLP with a smaller field by repeating the proof enough times. This is only true if the joint randomness is derived correctly, i.e., the changes to Fiat-Shamir you propose matter for security. I agree that the change seems intuitively safe, but we'd need to think through the security reduction to confirm this intuition. What Fiat-Shamir does is take an interactive protocol and make it non-interactive. Generally we think of this protocol as being sequential: the verifier sends a challenge, the prover responds; the verifier sends the next challenge, the prover sends the next response, and so on. In the interactive version of "multi-proof Prio3" (i.e., your proposal), it seems like all of these challenge-response steps are done concurrently. I'm not sure if/how this feature would impact the usual security reduction. It may be that we need to derive each joint randomness such that it depends on the previously generated proof. Generally speaking, messing up Fiat-Shamir is a well-known source of bugs in practical ZKP systems. When need to be very careful about how we apply it. All of that said, I would support extending Prio3 as you suggest in order to unblock anyone who may want to implement/experiment with it. I'd like to suggest the following requirements for the change:
|
Thank you very much your inputs!
This is a little bit tricky. Theorem 4.3 in BBCGGI19 states that the the soundness error If we follow Theorem 1 in DPRS23 and simply replace For I am wondering if it makes sense to make |
One more clarification. Shall I continue with PR for this draft or PR for libprio-rs? |
I'm a bit lost here. Can you clarify how you expect the bound to change? Let's let Note that we can't apply [DPRS23, Theorem 1] directly here because we're tweaking the construction.
Do you mean that I think what we'd hope is that we can get roughly the same level of robustness at the cost of For what it's worth, I don't think 630 proofs is ever going to be feasible, especially since prove/query time for SumVec with dimension 100,000 is already on the order of milliseconds.
Let's start by extending the reference implementation: https://github.com/cfrg/draft-irtf-cfrg-vdaf/blob/main/poc/vdaf_prio3.py Once that's done we can move on to the draft itself. As far as libprio-rs goes, you'll have to ask the maintainers if they're willing to implement this change. (@divergentdave is one of them.) I'd hold off on this until we've settled more of the open questions. |
I don't think this will be an issue, because we can still write the FLIOP as having three half-rounds of communication. First, the prover sends all measurement shares to the verifier, second, the verifier sends On a related note, we will need to assume that the algorithm identifier commits to the choice of field and choice of |
The 630 number was for I think the upshot of this is that we can't gloss over the impact of gadget calls (and gadget degree) when we start stacking up many proofs over smaller fields, especially when measurements are large. For this choice of parameters, and with the existing single proof over Field128, we get a soundness error of roughly |
@cjpatton @divergentdave what are acceptable soundness errors in practise? If I understand correctly, the soundness error needs to be small enough so a brute force attack of |
Thank @divergentdave for clarifying up. . @cjpatton, sorry to confusion.
I mean 630 is roughly I am not sure we can assume
Sounds good. |
I put up this PR and appreciate your review. |
Thanks @albertpl for the PR, I'm reviewing now. But before we merge this, I would like us to have a better idea of what value of
|
I have one comment about soundness error of SumVec, or any circuit that uses random linear combination: there should be an additive factor of Still using
@cjpatton can you elaborate this part? I don’t quite understand it… |
@junyechen1996: Basically, for a fixed robustness bound, as your circuit gets more complex (i.e., more gadget calls), you need to compensate by increasing the size of the field (or the number of proofs). |
Yeah.
Field64 is our first choice too.
Yeah. That would be great!
I suppose some reasonable tradeoff between communication/computation cost and robustness is acceptable. Some guidance on robustness would be very helpful. |
I think of robustness as follows. If your robustness bound is EDIT: Take this analysis with a grain of salt, as the robustness depends somewhat on how well-resourced the adversary is. First, random oracle queries amount to doing pre-computation with the underlying XOF. Second, it depends partially on how many of the reports the attacker controls. In practice we'd observe a high rejection rate before we get to the point of a batch getting ruined. |
* Support multiproofs in Prio3 * Add new Prio3SumVec variant, i.e. Prio3SumVecWithMultiproof, with configuration (field size, number of proofs) * Add with_field class methods to introduce new SumVec with configurable field size
* Support multiproofs in Prio3 * Add new Prio3SumVec variant, i.e. Prio3SumVecWithMultiproof, with configuration (field size, number of proofs) * Add with_field class methods to introduce new SumVec with configurable field size
Great first PR, @albertpl! I think we're ready to start propagating the changes into the actual draft. While at it, please add yourself to the list of contributors in the acknowledgement section :) |
Great. Do you think we should wait for the robustness analysis? i.e. shall we quantify the robustness for the multiproof? |
The scheme is flexibile enough to "bump" robustness as needed (by adding more proofs or using a larger field), so I don't think we need to block on that. On the other hand, we don't want there to be a difference between the reference code and the draft. |
I don't think we need to block aligning the draft. (On the other hand, we don't want there to be a difference between the reference implementation and the draft for very long.) I think we need to come up with recommendations for choosing parameters, but his can wait for a later PR. For now, let's focus on nuts and bolts. |
Any progress on updating the text, @albertpl? Note that we are blocking the next draft on this. If you can't get to it within the couple of weeks, let us know. |
@cjpatton sorry. let me work on it this week. |
I have aligned the draft with the POC. Here is the PR. |
We've implemented the core feature; all that's left here is to provide guidance in the draft for choosing the parameters. I've opened a new issue to focus on this remaining work and am closing this issue. |
For Prio3, when joint randomness is used: * RECOMMEND Field128 * Field64 MAY be used, but `PROOFS` MUST be `3` The latter is motivated by issue #177. The recommendation is based on the upper bound given by {{DPRS23}}, Theorem 1 and a matching attack described by Bas Westerbaan (see issue #311). Co-authored-by: Shan <[email protected]>
For Prio3, when joint randomness is used: * RECOMMEND Field128 * Field64 MAY be used, but `PROOFS` MUST be `3` The latter is motivated by issue #177. The recommendation is based on the upper bound given by {{DPRS23}}, Theorem 1 and a matching attack described by Bas Westerbaan (see issue #311). Co-authored-by: Shan <[email protected]>
For Prio3, when joint randomness is used: * RECOMMEND Field128 * Field64 MAY be used, but `PROOFS` MUST be `3` The latter is motivated by issue #177. The recommendation is based on the upper bound given by {{DPRS23}}, Theorem 1 and a matching attack described by Bas Westerbaan (see issue #311). Co-authored-by: Shan <[email protected]>
This would trade communication cost for CPU time.
The text was updated successfully, but these errors were encountered: