Hash Equivalence for Serialized Structures

Hey all,
I am trying to use Rust for some cryptograph domain and need to serialize datastructures like HashMaps, structs etc. Now I hash using sha256 algorithm on a &[u8] which I get from serialized version of the data-structures. The problem is for the same structure for example HashMap, the serialized string might be different as it's in a way "Unordered" and so my hashes keeps on messing up. My question is what can be the trait constraints I should be having on my data-structures so that when I serialize them and compute hashes they always match! The problem solves when I use BTreeMap which I guess is because it has some sort of "Ordering". I want traits which would constraint this behaviour statically.

What's wrong with the standard Hash trait?

Edit: technically a type implementing Hash is not required to have a canonical serialized representation, but I don't think you'll find anything better for that short of making your trait and manually implementing it for the types that you know satisfy that requirement.

Precis. The trait you are looking for is Ord: Ord in std::cmp - Rust

yeah @SkiFire13 I though of that, but the thing is the constraint is that hash of the serialized version should match

yeah @firebits.io this also I though of using it, but this still does not guarantee that the hash of serialized version of it would match up?

Even when you use the Hash + Ord as the constraint?

yeah @firebits.io I believe this would maintain the ordering. I would need to check into the implementation of Serde I guess.

If you're looking specifically for something about the serialized version then you won't find anything standard and you'll have to roll your own trait.

Ord is for comparing different instances of a type. Here instead op wants a collection that internally has a fixed order of its items.

1 Like

I see. I thought Ord offered that guarantee as well.

yeah exactly! it's just not ordering types but specifically collection containing items which has some ordering like a vector or a BTreeMap

If you have an Ord type, you can put it into a BTreeSet.

Just to give you a counterexample, imagine an HashMap whose Ord implementation just creates a copy of the HashMap items, sorts them and then compares the sorted versions. This would be a valid Ord implementation, however the HashMap itself remained unsorted and could be serialized in such unsorted order. The same would apply to Hash by the way.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.