From e5e8160874b41a0a730676a452f0351e9dbf9c1e Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Tue, 6 Feb 2024 00:54:25 -0300 Subject: [PATCH 1/3] update: docs --- README.md | 205 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 167 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index d4652fb..1afd9dd 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,11 @@ The **simple and easy** implementation of **Rust Merkle Tree** [![Build](https://github.com/olivmath/merkletreers/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/olivmath/merkletreers/actions/workflows/build.yml) [![Test](https://github.com/olivmath/merkletreers/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/olivmath/merkletreers/actions/workflows/test.yml) [![Crates.io](https://img.shields.io/crates/v/merkletreers.svg)](https://crates.io/crates/merkletreers) - ![GitHub last commit](https://img.shields.io/github/last-commit/olivmath/merkletreers) ![GitHub commit activity](https://img.shields.io/github/commit-activity/m/olivmath/merkletreers) ![Crates.io](https://img.shields.io/crates/l/merkletreers) - ## Table of Contents - [Credits](#credits) @@ -38,7 +36,7 @@ merkletreers = "*" ## How to works -- *We use keccak-256 under-the-hood* +- _We use keccak-256 under-the-hood_ This library provides a clean and easy to use implementation of the Merkle Tree with the following features: @@ -47,7 +45,6 @@ This library provides a clean and easy to use implementation of the Merkle Tree - Create Proof - Verify Proof - ![](/asset.png) ## How to Use @@ -55,63 +52,195 @@ This library provides a clean and easy to use implementation of the Merkle Tree **Create a Merkle Tree** ```rust -use merkletreers::merkletree::tree::MerkleTree; - -let tree = MerkleTree::new(vec!["a","b","c","d"]); - -assert_eq!(tree.leafs(), [ - "3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb", - "b5553de315e0edf504d9150af82dafa5c4667fa618ed0a6f19c69b41166c5510", - "0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2", - "f1918e8562236eb17adc8502332f4c9c82bc14e19bfc0aa10ab674ff75b3d2f3", -]) +use merkletreers::tree::MerkleTree; +use merkletreers::utils::hash_it; + +// Hash each element of leaves to convert into a [u8;32] +let leaves = ["a", "b", "c", "d", "e"] + .iter() + .map(|data| { + let mut buffer = [0u8; 32]; + hash_it(data.as_bytes(), &mut buffer); + buffer + }) + .collect::>(); + +// Create our Merkle tree +let tree = MerkleTree::new(leaves); ``` - **Create a Root** ```rust -use merkletreers::merkletree::tree::MerkleTree; - -let tree = MerkleTree::new(vec!["a","b","c","d"]); - +use merkletreers::tree::MerkleTree; +use merkletreers::utils::hash_it; + +// Hash each element of leaves to convert into a [u8;32] +let leaves = ["a", "b", "c", "d", "e"] + .iter() + .map(|data| { + let mut buffer = [0u8; 32]; + hash_it(data.as_bytes(), &mut buffer); + buffer + }) + .collect::>(); + +// Create our Merkle tree +let tree = MerkleTree::new(leaves); + +// Create our Merkle Root +let root = tree.root; assert_eq!( - tree.root(), - vec!["115cbb4775ed495f3d954dfa47164359a97762b40059d9502895def16eed609c"], + root, + [ + 29, 208, 210, 166, 174, 70, 109, 102, 92, 178, 110, 26, 49, 240, 124, 87, 174, 93, 247, + 210, 188, 85, 156, 213, 130, 109, 65, 123, 233, 20, 26, 93 + ] ); ``` **Create Proof of a leaf** + ```rust -use merkletreers::merkletree::{tree::MerkleTree, node::Node}; +use merkletreers::node::{Node, Side}; +use merkletreers::tree::MerkleTree; +use merkletreers::utils::hash_it; + +// Hash each element of leaves to convert into a [u8;32] +let leaves = ["a", "b", "c", "d", "e"] + .iter() + .map(|data| { + let mut buffer = [0u8; 32]; + hash_it(data.as_bytes(), &mut buffer); + buffer + }) + .collect::>(); + +// Create our Merkle tree +let tree = MerkleTree::new(leaves); + +// Create our Merkle Root +let root = tree.root; +assert_eq!( + root, + [ + 29, 208, 210, 166, 174, 70, 109, 102, 92, 178, 110, 26, 49, 240, 124, 87, 174, 93, 247, + 210, 188, 85, 156, 213, 130, 109, 65, 123, 233, 20, 26, 93 + ] +); -let mtree = MerkleTree::new(vec!["a", "b", "c", "d"]); +// Create your Merkle Proof for 'c' element +// First we need hash element to convert into a [u8; 32] +let mut leaf = [0u8; 32]; +hash_it("c".as_bytes(), &mut leaf); +let proof = tree.make_proof(leaf); assert_eq!( - mtree.proof("a"), vec![ - Node::left("3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb"), - Node::right("b5553de315e0edf504d9150af82dafa5c4667fa618ed0a6f19c69b41166c5510"), - Node::right("64673cf40035df6d3a0d0143cc8426de49b9a93b9ad2d330cb4f0bc390a86d20") - ] + Node { + data: [ + 241, 145, 142, 133, 98, 35, 110, 177, 122, 220, 133, 2, 51, 47, 76, 156, 130, + 188, 20, 225, 155, 252, 10, 161, 10, 182, 116, 255, 117, 179, 210, 243 + ], + side: Side::RIGHT + }, + Node { + data: [ + 128, 91, 33, 216, 70, 177, 137, 239, 174, 176, 55, 125, 107, 176, 210, 1, 179, + 135, 42, 54, 62, 96, 124, 37, 8, 143, 2, 91, 12, 106, 225, 248 + ], + side: Side::LEFT + }, + Node { + data: [ + 168, 152, 44, 137, 216, 9, 135, 251, 154, 81, 14, 37, 152, 30, 233, 23, 2, 6, + 190, 33, 175, 60, 142, 14, 179, 18, 239, 29, 51, 130, 231, 97 + ], + side: Side::RIGHT + } + ], + proof ); ``` **Verify Proof of a leaf** + ```rust -``` +use merkletreers::node::{Node, Side}; +use merkletreers::tree::MerkleTree; +use merkletreers::utils::hash_it; + + +// Hash each element of leaves to convert into a [u8;32] +let leaves = ["a", "b", "c", "d", "e"] + .iter() + .map(|data| { + let mut buffer = [0u8; 32]; + hash_it(data.as_bytes(), &mut buffer); + buffer + }) + .collect::>(); + +// Create our Merkle tree +let tree = MerkleTree::new(leaves); + +// Create our Merkle Root +let root = tree.root; +assert_eq!( + root, + [ + 29, 208, 210, 166, 174, 70, 109, 102, 92, 178, 110, 26, 49, 240, 124, 87, 174, 93, 247, + 210, 188, 85, 156, 213, 130, 109, 65, 123, 233, 20, 26, 93 + ] +); + +// Create your Merkle Proof for 'c' element +// First we need hash element to convert into a [u8; 32] +let mut leaf = [0u8; 32]; +hash_it("c".as_bytes(), &mut leaf); +let proof = tree.make_proof(leaf); +assert_eq!( + vec![ + Node { + data: [ + 241, 145, 142, 133, 98, 35, 110, 177, 122, 220, 133, 2, 51, 47, 76, 156, 130, + 188, 20, 225, 155, 252, 10, 161, 10, 182, 116, 255, 117, 179, 210, 243 + ], + side: Side::RIGHT + }, + Node { + data: [ + 128, 91, 33, 216, 70, 177, 137, 239, 174, 176, 55, 125, 107, 176, 210, 1, 179, + 135, 42, 54, 62, 96, 124, 37, 8, 143, 2, 91, 12, 106, 225, 248 + ], + side: Side::LEFT + }, + Node { + data: [ + 168, 152, 44, 137, 216, 9, 135, 251, 154, 81, 14, 37, 152, 30, 233, 23, 2, 6, + 190, 33, 175, 60, 142, 14, 179, 18, 239, 29, 51, 130, 231, 97 + ], + side: Side::RIGHT + } + ], + proof +); +// Verify our Merkle Proof for 'c' element +let result = tree.check_proof(proof, leaf); +assert_eq!(result, root); +``` ## Roadmap -| Feature | Status | Priority | -|-|-|-| -| Create Root | ✅ | 🔥 | -| Create Proof | ✅ | 🔥 | -| Verify Proof | ⏰ | 🔥 | -| Support **[OpenZeppelin](https://docs.openzeppelin.com/contracts/4.x/utilities#verifying_merkle_proofs)** | ⏰ | 🔥 | -| Compatible with **[MerkleTreeJs](https://github.com/miguelmota/merkletreejs)** | ⏰ | 🔥 | -| Use any Hash function | ⏰ | 🧐 | -| Leafs of any size | ⏰ | 🧐 | +| Feature | Status | Priority | +| ------------------------------------------------------------------------------ | ------ | -------- | +| Create Root | ✅ | 🔥 | +| Create Proof | ✅ | 🔥 | +| Verify Proof | ✅ | 🔥 | +| Compatible with **[MerkleTreeJs](https://github.com/miguelmota/merkletreejs)** | ✅ | 🔥 | +| Compatible with **[Merkly](https://github.com/olivmath/merkly)** | ✅ | 🔥 | +| Leafs of any size | ✅ | 🧐 | +| Use any Hash function | ⏰ | 🧐 | ## Contributing From 80ac49736328bb19c0007e29882b174bd659bde5 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Tue, 6 Feb 2024 00:55:45 -0300 Subject: [PATCH 2/3] update: with formate and clippy --- src/lib.rs | 3 +-- src/merkle_proof.rs | 2 +- src/merkle_proof_check.rs | 4 ++-- src/tree.rs | 5 +++-- src/utils.rs | 3 +-- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fe3708f..8f5d8f9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,13 +2,12 @@ use node::Node; pub mod merkle_proof; pub mod merkle_proof_check; +pub mod merkle_proof_mixed; pub mod merkle_root; pub mod node; pub mod tree; -pub mod merkle_proof_mixed; pub mod utils; - pub type Proof = Vec; pub type Hash = [u8; 32]; pub type Leaf = [u8; 32]; diff --git a/src/merkle_proof.rs b/src/merkle_proof.rs index 47b157e..71e4c44 100644 --- a/src/merkle_proof.rs +++ b/src/merkle_proof.rs @@ -7,7 +7,7 @@ use crate::{Leaf, Proof}; pub fn merkle_proof(leaves: &[Leaf], leaf: Leaf) -> Proof { let mut proof: Proof = Vec::new(); - if is_power_of_two(leaves.len() as u32) == false { + if !is_power_of_two(leaves.len() as u32) { return merkle_proof_mixed_tree(leaves, leaf); } diff --git a/src/merkle_proof_check.rs b/src/merkle_proof_check.rs index fb1570a..5ebdcfe 100644 --- a/src/merkle_proof_check.rs +++ b/src/merkle_proof_check.rs @@ -1,7 +1,7 @@ use crate::utils::hash_function; -use crate::Proof; +use crate::{Leaf, Proof}; -pub fn merkle_proof_check(proof: Proof, leaf: [u8; 32]) -> [u8; 32] { +pub fn merkle_proof_check(proof: Proof, leaf: Leaf) -> Leaf { let mut current_hash = leaf; for node in proof { diff --git a/src/tree.rs b/src/tree.rs index feb9321..1914431 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -1,7 +1,8 @@ use crate::merkle_proof::merkle_proof; +use crate::merkle_proof_check::merkle_proof_check; use crate::merkle_root::merkle_root; use crate::node::Node; -use crate::{Leaf, Root}; +use crate::{Leaf, Proof, Root}; /// # 🌳 Merkle Tree /// - You can pass raw data @@ -21,7 +22,7 @@ impl MerkleTree { } impl MerkleTree { - pub fn make_proof(self, leaf: Leaf) -> Vec { + pub fn make_proof(&self, leaf: Leaf) -> Vec { merkle_proof(&self.leaves, leaf) } } diff --git a/src/utils.rs b/src/utils.rs index 6daee9c..9d4f36b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -20,6 +20,5 @@ pub fn is_power_of_two(number: u32) -> bool { let left: bool = number & (number - 1) == 0; let right: bool = number != 0; - let r = left && right; - r + left && right } From 6315c3458c98541e9735b393a35ede16bee0e377 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Tue, 6 Feb 2024 00:56:05 -0300 Subject: [PATCH 3/3] add: check merkle proof to main struct --- src/tree.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tree.rs b/src/tree.rs index 1914431..42d34a3 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -26,3 +26,9 @@ impl MerkleTree { merkle_proof(&self.leaves, leaf) } } + +impl MerkleTree { + pub fn check_proof(self, proof: Proof, leaf: Leaf) -> Leaf { + merkle_proof_check(proof, leaf) + } +}