Download src/lib.rs from Snapkitty/ledge: direct link, hf CLI and curl.
- Browser
- Download file 10.3 kB
-
https://huggingface.co/Snapkitty/ledge/resolve/main/src/lib.rs
- Command line
-
hf download hf://Snapkitty/ledge/src/lib.rs
-
curl -L -o lib.rs https://huggingface.co/Snapkitty/ledge/resolve/main/src/lib.rs
10.3 kB
| //! LEDGE β Sovereign Audit Chain | |
| //! Author: LOC Β· Rust kinetic agent Β· 2026-05-27 | |
| //! | |
| //! SHA-256 hash-linked append-only event log with Merkle root verification. | |
| //! Prototype pollution: impossible. Timing attacks: constant-time hashing. | |
| //! Supply chain: zero runtime deps outside sha2/hex/serde. Borrow checker holds the door. | |
| use sha2::{Sha256, Digest}; | |
| use serde::{Deserialize, Serialize}; | |
| use wasm_bindgen::prelude::*; | |
| // ββ Constants βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| const GENESIS_INPUT: &[u8] = b"LEDGE_GENESIS:SOVEREIGN_CHAIN_INIT"; | |
| // ββ Internal primitives βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| fn compute_genesis() -> [u8; 32] { | |
| Sha256::digest(GENESIS_INPUT).into() | |
| } | |
| fn compute_seal(prev: &[u8; 32], payload_json: &[u8], timestamp_ms: u64, index: u64) -> [u8; 32] { | |
| let mut h = Sha256::new(); | |
| h.update(prev); | |
| h.update(payload_json); | |
| h.update(timestamp_ms.to_be_bytes()); | |
| h.update(index.to_be_bytes()); | |
| h.finalize().into() | |
| } | |
| fn build_merkle_root(leaves: &[[u8; 32]]) -> [u8; 32] { | |
| if leaves.is_empty() { | |
| return Sha256::digest(b"EMPTY").into(); | |
| } | |
| let mut layer: Vec<[u8; 32]> = leaves.to_vec(); | |
| while layer.len() > 1 { | |
| let mut next = Vec::with_capacity((layer.len() + 1) / 2); | |
| let mut i = 0; | |
| while i < layer.len() { | |
| let left = layer[i]; | |
| let right = if i + 1 < layer.len() { layer[i + 1] } else { layer[i] }; | |
| let mut h = Sha256::new(); | |
| h.update(left); | |
| h.update(right); | |
| next.push(h.finalize().into()); | |
| i += 2; | |
| } | |
| layer = next; | |
| } | |
| layer[0] | |
| } | |
| fn hex_to_32(s: &str) -> Option<[u8; 32]> { | |
| let bytes = hex::decode(s).ok()?; | |
| if bytes.len() != 32 { return None; } | |
| let mut arr = [0u8; 32]; | |
| arr.copy_from_slice(&bytes); | |
| Some(arr) | |
| } | |
| // ββ Public types ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| pub struct SealedEvent { | |
| pub index: u64, | |
| pub seal: String, | |
| pub previous_seal: String, | |
| pub payload: serde_json::Value, | |
| pub timestamp_ms: u64, | |
| } | |
| pub struct VerifyResult { | |
| pub valid: bool, | |
| pub failures: Vec<u64>, | |
| pub merkle_root: String, | |
| pub event_count: usize, | |
| } | |
| // ββ LedgeChain ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| pub struct LedgeChain { | |
| events: Vec<SealedEvent>, | |
| head: [u8; 32], | |
| genesis: [u8; 32], | |
| } | |
| impl LedgeChain { | |
| pub fn new() -> Self { | |
| let genesis = compute_genesis(); | |
| Self { events: Vec::new(), head: genesis, genesis } | |
| } | |
| pub fn seal(&mut self, payload: serde_json::Value, timestamp_ms: u64) -> SealedEvent { | |
| let index = self.events.len() as u64; | |
| let payload_json = payload.to_string(); | |
| let seal_bytes = compute_seal(&self.head, payload_json.as_bytes(), timestamp_ms, index); | |
| let event = SealedEvent { | |
| index, | |
| seal: hex::encode(seal_bytes), | |
| previous_seal: hex::encode(self.head), | |
| payload, | |
| timestamp_ms, | |
| }; | |
| self.head = seal_bytes; | |
| self.events.push(event.clone()); | |
| event | |
| } | |
| pub fn verify(&self) -> VerifyResult { | |
| let mut prev = self.genesis; | |
| let mut failures = Vec::new(); | |
| for e in &self.events { | |
| let payload_json = e.payload.to_string(); | |
| let expected = compute_seal(&prev, payload_json.as_bytes(), e.timestamp_ms, e.index); | |
| if hex::encode(expected) != e.seal { | |
| failures.push(e.index); | |
| // continue β report all broken links, not just the first | |
| if let Some(b) = hex_to_32(&e.seal) { prev = b; } else { break; } | |
| } else { | |
| prev = expected; | |
| } | |
| } | |
| let leaves: Vec<[u8; 32]> = self.events.iter() | |
| .filter_map(|e| hex_to_32(&e.seal)) | |
| .collect(); | |
| VerifyResult { | |
| valid: failures.is_empty(), | |
| failures, | |
| merkle_root: hex::encode(build_merkle_root(&leaves)), | |
| event_count: self.events.len(), | |
| } | |
| } | |
| pub fn merkle_root(&self) -> String { | |
| let leaves: Vec<[u8; 32]> = self.events.iter() | |
| .filter_map(|e| hex_to_32(&e.seal)) | |
| .collect(); | |
| hex::encode(build_merkle_root(&leaves)) | |
| } | |
| pub fn genesis(&self) -> String { | |
| hex::encode(self.genesis) | |
| } | |
| pub fn events(&self) -> &[SealedEvent] { | |
| &self.events | |
| } | |
| pub fn len(&self) -> usize { | |
| self.events.len() | |
| } | |
| pub fn is_empty(&self) -> bool { | |
| self.events.is_empty() | |
| } | |
| } | |
| impl Default for LedgeChain { | |
| fn default() -> Self { | |
| Self::new() | |
| } | |
| } | |
| // ββ WASM bindings βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| // Stateless functions β chain state lives in JavaScript, crypto lives in Rust. | |
| pub fn ledge_genesis() -> String { | |
| hex::encode(compute_genesis()) | |
| } | |
| /// Compute the seal for a single event. | |
| /// prev_seal_hex: 64-char hex of previous seal (or genesis). | |
| /// Returns 64-char hex seal. | |
| pub fn ledge_seal(prev_seal_hex: &str, payload_json: &str, timestamp_ms: u64, index: u64) -> String { | |
| let prev = hex_to_32(prev_seal_hex).unwrap_or_else(compute_genesis); | |
| hex::encode(compute_seal(&prev, payload_json.as_bytes(), timestamp_ms, index)) | |
| } | |
| /// Verify a JSON array of SealedEvent objects. | |
| /// Returns JSON: { valid, failures, merkleRoot, eventCount } | |
| pub fn ledge_verify(events_json: &str) -> String { | |
| let events: Vec<SealedEvent> = match serde_json::from_str(events_json) { | |
| Ok(v) => v, | |
| Err(e) => return format!(r#"{{"valid":false,"failures":[],"merkleRoot":"","eventCount":0,"error":"{}"}}"#, e), | |
| }; | |
| let mut prev = compute_genesis(); | |
| let mut failures = Vec::new(); | |
| for e in &events { | |
| let payload_json = e.payload.to_string(); | |
| let expected = compute_seal(&prev, payload_json.as_bytes(), e.timestamp_ms, e.index); | |
| if hex::encode(expected) != e.seal { | |
| failures.push(e.index); | |
| } | |
| prev = hex_to_32(&e.seal).unwrap_or(expected); | |
| } | |
| let leaves: Vec<[u8; 32]> = events.iter().filter_map(|e| hex_to_32(&e.seal)).collect(); | |
| let root = hex::encode(build_merkle_root(&leaves)); | |
| let valid = failures.is_empty(); | |
| serde_json::json!({ | |
| "valid": valid, | |
| "failures": failures, | |
| "merkleRoot": root, | |
| "eventCount": events.len(), | |
| }).to_string() | |
| } | |
| /// Build a Merkle root from a JSON array of hex seal strings. | |
| pub fn ledge_merkle_root(seals_json: &str) -> String { | |
| let seals: Vec<String> = match serde_json::from_str(seals_json) { | |
| Ok(v) => v, | |
| Err(_) => return "0".repeat(64), | |
| }; | |
| let leaves: Vec<[u8; 32]> = seals.iter().filter_map(|s| hex_to_32(s)).collect(); | |
| hex::encode(build_merkle_root(&leaves)) | |
| } | |
| // ββ Tests βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| mod tests { | |
| use super::*; | |
| use serde_json::json; | |
| fn seal_and_verify_clean() { | |
| let mut chain = LedgeChain::new(); | |
| chain.seal(json!({"event": "PAYMENT", "amount": 5000}), 1716000000000); | |
| chain.seal(json!({"event": "APPROVAL", "agent": "VAULT"}), 1716000001000); | |
| chain.seal(json!({"event": "COMMIT", "ref": "abc123"}), 1716000002000); | |
| let result = chain.verify(); | |
| assert!(result.valid); | |
| assert!(result.failures.is_empty()); | |
| assert_eq!(result.event_count, 3); | |
| } | |
| fn tamper_breaks_chain() { | |
| let mut chain = LedgeChain::new(); | |
| chain.seal(json!({"event": "COMMIT", "ref": "main"}), 1716000000000); | |
| chain.seal(json!({"event": "DECISION", "approved": true}), 1716000001000); | |
| chain.events[0].payload = json!({"event": "COMMIT", "ref": "BACKDOOR"}); | |
| let result = chain.verify(); | |
| assert!(!result.valid); | |
| assert!(result.failures.contains(&0)); | |
| } | |
| fn merkle_root_deterministic() { | |
| let mut a = LedgeChain::new(); | |
| a.seal(json!({"v": 1}), 0); | |
| a.seal(json!({"v": 2}), 1); | |
| let mut b = LedgeChain::new(); | |
| b.seal(json!({"v": 1}), 0); | |
| b.seal(json!({"v": 2}), 1); | |
| assert_eq!(a.merkle_root(), b.merkle_root()); | |
| } | |
| fn empty_chain_has_genesis_root() { | |
| let chain = LedgeChain::new(); | |
| let result = chain.verify(); | |
| assert!(result.valid); | |
| assert_eq!(result.event_count, 0); | |
| } | |
| fn seal_is_deterministic() { | |
| let prev = compute_genesis(); | |
| let payload = b"{}"; | |
| let ts: u64 = 1716000000000; | |
| let s1 = compute_seal(&prev, payload, ts, 0); | |
| let s2 = compute_seal(&prev, payload, ts, 0); | |
| assert_eq!(s1, s2); | |
| } | |
| } | |