stellar_contract_utils/crypto/
hashable.rs

1//! Generic hashing support.
2
3use soroban_sdk::{Bytes, BytesN};
4
5use crate::crypto::hasher::Hasher;
6
7/// A hashable type.
8///
9/// Types implementing `Hashable` are able to be [`Hashable::hash`]ed with an
10/// instance of [`Hasher`].
11pub trait Hashable {
12    /// Feeds this value into the given [`Hasher`].
13    fn hash<H: Hasher>(&self, hasher: &mut H);
14}
15
16impl Hashable for BytesN<32> {
17    #[inline]
18    fn hash<H: Hasher>(&self, hasher: &mut H) {
19        hasher.update(self.into());
20    }
21}
22
23impl Hashable for Bytes {
24    #[inline]
25    fn hash<H: Hasher>(&self, hasher: &mut H) {
26        hasher.update(self.clone());
27    }
28}
29
30/// Hash the pair `(a, b)` with `hasher`.
31///
32/// Returns the finalized hash output from the hasher.
33///
34/// # Arguments
35///
36/// * `a` - The first value to hash.
37/// * `b` - The second value to hash.
38/// * `hasher` - The hasher to use.
39#[inline]
40pub fn hash_pair<S, H>(a: &H, b: &H, mut hasher: S) -> S::Output
41where
42    H: Hashable + ?Sized,
43    S: Hasher,
44{
45    a.hash(&mut hasher);
46    b.hash(&mut hasher);
47    hasher.finalize()
48}
49
50/// Sort the pair `(a, b)` and hash the result with `hasher`. Frequently used
51/// when working with merkle proofs.
52///
53/// Returns the finalized hash output from the hasher.
54///
55/// # Arguments
56///
57/// * `a` - The first value to hash.
58/// * `b` - The second value to hash.
59/// * `hasher` - The hasher to use.
60#[inline]
61pub fn commutative_hash_pair<S, H>(a: &H, b: &H, hasher: S) -> S::Output
62where
63    H: Hashable + PartialOrd,
64    S: Hasher,
65{
66    if a > b {
67        hash_pair(b, a, hasher)
68    } else {
69        hash_pair(a, b, hasher)
70    }
71}