-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Secure finishing for Hasher #1768
Comments
Just some thoughts : I think finishing semantics can vary among hash functions. If you want a hash trait usable for protocols, not just local hash maps, then endianness matters. Also, it's unclear how/if a hash trait, or many writer-like traits, can really consume a I'd propose using separate traits for hash function input and output, so the input trait can be very general, live in |
@burdges Good points. For split input I wish I didn't know there was so much diversity in finalization. |
I suppose SHA3's Shake output mode could be handled by returning an associated reader-like type or something, so maybe one does only need the associated type. We should therefore not need to think about output traits now, except that you need an associated type, not just an associated constant. It's true hash functions normally cannot fail, so the error type is irksome. I know a Argon2 would often be configured to allocate many megabytes, or even gigabytes, of memory though, so presumably one wants an Argon2 builder function that does the allocation, and can fail, but returns an object that consumes input without the possibility of failure. I suspect there are cleaner solutions to endianness than the ByteOrder create with slices and I understand why reader traits do not have endianness as a type parameter, well usually they're outputting to something like JSON that does not care. I suspect hashing might benefit from making endianness a type parameter of the hash input trait. |
I'll look at your links in more detail tomorow, but see jethrogb/rust-core_io#3 for me trying to get maintainable better Read/Write. |
At least there is an explanation for my worries around fixed size arrays in #1772 |
I suppose the byteorder crate's tendency to specify endianness with each write or read is actually incorrect. Instead, endianness should be embedded in the type of the hasher and its builder, maybe via some wrapper hasher and/or builder that sets the endianness. |
That's easily done too. With |
I'd think hashers should take native endianness by default, given that they're frequently used for internal data structures like |
Is there anything wrong with just adding an associated type?
It might break some code around There is another issue that some hash functions cannot, or should not, copy their internal state, so you likely want this In principle, one could maybe avoid the associated type as follows, but doing so seems worse.
Initially I was thinking about |
Just posted a little wrapper that addresses the endianness issue. Interestingly it would not work with the |
Appears an associated If the associated type is actually painful, even with the default, then an approach like
likely restricts the breakage to the If nothing like that works then crypto code can always import some hashish crate that does roughly :
|
+1. Restricting Hasher to u64 output makes it unusable for anything cryptography-related |
Just as an aside, we're unsure exactly what a secure hasher actually looks like, much less what a generic one looks like. Almost all cryptographic hashing interfaces like digest really suck, due to being modeled on NIST's obsolete hash function competition requirements. In particular, these interfaces encourage wasting enormous amounts of time micro-optimizing the domain separation. At the lower level, we should abandon all existing hash function and stream cipher based interfaces in favor of mapping permutations into STROBE-like interfaces, but actually doing a zero cost interface for STROBE looks painful, certainly without const generics. Above this, merlin currently provides the nicest interface for discrete log based signatures and zero knowledge proofs. In essence, you write traits that map your types data into hashing like calls that support good domain separation. Isolating the domain separation into tiers like this prevents micro-optimizations that waste protocol designer time. Also STROBE-like constructions could likely "double" their rate by feeding the domain separators into hash state separately, so we should eventually outperform the legacy interfaces. Above this, we want domain separation inferred so the interface should look more like serde, etc. |
Well regardless of the algorithm, we need to be able to get more bits of information out of it. It's been a while since I thought of this. Are enough language features stable for this? |
With sufficiently expressive associated constants (including rust-lang/rust#34344), it would be nice to provide scaffolding for secure hashing without allocation by extending
Hasher
like:[I think specialization might also be required to write that default method; I forget what syntax is needed.]
The text was updated successfully, but these errors were encountered: