1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
use cryptoxide::{blake2b::Blake2b, digest::Digest};

pub(crate) const BLAKE_2B_256_HASH_SIZE: usize = 256 / 8;

/// Helper function to generate the `blake2b_256` hash of a byte slice
pub(crate) fn hash(bytes: &[u8]) -> [u8; BLAKE_2B_256_HASH_SIZE] {
    let mut digest = [0u8; BLAKE_2B_256_HASH_SIZE];
    let mut context = Blake2b::new(BLAKE_2B_256_HASH_SIZE);
    context.input(bytes);
    context.result(&mut digest);

    digest
}

#[cfg(test)]
mod tests {
    use super::*;

    // these consts are taken from cip 15 test vectors
    const HASH_BYTES_HEX: &str = "a3d63f26cd94002443bc24f24b0a150f2c7996cd3a3fd247248de396faea6a5f";
    const METADATA_CBOR_HEX_BYTES: &str = "a119ef64a40158200036ef3e1f0d3f5989e2d155ea54bdb2a72c4c456ccb959af4c94868f473f5a002582086870efc99c453a873a16492ce87738ec79a0ebd064379a62e2c9cf4e119219e03581de0ae3a0a7aeda4aea522e74e4fe36759fca80789a613a58a4364f6ecef041904d2";

    fn hex_test(content_hex: &str, hash_hex: &str) {
        let content_bytes = hex::decode(content_hex).unwrap();
        let hash_bytes = hex::decode(hash_hex).unwrap();

        let hashed = hash(&content_bytes);

        assert_eq!(hashed.to_vec(), hash_bytes);
    }

    // Some test cases generated by cyber chef
    #[test]
    fn hashes_correctly() {
        hex_test(
            "0000",
            "9ee6dfb61a2fb903df487c401663825643bb825d41695e63df8af6162ab145a6",
        );
        hex_test(METADATA_CBOR_HEX_BYTES, HASH_BYTES_HEX);
    }
}