Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs/update #10

Merged
merged 3 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 167 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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:

Expand All @@ -47,71 +45,202 @@ This library provides a clean and easy to use implementation of the Merkle Tree
- Create Proof
- Verify Proof


![](/asset.png)

## How to Use

**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::<Vec<[u8; 32]>>();

// 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::<Vec<[u8; 32]>>();

// 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::<Vec<[u8; 32]>>();

// 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::<Vec<[u8; 32]>>();

// 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

Expand Down
3 changes: 1 addition & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Node>;
pub type Hash = [u8; 32];
pub type Leaf = [u8; 32];
Expand Down
2 changes: 1 addition & 1 deletion src/merkle_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions src/merkle_proof_check.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
11 changes: 9 additions & 2 deletions src/tree.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -21,7 +22,13 @@ impl MerkleTree {
}

impl MerkleTree {
pub fn make_proof(self, leaf: Leaf) -> Vec<Node> {
pub fn make_proof(&self, leaf: Leaf) -> Vec<Node> {
merkle_proof(&self.leaves, leaf)
}
}

impl MerkleTree {
pub fn check_proof(self, proof: Proof, leaf: Leaf) -> Leaf {
merkle_proof_check(proof, leaf)
}
}
3 changes: 1 addition & 2 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Loading