From c402255ea5ef6510a583b79e49f4246dc618c362 Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Wed, 25 Jun 2025 10:31:21 +0200 Subject: Proofer uses self hasher on `verify` --- src/lib.rs | 9 +++------ src/proof.rs | 45 +++++++++++++++++++++++++-------------------- 2 files changed, 28 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index 497dbac..b23f7d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,22 +26,20 @@ //! "a08c44656fb3f561619b8747a0d1dabe97126d9ed6e0cafbd7ce08ebe12d55ca" //! ); //! -//! let proofer = DefaultProofer::new(&hasher, tree.leaves().clone()); +//! let proofer = DefaultProofer::new(hasher, tree.leaves().clone()); //! //! let proof = proofer.generate(0).expect("proof generation failed"); //! //! assert!(proofer.verify( //! &proof, //! &files[0], -//! "a08c44656fb3f561619b8747a0d1dabe97126d9ed6e0cafbd7ce08ebe12d55ca", -//! &hasher +//! "a08c44656fb3f561619b8747a0d1dabe97126d9ed6e0cafbd7ce08ebe12d55ca" //! )); //! //! assert!(!proofer.verify( //! &proof, //! &files[0], -//! "a08c44656fb3f561619b87_NOT_VALID_HASH_9ed6e0cafbd7ce08ebe12d55ca", -//! &hasher +//! "a08c44656fb3f561619b87_NOT_VALID_HASH_9ed6e0cafbd7ce08ebe12d55ca" //! )); //! //! let proof = proofer.generate(1).expect("proof generation failed"); @@ -50,7 +48,6 @@ //! &proof, //! &files[1], //! "a08c44656fb3f561619b8747a0d1dabe97126d9ed6e0cafbd7ce08ebe12d55ca", -//! &hasher //! )); //! //! ``` diff --git a/src/proof.rs b/src/proof.rs index c893b08..d835b87 100644 --- a/src/proof.rs +++ b/src/proof.rs @@ -42,28 +42,33 @@ pub trait Proofer { /// * `proof` - The Merkle proof. /// * `data` - The original data to verify. /// * `root_hash` - The expected root hash of the tree. - /// * `hasher` - The hasher used to construct the tree. /// /// # Returns /// /// `true` if the proof is valid and the data exists in the tree, `false` otherwise. - fn verify(&self, proof: &MerkleProof, data: T, root_hash: &str, hasher: &dyn Hasher) -> bool + fn verify(&self, proof: &MerkleProof, data: T, root_hash: &str) -> bool where T: AsRef<[u8]>; } -pub struct DefaultProofer<'a> { - hasher: &'a dyn Hasher, +pub struct DefaultProofer { + hasher: H, leaves: Vec, } -impl<'a> DefaultProofer<'a> { - pub fn new(hasher: &'a dyn Hasher, leaves: Vec) -> Self { +impl DefaultProofer +where + H: Hasher, +{ + pub fn new(hasher: H, leaves: Vec) -> Self { Self { hasher, leaves } } } -impl Proofer for DefaultProofer<'_> { +impl Proofer for DefaultProofer +where + H: Hasher, +{ fn generate(&self, index: usize) -> Option { if index >= self.leaves.len() { return None; @@ -122,12 +127,12 @@ impl Proofer for DefaultProofer<'_> { }) } - fn verify(&self, proof: &MerkleProof, data: T, root_hash: &str, hasher: &dyn Hasher) -> bool + fn verify(&self, proof: &MerkleProof, data: T, root_hash: &str) -> bool where T: AsRef<[u8]>, { // Start with the hash of the data - let mut current_hash = hasher.hash(data.as_ref()); + let mut current_hash = self.hasher.hash(data.as_ref()); // Walk up the tree using the proof path for proof_node in &proof.path { @@ -135,7 +140,7 @@ impl Proofer for DefaultProofer<'_> { NodeChildType::Left => format!("{}{}", proof_node.hash, current_hash), NodeChildType::Right => format!("{}{}", current_hash, proof_node.hash), }; - current_hash = hasher.hash(combined.as_bytes()); + current_hash = self.hasher.hash(combined.as_bytes()); } // Check if the computed root matches the expected root @@ -154,12 +159,12 @@ mod tests { let hasher = DummyHasher; let data = vec!["a", "b", "c", "d"]; let tree = MerkleTree::new(hasher.clone(), data.clone()); - let proofer = DefaultProofer::new(&hasher, tree.leaves()); + let proofer = DefaultProofer::new(hasher, tree.leaves()); for (index, item) in data.iter().enumerate() { let proof = proofer.generate(index).unwrap(); - assert!(proofer.verify(&proof, item, tree.root().hash(), &hasher)); + assert!(proofer.verify(&proof, item, tree.root().hash())); } } @@ -168,12 +173,12 @@ mod tests { let hasher = SHA256Hasher::new(); let data = vec!["a", "b", "c", "d"]; let tree = MerkleTree::new(hasher.clone(), data.clone()); - let proofer = DefaultProofer::new(&hasher, tree.leaves().clone()); + let proofer = DefaultProofer::new(hasher, tree.leaves().clone()); for (index, item) in data.iter().enumerate() { let proof = proofer.generate(index).unwrap(); - assert!(proofer.verify(&proof, item, tree.root().hash(), &hasher)); + assert!(proofer.verify(&proof, item, tree.root().hash())); } } @@ -182,15 +187,15 @@ mod tests { let hasher = SHA256Hasher::new(); let data = vec!["a", "b", "c", "d"]; let tree = MerkleTree::new(hasher.clone(), data.clone()); - let proofer = DefaultProofer::new(&hasher, tree.leaves().clone()); + let proofer = DefaultProofer::new(hasher, tree.leaves().clone()); let proof = proofer.generate(0).unwrap(); - assert!(proofer.verify(&proof, b"a", tree.root().hash(), &hasher)); - assert!(!proofer.verify(&proof, b"b", tree.root().hash(), &hasher)); - assert!(!proofer.verify(&proof, b"c", tree.root().hash(), &hasher)); - assert!(!proofer.verify(&proof, b"d", tree.root().hash(), &hasher)); + assert!(proofer.verify(&proof, b"a", tree.root().hash())); + assert!(!proofer.verify(&proof, b"b", tree.root().hash())); + assert!(!proofer.verify(&proof, b"c", tree.root().hash())); + assert!(!proofer.verify(&proof, b"d", tree.root().hash())); - assert!(!proofer.verify(&proof, b"e", tree.root().hash(), &hasher)); + assert!(!proofer.verify(&proof, b"e", tree.root().hash())); } } -- cgit v1.2.3-71-g8e6c