Skip to content
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

Securely instantiating the PRG #106

Closed
cjpatton opened this issue Aug 16, 2022 · 7 comments · Fixed by #136
Closed

Securely instantiating the PRG #106

cjpatton opened this issue Aug 16, 2022 · 7 comments · Fixed by #136
Assignees
Labels

Comments

@cjpatton
Copy link
Collaborator

In Prio3, PrgAes128.derive_seed() is used with a fixed seed for the Fiat-Shamir heuristic. We need to decide if this is safe. It would be sufficient to prove, say, that this function is indifferentiable from a random oracle when modeling AES as an ideal cipher.

Note that we might end up picking a PRG in #32 that is already safe a safe choice here, in which case we should just replace PrgAes128.

@cjpatton cjpatton changed the title PrgAes128 as a random oracle Modeling PrgAes128 as a random oracle Aug 24, 2022
@cjpatton
Copy link
Collaborator Author

cjpatton commented Dec 2, 2022

TODO:

  • Add Prg variant based on SHA-3 (SHAKE)
  • Either dump PrgAes128 or replace it with a is fixed-key alternative and can instantiate Prg.

@cjpatton
Copy link
Collaborator Author

cjpatton commented Dec 2, 2022

@cjpatton cjpatton changed the title Modeling PrgAes128 as a random oracle Securely instantiating the PRG Jan 5, 2023
@cjpatton cjpatton self-assigned this Jan 5, 2023
@cjpatton
Copy link
Collaborator Author

cjpatton commented Jan 5, 2023

I put together a couple prototypes of PRG alternatives in libprio: https://github.com/divviup/libprio-rs/compare/cjpatton/prg-prototypes

One is based on KangarooTwelve (a CFRG spec) and the other is based on SHA-3 (SHAKE128). Initial benchmarks are encouraging. The following table shows Prio3CountVec shard time on my laptop for various input lengths with no multithreading:

PRG 100 1000 10,000
PrgAes128 (status quo) 149.72 us 3.13 ms 22.6 ms
PrgK12 (KangarooTwelve) 156.69 us 3.15 ms 22.7 ms
PrgSha3 (SHA-3) 171.14 us 3.21 ms 23.6 ms

We still need to benchmark Poplar1. The implementation is WIP: divviup/libprio-rs#381

@cjpatton
Copy link
Collaborator Author

Per @simon-friedberger's request, I've updated the benchmark branch of libprio with a PRG based on HKDF-SHA256. I played around with a few variants, all are roughly as performant:

PRG 100 1000 10,000
PrgHkdfSha256 465.88 us n/a n/a

(Note that input sizes of 1000 and 10,000 exceed the the maximum output length for HKDF-SHA256.)

The performance is quite bad compared to the other algorithms. I'm not sure if we're using a software implementation of SHA-256, but if we are, these numbers aren't too surprising given how much hashing is involved in HKDF.

@cjpatton
Copy link
Collaborator Author

@divergentdave and I have been working on Poplar1 in libprio: divviup/libprio-rs#434

We're still working on benchmarks, but so far it looks like SHA-3 is up to 40% more expensive than PrgAes128. This confirms @schoppmp's hypothesis that Prio is arithmetic-bound and Poplar is PRG-bound.

@cjpatton
Copy link
Collaborator Author

cjpatton commented Feb 3, 2023

We have merged the basic functionality for Poplar1 into libprio (🎉). I have also updated my PRG prototypes branch (https://github.com/divviup/libprio-rs/compare/cjpatton/prg-prototypes) with benchmarks with Poplar1 using the current PrgAes128 and the alternative PrgSha3. The table below summarizes shard and preparation timings for both variants and for various bit lengths.

PRG 16 bits 64 bits 128 bits 256
PrgAes128 shard time 49.4 us 143.8 us 270.6 us 519.5 us
PrgSha3 shard time 49.2 us 143.8 us 268.9 us 518.2 us
PrgAes128 prep time 438.2 us 1.4 ms 2.7 ms 5.3 ms
PrgSha3 prep time 667.0 us 2.4 ms 4.5 ms 8.9 ms

(*) For prep time, we're measuring the time it takes for an Aggregator to evaluate an IDPF share and compute its sketch share. We are evaluating at the last level the three, which exhibits worst case performance. Prep time is sensitive not only to the the number of candidate prefixes, but the distribution. This is because the IDPF evaluation caches intermediate results. To compute the candidate prefixes, we sample 1000 measurements from a Zipf distribution (as suggested by the original Poplar paper) and compute the prefix tree for threshold = 10.

Observations:

  1. There is no significant difference between the shard times, regardless of the input length. (Good news for the Client.)
  2. For the range of bit lengths tested, prep time regresses by as much as 67%.

Caveats:

  1. We are still investigating the best caching strategy for IDPF evaluation (Investigate optimal caching strategy for IDPF evaluation in Poplar1 divviup/libprio-rs#441). We expect we will be able to improve performance, at least somewhat, across the board.
  2. If the application can cache per-report IDPF state, then much of this runtime would be amortized across all of the levels.

@cjpatton
Copy link
Collaborator Author

cjpatton commented Feb 3, 2023

Conclusion: SHA-3 performs well enough in all situations except IDPF evaluation. There the performance hit is significant enough to warrant investigating an alternative that has hardware support.I propose focusing #32 on this question. Further, there is no need to design to the Prg API; something designed specifically for IDPF would make sense.

In the meantime, I propose we go ahead with replacing PrgAes128 with something based on SHA-3. Here is my proposal: #136

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant