1pub const LE_FS_PUBLIC_BINDING_LAYOUT_VERSION: u32 = 1;
7
8pub const DOMAIN_MS: &str = "QSSM-MS-v1.0";
9pub const DOMAIN_LE: &str = "QSSM-LE-v1.0";
10pub const DOMAIN_MERKLE_PARENT: &str = "QSSM-MERKLE-PARENT-v1.0";
12pub const DOMAIN_SDK_MS_SEED: &str = "QSSM-SDK-MS-SEED-v1";
14pub const DOMAIN_SDK_LE_WITNESS: &str = "QSSM-SDK-LE-WITNESS-v1";
16pub const DOMAIN_SDK_LE_MASK: &str = "QSSM-SDK-LE-MASK-v1";
18
19#[inline]
20pub fn blake3_hash(data: &[u8]) -> [u8; 32] {
21 *blake3::hash(data).as_bytes()
22}
23
24pub fn hash_domain(domain: &str, chunks: &[&[u8]]) -> [u8; 32] {
26 let mut h = blake3::Hasher::new();
27 h.update(domain.as_bytes());
28 for c in chunks {
29 h.update(c);
30 }
31 *h.finalize().as_bytes()
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37
38 #[test]
39 fn domain_tags_diverge_for_same_chunks() {
40 let chunk: &[u8] = b"shared-payload";
41 assert_ne!(
42 hash_domain(DOMAIN_MS, &[chunk]),
43 hash_domain(DOMAIN_LE, &[chunk])
44 );
45 assert_ne!(
46 hash_domain(DOMAIN_SDK_MS_SEED, &[chunk]),
47 hash_domain(DOMAIN_SDK_LE_WITNESS, &[chunk])
48 );
49 assert_ne!(
50 hash_domain(DOMAIN_SDK_LE_MASK, &[chunk]),
51 hash_domain(DOMAIN_MERKLE_PARENT, &[chunk])
52 );
53 }
54}