Skip to content

hash2curve: move oversized DST requirements to runtime errors #1901

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

Merged
merged 1 commit into from
Jun 13, 2025

Conversation

daxpedda
Copy link
Contributor

@daxpedda daxpedda commented Jun 12, 2025

This PR introduces two changes:

  • Remove requirements that were only relevant for oversized DSTs. Now these requirements are checked on runtime. While this is unfortunate, the currently limitations simply was that usage with regular sized DSTs incurred limitations that were not necessary.
  • Change len_in_bytes from NonZero<usize> to NonZero<u16>. This isn't a big improvement because the error is just moved from expand_msg() to the various GroupDigest methods.

Companion PR: RustCrypto/elliptic-curves#1256.


I know I have been refactoring this API over and over again, but I actually think this is the last of it (apart from #872 with generic_const_exprs).

But for completions sake I want to mention the following from the spec:

It is possible, however, to entirely avoid this overhead by taking advantage of the fact that Z_pad depends only on H, and not on the arguments to expand_message_xmd. To do so, first precompute and save the internal state of H after ingesting Z_pad. Then, when computing b_0, initialize H using the saved state. Further details are implementation dependent and are beyond the scope of this document.

In summary, we could cache this part:

let mut b_0 = HashT::default();
b_0.update(&Array::<u8, HashT::BlockSize>::default());

Doing this requires passing ExpandMsg state, which would change the entire API having to add a parameter to every function.

However, as the spec mentions, the cost of not caching it is most likely negligible. We will see in the future if this shows up in benchmarks and if it does we can re-evaluate. I don't believe this will be the case though.

Alternatively, we could add a trait to digest which allows users to construct a hash prefixed with a BlockSize full of zeros that has been computed at compile-time. Which would also require no changes to the API except binding to this trait.

Additionally change `len_in_bytes` from `NonZero<usize>` to `NonZero<u16>`.
@daxpedda daxpedda requested a review from tarcieri June 12, 2025 16:46
@tarcieri
Copy link
Member

construct a hash prefixed with a BlockSize full of zeros that has been computed at compile-time

I don't think this is going to work in generic code until you can have const impls of traits.

That said it would be interesting to have const fn support for various digests. I've seen PoC impls in the past, though it's probably much easier now with const_mut_refs

Copy link
Member

@tarcieri tarcieri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would like to see a https://github.com/RustCrypto/elliptic-curves/ PR before merging

@daxpedda
Copy link
Contributor Author

Done in RustCrypto/elliptic-curves#1256.

@tarcieri tarcieri merged commit 0eab8e2 into RustCrypto:master Jun 13, 2025
12 checks passed
tarcieri pushed a commit to RustCrypto/elliptic-curves that referenced this pull request Jun 13, 2025
* Update to changes in `BatchNormalize` (RustCrypto/traits#1896)
* Update to hash2curve changes (RustCrypto/traits#1901)
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

Successfully merging this pull request may close these issues.

2 participants