RustCrypto / utils

Utility crates used in RustCrypto
434 stars 129 forks source link

Crate for cryptographically hashing structs #2

Open newpavlov opened 7 years ago

newpavlov commented 7 years ago

In short: it would be good to have a way a standard way to hash structures. Probably the best approach would be to utilize serde for this.

See this issue for detailed discussion.

mzabaluev commented 6 years ago

Sorry for cross-posting from RustCrypto/traits#13, just noticed it has been closed:

Could you post a brief recap of the serde-related discussion here as well? Is Serialize a good fit for machine-independent representations, or should the hashing backend make do with lots of unimplemented! to backstop non-portable hash implementations?

mzabaluev commented 6 years ago

I think now that a serde::Serializer impl tuned with "personality" traits could be an adequate solution, assuming that data type serialization impls do not leak machine-dependent value information into serialized data a lot (they'd be wrong to do so in the general ser/de impls, or how would they then deserialize?).

The personality traits would have to include potentially orthogonal answers to:

All this could make serde-based hashing too cumbersome to use, in comparison to whipping up a digest_hash::Hash impl for your type if it cannot be procedurally derived.

mzabaluev commented 6 years ago

Here's my attempt at it: https://github.com/mzabaluev/digest-hash-rs

Not publishing on crates.io yet, so as to not spoil the namespace in case the Rust Crypto team finds the crate unsuitable. I'd like to get a review and some sort of a yes/no survey some time soon. Be kind :)

newpavlov commented 6 years ago

I think it will be hard to compete with serde in terms of coverage, so ideally we should utilize it if possible.

I am not that familiar with this problem, so @tarcieri is the right person to discuss it. I hope he will add his input.

mzabaluev commented 6 years ago

As I tried to explain in the README, a Serializer backend would force all kinds of opinionated data representation choices on the instance of the digest serializer, and these choices will be decoupled from the concrete data structures.

Consider this scenario:

// crate a
#[derive(Serialize)]
pub struct A {
     foo: char
}
// crate b
extern crate a;
#[derive(Serialize)]
pub struct B {
    bar: a::A
}

The application wishing to calculate a hash of B through the hypothetical Serializer backend would have to be aware that the choice of how to hash the inner char would affect the result, even though the char is an implementation detail of A and may be not easily visible to the application developer: she'd have to either look at the source of a if that is available, or find it in a serialization dump of B made in a human-readable format.

mzabaluev commented 6 years ago

I have published my crate as digest-hash.