diff --git a/docs/merkle/index.html b/docs/merkle/index.html index ea6e9d2..7d7ee5e 100644 --- a/docs/merkle/index.html +++ b/docs/merkle/index.html @@ -47,7 +47,7 @@ [] - [src] + [src]

merkle implements a Merkle Tree in Rust.

Structs

diff --git a/docs/merkle/merkletree/struct.Proof.html b/docs/merkle/merkletree/struct.Proof.html deleted file mode 100644 index 3c58e04..0000000 --- a/docs/merkle/merkletree/struct.Proof.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - -

Redirecting to ../../merkle/struct.Proof.html...

- - - \ No newline at end of file diff --git a/docs/merkle/struct.MerkleTree.html b/docs/merkle/struct.MerkleTree.html index 9defb0b..18e913c 100644 --- a/docs/merkle/struct.MerkleTree.html +++ b/docs/merkle/struct.MerkleTree.html @@ -47,31 +47,30 @@ [] - [src] + [src]
pub struct MerkleTree<D, T> {
-    pub digest: D,
-    pub tree: Tree<T>,
-    pub height: usize,
-    pub count: usize,
+    // some fields omitted
 }

A Merkle tree is a binary tree, with values of type T at the leafs, and where every node holds the hash of the concatenation of the hashes of its children nodes.

-

Fields

digest: D -

The hashing function used by this Merkle tree

-
tree: Tree<T> -

The inner binary tree

-
height: usize -

The height of the tree

-
count: usize -

The number of leaf nodes in the tree

-

Methods

impl<D, T> MerkleTree<D, T> where D: Digest + Clone, T: Into<Vec<u8>> + Clone
[src]

-

fn from_vec(digest: D, values: Vec<T>) -> Self

-

Constructs a Merkle Tree from a vector of data blocks

+

Methods

impl<D, T> MerkleTree<D, T> where D: Digest + Clone, T: Into<Vec<u8>> + Clone
[src]

+

fn from_vec_unsafe(digest: D, values: Vec<T>) -> Self

+

Constructs a Merkle Tree from a vector of data blocks. +WARNING: Panics if values is empty!

+

fn from_vec(digest: D, values: Vec<T>) -> Option<Self>

+

Constructs a Merkle Tree from a vector of data blocks. +Returns None if values is empty.

+

fn digest(&self) -> &D

+

Returns the hash function used in this Merkle tree

fn root_hash(&self) -> &Vec<u8>

-

Returns the tree's root hash

+

Returns the root hash of Merkle tree

+

fn height(&self) -> usize

+

Returns the height of Merkle tree

+

fn count(&self) -> usize

+

Returns the number of leaves in the Merkle tree

fn gen_proof(&self, value: &T) -> Option<Proof<D, T>>

Generate an inclusion proof for the given value. -None is returned if the given value is not found in the tree.

+Returns None if the given value is not found in the tree.

diff --git a/docs/merkle/struct.Proof.html b/docs/merkle/struct.Proof.html index 8bd636f..43be851 100644 --- a/docs/merkle/struct.Proof.html +++ b/docs/merkle/struct.Proof.html @@ -47,22 +47,18 @@ [] - [src] + [src]
pub struct Proof<D, T> {
-    pub digest: D,
-    pub root_hash: Vec<u8>,
-    pub block: ProofBlock,
-    pub value: T,
+    // some fields omitted
 }

An inclusion proof represent the fact that a value is a member of a MerkleTree with root hash root_hash, and hash function digest.

-

Fields

digest: D - root_hash: Vec<u8> - block: ProofBlock - value: T -

Methods

impl<D, T> Proof<D, T> where D: Digest + Clone, T: Into<Vec<u8>> + Clone
[src]

-

fn validate(&self, root_hash: &Vec<u8>) -> bool

-

fn validate_block(&self, block: &ProofBlock, digest: &mut D) -> bool

-
+

Methods

impl<D, T> Proof<D, T> where D: Digest + Clone, T: Into<Vec<u8>> + Clone
[src]

+

fn new(digest: D, root_hash: Vec<u8>, lemma: Lemma) -> Self

+

Constructs a new Proof

+

fn validate(&self, root_hash: &Vec<u8>) -> bool

+

Checks whether this inclusion proof is well-formed, +and whether its root hash matches the given root_hash.

+
diff --git a/docs/search-index.js b/docs/search-index.js index ce47aca..ea78130 100644 --- a/docs/search-index.js +++ b/docs/search-index.js @@ -1,3 +1,3 @@ var searchIndex = {}; -searchIndex["merkle"] = {"doc":"*merkle* implements a Merkle Tree in Rust.","items":[[3,"MerkleTree","merkle","A Merkle tree is a binary tree, with values of type `T` at the leafs,\nand where every node holds the hash of the concatenation of the hashes of\nits children nodes.",null,null],[12,"digest","","The hashing function used by this Merkle tree",0,null],[12,"tree","","The inner binary tree",0,null],[12,"height","","The height of the tree",0,null],[12,"count","","The number of leaf nodes in the tree",0,null],[3,"Proof","","An inclusion proof represent the fact that a `value` is a member\nof a `MerkleTree` with root hash `root_hash`, and hash function `digest`.",null,null],[12,"digest","","",1,null],[12,"root_hash","","",1,null],[12,"block","","",1,null],[12,"value","","",1,null],[11,"from_vec","","Constructs a Merkle Tree from a vector of data blocks",0,{"inputs":[{"name":"d"},{"name":"vec"}],"output":{"name":"self"}}],[11,"root_hash","","Returns the tree's root hash",0,null],[11,"gen_proof","","Generate an inclusion proof for the given value.\n`None` is returned if the given value is not found in the tree.",0,null],[11,"validate","","",1,null],[11,"validate_block","","",1,null]],"paths":[[3,"MerkleTree"],[3,"Proof"]]}; +searchIndex["merkle"] = {"doc":"*merkle* implements a Merkle Tree in Rust.","items":[[3,"MerkleTree","merkle","A Merkle tree is a binary tree, with values of type `T` at the leafs,\nand where every node holds the hash of the concatenation of the hashes of\nits children nodes.",null,null],[3,"Proof","","An inclusion proof represent the fact that a `value` is a member\nof a `MerkleTree` with root hash `root_hash`, and hash function `digest`.",null,null],[11,"from_vec_unsafe","","Constructs a Merkle Tree from a vector of data blocks.\nWARNING: Panics if `values` is empty!",0,{"inputs":[{"name":"d"},{"name":"vec"}],"output":{"name":"self"}}],[11,"from_vec","","Constructs a Merkle Tree from a vector of data blocks.\nReturns None if `values` is empty.",0,{"inputs":[{"name":"d"},{"name":"vec"}],"output":{"name":"option"}}],[11,"digest","","Returns the hash function used in this Merkle tree",0,null],[11,"root_hash","","Returns the root hash of Merkle tree",0,null],[11,"height","","Returns the height of Merkle tree",0,null],[11,"count","","Returns the number of leaves in the Merkle tree",0,null],[11,"gen_proof","","Generate an inclusion proof for the given value.\nReturns `None` if the given value is not found in the tree.",0,null],[11,"new","","Constructs a new `Proof`",1,{"inputs":[{"name":"d"},{"name":"vec"},{"name":"lemma"}],"output":{"name":"self"}}],[11,"validate","","Checks whether this inclusion proof is well-formed,\nand whether its root hash matches the given `root_hash`.",1,null]],"paths":[[3,"MerkleTree"],[3,"Proof"]]}; initSearch(searchIndex); diff --git a/docs/src/merkle/src/lib.rs.html b/docs/src/merkle/src/lib.rs.html index ce41b53..84e2019 100644 --- a/docs/src/merkle/src/lib.rs.html +++ b/docs/src/merkle/src/lib.rs.html @@ -60,7 +60,9 @@ 16 17 18 +19
+#![warn(missing_docs)]
 
 //! *merkle* implements a Merkle Tree in Rust.
 
diff --git a/docs/src/merkle/src/merkletree.rs.html b/docs/src/merkle/src/merkletree.rs.html
index 3ca2e61..b15c1d9 100644
--- a/docs/src/merkle/src/merkletree.rs.html
+++ b/docs/src/merkle/src/merkletree.rs.html
@@ -152,46 +152,65 @@
 108
 109
 110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
 
+
 use crypto::digest::Digest;
 
-use tree::{ Tree };
-use merkledigest::{ MerkleDigest };
+use tree::Tree;
+use merkledigest::MerkleDigest;
 
-pub use proof::{
-    Proof,
-    ProofBlock
-};
+use proof::{ Proof, Lemma };
 
 /// A Merkle tree is a binary tree, with values of type `T` at the leafs,
 /// and where every node holds the hash of the concatenation of the hashes of
 /// its children nodes.
 pub struct MerkleTree<D, T> {
     /// The hashing function used by this Merkle tree
-    pub digest: D,
+    digest: D,
 
-    /// The inner binary tree
-    pub tree: Tree<T>,
+    /// The root of the inner binary tree
+    root: Tree<T>,
 
     /// The height of the tree
-    pub height: usize,
+    height: usize,
 
     /// The number of leaf nodes in the tree
-    pub count: usize
+    count: usize
 }
 
 impl <D, T> MerkleTree<D, T> where D: Digest + Clone, T: Into<Vec<u8>> + Clone {
 
-    /// Constructs a Merkle Tree from a vector of data blocks
-    pub fn from_vec(mut digest: D, values: Vec<T>) -> Self {
+    /// Constructs a Merkle Tree from a vector of data blocks.  
+    /// WARNING: Panics if `values` is empty!
+    pub fn from_vec_unsafe(digest: D, values: Vec<T>) -> Self {
+        Self::from_vec(digest, values).unwrap()
+    }
+
+    /// Constructs a Merkle Tree from a vector of data blocks.  
+    /// Returns None if `values` is empty.
+    pub fn from_vec(mut digest: D, values: Vec<T>) -> Option<Self> {
         if values.is_empty() {
-            panic!("Cannot build a Merkle tree from an empty vector.");
+            return None
         }
 
         let count      = values.len();
         let mut height = 0;
-
-        let mut cur = Vec::with_capacity(count);
+        let mut cur    = Vec::with_capacity(count);
 
         for v in values.into_iter() {
             let leaf = Tree::make_leaf(&mut digest, v);
@@ -209,8 +228,8 @@
                     let right = cur.remove(0);
 
                     let combined_hash = digest.combine_hashes(
-                        left.get_hash(),
-                        right.get_hash()
+                        left.hash(),
+                        right.hash()
                     );
 
                     let node = Tree::Node {
@@ -230,34 +249,45 @@
 
         assert!(cur.len() == 1);
 
-        let tree = cur.remove(0);
+        let root = cur.remove(0);
 
-        MerkleTree {
+        Some(MerkleTree {
             digest: digest,
-            tree: tree,
+            root: root,
             height: height,
             count: count
-        }
+        })
     }
 
-    /// Returns the tree's root hash
+    /// Returns the hash function used in this Merkle tree
+    pub fn digest(&self) -> &D {
+        &self.digest
+    }
+
+    /// Returns the root hash of Merkle tree
     pub fn root_hash(&self) -> &Vec<u8> {
-        self.tree.get_hash()
+        self.root.hash()
+    }
+
+    /// Returns the height of Merkle tree
+    pub fn height(&self) -> usize {
+        self.height
+    }
+
+    /// Returns the number of leaves in the Merkle tree
+    pub fn count(&self) -> usize {
+        self.count
     }
 
     /// Generate an inclusion proof for the given value.
-    /// `None` is returned if the given value is not found in the tree.
+    /// Returns `None` if the given value is not found in the tree.
     pub fn gen_proof(&self, value: &T) -> Option<Proof<D, T>> {
         let mut digest = self.digest.clone();
-        let hash       = digest.hash_bytes(&value.clone().into());
+        let root_hash  = self.root_hash().clone();
+        let node_hash  = digest.hash_bytes(&value.clone().into());
 
-        ProofBlock::new(&self.tree, &hash).map(|block|
-            Proof {
-                digest: digest,
-                root_hash: self.root_hash().clone(),
-                block: block,
-                value: value.clone()
-            }
+        Lemma::new(&self.root, &node_hash).map(|lemma|
+            Proof::new(digest, root_hash, lemma)
         )
     }
 
diff --git a/docs/src/merkle/src/proof.rs.html b/docs/src/merkle/src/proof.rs.html
index 50805ea..d4986a9 100644
--- a/docs/src/merkle/src/proof.rs.html
+++ b/docs/src/merkle/src/proof.rs.html
@@ -172,130 +172,190 @@
 128
 129
 130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
 
 
+use std::marker::PhantomData;
+
 use crypto::digest::Digest;
 
-use merkledigest::{ MerkleDigest };
-use tree::{ Tree };
+use tree::Tree;
+use merkledigest::MerkleDigest;
 
 /// An inclusion proof represent the fact that a `value` is a member
 /// of a `MerkleTree` with root hash `root_hash`, and hash function `digest`.
 pub struct Proof<D, T> {
-    pub digest: D,
-    pub root_hash: Vec<u8>,
-    pub block: ProofBlock,
-    pub value: T
+    digest: D,
+    root_hash: Vec<u8>,
+    lemma: Lemma,
+    _value_marker: PhantomData<T>
 }
 
 impl <D, T> Proof<D, T> where D: Digest + Clone, T: Into<Vec<u8>> + Clone {
 
+    /// Constructs a new `Proof`
+    pub fn new(digest: D, root_hash: Vec<u8>, lemma: Lemma) -> Self {
+        Proof {
+            digest: digest,
+            root_hash: root_hash,
+            lemma: lemma,
+            _value_marker: PhantomData
+        }
+    }
+
+    /// Checks whether this inclusion proof is well-formed,
+    /// and whether its root hash matches the given `root_hash`.
     pub fn validate(&self, root_hash: &Vec<u8>) -> bool {
-        if self.root_hash != *root_hash || self.block.node_hash != *root_hash {
+        if self.root_hash != *root_hash || self.lemma.node_hash != *root_hash {
             return false
         }
 
-        self.validate_block(&self.block, &mut self.digest.clone())
+        self.validate_lemma(&self.lemma, &mut self.digest.clone())
     }
 
-    pub fn validate_block(&self, block: &ProofBlock, digest: &mut D) -> bool {
-        match block.sub_proof {
+    fn validate_lemma(&self, lemma: &Lemma, digest: &mut D) -> bool {
+        match lemma.sub_lemma {
 
             None =>
-                block.sibling_hash == Positioned::Nowhere,
+                lemma.sibling_hash.is_none(),
 
             Some(ref sub) =>
-                match block.sibling_hash {
-                    Positioned::Nowhere =>
+                match lemma.sibling_hash {
+                    None =>
                         false,
 
-                    Positioned::Left(ref hash) => {
-                        let hashes_match = digest.combine_hashes(&hash, &sub.node_hash) == block.node_hash;
-                        hashes_match && self.validate_block(sub, digest)
+                    Some(Positioned::Left(ref hash)) => {
+                        let hashes_match = digest.combine_hashes(&hash, &sub.node_hash) == lemma.node_hash;
+                        hashes_match && self.validate_lemma(sub, digest)
                     }
 
-                    Positioned::Right(ref hash) => {
-                        let hashes_match = digest.combine_hashes(&sub.node_hash, &hash) == block.node_hash;
-                        hashes_match && self.validate_block(sub, digest)
+                    Some(Positioned::Right(ref hash)) => {
+                        let hashes_match = digest.combine_hashes(&sub.node_hash, &hash) == lemma.node_hash;
+                        hashes_match && self.validate_lemma(sub, digest)
                     }
 
                 }
         }
     }
 
+    #[cfg(test)]
+    pub fn lemma_mut(&mut self) -> &mut Lemma {
+        &mut self.lemma
+    }
+
 }
 
 
-/// A `ProofBlock` is a linked-list holding the hash of the node, the hash of its sibling node,
-/// and the rest of the inclusion proof.
-pub struct ProofBlock {
-    pub node_hash: Vec<u8>,
-    pub sibling_hash: Positioned<Vec<u8>>,
-    pub sub_proof: Option<Box<ProofBlock>>
+/// A `Lemma` holds the hash of a node, the hash of its sibling node,
+/// and a sub lemma, whose `node_hash`, when combined with this `sibling_hash`
+/// must be equal to this `node_hash`.
+pub struct Lemma {
+    node_hash: Vec<u8>,
+    sibling_hash: Option<Positioned<Vec<u8>>>,
+    sub_lemma: Option<Box<Lemma>>
 }
 
-impl ProofBlock {
+impl Lemma {
 
-    /// Attempt to generate a proof that the hash `needle` is a member of the given `tree`.
-    pub fn new<T>(tree: &Tree<T>, needle: &Vec<u8>) -> Option<ProofBlock>
-        where T: Into<Vec<u8>> + Clone
-    {
+    /// Attempts to generate a proof that the a value with hash `needle` is a member of the given `tree`.
+    pub fn new<T>(tree: &Tree<T>, needle: &Vec<u8>) -> Option<Lemma> where T: Into<Vec<u8>> + Clone {
         match *tree {
             Tree::Leaf { ref hash, .. } =>
-                ProofBlock::new_leaf_proof(hash, needle),
+                Lemma::new_leaf_proof(hash, needle),
 
             Tree::Node { ref hash, ref left, ref right } =>
-                ProofBlock::new_tree_proof(hash, needle, left, right)
+                Lemma::new_tree_proof(hash, needle, left, right)
         }
     }
 
-    fn new_leaf_proof(hash: &Vec<u8>, needle: &Vec<u8>) -> Option<ProofBlock> {
+    fn new_leaf_proof(hash: &Vec<u8>, needle: &Vec<u8>) -> Option<Lemma> {
         if *hash == *needle {
-            Some(ProofBlock {
+            Some(Lemma {
                 node_hash: hash.clone(),
-                sibling_hash: Positioned::Nowhere,
-                sub_proof: None
+                sibling_hash: None,
+                sub_lemma: None
             })
         } else {
             None
         }
     }
 
-    fn new_tree_proof<T>(hash: &Vec<u8>, needle: &Vec<u8>, left: &Tree<T>, right: &Tree<T>) -> Option<ProofBlock>
+    fn new_tree_proof<T>(hash: &Vec<u8>, needle: &Vec<u8>, left: &Tree<T>, right: &Tree<T>) -> Option<Lemma>
         where T: Into<Vec<u8>> + Clone
     {
-        ProofBlock::new(left, needle)
-            .map(|block| {
-                let right_hash = right.get_hash().clone();
-                let sub_proof = Positioned::Right(right_hash);
-                (block, sub_proof)
+        Lemma::new(left, needle)
+            .map(|lemma| {
+                let right_hash = right.hash().clone();
+                let sub_lemma = Some(Positioned::Right(right_hash));
+                (lemma, sub_lemma)
             })
             .or_else(|| {
-                let sub_proof = ProofBlock::new(right, needle);
-                sub_proof.map(|block| {
-                    let left_hash = left.get_hash().clone();
-                    let sub_proof = Positioned::Left(left_hash);
-                    (block, sub_proof)
+                let sub_lemma = Lemma::new(right, needle);
+                sub_lemma.map(|lemma| {
+                    let left_hash = left.hash().clone();
+                    let sub_lemma = Some(Positioned::Left(left_hash));
+                    (lemma, sub_lemma)
                 })
             })
-            .map(|(sub_proof, sibling_hash)| {
-                ProofBlock {
+            .map(|(sub_lemma, sibling_hash)| {
+                Lemma {
                     node_hash: hash.clone(),
                     sibling_hash: sibling_hash,
-                    sub_proof: Some(Box::new(sub_proof))
+                    sub_lemma: Some(Box::new(sub_lemma))
                 }
             })
     }
 
+    #[cfg(test)]
+    pub fn node_hash_mut(&mut self) -> &mut Vec<u8> {
+        &mut self.node_hash
+    }
+
+    #[cfg(test)]
+    pub fn sibling_hash_mut(&mut self) -> &mut Option<Positioned<Vec<u8>>> {
+        &mut self.sibling_hash
+    }
+
+    #[cfg(test)]
+    pub fn sub_lemma_mut(&mut self) -> &mut Option<Box<Lemma>> {
+        &mut self.sub_lemma
+    }
+
 }
 
-/// Tags a value so that we know from in branch (if any) it was found.
+/// Tags a value so that we know from which branch of a `Tree` (if any) it was found.
 #[derive(PartialEq)]
 pub enum Positioned<T> {
 
-    /// No value was found
-    Nowhere,
-
     /// The value was found in the left branch
     Left(T),
 
diff --git a/docs/src/merkle/src/tree.rs.html b/docs/src/merkle/src/tree.rs.html
index 5221b03..75857ef 100644
--- a/docs/src/merkle/src/tree.rs.html
+++ b/docs/src/merkle/src/tree.rs.html
@@ -99,7 +99,7 @@
 
 pub use proof::{
     Proof,
-    ProofBlock,
+    Lemma,
     Positioned
 };
 
@@ -134,7 +134,7 @@
     }
 
     /// Returns a hash from the tree.
-    pub fn get_hash(&self) -> &Vec<u8> {
+    pub fn hash(&self) -> &Vec<u8> {
         match *self {
             Tree::Leaf { ref hash, .. } => hash,
             Tree::Node { ref hash, .. } => hash