qualia_core_db/modalities/
carrier.rs1use crate::NQuin;
11
12pub fn media_tag(blob: &[u8]) -> u64 {
15 let h = blake3::hash(blob);
16 let b = h.as_bytes();
17 u64::from_le_bytes([b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]])
18}
19
20#[inline]
23pub fn verify_binding(blob: &[u8], bound_media_tag: u64) -> bool {
24 media_tag(blob) == bound_media_tag
25}
26
27pub fn extract_payload(payload: &[NQuin], out: &mut [NQuin]) -> usize {
30 let n = payload.len().min(out.len());
31 out[..n].copy_from_slice(&payload[..n]);
32 n
33}
34
35pub fn merkle_node(children: &[u64]) -> u64 {
41 let mut hasher = blake3::Hasher::new();
42 for &c in children {
43 hasher.update(&c.to_le_bytes());
44 }
45 u64::from_le_bytes(hasher.finalize().as_bytes()[..8].try_into().unwrap())
46}
47
48#[inline]
50pub fn verify_merkle_node(node_tag: u64, children: &[u64]) -> bool {
51 merkle_node(children) == node_tag
52}
53
54#[derive(Default)]
60pub struct StreamHasher {
61 inner: blake3::Hasher,
62}
63
64impl StreamHasher {
65 pub fn new() -> Self {
66 Self {
67 inner: blake3::Hasher::new(),
68 }
69 }
70 pub fn update(&mut self, chunk: &[u8]) {
72 self.inner.update(chunk);
73 }
74 pub fn finalize(&self) -> u64 {
76 u64::from_le_bytes(self.inner.finalize().as_bytes()[..8].try_into().unwrap())
77 }
78}
79
80#[inline]
87pub fn multisig_satisfied(valid_signers: usize, k: usize) -> bool {
88 k > 0 && valid_signers >= k
89}
90
91pub fn redaction_preserves_root(leaf_tags: &[u64], original_root: u64) -> bool {
98 merkle_node(leaf_tags) == original_root
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 fn quin(s: u64, o: u64) -> NQuin {
106 let mut q = NQuin {
107 subject: s,
108 predicate: 7,
109 object: o,
110 context: 0,
111 metadata: 0,
112 parity: 0,
113 };
114 q.parity = q.subject ^ q.predicate ^ q.object ^ q.context;
115 q
116 }
117
118 #[test]
119 fn media_tag_is_deterministic_and_content_addressed() {
120 let blob = b"a signed evidentiary photograph's bytes";
121 let tag = media_tag(blob);
122 assert_eq!(tag, media_tag(blob), "deterministic");
123 assert_ne!(tag, media_tag(b"different bytes"), "content-addressed");
124 }
125
126 #[test]
127 fn binding_is_tamper_evident() {
128 let blob = b"original media";
129 let tag = media_tag(blob);
130 assert!(verify_binding(blob, tag), "intact media verifies");
131 assert!(
132 !verify_binding(b"tampered media", tag),
133 "any edit breaks the binding"
134 );
135 }
136
137 #[test]
138 fn payload_extracts_round_trip() {
139 let payload = [quin(1, 2), quin(3, 4)];
140 let mut out = [NQuin::default(); 4];
141 let n = extract_payload(&payload, &mut out);
142 assert_eq!(n, 2);
143 assert_eq!(out[0].subject, 1);
144 assert_eq!(out[1].object, 4);
145 }
146
147 #[test]
148 fn merkle_dag_node_is_order_sensitive_and_tamper_evident() {
149 let a = media_tag(b"leaf-a");
150 let b = media_tag(b"leaf-b");
151 let root = merkle_node(&[a, b]);
152 assert!(verify_merkle_node(root, &[a, b]));
153 assert_ne!(
154 merkle_node(&[a, b]),
155 merkle_node(&[b, a]),
156 "order matters in a DAG"
157 );
158 assert!(
159 !verify_merkle_node(root, &[a, media_tag(b"tampered")]),
160 "any child change breaks it"
161 );
162 }
163
164 #[test]
165 fn streaming_hash_equals_one_shot() {
166 let blob = b"a very large evidentiary recording streamed in chunks";
167 let mut sh = StreamHasher::new();
168 sh.update(&blob[..10]);
169 sh.update(&blob[10..30]);
170 sh.update(&blob[30..]);
171 assert_eq!(
172 sh.finalize(),
173 media_tag(blob),
174 "streaming == one-shot media_tag"
175 );
176 }
177
178 #[test]
179 fn multisig_threshold_and_verifiable_redaction() {
180 assert!(multisig_satisfied(2, 2));
182 assert!(multisig_satisfied(3, 2));
183 assert!(!multisig_satisfied(1, 2));
184 assert!(!multisig_satisfied(3, 0), "a zero threshold is invalid");
185
186 let l0 = media_tag(b"public clause");
188 let l1 = media_tag(b"private medical detail");
189 let root = merkle_node(&[l0, l1]);
190 assert!(redaction_preserves_root(&[l0, l1], root));
192 assert!(!redaction_preserves_root(&[l0, media_tag(b"forged")], root));
194 }
195}