Skip to main content

yule_verify/
lib.rs

1pub mod keys;
2pub mod manifest;
3pub mod merkle;
4pub mod signature;
5
6use crate::manifest::ModelManifest;
7use crate::merkle::MerkleTree;
8use yule_core::error::{Result, YuleError};
9
10pub struct IntegrityVerifier {
11    merkle: MerkleTree,
12}
13
14impl IntegrityVerifier {
15    pub fn new() -> Self {
16        Self {
17            merkle: MerkleTree::new(),
18        }
19    }
20
21    /// Full model verification: merkle root + manifest signature.
22    pub fn verify_model(
23        &self,
24        manifest: &ModelManifest,
25        tensor_data: &[u8],
26    ) -> Result<VerificationResult> {
27        // 1. verify merkle root matches tensor data
28        let root = self.merkle.build(tensor_data);
29        let merkle_valid = root.hash == manifest.merkle_root;
30
31        if !merkle_valid {
32            return Err(YuleError::Verification(
33                "merkle root mismatch — tensor data has been modified".into()
34            ));
35        }
36
37        // 2. verify publisher signature
38        let signature_valid = match manifest.verify_signature() {
39            Ok(valid) => Some(valid),
40            Err(_) => Some(false),
41        };
42
43        Ok(VerificationResult {
44            root_hash: root.hash,
45            tensor_count: manifest.tensor_hashes.len(),
46            verified: merkle_valid && signature_valid.unwrap_or(false),
47            signature_valid,
48        })
49    }
50
51    /// Verify only the merkle root (no manifest needed).
52    pub fn verify_merkle_only(&self, tensor_data: &[u8], expected_root: &[u8; 32]) -> bool {
53        self.merkle.verify(tensor_data, expected_root)
54    }
55}
56
57impl Default for IntegrityVerifier {
58    fn default() -> Self {
59        Self::new()
60    }
61}
62
63#[derive(Debug)]
64pub struct VerificationResult {
65    pub root_hash: [u8; 32],
66    pub tensor_count: usize,
67    pub verified: bool,
68    pub signature_valid: Option<bool>,
69}