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

hash2curve: why expand_message receives multiple messages? #1309

Closed
armfazh opened this issue May 14, 2023 · 8 comments
Closed

hash2curve: why expand_message receives multiple messages? #1309

armfazh opened this issue May 14, 2023 · 8 comments

Comments

@armfazh
Copy link

armfazh commented May 14, 2023

why expand_message function receives multiple messages and multiple DSTs?
This seems counter-intuitive when invoking the top-level hash to curve function.

fn expand_message(
    msgs: &[&[u8]],
    dsts: &'a [&'a [u8]],
    len_in_bytes: usize
) -> Result<Self::Expander>

If the purpose is to provide a way to call "Update" many times as in a regular hash function, then I don't think is the right approach, since that case is useful when one doesn't not the full message to be hashed. However, this API requires to passing an array of all the parts of the message.

Happy to discuss more about the API design of this function.

@daxpedda
Copy link
Contributor

daxpedda commented May 14, 2023

If the purpose is to provide a way to call "Update" many times as in a regular hash function, then I don't think is the right approach, since that case is useful when one doesn't not the full message to be hashed.

It was not meant as an equivalent to an "update" function, but as a way to pass a message that isn't a contiguous slice of bytes, which is only useful if you want to avoid allocations. It's similar to what Hkdf::expand_multi_info() offers.

See more on that topic in the original PR: #876.

@burdges
Copy link

burdges commented May 14, 2023

I'd missed that hash2curve exists here, even though I searched, but only several months ago.

We've an ugly interface to hash-to-curve in Arkworks. I've submitted a refactoring in arkworks-rs/algebra#643 with the underlying principles being roughly:

  • A hash-to-field and hash-to-curve expose tooling that inputs an XofReader. -- This weakens the domain separation in the IRTF draft, but improves code reuse elsewhere, including other IRTF drafts. It avoids making curves dependent upon the hacky SHA2 XoF.
  • The SHA2 XoF is exposed for usage by other protocols. Input phase uses digest::Update not just a one &[u8] or &[&[u8]]. -- I provided my own Expander trait because I could not navigate the digest's core_api trait maze even merely to use XofReaderCore, much less build a Sha2Xof: ExtendableOutput, but a few people do understand digest's core_api and could do this.
  • An outer wrapper streamlines the security level computation required in the SHA2 XoF and elsewhere because this is curve specific not hash specific.

@tarcieri
Copy link
Member

Going to close this as it's asking a question which has since been answered.

I'd suggest opening a new issue with a proposal if you'd like to suggest an alternative design.

@burdges
Copy link

burdges commented May 14, 2023

It was not meant as an equivalent to an "update" function, but as a way to pass a message that isn't a contiguous slice of bytes, which is only useful if you want to avoid allocations.

Odd. That is much of what Update does. Also, it would not always avoid the allocation per se, since you need a slice of slices somehow. An Iterator<Item=&[u8]> would be closer to what you describe, but I'd no trouble just using Update here.

@daxpedda
Copy link
Contributor

It avoids making curves dependent upon the hacky SHA2 XoF.

I don't think I completely followed what you said here, but I think a sort of Expander or Update thing would be better then &[&[u8]]. Though the API will be more complicated.

Personally the current API does what I need it to, though I would be happy to give some input and review code (I'm not a maintainer here) if somebody wants to make a PR, @armfazh.

Also, it would not always avoid the allocation per se, since you need a slice of slices somehow. An Iterator<Item=&[u8]> would be closer to what you describe, [..]

A slice of slices can be created ad-hoc if the number of slices isn't dynamic. But I think I mentioned this in the last PR, an Iterator would have been better, but it wasn't worth the complication without a use-case.

@burdges
Copy link

burdges commented May 14, 2023

It's a messy draft so yeah complexity happens. In particular I invoke the security level computation in 3 or 4 places to give the nicer interface, but so what.

The draft provides some ciphersuits involving their SHA2 XoF, but also permits using shake128 with those same curves. I'd hope some people do so, or at least new curves hopefully select shake128. It's nice if the interface supports this modularity.

We interpret the draft as imply a preference for Elligator, so a curve with a common Edwards form like BLS12-377 should use Elligator, even if it also has an SW form. This should probably use shake128.

Afaik the only pressing reason for SHA2 over shake128, beside existing deployments, would be constraint count in zk circuits. I bet anyone who cares about this uses some bespoke zk circuit friendly hash like Poseidon.

@tarcieri
Copy link
Member

SHA-256 enjoys nearly ubiquitous support in hardware

@daxpedda
Copy link
Contributor

It's nice if the interface supports this modularity.

This isn't a problem here, the traits in elliptic-curve are just traits, they don't involve any specific hash algorithm or curve, you can use them with any hash or curve as long as the requirements are met.

On that note, I've been using OPAQUE with SHA3 and Ristretto255 for the OPRF and X25519 for the AKE with the help of these traits quite successfully.

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

4 participants