Conversation
|
I know how you like rebasing @Kixunil so I picked this one up for you. Feel free to holla if you don't want me doing it. |
Pull Request Test Coverage Report for Build 7999898364Details
💛 - Coveralls |
3e49d15 to
11378d1
Compare
This is Kix's work from rust-bitcoin#1555, picking it up to help out. I've just rebased it. The `Hash` trait requires for the hash type to support hashing arbitrary data. This is not great, since hash newtypes usually hash specific data. Hashing arbitrary data into newtypes is usually a bug or misunderstanding of the API. This change separates methods performing hashing of arbitrary data to a separate RawHash trait and provides a few helpers to make usage easier: - Add a private `engine()` method to the hash newtype - Add a `finalize()` method to `HashEngine` - Add a `hashes::hash` function Moves `TxMerkleNode` hash to the `merkle_tree` module because that is where implement the custom hashing and need access to its private inner hash. Closes rust-bitcoin#1481 Co-developed-by: Martin Habovstiak <martin.habovstiak@gmail.com>
11378d1 to
bc5bb0a
Compare
|
After thinking about this for a bit I would suggest
Basically our "generic hash" trait is replaced entirely with a "generic hash engine" trait, which will be sufficient to implement HMAC, which I think is the prototypical algorithm that requires a generic hash. Then the concrete hash type would have intrinsic methods that do
And finally, our main lib.rs should have convenience methods which wrap the above constructors. This will make our API a little noisy but will help people who show up thinking "how the hell do I just sha2 hash some bytes?". |
|
I'm good to try to implement all that, doing so will make this definitely not a "just rebase Kixs' work" PR so I'll wait for @Kixunil to respond first, also for any additional ideas. |
I was considering this, however:
However we could move
Only if it has a default implementation.
I think
IIRC it's unsupported outside traits But generally I agree with let's make hash types trait-free and only have traits for absolutely required things. |
I think it could be generic over
Agreed, though if
All of my suggested associated types are on the |
I don't understand this. There's one more issue though: currently |
I don't understand what the If we say "
Ah, you're right. If |
You seem to be confusing
I think we should reserve |
Yes, but in my proposal we invert this and then the |
|
OK, that seems to make sense. Thinking about it we probably only need: pub trait HashEngine: Default {
type Digest: AsRef<[u8]>;
fn update(&mut self, bytes: &[u8]);
fn finalize(self) -> Self::Digest;
fn hash(bytes: &[u8]) -> Self::Digest {
let mut engine = Self::default();
engine.update(bytes);
engine.finalize()
}
}
// A general version of ThirtytwoByteHash
pub trait KnownPreimageHash: AsRef<Self::Bytes> {
type Bytes: AsRef<[u8]>;
}This should cover merkle trees, HMACs and |
|
@Kixunil we also need the ability to extract midstates in order to do "compact merkle trees" in rust-elements, and to implement precomputed hash engines (such as tagged hashes, though because those will be in the library, we don't necessarily need to enable a nice API). So I think we want a second Alternately, we could just add a method (Note that our current implementation treats only the bytes of the engine as a "midstate". But you've complained, I think correctly, that the midstate ought to also include the length. If the user thinks this doesn't matter for some reason they can ignore the length when extracting it and provide 0 when constructing.) |
|
I don't understand, |
Hmm, yeah, I guess so. There are things I could imagine doing with midstates that I'd like to do generically (e.g. "fast merkle trees") but actually none of them are safe to do with generic hashes. If you are messing with midstates you should know exactly what hash you're using and therefore be using concrete types. |
|
This is no longer just "pick up Kix's work and rebase" - leaving until after release of 0.32.0 (either to be done by myself or by @Kixunil). |
|
This work is shelved in favour of #2770 |
This is Kix's work from #1555, picking it up to help out. I've just rebased it and bumped the version of
hashesto0.14.0.The
Hashtrait requires for the hash type to support hashing arbitrary data. This is not great, since hash newtypes usually hash specific data. Hashing arbitrary data into newtypes is usually a bug or misunderstanding of the API.This change separates methods performing hashing of arbitrary data to a separate RawHash trait and provides a few helpers to make usage easier:
engine()method to the hash newtypefinalize()method toHashEnginehashes::hashfunctionMoves
TxMerkleNodehash to themerkle_treemodule because that is where implement the custom hashing and need access to its private inner hash.Closes #1481