Skip to main content

lib_compression/
traits.rs

1//! Abstraction traits for external dependencies
2//!
3//! This module defines minimal traits that abstract away internal workspace
4//! dependencies. Each trait has a default implementation that works standalone,
5//! allowing lib-compression to function without requiring lib-proofs, lib-storage,
6//! or lib-neural-mesh.
7//!
8//! # Usage
9//!
10//! ```rust
11//! use lib_compression::traits::{ProofBackend, DhtStorage, ModelCompressor};
12//!
13//! // Use default implementations (no external deps required)
14//! let proof = DefaultProofBackend;
15//! let dht = MemoryDht::default();
16//! let compressor = DefaultModelCompressor;
17//! ```
18
19use std::collections::HashMap;
20use std::sync::{Arc, RwLock};
21
22use crate::error::Result;
23
24// =============================================================================
25// Proof Backend Trait (abstracts lib-proofs)
26// =============================================================================
27
28/// Zero-knowledge proof backend for range proofs and Merkle trees.
29///
30/// Default implementation uses BLAKE3 hashes as a lightweight fallback.
31/// Enable `zk-proofs` feature for real Bulletproofs/Plonky2 support.
32pub trait ProofBackend: Send + Sync {
33    /// Generate a range proof for a value.
34    fn generate_range_proof(&self, value: u64, min: u64, max: u64) -> Result<Vec<u8>>;
35
36    /// Verify a range proof.
37    fn verify_range_proof(&self, proof: &[u8], min: u64, max: u64) -> Result<bool>;
38
39    /// Compute Merkle root from leaves.
40    fn merkle_root(&self, leaves: &[Vec<u8>]) -> Result<[u8; 32]>;
41
42    /// Generate Merkle inclusion proof.
43    fn generate_merkle_proof(&self, leaves: &[Vec<u8>], index: usize) -> Result<MerkleProof>;
44
45    /// Verify Merkle inclusion proof.
46    fn verify_merkle_proof(&self, proof: &MerkleProof, root: &[u8; 32], leaf: &[u8]) -> Result<bool>;
47}
48
49/// Merkle proof structure.
50#[derive(Debug, Clone)]
51pub struct MerkleProof {
52    pub leaf: Vec<u8>,
53    pub path: Vec<[u8; 32]>,
54    pub indices: Vec<u8>,
55}
56
57/// Default proof backend using BLAKE3 (no ZK, just hashes).
58#[derive(Debug, Clone, Copy)]
59pub struct DefaultProofBackend;
60
61impl ProofBackend for DefaultProofBackend {
62    fn generate_range_proof(&self, value: u64, min: u64, max: u64) -> Result<Vec<u8>> {
63        // Fallback: just encode the value as "proof" (not cryptographically sound,
64        // but works for testing and non-ZK use cases)
65        if value < min || value > max {
66            return Err(crate::error::CompressionError::InvalidParameter(
67                format!("Value {} outside range [{}, {}]", value, min, max)
68            ));
69        }
70        Ok(value.to_le_bytes().to_vec())
71    }
72
73    fn verify_range_proof(&self, proof: &[u8], min: u64, max: u64) -> Result<bool> {
74        if proof.len() != 8 {
75            return Ok(false);
76        }
77        let value = u64::from_le_bytes(proof.try_into().unwrap());
78        Ok(value >= min && value <= max)
79    }
80
81    fn merkle_root(&self, leaves: &[Vec<u8>]) -> Result<[u8; 32]> {
82        if leaves.is_empty() {
83            return Ok([0u8; 32]);
84        }
85        
86        // Simple BLAKE3-based Merkle tree
87        let mut current_level: Vec<[u8; 32]> = leaves
88            .iter()
89            .map(|leaf| blake3::hash(leaf).into())
90            .collect();
91
92        while current_level.len() > 1 {
93            let mut next_level = Vec::new();
94            for chunk in current_level.chunks(2) {
95                let hash = if chunk.len() == 2 {
96                    let mut hasher = blake3::Hasher::new();
97                    hasher.update(&chunk[0]);
98                    hasher.update(&chunk[1]);
99                    hasher.finalize()
100                } else {
101                    blake3::Hasher::new().finalize()
102                };
103                next_level.push(hash.into());
104            }
105            current_level = next_level;
106        }
107
108        Ok(current_level[0])
109    }
110
111    fn generate_merkle_proof(&self, leaves: &[Vec<u8>], index: usize) -> Result<MerkleProof> {
112        if index >= leaves.len() {
113            return Err(crate::error::CompressionError::InvalidParameter(
114                format!("Index {} out of bounds for {} leaves", index, leaves.len())
115            ));
116        }
117
118        let leaf_hash = blake3::hash(&leaves[index]);
119        let mut path = Vec::new();
120        let mut indices = Vec::new();
121        
122        let mut current_level: Vec<[u8; 32]> = leaves
123            .iter()
124            .map(|leaf| blake3::hash(leaf).into())
125            .collect();
126        
127        let mut current_index = index;
128
129        while current_level.len() > 1 {
130            let sibling_index = if current_index % 2 == 0 {
131                current_index + 1
132            } else {
133                current_index - 1
134            };
135
136            if sibling_index < current_level.len() {
137                path.push(current_level[sibling_index]);
138                indices.push((current_index % 2) as u8);
139            }
140
141            // Build next level
142            let mut next_level = Vec::new();
143            for chunk in current_level.chunks(2) {
144                let hash = if chunk.len() == 2 {
145                    let mut hasher = blake3::Hasher::new();
146                    hasher.update(&chunk[0]);
147                    hasher.update(&chunk[1]);
148                    hasher.finalize()
149                } else {
150                    blake3::Hasher::new().finalize()
151                };
152                next_level.push(hash.into());
153            }
154            
155            current_level = next_level;
156            current_index /= 2;
157        }
158
159        Ok(MerkleProof {
160            leaf: leaf_hash.as_bytes().to_vec(),
161            path,
162            indices,
163        })
164    }
165
166    fn verify_merkle_proof(&self, proof: &MerkleProof, root: &[u8; 32], leaf: &[u8]) -> Result<bool> {
167        let mut current_hash: [u8; 32] = blake3::hash(leaf).into();
168        
169        for (i, sibling) in proof.path.iter().enumerate() {
170            let mut hasher = blake3::Hasher::new();
171            if proof.indices[i] == 0 {
172                hasher.update(&current_hash);
173                hasher.update(sibling);
174            } else {
175                hasher.update(sibling);
176                hasher.update(&current_hash);
177            }
178            current_hash = hasher.finalize().into();
179        }
180
181        Ok(current_hash == *root)
182    }
183}
184
185// =============================================================================
186// DHT Storage Trait (abstracts lib-storage::DhtNodeManager)
187// =============================================================================
188
189/// Distributed hash table storage backend.
190///
191/// Default implementation is in-memory (for testing/standalone usage).
192/// Enable `dht-storage` feature for real lib-storage integration.
193pub trait DhtStorage: Send + Sync {
194    /// Store a value in the DHT.
195    fn store(&self, key: &[u8], data: &[u8]) -> Result<()>;
196
197    /// Retrieve a value from the DHT.
198    fn retrieve(&self, key: &[u8]) -> Result<Option<Vec<u8>>>;
199
200    /// Delete a value from the DHT.
201    fn delete(&self, key: &[u8]) -> Result<()>;
202
203    /// Check if a key exists in the DHT.
204    fn exists(&self, key: &[u8]) -> Result<bool>;
205}
206
207/// In-memory DHT storage (default implementation).
208#[derive(Clone)]
209pub struct MemoryDht {
210    data: Arc<RwLock<HashMap<[u8; 32], Vec<u8>>>>,
211}
212
213impl Default for MemoryDht {
214    fn default() -> Self {
215        Self::new()
216    }
217}
218
219impl MemoryDht {
220    pub fn new() -> Self {
221        Self {
222            data: Arc::new(RwLock::new(HashMap::new())),
223        }
224    }
225}
226
227impl DhtStorage for MemoryDht {
228    fn store(&self, key: &[u8], data: &[u8]) -> Result<()> {
229        let mut key_array = [0u8; 32];
230        key_array.copy_from_slice(&key[..32.min(key.len())]);
231        
232        let mut guard = self.data.write().unwrap();
233        guard.insert(key_array, data.to_vec());
234        Ok(())
235    }
236
237    fn retrieve(&self, key: &[u8]) -> Result<Option<Vec<u8>>> {
238        let mut key_array = [0u8; 32];
239        key_array.copy_from_slice(&key[..32.min(key.len())]);
240        
241        let guard = self.data.read().unwrap();
242        Ok(guard.get(&key_array).cloned())
243    }
244
245    fn delete(&self, key: &[u8]) -> Result<()> {
246        let mut key_array = [0u8; 32];
247        key_array.copy_from_slice(&key[..32.min(key.len())]);
248        
249        let mut guard = self.data.write().unwrap();
250        guard.remove(&key_array);
251        Ok(())
252    }
253
254    fn exists(&self, key: &[u8]) -> Result<bool> {
255        let mut key_array = [0u8; 32];
256        key_array.copy_from_slice(&key[..32.min(key.len())]);
257        
258        let guard = self.data.read().unwrap();
259        Ok(guard.contains_key(&key_array))
260    }
261}
262
263// =============================================================================
264// Model Compressor Trait (abstracts lib-neural-mesh)
265// =============================================================================
266
267/// Model-based compression interface.
268///
269/// Default implementation is a no-op (passthrough).
270/// Enable `ml-support` feature for real neural mesh integration.
271pub trait ModelCompressor: Send + Sync {
272    /// Compress data using model-based techniques.
273    fn compress(&self, data: &[u8]) -> Result<Vec<u8>>;
274
275    /// Decompress model-compressed data.
276    fn decompress(&self, data: &[u8]) -> Result<Vec<u8>>;
277
278    /// Get the name of this compressor.
279    fn name(&self) -> &str;
280}
281
282/// Default passthrough compressor (no compression).
283#[derive(Debug, Clone, Copy)]
284pub struct DefaultModelCompressor;
285
286impl ModelCompressor for DefaultModelCompressor {
287    fn compress(&self, data: &[u8]) -> Result<Vec<u8>> {
288        Ok(data.to_vec())
289    }
290
291    fn decompress(&self, data: &[u8]) -> Result<Vec<u8>> {
292        Ok(data.to_vec())
293    }
294
295    fn name(&self) -> &str {
296        "passthrough"
297    }
298}