1use serde::{Deserialize, Serialize};
7use serde_big_array::BigArray;
8use uuid::Uuid;
9
10use crate::hlc::Hlc;
11
12#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
17pub struct StateRoot {
18 pub hash: [u8; 32],
20
21 pub parent: Option<[u8; 32]>,
23
24 pub hlc: Hlc,
26
27 pub device_id: Uuid,
29
30 #[serde(with = "BigArray")]
32 pub signature: [u8; 64],
33
34 pub seq: u64,
36}
37
38impl StateRoot {
39 pub fn new(
41 hash: [u8; 32],
42 parent: Option<[u8; 32]>,
43 hlc: Hlc,
44 device_id: Uuid,
45 seq: u64,
46 ) -> Self {
47 Self {
48 hash,
49 parent,
50 hlc,
51 device_id,
52 signature: [0u8; 64], seq,
54 }
55 }
56
57 pub fn signing_bytes(&self) -> Vec<u8> {
62 let mut bytes = Vec::with_capacity(114);
63 bytes.extend_from_slice(&self.hash);
64 if let Some(parent) = &self.parent {
65 bytes.extend_from_slice(parent);
66 } else {
67 bytes.extend_from_slice(&[0u8; 32]);
68 }
69 bytes.extend_from_slice(&self.hlc.to_bytes());
70 bytes.extend_from_slice(self.device_id.as_bytes());
71 bytes.extend_from_slice(&self.seq.to_le_bytes());
72 bytes
73 }
74
75 pub fn is_genesis(&self) -> bool {
77 self.parent.is_none()
78 }
79
80 pub fn hash_hex(&self) -> String {
82 use std::fmt::Write;
83 let mut s = String::with_capacity(64);
84 for b in &self.hash {
85 let _ = write!(s, "{b:02x}");
86 }
87 s
88 }
89
90 pub fn short_hash(&self) -> String {
92 self.hash_hex()[..8].to_string()
93 }
94
95 pub fn sign(&mut self, signing_key: &ed25519_dalek::SigningKey) {
97 use ed25519_dalek::Signer;
98 let bytes = self.signing_bytes();
99 let signature = signing_key.sign(&bytes);
100 self.signature = signature.to_bytes();
101 }
102
103 pub fn verify(
105 &self,
106 verifying_key: &ed25519_dalek::VerifyingKey,
107 ) -> Result<(), ed25519_dalek::SignatureError> {
108 use ed25519_dalek::Verifier;
109 let bytes = self.signing_bytes();
110 let signature = ed25519_dalek::Signature::from_bytes(&self.signature);
111 verifying_key.verify(&bytes, &signature)
112 }
113}
114
115pub fn compute_merkle_root(hashes: &[[u8; 32]]) -> [u8; 32] {
117 if hashes.is_empty() {
118 return *blake3::hash(b"empty").as_bytes();
119 }
120 if hashes.len() == 1 {
121 return hashes[0];
122 }
123 let mut current_level: Vec<[u8; 32]> = hashes.to_vec();
124 while current_level.len() > 1 {
125 let mut next_level = Vec::new();
126 for pair in current_level.chunks(2) {
127 if pair.len() == 2 {
128 let mut hasher = blake3::Hasher::new();
129 hasher.update(&pair[0]);
130 hasher.update(&pair[1]);
131 next_level.push(*hasher.finalize().as_bytes());
132 } else {
133 let mut hasher = blake3::Hasher::new();
134 hasher.update(&pair[0]);
135 hasher.update(&pair[0]);
136 next_level.push(*hasher.finalize().as_bytes());
137 }
138 }
139 current_level = next_level;
140 }
141 current_level[0]
142}
143
144pub fn compute_state_root_composition(
146 doc_root: [u8; 32],
147 chunk_root: [u8; 32],
148 emb_root: [u8; 32],
149 edge_root: [u8; 32],
150) -> [u8; 32] {
151 let mut hasher = blake3::Hasher::new();
152 hasher.update(&doc_root);
153 hasher.update(&chunk_root);
154 hasher.update(&emb_root);
155 hasher.update(&edge_root);
156 *hasher.finalize().as_bytes()
157}
158
159pub fn generate_merkle_proof(hashes: &[[u8; 32]], index: usize) -> Vec<([u8; 32], bool)> {
164 let mut proof = Vec::new();
165 let mut current_level = hashes.to_vec();
166 let mut idx = index;
167 while current_level.len() > 1 {
168 let sibling_idx = if idx.is_multiple_of(2) {
169 if idx + 1 < current_level.len() {
170 idx + 1
171 } else {
172 idx
173 }
174 } else {
175 idx - 1
176 };
177
178 let is_sibling_left = !idx.is_multiple_of(2);
183 proof.push((current_level[sibling_idx], is_sibling_left));
184
185 let mut next_level = Vec::new();
186 for pair in current_level.chunks(2) {
187 if pair.len() == 2 {
188 let mut hasher = blake3::Hasher::new();
189 hasher.update(&pair[0]);
190 hasher.update(&pair[1]);
191 next_level.push(*hasher.finalize().as_bytes());
192 } else {
193 let mut hasher = blake3::Hasher::new();
194 hasher.update(&pair[0]);
195 hasher.update(&pair[0]);
196 next_level.push(*hasher.finalize().as_bytes());
197 }
198 }
199 idx /= 2;
200 current_level = next_level;
201 }
202 proof
203}
204
205pub fn verify_merkle_proof(
207 data: &[u8; 32],
208 _index: usize,
209 proof: &[([u8; 32], bool)],
210 root: &[u8; 32],
211) -> bool {
212 let mut current_hash = *data;
213 for (sibling, is_left) in proof {
214 let mut hasher = blake3::Hasher::new();
215 if *is_left {
216 hasher.update(sibling);
217 hasher.update(¤t_hash);
218 } else {
219 hasher.update(¤t_hash);
220 hasher.update(sibling);
221 }
222 current_hash = *hasher.finalize().as_bytes();
223 }
224 current_hash == *root
225}
226
227#[cfg(test)]
228mod tests {
229 use super::*;
230
231 fn test_hlc() -> Hlc {
232 Hlc::new(1234567890, [0u8; 16])
233 }
234
235 #[test]
236 fn test_state_root_creation() {
237 let root = StateRoot::new([1u8; 32], None, test_hlc(), Uuid::from_bytes([1u8; 16]), 0);
238
239 assert!(root.is_genesis());
240 assert_eq!(root.seq, 0);
241 }
242
243 #[test]
244 fn test_state_chain() {
245 let genesis = StateRoot::new(
246 [1u8; 32],
247 None,
248 Hlc::new(1000, [0u8; 16]),
249 Uuid::from_bytes([1u8; 16]),
250 0,
251 );
252
253 let second = StateRoot::new(
254 [2u8; 32],
255 Some(genesis.hash),
256 Hlc::new(2000, [0u8; 16]),
257 genesis.device_id,
258 1,
259 );
260
261 assert!(genesis.is_genesis());
262 assert!(!second.is_genesis());
263 assert_eq!(second.parent, Some(genesis.hash));
264 }
265
266 #[test]
267 fn test_signing_bytes_deterministic() {
268 let root = StateRoot::new(
269 [42u8; 32],
270 Some([1u8; 32]),
271 test_hlc(),
272 Uuid::from_bytes([0u8; 16]),
273 5,
274 );
275
276 let bytes1 = root.signing_bytes();
277 let bytes2 = root.signing_bytes();
278
279 assert_eq!(bytes1, bytes2);
280 assert_eq!(bytes1.len(), 114);
282 }
283
284 #[test]
285 fn test_signing_bytes_includes_hlc() {
286 let root1 = StateRoot::new(
287 [1u8; 32],
288 None,
289 Hlc::new(1000, [0u8; 16]),
290 Uuid::from_bytes([0u8; 16]),
291 0,
292 );
293
294 let root2 = StateRoot::new(
295 [1u8; 32],
296 None,
297 Hlc::new(2000, [0u8; 16]),
298 Uuid::from_bytes([0u8; 16]),
299 0,
300 );
301
302 assert_ne!(root1.signing_bytes(), root2.signing_bytes());
304 }
305
306 #[test]
309 fn test_compute_merkle_root_empty() {
310 let empty_hashes: [[u8; 32]; 0] = [];
311 let root = compute_merkle_root(&empty_hashes);
312 let expected = *blake3::hash(b"empty").as_bytes();
313 assert_eq!(root, expected);
314 }
315
316 #[test]
317 fn test_compute_merkle_root_single_entity() {
318 let hashes = [[1u8; 32]];
319 let root = compute_merkle_root(&hashes);
320 assert_eq!(root, [1u8; 32]);
321 }
322
323 #[test]
324 fn test_compute_merkle_root_odd_number_entities() {
325 let hashes: [[u8; 32]; 3] = [[1u8; 32], [2u8; 32], [3u8; 32]];
326 let root = compute_merkle_root(&hashes);
327 assert_eq!(root.len(), 32);
328 }
329
330 #[test]
331 fn test_compute_merkle_root_deterministic() {
332 let hashes: [[u8; 32]; 4] = [[10u8; 32], [20u8; 32], [30u8; 32], [40u8; 32]];
333 let root1 = compute_merkle_root(&hashes);
334 let root2 = compute_merkle_root(&hashes);
335 assert_eq!(root1, root2);
336 }
337
338 #[test]
339 fn test_compute_state_root_composition() {
340 let doc_root = [1u8; 32];
341 let chunk_root = [2u8; 32];
342 let emb_root = [3u8; 32];
343 let edge_root = [4u8; 32];
344 let composed = compute_state_root_composition(doc_root, chunk_root, emb_root, edge_root);
345 assert_eq!(composed.len(), 32);
346 }
347
348 #[test]
349 fn test_state_root_parent_chain() {
350 let hlc = Hlc::new(1000, [1u8; 16]);
351 let device_id = Uuid::from_bytes([1u8; 16]);
352 let genesis = StateRoot::new([1u8; 32], None, hlc.clone(), device_id, 0);
353 assert!(genesis.is_genesis());
354 let second = StateRoot::new(
355 [2u8; 32],
356 Some(genesis.hash),
357 Hlc::new(2000, [1u8; 16]),
358 device_id,
359 1,
360 );
361 assert!(!second.is_genesis());
362 }
363
364 #[test]
365 fn test_state_root_sequence_number() {
366 let hlc = Hlc::new(1000, [1u8; 16]);
367 let device_id = Uuid::from_bytes([1u8; 16]);
368 let root0 = StateRoot::new([1u8; 32], None, hlc.clone(), device_id, 0);
369 let root1 = StateRoot::new(
370 [2u8; 32],
371 Some(root0.hash),
372 Hlc::new(2000, [1u8; 16]),
373 device_id,
374 1,
375 );
376 assert!(root0.seq < root1.seq);
377 }
378
379 #[test]
380 fn test_merkle_proof_generation() {
381 let hashes: [[u8; 32]; 4] = [[1u8; 32], [2u8; 32], [3u8; 32], [4u8; 32]];
382 let proof = generate_merkle_proof(&hashes, 0);
383 assert!(!proof.is_empty());
384 }
385
386 #[test]
387 fn test_merkle_proof_verification_valid() {
388 let hashes: [[u8; 32]; 2] = [[1u8; 32], [2u8; 32]];
390 let _root = compute_merkle_root(&hashes);
391 let proof = generate_merkle_proof(&hashes, 0);
392 assert!(!proof.is_empty());
394 for (sibling, is_left) in &proof {
395 assert_eq!(sibling.len(), 32);
396 let _ = is_left;
398 }
399 }
400
401 #[test]
402 fn test_merkle_proof_verification_invalid() {
403 let hashes: [[u8; 32]; 2] = [[1u8; 32], [2u8; 32]];
405 let proof = generate_merkle_proof(&hashes, 0);
406 assert!(!proof.is_empty());
407 }
408
409 #[test]
410 fn test_merkle_proof_inclusion() {
411 let hashes: [[u8; 32]; 3] = [[10u8; 32], [20u8; 32], [30u8; 32]];
413
414 for i in 0..3 {
415 let proof = generate_merkle_proof(&hashes, i);
416 assert!(!proof.is_empty());
417 }
418 }
419}