Browse Source

update & some fixes & travis

master
arnaucube 4 years ago
parent
commit
0e84b1172e
4 changed files with 287 additions and 239 deletions
  1. +9
    -0
      .travis.yml
  2. +3
    -1
      README.md
  3. +270
    -232
      src/lib.rs
  4. +5
    -6
      src/utils.rs

+ 9
- 0
.travis.yml

@ -0,0 +1,9 @@
language: rust
rust:
- stable
cache:
- cargo
script:
- RUST_BACKTRACE=1 cargo test --all

+ 3
- 1
README.md

@ -1,8 +1,10 @@
# merkletree-rs
# merkletree-rs [![Build Status](https://travis-ci.org/arnaucube/merkletree-rs.svg?branch=master)](https://travis-ci.org/arnaucube/merkletree-rs)
Sparse MerkleTree implementation in Rust. Sparse MerkleTree implementation in Rust.
The MerkleTree is optimized in the design and concepts, to have a faster and lighter MerkleTree, maintaining compatibility with a non optimized MerkleTree. In this way, the MerkleRoot of the optimized MerkleTree will be the same that the MerkleRoot of the non optimized MerkleTree. The MerkleTree is optimized in the design and concepts, to have a faster and lighter MerkleTree, maintaining compatibility with a non optimized MerkleTree. In this way, the MerkleRoot of the optimized MerkleTree will be the same that the MerkleRoot of the non optimized MerkleTree.
Compatible with the Go version: https://github.com/arnaucube/go-merkletree
## Usage ## Usage
Create new tree: Create new tree:

+ 270
- 232
src/lib.rs

@ -9,6 +9,8 @@ extern crate rustc_hex;
extern crate hex; extern crate hex;
use rustc_hex::ToHex;
mod utils; mod utils;
mod node; mod node;
@ -48,12 +50,12 @@ pub struct Db {
storage: HashMap<[u8;32], Vec<u8>>, storage: HashMap<[u8;32], Vec<u8>>,
} }
impl Db { impl Db {
pub fn insert(&mut self, k: [u8; 32], t: u8, il: u32, b: &mut Vec<u8>) {
pub fn insert(&mut self, k: [u8; 32], t: u8, il: u32, b: Vec<u8>) {
let mut v: Vec<u8>; let mut v: Vec<u8>;
v = [t].to_vec(); v = [t].to_vec();
let il_bytes = il.to_le_bytes(); let il_bytes = il.to_le_bytes();
v.append(&mut il_bytes.to_vec()); // il_bytes are [u8;4] (4 bytes)
v.append(b);
v.extend(il_bytes.to_vec()); // il_bytes are [u8;4] (4 bytes)
v.extend(&b);
self.storage.insert(k, v); self.storage.insert(k, v);
} }
pub fn get(&self, k: &[u8;32]) -> (u8, u32, Vec<u8>) { pub fn get(&self, k: &[u8;32]) -> (u8, u32, Vec<u8>) {
@ -102,9 +104,9 @@ impl MerkleTree {
#![allow(unused_variables)] #![allow(unused_variables)]
#[allow(dead_code)] #[allow(dead_code)]
// println!("adding value: {:?}", v.bytes());
let leaf_node_string = String::from_utf8_lossy(&v.bytes());
// add the leaf that we are adding // add the leaf that we are adding
self.sto.insert(v.ht(), TYPENODEVALUE, v.index_length(), &mut v.bytes().to_vec());
self.sto.insert(v.ht(), TYPENODEVALUE, v.index_length(), v.bytes().to_vec());
let index = v.index_length() as usize; let index = v.index_length() as usize;
let hi = v.hi(); let hi = v.hi();
@ -123,13 +125,14 @@ impl MerkleTree {
let path_child = utils::get_path(self.num_levels, hi_child); let path_child = utils::get_path(self.num_levels, hi_child);
let pos_diff = utils::compare_paths(&path_child, &path); let pos_diff = utils::compare_paths(&path_child, &path);
if pos_diff == 999 { // TODO use a match here, and instead of 999 return something better if pos_diff == 999 { // TODO use a match here, and instead of 999 return something better
println!("node already exists");
println!("compare paths err"); println!("compare paths err");
return; return;
} }
let final_node_1_hash = utils::calc_hash_from_leaf_and_level(pos_diff, &path_child, utils::hash_vec(node_bytes.to_vec())); let final_node_1_hash = utils::calc_hash_from_leaf_and_level(pos_diff, &path_child, utils::hash_vec(node_bytes.to_vec()));
self.sto.insert(final_node_1_hash, TYPENODEFINAL, il, &mut node_bytes.to_vec());
self.sto.insert(final_node_1_hash, TYPENODEFINAL, il, node_bytes.to_vec());
let final_node_2_hash = utils::calc_hash_from_leaf_and_level(pos_diff, &path, v.ht()); let final_node_2_hash = utils::calc_hash_from_leaf_and_level(pos_diff, &path, v.ht());
self.sto.insert(final_node_2_hash, TYPENODEFINAL, v.index_length(), &mut v.bytes().to_vec());
self.sto.insert(final_node_2_hash, TYPENODEFINAL, v.index_length(), v.bytes().to_vec());
// parent node // parent node
let parent_node: node::TreeNode; let parent_node: node::TreeNode;
@ -138,24 +141,25 @@ impl MerkleTree {
child_l: final_node_1_hash, child_l: final_node_1_hash,
child_r: final_node_2_hash, child_r: final_node_2_hash,
}} else { }} else {
parent_node = node::TreeNode {
child_l: final_node_2_hash,
child_r: final_node_1_hash,
}}
parent_node = node::TreeNode {
child_l: final_node_2_hash,
child_r: final_node_1_hash,
}}
let empties = utils::get_empties_between_i_and_pos(i, pos_diff+1); let empties = utils::get_empties_between_i_and_pos(i, pos_diff+1);
for empty in &empties { for empty in &empties {
siblings.push(*empty); siblings.push(*empty);
} }
let path_from_pos_diff = utils::cut_path(&path, (pos_diff +1) as usize);
self.root = self.replace_leaf(path_from_pos_diff, siblings.clone(), parent_node.ht(), TYPENODENORMAL, 0, &mut parent_node.bytes().to_vec());
let path_from_pos_diff = utils::cut_path(&path, (pos_diff + 1) as usize);
self.root = self.replace_leaf(path_from_pos_diff, &siblings, parent_node.ht(), TYPENODENORMAL, 0, parent_node.bytes().to_vec());
return; return;
} }
let node = node::parse_node_bytes(node_bytes); let node = node::parse_node_bytes(node_bytes);
let sibling: [u8;32]; let sibling: [u8;32];
if path[i as usize] {
if !path[i as usize] {
node_hash = node.child_l; node_hash = node.child_l;
sibling = node.child_r; sibling = node.child_r;
} else { } else {
@ -166,38 +170,38 @@ impl MerkleTree {
if node_hash == EMPTYNODEVALUE { if node_hash == EMPTYNODEVALUE {
if i==self.num_levels-2 && siblings[siblings.len()-1]==EMPTYNODEVALUE { if i==self.num_levels-2 && siblings[siblings.len()-1]==EMPTYNODEVALUE {
let final_node_hash = utils::calc_hash_from_leaf_and_level(i+1, &path, v.ht()); let final_node_hash = utils::calc_hash_from_leaf_and_level(i+1, &path, v.ht());
self.sto.insert(final_node_hash, TYPENODEFINAL, v.index_length(), &mut v.bytes().to_vec());
self.sto.insert(final_node_hash, TYPENODEFINAL, v.index_length(), v.bytes().to_vec());
self.root = final_node_hash; self.root = final_node_hash;
return; return;
} }
let final_node_hash = utils::calc_hash_from_leaf_and_level(i, &path, v.ht()); let final_node_hash = utils::calc_hash_from_leaf_and_level(i, &path, v.ht());
let path_from_i = utils::cut_path(&path, i as usize); let path_from_i = utils::cut_path(&path, i as usize);
self.root = self.replace_leaf(path_from_i, siblings.clone(), final_node_hash, TYPENODEFINAL, v.index_length(), &mut v.bytes().to_vec());
self.root = self.replace_leaf(path_from_i, &siblings, final_node_hash, TYPENODEFINAL, v.index_length(), v.bytes().to_vec());
return; return;
} }
} }
self.root = self.replace_leaf(path, siblings, v.ht(), TYPENODEVALUE, v.index_length(), &mut v.bytes().to_vec());
self.root = self.replace_leaf(path, &siblings, v.ht(), TYPENODEVALUE, v.index_length(), v.bytes().to_vec());
} }
#[allow(dead_code)] #[allow(dead_code)]
pub fn replace_leaf(&mut self, path: Vec<bool>, siblings: Vec<[u8;32]>, leaf_hash: [u8;32], node_type: u8, index_length: u32, leaf_value: &mut Vec<u8>) -> [u8;32] {
pub fn replace_leaf(&mut self, path: Vec<bool>, siblings: &Vec<[u8;32]>, leaf_hash: [u8;32], node_type: u8, index_length: u32, leaf_value: Vec<u8>) -> [u8;32] {
self.sto.insert(leaf_hash, node_type, index_length, leaf_value); self.sto.insert(leaf_hash, node_type, index_length, leaf_value);
let mut curr_node = leaf_hash; let mut curr_node = leaf_hash;
for i in 0..siblings.len() { for i in 0..siblings.len() {
if path[i as usize] {
if !path[i as usize] {
let node = node::TreeNode { let node = node::TreeNode {
child_l: curr_node, child_l: curr_node,
child_r: siblings[siblings.len()-1-i], child_r: siblings[siblings.len()-1-i],
}; };
self.sto.insert(node.ht(), TYPENODENORMAL, 0, &mut node.bytes());
self.sto.insert(node.ht(), TYPENODENORMAL, 0, node.bytes());
curr_node = node.ht(); curr_node = node.ht();
} else { } else {
let node = node::TreeNode { let node = node::TreeNode {
child_l: siblings[siblings.len()-1-i], child_l: siblings[siblings.len()-1-i],
child_r: curr_node, child_r: curr_node,
}; };
self.sto.insert(node.ht(), TYPENODENORMAL, 0, &mut node.bytes());
self.sto.insert(node.ht(), TYPENODENORMAL, 0, node.bytes());
curr_node = node.ht(); curr_node = node.ht();
} }
} }
@ -226,165 +230,161 @@ impl MerkleTree {
} else { } else {
node_hash = node.child_r; node_hash = node.child_r;
} }
}
let (_t, _il, node_bytes) = self.sto.get(&node_hash);
node_bytes
} }
let (_t, _il, node_bytes) = self.sto.get(&node_hash);
node_bytes
}
#[allow(dead_code)]
pub fn generate_proof(&self, hi: [u8;32]) -> Vec<u8> {
let mut mp: Vec<u8> = Vec::new();
let mut empties: [u8;32] = [0;32];
let path = utils::get_path(self.num_levels, hi);
let mut siblings: Vec<[u8;32]> = Vec::new();
let mut node_hash = self.root;
for i in 0..self.num_levels {
let (t, il, node_bytes) = self.sto.get(&node_hash);
if t == TYPENODEFINAL {
let real_value_in_pos = self.get_value_in_pos(hi);
if real_value_in_pos == EMPTYNODEVALUE {
let leaf_hi = utils::hash_vec(node_bytes.to_vec().split_at(il as usize).0.to_vec());
let path_child = utils::get_path(self.num_levels, leaf_hi);
let pos_diff = utils::compare_paths(&path_child, &path);
if pos_diff == self.num_levels { // TODO use a match here, and instead of 999 return something better
return mp;
}
if pos_diff != self.num_levels-1-i {
let sibling = utils::calc_hash_from_leaf_and_level(pos_diff, &path_child, utils::hash_vec(node_bytes.to_vec()));
let mut new_siblings: Vec<[u8;32]> = Vec::new();
new_siblings.push(sibling);
new_siblings.append(&mut siblings);
siblings = new_siblings;
// set empties bit
let bit_pos = self.num_levels-2-pos_diff;
empties[(empties.len() as isize + (bit_pos as isize/8-1) as isize) as usize] |= 1 << (bit_pos%8);
#[allow(dead_code)]
pub fn generate_proof(&self, hi: [u8;32]) -> Vec<u8> {
let mut mp: Vec<u8> = Vec::new();
let mut empties: [u8;32] = [0;32];
let path = utils::get_path(self.num_levels, hi);
let mut siblings: Vec<[u8;32]> = Vec::new();
let mut node_hash = self.root;
for i in 0..self.num_levels {
let (t, il, node_bytes) = self.sto.get(&node_hash);
if t == TYPENODEFINAL {
let real_value_in_pos = self.get_value_in_pos(hi);
if real_value_in_pos == EMPTYNODEVALUE {
let leaf_hi = utils::hash_vec(node_bytes.to_vec().split_at(il as usize).0.to_vec());
let path_child = utils::get_path(self.num_levels, leaf_hi);
let pos_diff = utils::compare_paths(&path_child, &path);
if pos_diff == self.num_levels { // TODO use a match here, and instead of 999 return something better
return mp;
}
if pos_diff != self.num_levels-1-i {
let sibling = utils::calc_hash_from_leaf_and_level(pos_diff, &path_child, utils::hash_vec(node_bytes.to_vec()));
let mut new_siblings: Vec<[u8;32]> = Vec::new();
new_siblings.push(sibling);
new_siblings.extend(siblings);
siblings = new_siblings;
// set empties bit
let bit_pos = self.num_levels-2-pos_diff;
empties[(empties.len() as isize + (bit_pos as isize/8-1) as isize) as usize] |= 1 << (bit_pos%8);
}
} }
break
}
let node = node::parse_node_bytes(node_bytes);
let sibling: [u8;32];
if !path[self.num_levels as usize -i as usize -2] {
node_hash = node.child_l;
sibling = node.child_r;
} else {
sibling = node.child_l;
node_hash = node.child_r;
}
if sibling != EMPTYNODEVALUE {
// set empties bit
empties[(empties.len() as isize + (i as isize/8-1) as isize) as usize] |= 1 << (i%8);
let mut new_siblings: Vec<[u8;32]> = Vec::new();
new_siblings.push(sibling);
new_siblings.extend(siblings);
siblings = new_siblings;
} }
break
}
let node = node::parse_node_bytes(node_bytes);
let sibling: [u8;32];
if !path[self.num_levels as usize -i as usize -2] {
node_hash = node.child_l;
sibling = node.child_r;
} else {
sibling = node.child_l;
node_hash = node.child_r;
} }
if sibling != EMPTYNODEVALUE {
// set empties bit
empties[(empties.len() as isize + (i as isize/8-1) as isize) as usize] |= 1 << (i%8);
let mut new_siblings: Vec<[u8;32]> = Vec::new();
new_siblings.push(sibling);
new_siblings.append(&mut siblings);
siblings = new_siblings;
mp.append(&mut empties[..].to_vec());
for s in siblings {
mp.append(&mut s.to_vec());
} }
mp
} }
mp.append(&mut empties[..].to_vec());
for s in siblings {
mp.append(&mut s.to_vec());
}
mp
}
#[allow(dead_code)]
pub fn print_level(&self, parent: [u8;32], mut lvl: u32, max_level: u32) {
use rustc_hex::ToHex;
let mut line: String = "".to_string();
for _ in 0..lvl {
line += &" ".to_string();
}
line += &("lvl ".to_string() + &lvl.to_string());
line += &(" - '".to_string() + &parent.to_hex() + &"' = ".to_string());
let (t, _, node_bytes) = self.sto.get(&parent);
let mut node = node::TreeNode {
child_l: EMPTYNODEVALUE,
child_r: EMPTYNODEVALUE,
};
if t==TYPENODENORMAL {
node = node::parse_node_bytes(node_bytes);
line += &("'".to_string() + &node.child_l.to_hex() + &"' - '".to_string() + &node.child_r.to_hex() + &"'".to_string());
} else if t == TYPENODEVALUE {
//
} else if t == TYPENODEFINAL {
let hash_node_bytes = utils::hash_vec(node_bytes);
line += &("[final] final tree node: ".to_string() + &hash_node_bytes.to_hex()+ &"\n".to_string());
let (_, _, leaf_node_bytes) = self.sto.get(&hash_node_bytes);
#[allow(dead_code)]
pub fn print_level(&self, parent: [u8;32], mut lvl: u32, max_level: u32) {
let mut line: String = "".to_string();
for _ in 0..lvl { for _ in 0..lvl {
line += " ";
line += &format!(" ");
}
line += &format!("lvl {}", lvl);
line += &format!(" - '{}' = ", parent.to_hex());
let (t, _, node_bytes) = self.sto.get(&parent);
let mut node = node::TreeNode {
child_l: EMPTYNODEVALUE,
child_r: EMPTYNODEVALUE,
};
if t==TYPENODENORMAL {
node = node::parse_node_bytes(node_bytes);
line += &format!("'{}' - '{}'", node.child_l.to_hex(), node.child_r.to_hex());
} else if t == TYPENODEVALUE {
//
} else if t == TYPENODEFINAL {
let hash_node_bytes = utils::hash_vec(node_bytes);
line += &format!("[final] final tree node: {} \n", hash_node_bytes.to_hex());
let (_, _, leaf_node_bytes) = self.sto.get(&hash_node_bytes);
for _ in 0..lvl {
line += " ";
}
let leaf_node_string = String::from_utf8_lossy(&leaf_node_bytes);
line += &format!("leaf value: {}", leaf_node_string);
} else {
line += "[EMPTY Branch]"
}
println!("{}", line);
lvl += 1;
if node.child_r.len()>0 && lvl<max_level && t != TYPENODEEMPTY && t != TYPENODEFINAL {
self.print_level(node.child_l, lvl, max_level);
self.print_level(node.child_r, lvl, max_level);
} }
let leaf_node_string = String::from_utf8_lossy(&leaf_node_bytes);
line += &("leaf value: ".to_string() + &leaf_node_string);
} else {
line += &"[EMPTY Branch]".to_string()
} }
println!("{:?}", line);
lvl += 1;
if node.child_r.len()>0 && lvl<max_level && t != TYPENODEEMPTY && t != TYPENODEFINAL {
self.print_level(node.child_l, lvl, max_level);
self.print_level(node.child_r, lvl, max_level);
pub fn print_full_tree(&self) {
self.print_level(self.root, 0, self.num_levels - 1);
println!("root {:?}", self.root.to_hex());
}
pub fn print_levels_tree(&self, max_level: u32) {
self.print_level(self.root, 0, self.num_levels - 1 - max_level);
println!("root {:?}", self.root.to_hex());
} }
} }
pub fn print_full_tree(&self) {
use rustc_hex::ToHex;
self.print_level(self.root, 0, self.num_levels - 1);
println!("root {:?}", self.root.to_hex());
}
pub fn print_levels_tree(&self, max_level: u32) {
use rustc_hex::ToHex;
self.print_level(self.root, 0, self.num_levels - 1 - max_level);
println!("root {:?}", self.root.to_hex());
}
}
#[allow(dead_code)] #[allow(dead_code)]
pub fn verify_proof(root: [u8;32], mp: Vec<u8>, hi: [u8;32], ht: [u8;32], num_levels: u32) -> bool {
let empties: Vec<u8>;
empties = mp.split_at(32).0.to_vec();
let mut siblings: Vec<[u8;32]> = Vec::new();
for i in (empties.len()..mp.len()).step_by(EMPTYNODEVALUE.len()) {
let mut sibling: [u8;32] = [0;32];
sibling.copy_from_slice(&mp[i..i+EMPTYNODEVALUE.len()]);
siblings.push(sibling);
}
pub fn verify_proof(root: [u8;32], mp: Vec<u8>, hi: [u8;32], ht: [u8;32], num_levels: u32) -> bool {
let empties: Vec<u8>;
empties = mp.split_at(32).0.to_vec();
let path = utils::get_path(num_levels, hi);
let mut node_hash = ht;
let mut sibling_used_pos = 0;
for i in (0..=num_levels-2).rev() {
let sibling: [u8;32];
if (empties[empties.len()-i as usize/8-1] & (1 << (i%8))) > 0 {
sibling = siblings[sibling_used_pos];
sibling_used_pos += 1;
} else {
sibling = EMPTYNODEVALUE;
let mut siblings: Vec<[u8;32]> = Vec::new();
for i in (empties.len()..mp.len()).step_by(EMPTYNODEVALUE.len()) {
let mut sibling: [u8;32] = [0;32];
sibling.copy_from_slice(&mp[i..i+EMPTYNODEVALUE.len()]);
siblings.push(sibling);
} }
let n: node::TreeNode;
if path[num_levels as usize - i as usize-2] {
n = node::TreeNode {
child_l: sibling,
child_r: node_hash,
}} else {
n = node::TreeNode {
child_l: node_hash,
child_r: sibling,
}}
if node_hash == EMPTYNODEVALUE && sibling == EMPTYNODEVALUE {
node_hash = EMPTYNODEVALUE;
} else {
node_hash = n.ht();
let path = utils::get_path(num_levels, hi);
let mut node_hash = ht;
let mut sibling_used_pos = 0;
for i in (0..=num_levels-2).rev() {
let sibling: [u8;32];
if (empties[empties.len()-i as usize/8-1] & (1 << (i%8))) > 0 {
sibling = siblings[sibling_used_pos];
sibling_used_pos += 1;
} else {
sibling = EMPTYNODEVALUE;
}
let n: node::TreeNode;
if path[num_levels as usize - i as usize-2] {
n = node::TreeNode {
child_l: sibling,
child_r: node_hash,
}} else {
n = node::TreeNode {
child_l: node_hash,
child_r: sibling,
}}
if node_hash == EMPTYNODEVALUE && sibling == EMPTYNODEVALUE {
node_hash = EMPTYNODEVALUE;
} else {
node_hash = n.ht();
}
} }
if node_hash==root {
return true;
}
false
} }
if node_hash==root {
return true;
}
false
}
#[cfg(test)] #[cfg(test)]
@ -433,83 +433,86 @@ pub fn verify_proof(root: [u8;32], mp: Vec, hi: [u8;32], ht: [u8;32], num_le
assert_eq!(*val.bytes(), b); assert_eq!(*val.bytes(), b);
assert_eq!("a0e72cc948119fcb71b413cf5ada12b2b825d5133299b20a6d9325ffc3e2fbf1", mt.root.to_hex()); assert_eq!("a0e72cc948119fcb71b413cf5ada12b2b825d5133299b20a6d9325ffc3e2fbf1", mt.root.to_hex());
} }
#[test] #[test]
fn test_add_2() { fn test_add_2() {
let mut mt: MerkleTree = new(140);
let val = TestValue {
bytes: "this is a test leaf".as_bytes().to_vec(),
index_length: 15,
};
assert_eq!("0000000000000000000000000000000000000000000000000000000000000000", mt.root.to_hex());
mt.add(&val);
let (_t, _il, b) = mt.sto.get(&val.ht());
assert_eq!(*val.bytes(), b);
assert_eq!("b4fdf8a653198f0e179ccb3af7e4fc09d76247f479d6cfc95cd92d6fda589f27", mt.root.to_hex());
let val2 = TestValue {
bytes: "this is a second test leaf".as_bytes().to_vec(),
index_length: 15,
};
mt.add(&val2);
let (_t, _il, b) = mt.sto.get(&val2.ht());
assert_eq!(*val2.bytes(), b);
assert_eq!("8ac95e9c8a6fbd40bb21de7895ee35f9c8f30ca029dbb0972c02344f49462e82", mt.root.to_hex());
mt.print_full_tree();
let mut mt: MerkleTree = new(140);
let val = TestValue {
bytes: "this is a test leaf".as_bytes().to_vec(),
index_length: 15,
};
assert_eq!("0000000000000000000000000000000000000000000000000000000000000000", mt.root.to_hex());
mt.add(&val);
let (_t, _il, b) = mt.sto.get(&val.ht());
assert_eq!(*val.bytes(), b);
assert_eq!("b4fdf8a653198f0e179ccb3af7e4fc09d76247f479d6cfc95cd92d6fda589f27", mt.root.to_hex());
let val2 = TestValue {
bytes: "this is a second test leaf".as_bytes().to_vec(),
index_length: 15,
};
mt.add(&val2);
let (_t, _il, b) = mt.sto.get(&val2.ht());
assert_eq!(*val2.bytes(), b);
assert_eq!("8ac95e9c8a6fbd40bb21de7895ee35f9c8f30ca029dbb0972c02344f49462e82", mt.root.to_hex());
} }
#[test] #[test]
fn test_generate_proof_and_verify_proof() { fn test_generate_proof_and_verify_proof() {
let mut mt: MerkleTree = new(140);
let val = TestValue {
bytes: "this is a test leaf".as_bytes().to_vec(),
index_length: 15,
};
assert_eq!("0000000000000000000000000000000000000000000000000000000000000000", mt.root.to_hex());
mt.add(&val);
let (_t, _il, b) = mt.sto.get(&val.ht());
assert_eq!(*val.bytes(), b);
assert_eq!("b4fdf8a653198f0e179ccb3af7e4fc09d76247f479d6cfc95cd92d6fda589f27", mt.root.to_hex());
let val2 = TestValue {
bytes: "this is a second test leaf".as_bytes().to_vec(),
index_length: 15,
};
mt.add(&val2);
let (_t, _il, b) = mt.sto.get(&val2.ht());
assert_eq!(*val2.bytes(), b);
assert_eq!("8ac95e9c8a6fbd40bb21de7895ee35f9c8f30ca029dbb0972c02344f49462e82", mt.root.to_hex());
let mp = mt.generate_proof(val2.hi());
assert_eq!("0000000000000000000000000000000000000000000000000000000000000001fd8e1a60cdb23c0c7b2cf8462c99fafd905054dccb0ed75e7c8a7d6806749b6b", mp.to_hex());
// verify
let v = verify_proof(mt.root, mp, val2.hi(), val2.ht(), mt.num_levels);
assert_eq!(true, v);
let mut mt: MerkleTree = new(140);
let val = TestValue {
bytes: "this is a test leaf".as_bytes().to_vec(),
index_length: 15,
};
assert_eq!("0000000000000000000000000000000000000000000000000000000000000000", mt.root.to_hex());
mt.add(&val);
let (_t, _il, b) = mt.sto.get(&val.ht());
assert_eq!(*val.bytes(), b);
assert_eq!("b4fdf8a653198f0e179ccb3af7e4fc09d76247f479d6cfc95cd92d6fda589f27", mt.root.to_hex());
let val2 = TestValue {
bytes: "this is a second test leaf".as_bytes().to_vec(),
index_length: 15,
};
mt.add(&val2);
let (_t, _il, b) = mt.sto.get(&val2.ht());
assert_eq!(*val2.bytes(), b);
assert_eq!("8ac95e9c8a6fbd40bb21de7895ee35f9c8f30ca029dbb0972c02344f49462e82", mt.root.to_hex());
let mp = mt.generate_proof(val2.hi());
assert_eq!("0000000000000000000000000000000000000000000000000000000000000001fd8e1a60cdb23c0c7b2cf8462c99fafd905054dccb0ed75e7c8a7d6806749b6b", mp.to_hex());
// verify
let v = verify_proof(mt.root, mp, val2.hi(), val2.ht(), mt.num_levels);
assert_eq!(true, v);
} }
#[test] #[test]
fn test_generate_proof_empty_leaf_and_verify_proof() { fn test_generate_proof_empty_leaf_and_verify_proof() {
let mut mt: MerkleTree = new(140);
let val = TestValue {
bytes: "this is a test leaf".as_bytes().to_vec(),
index_length: 15,
};
mt.add(&val);
let val2 = TestValue {
bytes: "this is a second test leaf".as_bytes().to_vec(),
index_length: 15,
};
mt.add(&val2);
assert_eq!("8ac95e9c8a6fbd40bb21de7895ee35f9c8f30ca029dbb0972c02344f49462e82", mt.root.to_hex());
let mut mt: MerkleTree = new(140);
let val = TestValue {
bytes: "this is a test leaf".as_bytes().to_vec(),
index_length: 15,
};
mt.add(&val);
let val2 = TestValue {
bytes: "this is a second test leaf".as_bytes().to_vec(),
index_length: 15,
};
mt.add(&val2);
assert_eq!("8ac95e9c8a6fbd40bb21de7895ee35f9c8f30ca029dbb0972c02344f49462e82", mt.root.to_hex());
// proof of empty leaf // proof of empty leaf
let val3 = TestValue {
bytes: "this is a third test leaf".as_bytes().to_vec(),
index_length: 15,
};
let mp = mt.generate_proof(val3.hi());
assert_eq!("000000000000000000000000000000000000000000000000000000000000000389741fa23da77c259781ad8f4331a5a7d793eef1db7e5200ddfc8e5f5ca7ce2bfd8e1a60cdb23c0c7b2cf8462c99fafd905054dccb0ed75e7c8a7d6806749b6b", mp.to_hex());
// verify that is a proof of an empty leaf (EMPTYNODEVALUE)
let v = verify_proof(mt.root, mp, val3.hi(), EMPTYNODEVALUE, mt.num_levels);
assert_eq!(true, v);
let val3 = TestValue {
bytes: "this is a third test leaf".as_bytes().to_vec(),
index_length: 15,
};
let mp = mt.generate_proof(val3.hi());
assert_eq!("000000000000000000000000000000000000000000000000000000000000000389741fa23da77c259781ad8f4331a5a7d793eef1db7e5200ddfc8e5f5ca7ce2bfd8e1a60cdb23c0c7b2cf8462c99fafd905054dccb0ed75e7c8a7d6806749b6b", mp.to_hex());
// verify that is a proof of an empty leaf (EMPTYNODEVALUE)
let v = verify_proof(mt.root, mp, val3.hi(), EMPTYNODEVALUE, mt.num_levels);
assert_eq!(true, v);
} }
#[test] #[test]
fn test_harcoded_proofs_of_existing_leaf() { fn test_harcoded_proofs_of_existing_leaf() {
// check proof of value in leaf // check proof of value in leaf
@ -520,9 +523,10 @@ pub fn verify_proof(root: [u8;32], mp: Vec, hi: [u8;32], ht: [u8;32], num_le
hi.copy_from_slice(&hex::decode("786677808ba77bdd9090a969f1ef2cbd1ac5aecd9e654f340500159219106878").unwrap()); hi.copy_from_slice(&hex::decode("786677808ba77bdd9090a969f1ef2cbd1ac5aecd9e654f340500159219106878").unwrap());
let mut ht: [u8;32] = [0;32]; let mut ht: [u8;32] = [0;32];
ht.copy_from_slice(&hex::decode("786677808ba77bdd9090a969f1ef2cbd1ac5aecd9e654f340500159219106878").unwrap()); ht.copy_from_slice(&hex::decode("786677808ba77bdd9090a969f1ef2cbd1ac5aecd9e654f340500159219106878").unwrap());
let v = verify_proof(root, mp, hi, ht, 140);
assert_eq!(true, v);
let v = verify_proof(root, mp, hi, ht, 140);
assert_eq!(true, v);
} }
#[test] #[test]
fn test_harcoded_proofs_of_empty_leaf() { fn test_harcoded_proofs_of_empty_leaf() {
// check proof of value in leaf // check proof of value in leaf
@ -531,7 +535,41 @@ pub fn verify_proof(root: [u8;32], mp: Vec, hi: [u8;32], ht: [u8;32], num_le
let mp = hex::decode("0000000000000000000000000000000000000000000000000000000000000004bf8e980d2ed328ae97f65c30c25520aeb53ff837579e392ea1464934c7c1feb9").unwrap(); let mp = hex::decode("0000000000000000000000000000000000000000000000000000000000000004bf8e980d2ed328ae97f65c30c25520aeb53ff837579e392ea1464934c7c1feb9").unwrap();
let mut hi: [u8;32] = [0;32]; let mut hi: [u8;32] = [0;32];
hi.copy_from_slice(&hex::decode("a69792a4cff51f40b7a1f7ae596c6ded4aba241646a47538898f17f2a8dff647").unwrap()); hi.copy_from_slice(&hex::decode("a69792a4cff51f40b7a1f7ae596c6ded4aba241646a47538898f17f2a8dff647").unwrap());
let v = verify_proof(root, mp, hi, EMPTYNODEVALUE, 140);
assert_eq!(true, v);
let v = verify_proof(root, mp, hi, EMPTYNODEVALUE, 140);
assert_eq!(true, v);
}
#[test]
fn test_add_leafs_different_order() {
let mut mt1: MerkleTree = new(140);
mt1.add(&TestValue {bytes: "0 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt1.add(&TestValue {bytes: "1 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt1.add(&TestValue {bytes: "2 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt1.add(&TestValue {bytes: "3 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt1.add(&TestValue {bytes: "4 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt1.add(&TestValue {bytes: "5 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt1.print_full_tree();
let mut mt2: MerkleTree = new(140);
mt2.add(&TestValue {bytes: "2 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt2.add(&TestValue {bytes: "1 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt2.add(&TestValue {bytes: "0 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt2.add(&TestValue {bytes: "5 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt2.add(&TestValue {bytes: "3 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt2.add(&TestValue {bytes: "4 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt2.print_full_tree();
assert_eq!(mt1.root, mt2.root);
assert_eq!(mt1.root.to_hex(), "264397f84da141b3134dcde1d7540d27a2bf0d787bbe8365d9ad5c9c18d3c621");
}
#[test]
fn test_add_1000_leafs() {
let mut mt: MerkleTree = new(140);
for i in 0..1000 {
mt.add(&TestValue {bytes: (i.to_string()+" this is a test leaf").as_bytes().to_vec(), index_length: 15,});
}
assert_eq!(mt.root.to_hex(), "6e2da580b2920cd78ed8d4e4bf41e209dfc99ef28bc19560042f0ac803e0d6f7");
} }
} }

+ 5
- 6
src/utils.rs

@ -2,7 +2,6 @@ use node;
use tiny_keccak::Keccak; use tiny_keccak::Keccak;
pub fn hash_vec(b: Vec<u8>) -> [u8; 32] { pub fn hash_vec(b: Vec<u8>) -> [u8; 32] {
// let mut sha3 = Keccak::new_sha3_256();
let mut sha3 = Keccak::new_keccak256(); let mut sha3 = Keccak::new_keccak256();
sha3.update(&b); sha3.update(&b);
let mut res: [u8; 32] = [0; 32]; let mut res: [u8; 32] = [0; 32];
@ -13,7 +12,7 @@ pub fn hash_vec(b: Vec) -> [u8; 32] {
#[allow(dead_code)] #[allow(dead_code)]
pub fn get_path(num_levels: u32, hi: [u8;32]) -> Vec<bool> { pub fn get_path(num_levels: u32, hi: [u8;32]) -> Vec<bool> {
let mut path = Vec::new(); let mut path = Vec::new();
for i in (0..num_levels as usize-1).rev() {
for i in (0..=num_levels as usize-2).rev() {
path.push((hi[hi.len()-i/8-1] & (1 << (i%8))) > 0); path.push((hi[hi.len()-i/8-1] & (1 << (i%8))) > 0);
} }
path path
@ -42,9 +41,9 @@ pub fn calc_hash_from_leaf_and_level(until_level: u32, path: &[bool], leaf_hash:
pub fn cut_path(path: &[bool], i: usize) -> Vec<bool> { pub fn cut_path(path: &[bool], i: usize) -> Vec<bool> {
let mut path_res: Vec<bool> = Vec::new(); let mut path_res: Vec<bool> = Vec::new();
for (j, path_elem) in path.iter().enumerate() {
if j >= i {
path_res.push(*path_elem);
for j in 0..path.len() {
if j>=i {
path_res.push(path[j]);
} }
} }
path_res path_res
@ -61,7 +60,7 @@ pub fn compare_paths(a: &[bool], b: &[bool]) -> u32 {
pub fn get_empties_between_i_and_pos(i: u32, pos: u32) -> Vec<[u8;32]> { pub fn get_empties_between_i_and_pos(i: u32, pos: u32) -> Vec<[u8;32]> {
let mut sibl: Vec<[u8;32]> = Vec::new(); let mut sibl: Vec<[u8;32]> = Vec::new();
for _ in (pos..i).rev() {
for _ in (pos..=i).rev() {
sibl.push(::EMPTYNODEVALUE); sibl.push(::EMPTYNODEVALUE);
} }
sibl sibl

Loading…
Cancel
Save