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

Try to reduce duplication between XofFixedKeyAes128 and XofFixedKeyAes128Key #1147

Open
divergentdave opened this issue Nov 26, 2024 · 0 comments

Comments

@divergentdave
Copy link
Contributor

As noted in PR #1146, there's duplication between XofFixedKeyAes128Key::new() and <XofFixedKeyAes128 as Xof<16>>::init()/<XofFixedKeyAes128 as Xof<16>>::into_seed_stream(). This originated because XofFixedKeyAes128Key was added after the Xof trait was defined, as an optimization for its use in Poplar1. XofFixedKeyAes128Key::new() takes in a domain separation tag and a binder first, then returns an object that turns seeds into SeedStreamFixedKeyAes128. This is a better fit for Poplar1, and IDPFs in general, which make a lot of XOF calls with the same DST and binder, but different seeds. Performing the TurboSHAKE part of the derivation up front, and then reusing the resulting AES key with multiple seeds, saves a lot of redundant hashing. Contrast that with the Xof trait, where init() takes in a seed and a DST first, then the binder is provided over successive calls to update(), and finally into_seed_stream() produces a SeedStream object. This is a better fit for Prio3, where the binder may be long, as in joint randomness derivation. The update() method lets us encode one input share field element at a time, then hash it into the Xof object.

VDAF draft-13 complicates matters slightly, since the DST now has two parts, one that's static for each callsite and one that's passed in from the application. PR #1146 implements this change.

It would be nice to have a sequence of builder objects, each with their own update methods, to take in the DST and binder a piece at a time. Unfortunately, XofTurboShake128 and XofFixedKeyAes128 consume their arguments in different orders, so we'd either need to make use of callbacks, or change the spec. XofTurboShake128 feeds everything into TurboSHAKE128, in the order DST, seed, binder. XofFixedKeyAes128 feeds just the DST and binder into TurboSHAKE128, then extracts an AES key from that, and uses the key and seed in each invocation of the PRG. Changing the order in which XofTurboShake128 hashes into the sponge would be possible, but uncomfortable, since we'd have our variable-length component without a length prefix in the middle of the input, instead of at the end, for XofTurboShake128.

If we can't come up with a better universal API, we could at least extract common portions of XofFixedKeyAes128 into helper functions.

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

No branches or pull requests

1 participant