Implement inclusion proof generation and verification.

This commit is contained in:
Romain Ruetschi
2016-11-11 16:32:25 +01:00
committed by Frederic Jacobs
parent 8c2ee9538f
commit b4cd7537b5
54 changed files with 1592 additions and 712 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
target/debug
Cargo.lock
target/

View File

@ -0,0 +1,10 @@
(function() {var implementors = {};
implementors["merkle"] = ["impl&lt;T:&nbsp;<a class='trait' href='https://doc.rust-lang.org/nightly/core/cmp/trait.PartialEq.html' title='core::cmp::PartialEq'>PartialEq</a>&gt; <a class='trait' href='https://doc.rust-lang.org/nightly/core/cmp/trait.PartialEq.html' title='core::cmp::PartialEq'>PartialEq</a> for <a class='enum' href='merkle/enum.Positioned.html' title='merkle::Positioned'>Positioned</a>&lt;T&gt;",];
if (window.register_implementors) {
window.register_implementors(implementors);
} else {
window.pending_implementors = implementors;
}
})()

View File

@ -1,10 +0,0 @@
(function() {var implementors = {};
implementors["merkle"] = [];
if (window.register_implementors) {
window.register_implementors(implementors);
} else {
window.pending_implementors = implementors;
}
})()

View File

@ -26,7 +26,7 @@ h1.fqn {
h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) {
border-bottom-color: #DDDDDD;
}
.in-band, code {
.in-band {
background-color: white;
}
@ -34,7 +34,7 @@ div.stability > em > code {
background-color: initial;
}
.docblock code {
.docblock code, .docblock-short code {
background-color: #F5F5F5;
}
pre {
@ -107,13 +107,13 @@ nav.main .current {
border-bottom-color: #000;
}
nav.main .separator {
border-color: 1px solid #000;
border: 1px solid #000;
}
a {
color: #000;
}
.docblock a, .stability a {
.docblock a, .docblock-short a, .stability a {
color: #3873AD;
}

View File

@ -34,7 +34,8 @@
"primitive",
"associatedtype",
"constant",
"associatedconstant"];
"associatedconstant",
"union"];
// used for special search precedence
var TY_PRIMITIVE = itemTypes.indexOf("primitive");
@ -577,10 +578,6 @@
displayPath = item.path + '::';
href = rootPath + item.path.replace(/::/g, '/') + '/' +
name + '/index.html';
} else if (type === 'static' || type === 'reexport') {
displayPath = item.path + '::';
href = rootPath + item.path.replace(/::/g, '/') +
'/index.html';
} else if (type === "primitive") {
displayPath = "";
href = rootPath + item.path.replace(/::/g, '/') +
@ -591,9 +588,14 @@
} else if (item.parent !== undefined) {
var myparent = item.parent;
var anchor = '#' + type + '.' + name;
displayPath = item.path + '::' + myparent.name + '::';
var parentType = itemTypes[myparent.ty];
if (parentType === "primitive") {
displayPath = myparent.name + '::';
} else {
displayPath = item.path + '::' + myparent.name + '::';
}
href = rootPath + item.path.replace(/::/g, '/') +
'/' + itemTypes[myparent.ty] +
'/' + parentType +
'.' + myparent.name +
'.html' + anchor;
} else {

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=trait.MerkleDigest.html">
</head>
<body>
<p>Redirecting to <a href="trait.MerkleDigest.html">trait.MerkleDigest.html</a>...</p>
<script>location.replace("trait.MerkleDigest.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=struct.MerkleTree.html">
</head>
<body>
<p>Redirecting to <a href="struct.MerkleTree.html">struct.MerkleTree.html</a>...</p>
<script>location.replace("struct.MerkleTree.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=enum.Positioned.html">
</head>
<body>
<p>Redirecting to <a href="enum.Positioned.html">enum.Positioned.html</a>...</p>
<script>location.replace("enum.Positioned.html" + location.search + location.hash);</script>
</body>
</html>

10
docs/merkle/Proof.t.html Normal file
View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=struct.Proof.html">
</head>
<body>
<p>Redirecting to <a href="struct.Proof.html">struct.Proof.html</a>...</p>
<script>location.replace("struct.Proof.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=struct.ProofBlock.html">
</head>
<body>
<p>Redirecting to <a href="struct.ProofBlock.html">struct.ProofBlock.html</a>...</p>
<script>location.replace("struct.ProofBlock.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,126 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="rustdoc">
<meta name="description" content="API documentation for the Rust `Positioned` enum in crate `merkle`.">
<meta name="keywords" content="rust, rustlang, rust-lang, Positioned">
<title>merkle::Positioned - Rust</title>
<link rel="stylesheet" type="text/css" href="../rustdoc.css">
<link rel="stylesheet" type="text/css" href="../main.css">
</head>
<body class="rustdoc">
<!--[if lte IE 8]>
<div class="warning">
This old browser is unsupported and will most likely display funky
things.
</div>
<![endif]-->
<nav class="sidebar">
<p class='location'><a href='index.html'>merkle</a></p><script>window.sidebarCurrent = {name: 'Positioned', ty: 'enum', relpath: ''};</script><script defer src="sidebar-items.js"></script>
</nav>
<nav class="sub">
<form class="search-form js-only">
<div class="search-container">
<input class="search-input" name="search"
autocomplete="off"
placeholder="Click or press S to search, ? for more options…"
type="search">
</div>
</form>
</nav>
<section id='main' class="content enum">
<h1 class='fqn'><span class='in-band'>Enum <a href='index.html'>merkle</a>::<wbr><a class='enum' href=''>Positioned</a></span><span class='out-of-band'><span id='render-detail'>
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
[<span class='inner'>&#x2212;</span>]
</a>
</span><a id='src-158' class='srclink' href='../src/merkle/src/proof.rs.html#121-131' title='goto source code'>[src]</a></span></h1>
<pre class='rust enum'>pub enum Positioned&lt;T&gt; {
Nowhere,
Left(T),
Right(T),
}</pre><div class='docblock'><p>Tags a value so that we know from in branch (if any) it was found.</p>
</div><h2 class='variants'>Variants</h2>
<span id='variant.Nowhere' class='variant'><span id='Nowhere.v' class='invisible'><code>Nowhere</code></span></span><div class='docblock'><p>No value was found</p>
</div><span id='variant.Left' class='variant'><span id='Left.v' class='invisible'><code>Left(T)</code></span></span><div class='docblock'><p>The value was found in the left branch</p>
</div><span id='variant.Right' class='variant'><span id='Right.v' class='invisible'><code>Right(T)</code></span></span><div class='docblock'><p>The value was found in the right branch</p>
</div><h2 id='implementations'>Trait Implementations</h2><h3 class='impl'><span class='in-band'><code>impl&lt;T:&nbsp;<a class='trait' href='https://doc.rust-lang.org/nightly/core/cmp/trait.PartialEq.html' title='core::cmp::PartialEq'>PartialEq</a>&gt; <a class='trait' href='https://doc.rust-lang.org/nightly/core/cmp/trait.PartialEq.html' title='core::cmp::PartialEq'>PartialEq</a> for <a class='enum' href='../merkle/enum.Positioned.html' title='merkle::Positioned'>Positioned</a>&lt;T&gt;</code></span><span class='out-of-band'><div class='ghost'></div><a id='src-165' class='srclink' href='../src/merkle/src/proof.rs.html#120' title='goto source code'>[src]</a></span></h3>
<div class='impl-items'><h4 id='method.eq' class='method'><span id='eq.v' class='invisible'><code>fn <a href='https://doc.rust-lang.org/nightly/core/cmp/trait.PartialEq.html#tymethod.eq' class='fnname'>eq</a>(&amp;self, __arg_0: &amp;<a class='enum' href='../merkle/enum.Positioned.html' title='merkle::Positioned'>Positioned</a>&lt;T&gt;) -&gt; <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.bool.html'>bool</a></code></span></h4>
<div class='docblock'><p>This method tests for <code>self</code> and <code>other</code> values to be equal, and is used by <code>==</code>. <a href="https://doc.rust-lang.org/nightly/core/cmp/trait.PartialEq.html#tymethod.eq">Read more</a></p>
</div><h4 id='method.ne' class='method'><span id='ne.v' class='invisible'><code>fn <a href='https://doc.rust-lang.org/nightly/core/cmp/trait.PartialEq.html#method.ne' class='fnname'>ne</a>(&amp;self, __arg_0: &amp;<a class='enum' href='../merkle/enum.Positioned.html' title='merkle::Positioned'>Positioned</a>&lt;T&gt;) -&gt; <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.bool.html'>bool</a></code></span></h4>
<div class='docblock'><p>This method tests for <code>!=</code>.</p>
</div></div></section>
<section id='search' class="content hidden"></section>
<section class="footer"></section>
<aside id="help" class="hidden">
<div>
<h1 class="hidden">Help</h1>
<div class="shortcuts">
<h2>Keyboard Shortcuts</h2>
<dl>
<dt>?</dt>
<dd>Show this help dialog</dd>
<dt>S</dt>
<dd>Focus the search field</dd>
<dt>&larrb;</dt>
<dd>Move up in search results</dd>
<dt>&rarrb;</dt>
<dd>Move down in search results</dd>
<dt>&#9166;</dt>
<dd>Go to active search result</dd>
<dt>+</dt>
<dd>Collapse/expand all sections</dd>
</dl>
</div>
<div class="infos">
<h2>Search Tricks</h2>
<p>
Prefix searches with a type followed by a colon (e.g.
<code>fn:</code>) to restrict the search to a given type.
</p>
<p>
Accepted types are: <code>fn</code>, <code>mod</code>,
<code>struct</code>, <code>enum</code>,
<code>trait</code>, <code>type</code>, <code>macro</code>,
and <code>const</code>.
</p>
<p>
Search functions by type signature (e.g.
<code>vec -> usize</code> or <code>* -> vec</code>)
</p>
</div>
</div>
</aside>
<script>
window.rootPath = "../";
window.currentCrate = "merkle";
</script>
<script src="../jquery.js"></script>
<script src="../main.js"></script>
<script defer src="../search-index.js"></script>
</body>
</html>

View File

@ -1,137 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="rustdoc">
<meta name="description" content="API documentation for the Rust `Tree` enum in crate `merkle`.">
<meta name="keywords" content="rust, rustlang, rust-lang, Tree">
<title>merkle::Tree - Rust</title>
<link rel="stylesheet" type="text/css" href="../rustdoc.css">
<link rel="stylesheet" type="text/css" href="../main.css">
</head>
<body class="rustdoc">
<!--[if lte IE 8]>
<div class="warning">
This old browser is unsupported and will most likely display funky
things.
</div>
<![endif]-->
<nav class="sidebar">
<p class='location'><a href='index.html'>merkle</a></p><script>window.sidebarCurrent = {name: 'Tree', ty: 'enum', relpath: ''};</script><script defer src="sidebar-items.js"></script>
</nav>
<nav class="sub">
<form class="search-form js-only">
<div class="search-container">
<input class="search-input" name="search"
autocomplete="off"
placeholder="Click or press S to search, ? for more options…"
type="search">
</div>
</form>
</nav>
<section id='main' class="content enum">
<h1 class='fqn'><span class='in-band'>Enum <a href='index.html'>merkle</a>::<wbr><a class='enum' href=''>Tree</a></span><span class='out-of-band'><span id='render-detail'>
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
[<span class='inner'>&#x2212;</span>]
</a>
</span><a id='src-9' class='srclink' href='../src/merkle/src/tree.rs.html#7-18' title='goto source code'>[src]</a></span></h1>
<pre class='rust enum'>pub enum Tree&lt;T&gt; {
Leaf {
hash: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;,
value: T,
},
Node {
hash: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;,
left: <a class='struct' href='https://doc.rust-lang.org/nightly/alloc/boxed/struct.Box.html' title='alloc::boxed::Box'>Box</a>&lt;<a class='enum' href='../merkle/enum.Tree.html' title='merkle::Tree'>Tree</a>&lt;T&gt;&gt;,
right: <a class='struct' href='https://doc.rust-lang.org/nightly/alloc/boxed/struct.Box.html' title='alloc::boxed::Box'>Box</a>&lt;<a class='enum' href='../merkle/enum.Tree.html' title='merkle::Tree'>Tree</a>&lt;T&gt;&gt;,
},
}</pre><div class='docblock'><p>Binary Tree where leaves hold a stand-alone value.</p>
</div><h2 class='variants'>Variants</h2>
<span id='variant.Leaf' class='variant'><code>Leaf</code></span><h3 class='fields'>Fields</h3>
<table><tr><td id='variant.Leaf.field.hash'><code>hash:&nbsp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code></td><td></td></tr><tr><td id='variant.Leaf.field.value'><code>value:&nbsp;T</code></td><td></td></tr></table><span id='variant.Node' class='variant'><code>Node</code></span><h3 class='fields'>Fields</h3>
<table><tr><td id='variant.Node.field.hash'><code>hash:&nbsp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code></td><td></td></tr><tr><td id='variant.Node.field.left'><code>left:&nbsp;<a class='struct' href='https://doc.rust-lang.org/nightly/alloc/boxed/struct.Box.html' title='alloc::boxed::Box'>Box</a>&lt;<a class='enum' href='../merkle/enum.Tree.html' title='merkle::Tree'>Tree</a>&lt;T&gt;&gt;</code></td><td></td></tr><tr><td id='variant.Node.field.right'><code>right:&nbsp;<a class='struct' href='https://doc.rust-lang.org/nightly/alloc/boxed/struct.Box.html' title='alloc::boxed::Box'>Box</a>&lt;<a class='enum' href='../merkle/enum.Tree.html' title='merkle::Tree'>Tree</a>&lt;T&gt;&gt;</code></td><td></td></tr></table><h2 id='methods'>Methods</h2><h3 class='impl'><span class='in-band'><code>impl&lt;T&gt; <a class='enum' href='../merkle/enum.Tree.html' title='merkle::Tree'>Tree</a>&lt;T&gt; <span class='where'>where T: <a class='trait' href='../merkle/trait.Hashable.html' title='merkle::Hashable'>Hashable</a></span></code></span><span class='out-of-band'><div class='ghost'></div><a id='src-18' class='srclink' href='../src/merkle/src/tree.rs.html#20-42' title='goto source code'>[src]</a></span></h3>
<div class='impl-items'><h4 id='method.new' class='method'><code>fn <a href='#method.new' class='fnname'>new</a>(hash: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;, value: T) -&gt; Self</code></h4>
<div class='docblock'><p>Create a new tree</p>
</div><h4 id='method.get_hash' class='method'><code>fn <a href='#method.get_hash' class='fnname'>get_hash</a>(&amp;self) -&gt; &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code></h4>
<div class='docblock'><p>Returns a hash from the tree.</p>
</div><h4 id='method.make_leaf' class='method'><code>fn <a href='#method.make_leaf' class='fnname'>make_leaf</a>&lt;D:&nbsp;Digest&gt;(digest: &amp;mut D, value: T) -&gt; <a class='enum' href='../merkle/enum.Tree.html' title='merkle::Tree'>Tree</a>&lt;T&gt;</code></h4>
<div class='docblock'><p>Create a new leaf</p>
</div></div></section>
<section id='search' class="content hidden"></section>
<section class="footer"></section>
<aside id="help" class="hidden">
<div>
<h1 class="hidden">Help</h1>
<div class="shortcuts">
<h2>Keyboard Shortcuts</h2>
<dl>
<dt>?</dt>
<dd>Show this help dialog</dd>
<dt>S</dt>
<dd>Focus the search field</dd>
<dt>&larrb;</dt>
<dd>Move up in search results</dd>
<dt>&rarrb;</dt>
<dd>Move down in search results</dd>
<dt>&#9166;</dt>
<dd>Go to active search result</dd>
<dt>+</dt>
<dd>Collapse/expand all sections</dd>
</dl>
</div>
<div class="infos">
<h2>Search Tricks</h2>
<p>
Prefix searches with a type followed by a colon (e.g.
<code>fn:</code>) to restrict the search to a given type.
</p>
<p>
Accepted types are: <code>fn</code>, <code>mod</code>,
<code>struct</code>, <code>enum</code>,
<code>trait</code>, <code>type</code>, <code>macro</code>,
and <code>const</code>.
</p>
<p>
Search functions by type signature (e.g.
<code>vec -> usize</code> or <code>* -> vec</code>)
</p>
</div>
</div>
</aside>
<script>
window.rootPath = "../";
window.currentCrate = "merkle";
window.playgroundUrl = "";
</script>
<script src="../jquery.js"></script>
<script src="../main.js"></script>
<script defer src="../search-index.js"></script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=../../merkle/trait.Hashable.html">
</head>
<body>
<p>Redirecting to <a href="../../merkle/trait.Hashable.html">../../merkle/trait.Hashable.html</a>...</p>
<script>location.replace("../../merkle/trait.Hashable.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -47,39 +47,52 @@
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
[<span class='inner'>&#x2212;</span>]
</a>
</span><a id='src-0' class='srclink' href='../src/merkle/src/lib.rs.html#2-17' title='goto source code'>[src]</a></span></h1>
</span><a id='src-0' class='srclink' href='../src/merkle/src/lib.rs.html#2-18' title='goto source code'>[src]</a></span></h1>
<div class='docblock'><p><em>merkle</em> implements a Merkle Tree in Rust.</p>
</div><h2 id='reexports' class='section-header'><a href="#reexports">Reexports</a></h2>
<table><tr><td><code>pub extern crate crypto;</code></td></tr></table><h2 id='structs' class='section-header'><a href="#structs">Structs</a></h2>
</div><h2 id='structs' class='section-header'><a href="#structs">Structs</a></h2>
<table>
<tr class=' module-item'>
<td><a class='struct' href='struct.MerkleTree.html'
title='merkle::MerkleTree'>MerkleTree</a></td>
<td class='docblock short'>
<p>The Merkle tree</p>
<td class='docblock-short'>
<p>A Merkle tree is a binary tree, with values of type <code>T</code> at the leafs,
and where every node holds the hash of the concatenation of the hashes of
its children nodes.</p>
</td>
</tr>
<tr class=' module-item'>
<td><a class='struct' href='struct.Proof.html'
title='merkle::Proof'>Proof</a></td>
<td class='docblock-short'>
<p>An inclusion proof represent the fact that <code>value</code> is a member of a <code>MerkleTree</code>
with root hash <code>root_hash</code>, and hash function <code>digest</code>.
A proof is a linked-list of <code>ProofBlock</code>s.
TODO: Represent a proof as a vector of ProofBlock instead of a linked-list?</p>
</td>
</tr>
<tr class=' module-item'>
<td><a class='struct' href='struct.ProofBlock.html'
title='merkle::ProofBlock'>ProofBlock</a></td>
<td class='docblock-short'>
<p>A <code>ProofBlock</code> is a linked-list holding the hash of the node, the hash of its sibling node,
and the rest of the inclusion proof.</p>
</td>
</tr></table><h2 id='enums' class='section-header'><a href="#enums">Enums</a></h2>
<table>
<tr class=' module-item'>
<td><a class='enum' href='enum.Tree.html'
title='merkle::Tree'>Tree</a></td>
<td class='docblock short'>
<p>Binary Tree where leaves hold a stand-alone value.</p>
<td><a class='enum' href='enum.Positioned.html'
title='merkle::Positioned'>Positioned</a></td>
<td class='docblock-short'>
<p>Tags a value so that we know from in branch (if any) it was found.</p>
</td>
</tr></table><h2 id='traits' class='section-header'><a href="#traits">Traits</a></h2>
<table>
<tr class=' module-item'>
<td><a class='trait' href='trait.Hashable.html'
title='merkle::Hashable'>Hashable</a></td>
<td class='docblock short'>
<p>By definition, data in the Merkle Tree must implement Hashable</p>
</td>
</tr>
<tr class=' module-item'>
<td><a class='trait' href='trait.MerkleDigest.html'
title='merkle::MerkleDigest'>MerkleDigest</a></td>
<td class='docblock short'>
<p>Extends the standard <code>crypto::digest::Digest</code> to play nicely with our Merkle Tree</p>
<td class='docblock-short'>
<p>The sole purpose of this trait is to extend the standard
<code>crypto::digest::Digest</code> with a couple utility functions.</p>
</td>
</tr></table></section>
<section id='search' class="content hidden"></section>
@ -137,11 +150,9 @@
<script>
window.rootPath = "../";
window.currentCrate = "merkle";
window.playgroundUrl = "";
</script>
<script src="../jquery.js"></script>
<script src="../main.js"></script>
<script defer src="../search-index.js"></script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=trait.MerkleDigest.html">
</head>
<body>
<p>Redirecting to <a href="trait.MerkleDigest.html">trait.MerkleDigest.html</a>...</p>
<script>location.replace("trait.MerkleDigest.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=struct.MerkleTree.html">
</head>
<body>
<p>Redirecting to <a href="struct.MerkleTree.html">struct.MerkleTree.html</a>...</p>
<script>location.replace("struct.MerkleTree.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=struct.Proof.html">
</head>
<body>
<p>Redirecting to <a href="struct.Proof.html">struct.Proof.html</a>...</p>
<script>location.replace("struct.Proof.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=struct.ProofBlock.html">
</head>
<body>
<p>Redirecting to <a href="struct.ProofBlock.html">struct.ProofBlock.html</a>...</p>
<script>location.replace("struct.ProofBlock.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=../../merkle/struct.Proof.html">
</head>
<body>
<p>Redirecting to <a href="../../merkle/struct.Proof.html">../../merkle/struct.Proof.html</a>...</p>
<script>location.replace("../../merkle/struct.Proof.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=../../merkle/struct.ProofBlock.html">
</head>
<body>
<p>Redirecting to <a href="../../merkle/struct.ProofBlock.html">../../merkle/struct.ProofBlock.html</a>...</p>
<script>location.replace("../../merkle/struct.ProofBlock.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=enum.Positioned.html">
</head>
<body>
<p>Redirecting to <a href="enum.Positioned.html">enum.Positioned.html</a>...</p>
<script>location.replace("enum.Positioned.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=struct.Proof.html">
</head>
<body>
<p>Redirecting to <a href="struct.Proof.html">struct.Proof.html</a>...</p>
<script>location.replace("struct.Proof.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=struct.ProofBlock.html">
</head>
<body>
<p>Redirecting to <a href="struct.ProofBlock.html">struct.ProofBlock.html</a>...</p>
<script>location.replace("struct.ProofBlock.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=../../merkle/enum.Positioned.html">
</head>
<body>
<p>Redirecting to <a href="../../merkle/enum.Positioned.html">../../merkle/enum.Positioned.html</a>...</p>
<script>location.replace("../../merkle/enum.Positioned.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=../../merkle/struct.Proof.html">
</head>
<body>
<p>Redirecting to <a href="../../merkle/struct.Proof.html">../../merkle/struct.Proof.html</a>...</p>
<script>location.replace("../../merkle/struct.Proof.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=../../merkle/struct.ProofBlock.html">
</head>
<body>
<p>Redirecting to <a href="../../merkle/struct.ProofBlock.html">../../merkle/struct.ProofBlock.html</a>...</p>
<script>location.replace("../../merkle/struct.ProofBlock.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -1 +1 @@
initSidebarItems({"enum":[["Tree","Binary Tree where leaves hold a stand-alone value."]],"struct":[["MerkleTree","The Merkle tree"]],"trait":[["Hashable","By definition, data in the Merkle Tree must implement Hashable"],["MerkleDigest","Extends the standard `crypto::digest::Digest` to play nicely with our Merkle Tree"]]});
initSidebarItems({"enum":[["Positioned","Tags a value so that we know from in branch (if any) it was found."]],"struct":[["MerkleTree","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."],["Proof","An inclusion proof represent the fact that `value` is a member of a `MerkleTree` with root hash `root_hash`, and hash function `digest`. A proof is a linked-list of `ProofBlock`s. TODO: Represent a proof as a vector of ProofBlock instead of a linked-list?"],["ProofBlock","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."]],"trait":[["MerkleDigest","The sole purpose of this trait is to extend the standard `crypto::digest::Digest` with a couple utility functions."]]});

View File

@ -47,19 +47,39 @@
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
[<span class='inner'>&#x2212;</span>]
</a>
</span><a id='src-52' class='srclink' href='../src/merkle/src/merkletree.rs.html#8-13' title='goto source code'>[src]</a></span></h1>
<pre class='rust struct'>pub struct MerkleTree&lt;D,&nbsp;T&gt; {
</span><a id='src-10' class='srclink' href='../src/merkle/src/merkletree.rs.html#14-26' title='goto source code'>[src]</a></span></h1>
<pre class='rust struct'>pub struct MerkleTree&lt;D, T&gt; {
pub digest: D,
pub tree: Tree&lt;T&gt;,
pub height: <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.usize.html'>usize</a>,
pub count: <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.usize.html'>usize</a>,
// some fields omitted
}</pre><div class='docblock'><p>The Merkle tree</p>
</div><h2 class='fields'>Fields</h2><span id='structfield.height' class='structfield'><code>height: <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.usize.html'>usize</a></code>
</span><span class='stab '></span><span id='structfield.count' class='structfield'><code>count: <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.usize.html'>usize</a></code>
</span><span class='stab '></span><h2 id='methods'>Methods</h2><h3 class='impl'><span class='in-band'><code>impl&lt;D,&nbsp;T&gt; <a class='struct' href='../merkle/struct.MerkleTree.html' title='merkle::MerkleTree'>MerkleTree</a>&lt;D,&nbsp;T&gt; <span class='where'>where D: Digest, T: <a class='trait' href='../merkle/trait.Hashable.html' title='merkle::Hashable'>Hashable</a></span></code></span><span class='out-of-band'><div class='ghost'></div><a id='src-59' class='srclink' href='../src/merkle/src/merkletree.rs.html#15-81' title='goto source code'>[src]</a></span></h3>
<div class='impl-items'><h4 id='method.from_vec' class='method'><code>fn <a href='#method.from_vec' class='fnname'>from_vec</a>(digest: D, values: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;T&gt;) -&gt; Self</code></h4>
<div class='docblock'><p>Constructs a Merkle Tree from a vector of data blocks.</p>
</div><h4 id='method.root_hash' class='method'><code>fn <a href='#method.root_hash' class='fnname'>root_hash</a>(&amp;self) -&gt; &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code></h4>
<div class='docblock'><p>Returns the tree&#39;s root hash.</p>
}</pre><div class='docblock'><p>A Merkle tree is a binary tree, with values of type <code>T</code> at the leafs,
and where every node holds the hash of the concatenation of the hashes of
its children nodes.</p>
</div><h2 class='fields'>Fields</h2><span id='structfield.digest' class='structfield'>
<span id='digest.v' class='invisible'>
<code>digest: D</code>
</span></span><span class='stab '></span><div class='docblock'><p>The hashing function used by this Merkle tree</p>
</div><span id='structfield.tree' class='structfield'>
<span id='tree.v' class='invisible'>
<code>tree: Tree&lt;T&gt;</code>
</span></span><span class='stab '></span><div class='docblock'><p>The inner binary tree</p>
</div><span id='structfield.height' class='structfield'>
<span id='height.v' class='invisible'>
<code>height: <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.usize.html'>usize</a></code>
</span></span><span class='stab '></span><div class='docblock'><p>The height of the tree</p>
</div><span id='structfield.count' class='structfield'>
<span id='count.v' class='invisible'>
<code>count: <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.usize.html'>usize</a></code>
</span></span><span class='stab '></span><div class='docblock'><p>The number of leaf nodes in the tree</p>
</div><h2 id='methods'>Methods</h2><h3 class='impl'><span class='in-band'><code>impl&lt;D, T&gt; <a class='struct' href='../merkle/struct.MerkleTree.html' title='merkle::MerkleTree'>MerkleTree</a>&lt;D, T&gt; <span class='where'>where D: Digest + <a class='trait' href='https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a>, T: <a class='trait' href='https://doc.rust-lang.org/nightly/core/convert/trait.Into.html' title='core::convert::Into'>Into</a>&lt;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;&gt; + <a class='trait' href='https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a></span></code></span><span class='out-of-band'><div class='ghost'></div><a id='src-17' class='srclink' href='../src/merkle/src/merkletree.rs.html#28-109' title='goto source code'>[src]</a></span></h3>
<div class='impl-items'><h4 id='method.from_vec' class='method'><span id='from_vec.v' class='invisible'><code>fn <a href='#method.from_vec' class='fnname'>from_vec</a>(digest: D, values: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;T&gt;) -&gt; Self</code></span></h4>
<div class='docblock'><p>Constructs a Merkle Tree from a vector of data blocks</p>
</div><h4 id='method.root_hash' class='method'><span id='root_hash.v' class='invisible'><code>fn <a href='#method.root_hash' class='fnname'>root_hash</a>(&amp;self) -&gt; &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code></span></h4>
<div class='docblock'><p>Returns the tree&#39;s root hash</p>
</div><h4 id='method.gen_proof' class='method'><span id='gen_proof.v' class='invisible'><code>fn <a href='#method.gen_proof' class='fnname'>gen_proof</a>(&amp;self, value: &amp;T) -&gt; <a class='enum' href='https://doc.rust-lang.org/nightly/core/option/enum.Option.html' title='core::option::Option'>Option</a>&lt;<a class='struct' href='../merkle/struct.Proof.html' title='merkle::Proof'>Proof</a>&lt;D, T&gt;&gt;</code></span></h4>
<div class='docblock'><p>Generate an inclusion proof for the given value.
<code>None</code> is returned if the given value is not found in the tree.</p>
</div></div></section>
<section id='search' class="content hidden"></section>
@ -116,11 +136,9 @@
<script>
window.rootPath = "../";
window.currentCrate = "merkle";
window.playgroundUrl = "";
</script>
<script src="../jquery.js"></script>
<script src="../main.js"></script>
<script defer src="../search-index.js"></script>
</body>
</html>

View File

@ -0,0 +1,136 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="rustdoc">
<meta name="description" content="API documentation for the Rust `Proof` struct in crate `merkle`.">
<meta name="keywords" content="rust, rustlang, rust-lang, Proof">
<title>merkle::Proof - Rust</title>
<link rel="stylesheet" type="text/css" href="../rustdoc.css">
<link rel="stylesheet" type="text/css" href="../main.css">
</head>
<body class="rustdoc">
<!--[if lte IE 8]>
<div class="warning">
This old browser is unsupported and will most likely display funky
things.
</div>
<![endif]-->
<nav class="sidebar">
<p class='location'><a href='index.html'>merkle</a></p><script>window.sidebarCurrent = {name: 'Proof', ty: 'struct', relpath: ''};</script><script defer src="sidebar-items.js"></script>
</nav>
<nav class="sub">
<form class="search-form js-only">
<div class="search-container">
<input class="search-input" name="search"
autocomplete="off"
placeholder="Click or press S to search, ? for more options…"
type="search">
</div>
</form>
</nav>
<section id='main' class="content struct">
<h1 class='fqn'><span class='in-band'>Struct <a href='index.html'>merkle</a>::<wbr><a class='struct' href=''>Proof</a></span><span class='out-of-band'><span id='render-detail'>
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
[<span class='inner'>&#x2212;</span>]
</a>
</span><a id='src-48' class='srclink' href='../src/merkle/src/proof.rs.html#11-16' title='goto source code'>[src]</a></span></h1>
<pre class='rust struct'>pub struct Proof&lt;D, T&gt; {
pub digest: D,
pub root_hash: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;,
pub block: <a class='struct' href='../merkle/struct.ProofBlock.html' title='merkle::ProofBlock'>ProofBlock</a>,
pub value: T,
}</pre><div class='docblock'><p>An inclusion proof represent the fact that <code>value</code> is a member of a <code>MerkleTree</code>
with root hash <code>root_hash</code>, and hash function <code>digest</code>.
A proof is a linked-list of <code>ProofBlock</code>s.
TODO: Represent a proof as a vector of ProofBlock instead of a linked-list?</p>
</div><h2 class='fields'>Fields</h2><span id='structfield.digest' class='structfield'>
<span id='digest.v' class='invisible'>
<code>digest: D</code>
</span></span><span class='stab '></span><span id='structfield.root_hash' class='structfield'>
<span id='root_hash.v' class='invisible'>
<code>root_hash: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code>
</span></span><span class='stab '></span><span id='structfield.block' class='structfield'>
<span id='block.v' class='invisible'>
<code>block: <a class='struct' href='../merkle/struct.ProofBlock.html' title='merkle::ProofBlock'>ProofBlock</a></code>
</span></span><span class='stab '></span><span id='structfield.value' class='structfield'>
<span id='value.v' class='invisible'>
<code>value: T</code>
</span></span><span class='stab '></span><h2 id='methods'>Methods</h2><h3 class='impl'><span class='in-band'><code>impl&lt;D, T&gt; <a class='struct' href='../merkle/struct.Proof.html' title='merkle::Proof'>Proof</a>&lt;D, T&gt; <span class='where'>where D: Digest + <a class='trait' href='https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a>, T: <a class='trait' href='https://doc.rust-lang.org/nightly/core/convert/trait.Into.html' title='core::convert::Into'>Into</a>&lt;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;&gt; + <a class='trait' href='https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a></span></code></span><span class='out-of-band'><div class='ghost'></div><a id='src-55' class='srclink' href='../src/merkle/src/proof.rs.html#18-53' title='goto source code'>[src]</a></span></h3>
<div class='impl-items'><h4 id='method.validate' class='method'><span id='validate.v' class='invisible'><code>fn <a href='#method.validate' class='fnname'>validate</a>(&amp;self, root_hash: &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;) -&gt; <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.bool.html'>bool</a></code></span></h4>
<h4 id='method.validate_block' class='method'><span id='validate_block.v' class='invisible'><code>fn <a href='#method.validate_block' class='fnname'>validate_block</a>(&amp;self, block: &amp;<a class='struct' href='../merkle/struct.ProofBlock.html' title='merkle::ProofBlock'>ProofBlock</a>, digest: &amp;mut D) -&gt; <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.bool.html'>bool</a></code></span></h4>
</div></section>
<section id='search' class="content hidden"></section>
<section class="footer"></section>
<aside id="help" class="hidden">
<div>
<h1 class="hidden">Help</h1>
<div class="shortcuts">
<h2>Keyboard Shortcuts</h2>
<dl>
<dt>?</dt>
<dd>Show this help dialog</dd>
<dt>S</dt>
<dd>Focus the search field</dd>
<dt>&larrb;</dt>
<dd>Move up in search results</dd>
<dt>&rarrb;</dt>
<dd>Move down in search results</dd>
<dt>&#9166;</dt>
<dd>Go to active search result</dd>
<dt>+</dt>
<dd>Collapse/expand all sections</dd>
</dl>
</div>
<div class="infos">
<h2>Search Tricks</h2>
<p>
Prefix searches with a type followed by a colon (e.g.
<code>fn:</code>) to restrict the search to a given type.
</p>
<p>
Accepted types are: <code>fn</code>, <code>mod</code>,
<code>struct</code>, <code>enum</code>,
<code>trait</code>, <code>type</code>, <code>macro</code>,
and <code>const</code>.
</p>
<p>
Search functions by type signature (e.g.
<code>vec -> usize</code> or <code>* -> vec</code>)
</p>
</div>
</div>
</aside>
<script>
window.rootPath = "../";
window.currentCrate = "merkle";
</script>
<script src="../jquery.js"></script>
<script src="../main.js"></script>
<script defer src="../search-index.js"></script>
</body>
</html>

View File

@ -0,0 +1,130 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="rustdoc">
<meta name="description" content="API documentation for the Rust `ProofBlock` struct in crate `merkle`.">
<meta name="keywords" content="rust, rustlang, rust-lang, ProofBlock">
<title>merkle::ProofBlock - Rust</title>
<link rel="stylesheet" type="text/css" href="../rustdoc.css">
<link rel="stylesheet" type="text/css" href="../main.css">
</head>
<body class="rustdoc">
<!--[if lte IE 8]>
<div class="warning">
This old browser is unsupported and will most likely display funky
things.
</div>
<![endif]-->
<nav class="sidebar">
<p class='location'><a href='index.html'>merkle</a></p><script>window.sidebarCurrent = {name: 'ProofBlock', ty: 'struct', relpath: ''};</script><script defer src="sidebar-items.js"></script>
</nav>
<nav class="sub">
<form class="search-form js-only">
<div class="search-container">
<input class="search-input" name="search"
autocomplete="off"
placeholder="Click or press S to search, ? for more options…"
type="search">
</div>
</form>
</nav>
<section id='main' class="content struct">
<h1 class='fqn'><span class='in-band'>Struct <a href='index.html'>merkle</a>::<wbr><a class='struct' href=''>ProofBlock</a></span><span class='out-of-band'><span id='render-detail'>
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
[<span class='inner'>&#x2212;</span>]
</a>
</span><a id='src-71' class='srclink' href='../src/merkle/src/proof.rs.html#58-62' title='goto source code'>[src]</a></span></h1>
<pre class='rust struct'>pub struct ProofBlock {
pub node_hash: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;,
pub sibling_hash: <a class='enum' href='../merkle/enum.Positioned.html' title='merkle::Positioned'>Positioned</a>&lt;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;&gt;,
pub sub_proof: <a class='enum' href='https://doc.rust-lang.org/nightly/core/option/enum.Option.html' title='core::option::Option'>Option</a>&lt;<a class='struct' href='https://doc.rust-lang.org/nightly/alloc/boxed/struct.Box.html' title='alloc::boxed::Box'>Box</a>&lt;<a class='struct' href='../merkle/struct.ProofBlock.html' title='merkle::ProofBlock'>ProofBlock</a>&gt;&gt;,
}</pre><div class='docblock'><p>A <code>ProofBlock</code> is a linked-list holding the hash of the node, the hash of its sibling node,
and the rest of the inclusion proof.</p>
</div><h2 class='fields'>Fields</h2><span id='structfield.node_hash' class='structfield'>
<span id='node_hash.v' class='invisible'>
<code>node_hash: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code>
</span></span><span class='stab '></span><span id='structfield.sibling_hash' class='structfield'>
<span id='sibling_hash.v' class='invisible'>
<code>sibling_hash: <a class='enum' href='../merkle/enum.Positioned.html' title='merkle::Positioned'>Positioned</a>&lt;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;&gt;</code>
</span></span><span class='stab '></span><span id='structfield.sub_proof' class='structfield'>
<span id='sub_proof.v' class='invisible'>
<code>sub_proof: <a class='enum' href='https://doc.rust-lang.org/nightly/core/option/enum.Option.html' title='core::option::Option'>Option</a>&lt;<a class='struct' href='https://doc.rust-lang.org/nightly/alloc/boxed/struct.Box.html' title='alloc::boxed::Box'>Box</a>&lt;<a class='struct' href='../merkle/struct.ProofBlock.html' title='merkle::ProofBlock'>ProofBlock</a>&gt;&gt;</code>
</span></span><span class='stab '></span><h2 id='methods'>Methods</h2><h3 class='impl'><span class='in-band'><code>impl <a class='struct' href='../merkle/struct.ProofBlock.html' title='merkle::ProofBlock'>ProofBlock</a></code></span><span class='out-of-band'><div class='ghost'></div><a id='src-75' class='srclink' href='../src/merkle/src/proof.rs.html#64-117' title='goto source code'>[src]</a></span></h3>
<div class='impl-items'><h4 id='method.new' class='method'><span id='new.v' class='invisible'><code>fn <a href='#method.new' class='fnname'>new</a>&lt;T&gt;(tree: &amp;Tree&lt;T&gt;, needle: &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;) -&gt; <a class='enum' href='https://doc.rust-lang.org/nightly/core/option/enum.Option.html' title='core::option::Option'>Option</a>&lt;<a class='struct' href='../merkle/struct.ProofBlock.html' title='merkle::ProofBlock'>ProofBlock</a>&gt; <span class='where'>where T: <a class='trait' href='https://doc.rust-lang.org/nightly/core/convert/trait.Into.html' title='core::convert::Into'>Into</a>&lt;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;&gt; + <a class='trait' href='https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a></span></code></span></h4>
<div class='docblock'><p>Attempt to generate a proof that the hash <code>needle</code> is a member of the given <code>tree</code>.</p>
</div></div></section>
<section id='search' class="content hidden"></section>
<section class="footer"></section>
<aside id="help" class="hidden">
<div>
<h1 class="hidden">Help</h1>
<div class="shortcuts">
<h2>Keyboard Shortcuts</h2>
<dl>
<dt>?</dt>
<dd>Show this help dialog</dd>
<dt>S</dt>
<dd>Focus the search field</dd>
<dt>&larrb;</dt>
<dd>Move up in search results</dd>
<dt>&rarrb;</dt>
<dd>Move down in search results</dd>
<dt>&#9166;</dt>
<dd>Go to active search result</dd>
<dt>+</dt>
<dd>Collapse/expand all sections</dd>
</dl>
</div>
<div class="infos">
<h2>Search Tricks</h2>
<p>
Prefix searches with a type followed by a colon (e.g.
<code>fn:</code>) to restrict the search to a given type.
</p>
<p>
Accepted types are: <code>fn</code>, <code>mod</code>,
<code>struct</code>, <code>enum</code>,
<code>trait</code>, <code>type</code>, <code>macro</code>,
and <code>const</code>.
</p>
<p>
Search functions by type signature (e.g.
<code>vec -> usize</code> or <code>* -> vec</code>)
</p>
</div>
</div>
</aside>
<script>
window.rootPath = "../";
window.currentCrate = "merkle";
</script>
<script src="../jquery.js"></script>
<script src="../main.js"></script>
<script defer src="../search-index.js"></script>
</body>
</html>

View File

@ -1,128 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="rustdoc">
<meta name="description" content="API documentation for the Rust `Hashable` trait in crate `merkle`.">
<meta name="keywords" content="rust, rustlang, rust-lang, Hashable">
<title>merkle::Hashable - Rust</title>
<link rel="stylesheet" type="text/css" href="../rustdoc.css">
<link rel="stylesheet" type="text/css" href="../main.css">
</head>
<body class="rustdoc">
<!--[if lte IE 8]>
<div class="warning">
This old browser is unsupported and will most likely display funky
things.
</div>
<![endif]-->
<nav class="sidebar">
<p class='location'><a href='index.html'>merkle</a></p><script>window.sidebarCurrent = {name: 'Hashable', ty: 'trait', relpath: ''};</script><script defer src="sidebar-items.js"></script>
</nav>
<nav class="sub">
<form class="search-form js-only">
<div class="search-container">
<input class="search-input" name="search"
autocomplete="off"
placeholder="Click or press S to search, ? for more options…"
type="search">
</div>
</form>
</nav>
<section id='main' class="content trait">
<h1 class='fqn'><span class='in-band'>Trait <a href='index.html'>merkle</a>::<wbr><a class='trait' href=''>Hashable</a></span><span class='out-of-band'><span id='render-detail'>
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
[<span class='inner'>&#x2212;</span>]
</a>
</span><a id='src-34' class='srclink' href='../src/merkle/src/hashable.rs.html#2-4' title='goto source code'>[src]</a></span></h1>
<pre class='rust trait'>pub trait Hashable {
fn <a href='#tymethod.to_bytes' class='fnname'>to_bytes</a>(&amp;self) -&gt; <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;;
}</pre><div class='docblock'><p>By definition, data in the Merkle Tree must implement Hashable</p>
</div>
<h2 id='required-methods'>Required Methods</h2>
<div class='methods'>
<h3 id='tymethod.to_bytes' class='method stab '><code>fn <a href='#tymethod.to_bytes' class='fnname'>to_bytes</a>(&amp;self) -&gt; <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code></h3></div>
<h2 id='implementors'>Implementors</h2>
<ul class='item-list' id='implementors-list'>
<li><code>impl Hashable for <a class='struct' href='https://doc.rust-lang.org/nightly/collections/string/struct.String.html' title='collections::string::String'>String</a></code></li>
<li><code>impl Hashable for <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a></code></li>
<li><code>impl Hashable for &amp;'static <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.str.html'>str</a></code></li>
</ul><script type="text/javascript" async
src="../implementors/merkle/trait.Hashable.js">
</script></section>
<section id='search' class="content hidden"></section>
<section class="footer"></section>
<aside id="help" class="hidden">
<div>
<h1 class="hidden">Help</h1>
<div class="shortcuts">
<h2>Keyboard Shortcuts</h2>
<dl>
<dt>?</dt>
<dd>Show this help dialog</dd>
<dt>S</dt>
<dd>Focus the search field</dd>
<dt>&larrb;</dt>
<dd>Move up in search results</dd>
<dt>&rarrb;</dt>
<dd>Move down in search results</dd>
<dt>&#9166;</dt>
<dd>Go to active search result</dd>
<dt>+</dt>
<dd>Collapse/expand all sections</dd>
</dl>
</div>
<div class="infos">
<h2>Search Tricks</h2>
<p>
Prefix searches with a type followed by a colon (e.g.
<code>fn:</code>) to restrict the search to a given type.
</p>
<p>
Accepted types are: <code>fn</code>, <code>mod</code>,
<code>struct</code>, <code>enum</code>,
<code>trait</code>, <code>type</code>, <code>macro</code>,
and <code>const</code>.
</p>
<p>
Search functions by type signature (e.g.
<code>vec -> usize</code> or <code>* -> vec</code>)
</p>
</div>
</div>
</aside>
<script>
window.rootPath = "../";
window.currentCrate = "merkle";
window.playgroundUrl = "";
</script>
<script src="../jquery.js"></script>
<script src="../main.js"></script>
<script defer src="../search-index.js"></script>
</body>
</html>

View File

@ -47,15 +47,18 @@
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
[<span class='inner'>&#x2212;</span>]
</a>
</span><a id='src-83' class='srclink' href='../src/merkle/src/merkledigest.rs.html#4-7' title='goto source code'>[src]</a></span></h1>
</span><a id='src-109' class='srclink' href='../src/merkle/src/merkledigest.rs.html#5-12' title='goto source code'>[src]</a></span></h1>
<pre class='rust trait'>pub trait MerkleDigest {
fn <a href='#tymethod.hash_bytes' class='fnname'>hash_bytes</a>(&amp;mut self, bytes: &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;) -&gt; <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;;
fn <a href='#tymethod.combine_hashes' class='fnname'>combine_hashes</a>(&amp;mut self, left: &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;, right: &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;) -&gt; <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;;
}</pre><div class='docblock'><p>Extends the standard <code>crypto::digest::Digest</code> to play nicely with our Merkle Tree</p>
}</pre><div class='docblock'><p>The sole purpose of this trait is to extend the standard
<code>crypto::digest::Digest</code> with a couple utility functions.</p>
</div>
<h2 id='required-methods'>Required Methods</h2>
<div class='methods'>
<h3 id='tymethod.hash_bytes' class='method stab '><code>fn <a href='#tymethod.hash_bytes' class='fnname'>hash_bytes</a>(&amp;mut self, bytes: &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;) -&gt; <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code></h3><h3 id='tymethod.combine_hashes' class='method stab '><code>fn <a href='#tymethod.combine_hashes' class='fnname'>combine_hashes</a>(&amp;mut self, left: &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;, right: &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;) -&gt; <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code></h3></div>
<h3 id='tymethod.hash_bytes' class='method stab '><span id='hash_bytes.v' class='invisible'><code>fn <a href='#tymethod.hash_bytes' class='fnname'>hash_bytes</a>(&amp;mut self, bytes: &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;) -&gt; <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code></span></h3><div class='docblock'><p>Compute the hash the given byte array</p>
</div><h3 id='tymethod.combine_hashes' class='method stab '><span id='combine_hashes.v' class='invisible'><code>fn <a href='#tymethod.combine_hashes' class='fnname'>combine_hashes</a>(&amp;mut self, left: &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;, right: &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;) -&gt; <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code></span></h3><div class='docblock'><p>Compute the hash of the concatenation of <code>left</code> and <code>right</code></p>
</div></div>
<h2 id='implementors'>Implementors</h2>
<ul class='item-list' id='implementors-list'>
<li><code>impl&lt;D&gt; MerkleDigest for D <span class='where'>where D: Digest</span></code></li>
@ -117,11 +120,9 @@
<script>
window.rootPath = "../";
window.currentCrate = "merkle";
window.playgroundUrl = "";
</script>
<script src="../jquery.js"></script>
<script src="../main.js"></script>
<script defer src="../search-index.js"></script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=enum.Positioned.html">
</head>
<body>
<p>Redirecting to <a href="enum.Positioned.html">enum.Positioned.html</a>...</p>
<script>location.replace("enum.Positioned.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=struct.Proof.html">
</head>
<body>
<p>Redirecting to <a href="struct.Proof.html">struct.Proof.html</a>...</p>
<script>location.replace("struct.Proof.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=struct.ProofBlock.html">
</head>
<body>
<p>Redirecting to <a href="struct.ProofBlock.html">struct.ProofBlock.html</a>...</p>
<script>location.replace("struct.ProofBlock.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=../../merkle/enum.Positioned.html">
</head>
<body>
<p>Redirecting to <a href="../../merkle/enum.Positioned.html">../../merkle/enum.Positioned.html</a>...</p>
<script>location.replace("../../merkle/enum.Positioned.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -1,10 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=../../merkle/enum.Tree.html">
</head>
<body>
<p>Redirecting to <a href="../../merkle/enum.Tree.html">../../merkle/enum.Tree.html</a>...</p>
<script>location.replace("../../merkle/enum.Tree.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=../../merkle/struct.Proof.html">
</head>
<body>
<p>Redirecting to <a href="../../merkle/struct.Proof.html">../../merkle/struct.Proof.html</a>...</p>
<script>location.replace("../../merkle/struct.Proof.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=../../merkle/struct.ProofBlock.html">
</head>
<body>
<p>Redirecting to <a href="../../merkle/struct.ProofBlock.html">../../merkle/struct.ProofBlock.html</a>...</p>
<script>location.replace("../../merkle/struct.ProofBlock.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -1,56 +0,0 @@
// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/*jslint browser: true, es5: true */
/*globals $: true, rootPath: true */
document.addEventListener('DOMContentLoaded', function() {
'use strict';
if (!window.playgroundUrl) {
return;
}
var featureRegexp = new RegExp('^\s*#!\\[feature\\(\.*?\\)\\]');
var elements = document.querySelectorAll('pre.rust-example-rendered');
Array.prototype.forEach.call(elements, function(el) {
el.onmouseover = function(e) {
if (el.contains(e.relatedTarget)) {
return;
}
var a = document.createElement('a');
a.setAttribute('class', 'test-arrow');
a.textContent = 'Run';
var code = el.previousElementSibling.textContent;
var channel = '';
if (featureRegexp.test(code)) {
channel = '&version=nightly';
}
a.setAttribute('href', window.playgroundUrl + '?code=' +
encodeURIComponent(code) + channel);
a.setAttribute('target', '_blank');
el.appendChild(a);
};
el.onmouseout = function(e) {
if (el.contains(e.relatedTarget)) {
return;
}
el.removeChild(el.querySelectorAll('a.test-arrow')[0]);
};
});
});

View File

@ -1,3 +1,5 @@
@import "normalize.css";
/**
* Copyright 2013 The Rust Project Developers. See the COPYRIGHT
* file at the top-level directory of this distribution and at
@ -59,8 +61,6 @@
src: local('Source Code Pro Semibold'), url("SourceCodePro-Semibold.woff") format('woff');
}
@import "normalize.css";
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
@ -130,11 +130,11 @@ code, pre {
font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", Inconsolata, monospace;
white-space: pre-wrap;
}
.docblock code {
.docblock code, .docblock-short code {
border-radius: 3px;
padding: 0 0.2em;
}
.docblock pre code {
.docblock pre code, .docblock-short pre code {
padding: 0;
}
pre {
@ -239,23 +239,23 @@ nav.sub {
}
.line-numbers span { cursor: pointer; }
.docblock.short p {
.docblock-short p {
display: inline;
}
.docblock.short.nowrap {
.docblock-short.nowrap {
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.docblock.short p {
.docblock-short p {
overflow: hidden;
text-overflow: ellipsis;
margin: 0;
}
.docblock.short code { white-space: nowrap; }
.docblock-short code { white-space: nowrap; }
.docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 {
border-bottom: 1px solid;
@ -284,7 +284,7 @@ h3.impl > .out-of-band {
font-size: 21px;
}
h4 > code, h3 > code {
h4 > code, h3 > code, .invisible > code {
position: inherit;
}
@ -292,6 +292,12 @@ h4 > code, h3 > code {
z-index: 5;
}
.invisible {
background: rgba(0, 0, 0, 0);
width: 100%;
display: inline-block;
}
.content .in-band {
margin: 0px;
padding: 0px;
@ -372,6 +378,11 @@ h4 > code, h3 > code {
font-size: 90%;
}
/* Shift where in trait listing down a line */
pre.trait .where::before {
content: '\a ';
}
nav {
border-bottom: 1px solid;
padding-bottom: 10px;
@ -403,7 +414,7 @@ a {
background: transparent;
}
.docblock a:hover, .stability a {
.docblock a:hover, .docblock-short a:hover, .stability a {
text-decoration: underline;
}
@ -453,7 +464,8 @@ a {
.content .search-results td:first-child { padding-right: 0; }
.content .search-results td:first-child a { padding-right: 10px; }
tr.result span.primitive::after { content: ' (primitive type)'; font-style: italic; color: black}
tr.result span.primitive::after { content: ' (primitive type)'; font-style: italic; color: black;
}
body.blur > :not(#help) {
filter: blur(8px);
@ -558,19 +570,26 @@ pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val,
pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; }
pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
pre.rust .lifetime { color: #B76514; }
pre.rust .question-mark {
color: #ff9011;
font-weight: bold;
}
.rusttest { display: none; }
pre.rust { position: relative; }
a.test-arrow {
background-color: rgba(78, 139, 202, 0.2);
display: inline-block;
position: absolute;
background-color: #4e8bca;
padding: 5px 10px 5px 10px;
border-radius: 5px;
font-size: 130%;
top: 5px;
right: 5px;
}
a.test-arrow:hover{
background-color: #4e8bca;
text-decoration: none;
}
.section-header:hover a:after {
content: '\2002\00a7\2002';
@ -660,6 +679,7 @@ span.since {
:target > code {
background: #FDFFD3;
opacity: 1;
}
/* Media Queries */

View File

@ -1,3 +1,3 @@
var searchIndex = {};
searchIndex["merkle"] = {"doc":"*merkle* implements a Merkle Tree in Rust.","items":[[3,"MerkleTree","merkle","The Merkle tree",null,null],[12,"height","","",0,null],[12,"count","","",0,null],[4,"Tree","","Binary Tree where leaves hold a stand-alone value.",null,null],[13,"Leaf","","",1,null],[12,"hash","merkle::Tree","",1,null],[12,"value","","",1,null],[13,"Node","merkle","",1,null],[12,"hash","merkle::Tree","",1,null],[12,"left","","",1,null],[12,"right","","",1,null],[11,"new","merkle","Create a new tree",1,{"inputs":[{"name":"vec"},{"name":"t"}],"output":{"name":"self"}}],[11,"get_hash","","Returns a hash from the tree.",1,null],[11,"make_leaf","","Create a new leaf",1,{"inputs":[{"name":"d"},{"name":"t"}],"output":{"name":"tree"}}],[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&#39;s root hash.",0,null],[8,"Hashable","","By definition, data in the Merkle Tree must implement Hashable",null,null],[10,"to_bytes","","",2,null],[8,"MerkleDigest","","Extends the standard `crypto::digest::Digest` to play nicely with our Merkle Tree",null,null],[10,"hash_bytes","","",3,null],[10,"combine_hashes","","",3,null]],"paths":[[3,"MerkleTree"],[4,"Tree"],[8,"Hashable"],[8,"MerkleDigest"]]};
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 `value` is a member of a `MerkleTree`\nwith root hash `root_hash`, and hash function `digest`.\nA proof is a linked-list of `ProofBlock`s.\nTODO: Represent a proof as a vector of ProofBlock instead of a linked-list?",null,null],[12,"digest","","",1,null],[12,"root_hash","","",1,null],[12,"block","","",1,null],[12,"value","","",1,null],[3,"ProofBlock","","A `ProofBlock` is a linked-list holding the hash of the node, the hash of its sibling node,\nand the rest of the inclusion proof.",null,null],[12,"node_hash","","",2,null],[12,"sibling_hash","","",2,null],[12,"sub_proof","","",2,null],[4,"Positioned","","Tags a value so that we know from in branch (if any) it was found.",null,null],[13,"Nowhere","","No value was found",3,null],[13,"Left","","The value was found in the left branch",3,null],[13,"Right","","The value was found in the right branch",3,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&#39;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],[11,"new","","Attempt to generate a proof that the hash `needle` is a member of the given `tree`.",2,{"inputs":[{"name":"tree"},{"name":"vec"}],"output":{"name":"option"}}],[11,"eq","","",3,null],[11,"ne","","",3,null],[8,"MerkleDigest","","The sole purpose of this trait is to extend the standard\n`crypto::digest::Digest` with a couple utility functions.",null,null],[10,"hash_bytes","","Compute the hash the given byte array",4,null],[10,"combine_hashes","","Compute the hash of the concatenation of `left` and `right`",4,null]],"paths":[[3,"MerkleTree"],[3,"Proof"],[3,"ProofBlock"],[4,"Positioned"],[8,"MerkleDigest"]]};
initSearch(searchIndex);

View File

@ -1,160 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="rustdoc">
<meta name="description" content="Source to the Rust file `src/hashable.rs`.">
<meta name="keywords" content="rust, rustlang, rust-lang">
<title>hashable.rs.html -- source</title>
<link rel="stylesheet" type="text/css" href="../../../rustdoc.css">
<link rel="stylesheet" type="text/css" href="../../../main.css">
</head>
<body class="rustdoc">
<!--[if lte IE 8]>
<div class="warning">
This old browser is unsupported and will most likely display funky
things.
</div>
<![endif]-->
<nav class="sidebar">
</nav>
<nav class="sub">
<form class="search-form js-only">
<div class="search-container">
<input class="search-input" name="search"
autocomplete="off"
placeholder="Click or press S to search, ? for more options…"
type="search">
</div>
</form>
</nav>
<section id='main' class="content source"><pre class="line-numbers"><span id="1"> 1</span>
<span id="2"> 2</span>
<span id="3"> 3</span>
<span id="4"> 4</span>
<span id="5"> 5</span>
<span id="6"> 6</span>
<span id="7"> 7</span>
<span id="8"> 8</span>
<span id="9"> 9</span>
<span id="10">10</span>
<span id="11">11</span>
<span id="12">12</span>
<span id="13">13</span>
<span id="14">14</span>
<span id="15">15</span>
<span id="16">16</span>
<span id="17">17</span>
<span id="18">18</span>
<span id="19">19</span>
<span id="20">20</span>
<span id="21">21</span>
<span id="22">22</span>
<span id="23">23</span>
<span id="24">24</span>
<span id="25">25</span>
</pre><pre class='rust '>
<span class='doccomment'>/// By definition, data in the Merkle Tree must implement Hashable</span>
<span class='kw'>pub</span> <span class='kw'>trait</span> <span class='ident'>Hashable</span> {
<span class='kw'>fn</span> <span class='ident'>to_bytes</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>;
}
<span class='doccomment'>/// Hashable implementation for standard String type</span>
<span class='kw'>impl</span> <span class='ident'>Hashable</span> <span class='kw'>for</span> <span class='ident'>String</span> {
<span class='kw'>fn</span> <span class='ident'>to_bytes</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span> {
<span class='self'>self</span>.<span class='ident'>clone</span>().<span class='ident'>into_bytes</span>()
}
}
<span class='comment'>// Implementation for standard u8 type</span>
<span class='kw'>impl</span> <span class='ident'>Hashable</span> <span class='kw'>for</span> <span class='ident'>u8</span> {
<span class='kw'>fn</span> <span class='ident'>to_bytes</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span> {
<span class='macro'>vec</span><span class='macro'>!</span>[<span class='op'>*</span><span class='self'>self</span>]
}
}
<span class='comment'>// Implementation for standard &amp;str type</span>
<span class='kw'>impl</span> <span class='ident'>Hashable</span> <span class='kw'>for</span> <span class='kw-2'>&amp;</span><span class='lifetime'>&#39;static</span> <span class='ident'>str</span> {
<span class='kw'>fn</span> <span class='ident'>to_bytes</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span> {
<span class='self'>self</span>.<span class='ident'>as_bytes</span>().<span class='ident'>to_vec</span>()
}
}
</pre>
</section>
<section id='search' class="content hidden"></section>
<section class="footer"></section>
<aside id="help" class="hidden">
<div>
<h1 class="hidden">Help</h1>
<div class="shortcuts">
<h2>Keyboard Shortcuts</h2>
<dl>
<dt>?</dt>
<dd>Show this help dialog</dd>
<dt>S</dt>
<dd>Focus the search field</dd>
<dt>&larrb;</dt>
<dd>Move up in search results</dd>
<dt>&rarrb;</dt>
<dd>Move down in search results</dd>
<dt>&#9166;</dt>
<dd>Go to active search result</dd>
<dt>+</dt>
<dd>Collapse/expand all sections</dd>
</dl>
</div>
<div class="infos">
<h2>Search Tricks</h2>
<p>
Prefix searches with a type followed by a colon (e.g.
<code>fn:</code>) to restrict the search to a given type.
</p>
<p>
Accepted types are: <code>fn</code>, <code>mod</code>,
<code>struct</code>, <code>enum</code>,
<code>trait</code>, <code>type</code>, <code>macro</code>,
and <code>const</code>.
</p>
<p>
Search functions by type signature (e.g.
<code>vec -> usize</code> or <code>* -> vec</code>)
</p>
</div>
</div>
</aside>
<script>
window.rootPath = "../../../";
window.currentCrate = "merkle";
window.playgroundUrl = "";
</script>
<script src="../../../jquery.js"></script>
<script src="../../../main.js"></script>
<script defer src="../../../search-index.js"></script>
</body>
</html>

View File

@ -59,24 +59,28 @@
<span id="15">15</span>
<span id="16">16</span>
<span id="17">17</span>
<span id="18">18</span>
<span id="19">19</span>
</pre><pre class='rust '>
<span class='doccomment'>//! *merkle* implements a Merkle Tree in Rust.</span>
<span class='attribute'>#[<span class='ident'>doc</span>(<span class='ident'>no_inline</span>)]</span>
<span class='kw'>pub</span> <span class='kw'>extern</span> <span class='kw'>crate</span> <span class='ident'>crypto</span>;
<span class='kw'>extern</span> <span class='kw'>crate</span> <span class='ident'>crypto</span>;
<span class='kw'>mod</span> <span class='ident'>tree</span>;
<span class='kw'>pub</span> <span class='kw'>use</span> <span class='ident'>tree</span>::{ <span class='ident'>Tree</span> };
<span class='kw'>mod</span> <span class='ident'>hashable</span>;
<span class='kw'>pub</span> <span class='kw'>use</span> <span class='ident'>hashable</span>::{ <span class='ident'>Hashable</span> };
<span class='kw'>mod</span> <span class='ident'>merkletree</span>;
<span class='kw'>pub</span> <span class='kw'>use</span> <span class='ident'>merkletree</span>::{ <span class='ident'>MerkleTree</span> };
<span class='kw'>mod</span> <span class='ident'>proof</span>;
<span class='kw'>pub</span> <span class='kw'>use</span> <span class='ident'>proof</span>::{ <span class='ident'>Proof</span>, <span class='ident'>ProofBlock</span>, <span class='ident'>Positioned</span> };
<span class='kw'>mod</span> <span class='ident'>merkledigest</span>;
<span class='kw'>pub</span> <span class='kw'>use</span> <span class='ident'>merkledigest</span>::{ <span class='ident'>MerkleDigest</span> };
<span class='kw'>mod</span> <span class='ident'>tree</span>;
<span class='attribute'>#[<span class='ident'>cfg</span>(<span class='ident'>test</span>)]</span>
<span class='kw'>mod</span> <span class='ident'>tests</span>;
</pre>
</section>
<section id='search' class="content hidden"></section>
@ -134,11 +138,9 @@
<script>
window.rootPath = "../../../";
window.currentCrate = "merkle";
window.playgroundUrl = "";
</script>
<script src="../../../jquery.js"></script>
<script src="../../../main.js"></script>
<script defer src="../../../search-index.js"></script>
</body>
</html>

View File

@ -75,12 +75,22 @@
<span id="31">31</span>
<span id="32">32</span>
<span id="33">33</span>
<span id="34">34</span>
<span id="35">35</span>
<span id="36">36</span>
<span id="37">37</span>
<span id="38">38</span>
</pre><pre class='rust '>
<span class='kw'>use</span> <span class='ident'>crypto</span>::<span class='ident'>digest</span>::<span class='ident'>Digest</span>;
<span class='doccomment'>/// Extends the standard `crypto::digest::Digest` to play nicely with our Merkle Tree</span>
<span class='doccomment'>/// The sole purpose of this trait is to extend the standard</span>
<span class='doccomment'>/// `crypto::digest::Digest` with a couple utility functions.</span>
<span class='kw'>pub</span> <span class='kw'>trait</span> <span class='ident'>MerkleDigest</span> {
<span class='doccomment'>/// Compute the hash the given byte array</span>
<span class='kw'>fn</span> <span class='ident'>hash_bytes</span>(<span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='self'>self</span>, <span class='ident'>bytes</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>;
<span class='doccomment'>/// Compute the hash of the concatenation of `left` and `right`</span>
<span class='kw'>fn</span> <span class='ident'>combine_hashes</span>(<span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='self'>self</span>, <span class='ident'>left</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>, <span class='ident'>right</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>;
}
@ -166,11 +176,9 @@
<script>
window.rootPath = "../../../";
window.currentCrate = "merkle";
window.playgroundUrl = "";
</script>
<script src="../../../jquery.js"></script>
<script src="../../../main.js"></script>
<script defer src="../../../search-index.js"></script>
</body>
</html>

View File

@ -42,104 +42,147 @@
</form>
</nav>
<section id='main' class="content source"><pre class="line-numbers"><span id="1"> 1</span>
<span id="2"> 2</span>
<span id="3"> 3</span>
<span id="4"> 4</span>
<span id="5"> 5</span>
<span id="6"> 6</span>
<span id="7"> 7</span>
<span id="8"> 8</span>
<span id="9"> 9</span>
<span id="10">10</span>
<span id="11">11</span>
<span id="12">12</span>
<span id="13">13</span>
<span id="14">14</span>
<span id="15">15</span>
<span id="16">16</span>
<span id="17">17</span>
<span id="18">18</span>
<span id="19">19</span>
<span id="20">20</span>
<span id="21">21</span>
<span id="22">22</span>
<span id="23">23</span>
<span id="24">24</span>
<span id="25">25</span>
<span id="26">26</span>
<span id="27">27</span>
<span id="28">28</span>
<span id="29">29</span>
<span id="30">30</span>
<span id="31">31</span>
<span id="32">32</span>
<span id="33">33</span>
<span id="34">34</span>
<span id="35">35</span>
<span id="36">36</span>
<span id="37">37</span>
<span id="38">38</span>
<span id="39">39</span>
<span id="40">40</span>
<span id="41">41</span>
<span id="42">42</span>
<span id="43">43</span>
<span id="44">44</span>
<span id="45">45</span>
<span id="46">46</span>
<span id="47">47</span>
<span id="48">48</span>
<span id="49">49</span>
<span id="50">50</span>
<span id="51">51</span>
<span id="52">52</span>
<span id="53">53</span>
<span id="54">54</span>
<span id="55">55</span>
<span id="56">56</span>
<span id="57">57</span>
<span id="58">58</span>
<span id="59">59</span>
<span id="60">60</span>
<span id="61">61</span>
<span id="62">62</span>
<span id="63">63</span>
<span id="64">64</span>
<span id="65">65</span>
<span id="66">66</span>
<span id="67">67</span>
<span id="68">68</span>
<span id="69">69</span>
<span id="70">70</span>
<span id="71">71</span>
<span id="72">72</span>
<span id="73">73</span>
<span id="74">74</span>
<span id="75">75</span>
<span id="76">76</span>
<span id="77">77</span>
<span id="78">78</span>
<span id="79">79</span>
<span id="80">80</span>
<span id="81">81</span>
<section id='main' class="content source"><pre class="line-numbers"><span id="1"> 1</span>
<span id="2"> 2</span>
<span id="3"> 3</span>
<span id="4"> 4</span>
<span id="5"> 5</span>
<span id="6"> 6</span>
<span id="7"> 7</span>
<span id="8"> 8</span>
<span id="9"> 9</span>
<span id="10"> 10</span>
<span id="11"> 11</span>
<span id="12"> 12</span>
<span id="13"> 13</span>
<span id="14"> 14</span>
<span id="15"> 15</span>
<span id="16"> 16</span>
<span id="17"> 17</span>
<span id="18"> 18</span>
<span id="19"> 19</span>
<span id="20"> 20</span>
<span id="21"> 21</span>
<span id="22"> 22</span>
<span id="23"> 23</span>
<span id="24"> 24</span>
<span id="25"> 25</span>
<span id="26"> 26</span>
<span id="27"> 27</span>
<span id="28"> 28</span>
<span id="29"> 29</span>
<span id="30"> 30</span>
<span id="31"> 31</span>
<span id="32"> 32</span>
<span id="33"> 33</span>
<span id="34"> 34</span>
<span id="35"> 35</span>
<span id="36"> 36</span>
<span id="37"> 37</span>
<span id="38"> 38</span>
<span id="39"> 39</span>
<span id="40"> 40</span>
<span id="41"> 41</span>
<span id="42"> 42</span>
<span id="43"> 43</span>
<span id="44"> 44</span>
<span id="45"> 45</span>
<span id="46"> 46</span>
<span id="47"> 47</span>
<span id="48"> 48</span>
<span id="49"> 49</span>
<span id="50"> 50</span>
<span id="51"> 51</span>
<span id="52"> 52</span>
<span id="53"> 53</span>
<span id="54"> 54</span>
<span id="55"> 55</span>
<span id="56"> 56</span>
<span id="57"> 57</span>
<span id="58"> 58</span>
<span id="59"> 59</span>
<span id="60"> 60</span>
<span id="61"> 61</span>
<span id="62"> 62</span>
<span id="63"> 63</span>
<span id="64"> 64</span>
<span id="65"> 65</span>
<span id="66"> 66</span>
<span id="67"> 67</span>
<span id="68"> 68</span>
<span id="69"> 69</span>
<span id="70"> 70</span>
<span id="71"> 71</span>
<span id="72"> 72</span>
<span id="73"> 73</span>
<span id="74"> 74</span>
<span id="75"> 75</span>
<span id="76"> 76</span>
<span id="77"> 77</span>
<span id="78"> 78</span>
<span id="79"> 79</span>
<span id="80"> 80</span>
<span id="81"> 81</span>
<span id="82"> 82</span>
<span id="83"> 83</span>
<span id="84"> 84</span>
<span id="85"> 85</span>
<span id="86"> 86</span>
<span id="87"> 87</span>
<span id="88"> 88</span>
<span id="89"> 89</span>
<span id="90"> 90</span>
<span id="91"> 91</span>
<span id="92"> 92</span>
<span id="93"> 93</span>
<span id="94"> 94</span>
<span id="95"> 95</span>
<span id="96"> 96</span>
<span id="97"> 97</span>
<span id="98"> 98</span>
<span id="99"> 99</span>
<span id="100">100</span>
<span id="101">101</span>
<span id="102">102</span>
<span id="103">103</span>
<span id="104">104</span>
<span id="105">105</span>
<span id="106">106</span>
<span id="107">107</span>
<span id="108">108</span>
<span id="109">109</span>
<span id="110">110</span>
</pre><pre class='rust '>
<span class='kw'>use</span> <span class='ident'>crypto</span>::<span class='ident'>digest</span>::<span class='ident'>Digest</span>;
<span class='kw'>use</span> <span class='ident'>tree</span>::{ <span class='ident'>Tree</span> };
<span class='kw'>use</span> <span class='ident'>hashable</span>::{ <span class='ident'>Hashable</span> };
<span class='kw'>use</span> <span class='ident'>merkledigest</span>::{ <span class='ident'>MerkleDigest</span> };
<span class='doccomment'>/// The Merkle tree</span>
<span class='kw'>pub</span> <span class='kw'>use</span> <span class='ident'>proof</span>::{
<span class='ident'>Proof</span>,
<span class='ident'>ProofBlock</span>
};
<span class='doccomment'>/// A Merkle tree is a binary tree, with values of type `T` at the leafs,</span>
<span class='doccomment'>/// and where every node holds the hash of the concatenation of the hashes of</span>
<span class='doccomment'>/// its children nodes.</span>
<span class='kw'>pub</span> <span class='kw'>struct</span> <span class='ident'>MerkleTree</span><span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> {
<span class='ident'>digest</span>: <span class='ident'>D</span>,
<span class='ident'>tree</span>: <span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>,
<span class='doccomment'>/// The hashing function used by this Merkle tree</span>
<span class='kw'>pub</span> <span class='ident'>digest</span>: <span class='ident'>D</span>,
<span class='doccomment'>/// The inner binary tree</span>
<span class='kw'>pub</span> <span class='ident'>tree</span>: <span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>,
<span class='doccomment'>/// The height of the tree</span>
<span class='kw'>pub</span> <span class='ident'>height</span>: <span class='ident'>usize</span>,
<span class='doccomment'>/// The number of leaf nodes in the tree</span>
<span class='kw'>pub</span> <span class='ident'>count</span>: <span class='ident'>usize</span>
}
<span class='kw'>impl</span> <span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> <span class='ident'>MerkleTree</span><span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> <span class='kw'>where</span> <span class='ident'>D</span>: <span class='ident'>Digest</span>, <span class='ident'>T</span>: <span class='ident'>Hashable</span> {
<span class='doccomment'>/// Constructs a Merkle Tree from a vector of data blocks.</span>
<span class='kw'>impl</span> <span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> <span class='ident'>MerkleTree</span><span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> <span class='kw'>where</span> <span class='ident'>D</span>: <span class='ident'>Digest</span> <span class='op'>+</span> <span class='ident'>Clone</span>, <span class='ident'>T</span>: <span class='ident'>Into</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span> <span class='op'>+</span> <span class='ident'>Clone</span> {
<span class='doccomment'>/// Constructs a Merkle Tree from a vector of data blocks</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>from_vec</span>(<span class='kw-2'>mut</span> <span class='ident'>digest</span>: <span class='ident'>D</span>, <span class='ident'>values</span>: <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='self'>Self</span> {
<span class='kw'>if</span> <span class='ident'>values</span>.<span class='ident'>is_empty</span>() {
<span class='macro'>panic</span><span class='macro'>!</span>(<span class='string'>&quot;Cannot build a Merkle tree from an empty vector.&quot;</span>);
@ -150,13 +193,11 @@
<span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>cur</span> <span class='op'>=</span> <span class='ident'>Vec</span>::<span class='ident'>with_capacity</span>(<span class='ident'>count</span>);
<span class='kw'>for</span> <span class='ident'>v</span> <span class='kw'>in</span> <span class='ident'>values</span>.<span class='ident'>into_iter</span>().<span class='ident'>rev</span>() {
<span class='kw'>for</span> <span class='ident'>v</span> <span class='kw'>in</span> <span class='ident'>values</span>.<span class='ident'>into_iter</span>() {
<span class='kw'>let</span> <span class='ident'>leaf</span> <span class='op'>=</span> <span class='ident'>Tree</span>::<span class='ident'>make_leaf</span>(<span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='ident'>digest</span>, <span class='ident'>v</span>);
<span class='ident'>cur</span>.<span class='ident'>push</span>(<span class='ident'>leaf</span>);
}
<span class='ident'>cur</span>.<span class='ident'>reverse</span>();
<span class='kw'>while</span> <span class='ident'>cur</span>.<span class='ident'>len</span>() <span class='op'>&gt;</span> <span class='number'>1</span> {
<span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>next</span> <span class='op'>=</span> <span class='ident'>Vec</span>::<span class='ident'>new</span>();
<span class='kw'>while</span> <span class='ident'>cur</span>.<span class='ident'>len</span>() <span class='op'>&gt;</span> <span class='number'>0</span> {
@ -199,12 +240,29 @@
}
}
<span class='doccomment'>/// Returns the tree&#39;s root hash.</span>
<span class='doccomment'>/// Returns the tree&#39;s root hash</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>root_hash</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span> {
<span class='self'>self</span>.<span class='ident'>tree</span>.<span class='ident'>get_hash</span>()
}
<span class='doccomment'>/// Generate an inclusion proof for the given value.</span>
<span class='doccomment'>/// `None` is returned if the given value is not found in the tree.</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>gen_proof</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>, <span class='ident'>value</span>: <span class='kw-2'>&amp;</span><span class='ident'>T</span>) <span class='op'>-&gt;</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>Proof</span><span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;&gt;</span> {
<span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>digest</span> <span class='op'>=</span> <span class='self'>self</span>.<span class='ident'>digest</span>.<span class='ident'>clone</span>();
<span class='kw'>let</span> <span class='ident'>hash</span> <span class='op'>=</span> <span class='ident'>digest</span>.<span class='ident'>hash_bytes</span>(<span class='kw-2'>&amp;</span><span class='ident'>value</span>.<span class='ident'>clone</span>().<span class='ident'>into</span>());
<span class='ident'>ProofBlock</span>::<span class='ident'>new</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>.<span class='ident'>tree</span>, <span class='kw-2'>&amp;</span><span class='ident'>hash</span>).<span class='ident'>map</span>(<span class='op'>|</span><span class='ident'>block</span><span class='op'>|</span>
<span class='ident'>Proof</span> {
<span class='ident'>digest</span>: <span class='ident'>digest</span>,
<span class='ident'>root_hash</span>: <span class='self'>self</span>.<span class='ident'>root_hash</span>().<span class='ident'>clone</span>(),
<span class='ident'>block</span>: <span class='ident'>block</span>,
<span class='ident'>value</span>: <span class='ident'>value</span>.<span class='ident'>clone</span>()
}
)
}
}
</pre>
</section>
<section id='search' class="content hidden"></section>
@ -262,11 +320,9 @@
<script>
window.rootPath = "../../../";
window.currentCrate = "merkle";
window.playgroundUrl = "";
</script>
<script src="../../../jquery.js"></script>
<script src="../../../main.js"></script>
<script defer src="../../../search-index.js"></script>
</body>
</html>

View File

@ -0,0 +1,372 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="rustdoc">
<meta name="description" content="Source to the Rust file `src/proof.rs`.">
<meta name="keywords" content="rust, rustlang, rust-lang">
<title>proof.rs.html -- source</title>
<link rel="stylesheet" type="text/css" href="../../../rustdoc.css">
<link rel="stylesheet" type="text/css" href="../../../main.css">
</head>
<body class="rustdoc">
<!--[if lte IE 8]>
<div class="warning">
This old browser is unsupported and will most likely display funky
things.
</div>
<![endif]-->
<nav class="sidebar">
</nav>
<nav class="sub">
<form class="search-form js-only">
<div class="search-container">
<input class="search-input" name="search"
autocomplete="off"
placeholder="Click or press S to search, ? for more options…"
type="search">
</div>
</form>
</nav>
<section id='main' class="content source"><pre class="line-numbers"><span id="1"> 1</span>
<span id="2"> 2</span>
<span id="3"> 3</span>
<span id="4"> 4</span>
<span id="5"> 5</span>
<span id="6"> 6</span>
<span id="7"> 7</span>
<span id="8"> 8</span>
<span id="9"> 9</span>
<span id="10"> 10</span>
<span id="11"> 11</span>
<span id="12"> 12</span>
<span id="13"> 13</span>
<span id="14"> 14</span>
<span id="15"> 15</span>
<span id="16"> 16</span>
<span id="17"> 17</span>
<span id="18"> 18</span>
<span id="19"> 19</span>
<span id="20"> 20</span>
<span id="21"> 21</span>
<span id="22"> 22</span>
<span id="23"> 23</span>
<span id="24"> 24</span>
<span id="25"> 25</span>
<span id="26"> 26</span>
<span id="27"> 27</span>
<span id="28"> 28</span>
<span id="29"> 29</span>
<span id="30"> 30</span>
<span id="31"> 31</span>
<span id="32"> 32</span>
<span id="33"> 33</span>
<span id="34"> 34</span>
<span id="35"> 35</span>
<span id="36"> 36</span>
<span id="37"> 37</span>
<span id="38"> 38</span>
<span id="39"> 39</span>
<span id="40"> 40</span>
<span id="41"> 41</span>
<span id="42"> 42</span>
<span id="43"> 43</span>
<span id="44"> 44</span>
<span id="45"> 45</span>
<span id="46"> 46</span>
<span id="47"> 47</span>
<span id="48"> 48</span>
<span id="49"> 49</span>
<span id="50"> 50</span>
<span id="51"> 51</span>
<span id="52"> 52</span>
<span id="53"> 53</span>
<span id="54"> 54</span>
<span id="55"> 55</span>
<span id="56"> 56</span>
<span id="57"> 57</span>
<span id="58"> 58</span>
<span id="59"> 59</span>
<span id="60"> 60</span>
<span id="61"> 61</span>
<span id="62"> 62</span>
<span id="63"> 63</span>
<span id="64"> 64</span>
<span id="65"> 65</span>
<span id="66"> 66</span>
<span id="67"> 67</span>
<span id="68"> 68</span>
<span id="69"> 69</span>
<span id="70"> 70</span>
<span id="71"> 71</span>
<span id="72"> 72</span>
<span id="73"> 73</span>
<span id="74"> 74</span>
<span id="75"> 75</span>
<span id="76"> 76</span>
<span id="77"> 77</span>
<span id="78"> 78</span>
<span id="79"> 79</span>
<span id="80"> 80</span>
<span id="81"> 81</span>
<span id="82"> 82</span>
<span id="83"> 83</span>
<span id="84"> 84</span>
<span id="85"> 85</span>
<span id="86"> 86</span>
<span id="87"> 87</span>
<span id="88"> 88</span>
<span id="89"> 89</span>
<span id="90"> 90</span>
<span id="91"> 91</span>
<span id="92"> 92</span>
<span id="93"> 93</span>
<span id="94"> 94</span>
<span id="95"> 95</span>
<span id="96"> 96</span>
<span id="97"> 97</span>
<span id="98"> 98</span>
<span id="99"> 99</span>
<span id="100">100</span>
<span id="101">101</span>
<span id="102">102</span>
<span id="103">103</span>
<span id="104">104</span>
<span id="105">105</span>
<span id="106">106</span>
<span id="107">107</span>
<span id="108">108</span>
<span id="109">109</span>
<span id="110">110</span>
<span id="111">111</span>
<span id="112">112</span>
<span id="113">113</span>
<span id="114">114</span>
<span id="115">115</span>
<span id="116">116</span>
<span id="117">117</span>
<span id="118">118</span>
<span id="119">119</span>
<span id="120">120</span>
<span id="121">121</span>
<span id="122">122</span>
<span id="123">123</span>
<span id="124">124</span>
<span id="125">125</span>
<span id="126">126</span>
<span id="127">127</span>
<span id="128">128</span>
<span id="129">129</span>
<span id="130">130</span>
<span id="131">131</span>
<span id="132">132</span>
</pre><pre class='rust '>
<span class='kw'>use</span> <span class='ident'>crypto</span>::<span class='ident'>digest</span>::<span class='ident'>Digest</span>;
<span class='kw'>use</span> <span class='ident'>merkledigest</span>::{ <span class='ident'>MerkleDigest</span> };
<span class='kw'>use</span> <span class='ident'>tree</span>::{ <span class='ident'>Tree</span> };
<span class='doccomment'>/// An inclusion proof represent the fact that `value` is a member of a `MerkleTree`</span>
<span class='doccomment'>/// with root hash `root_hash`, and hash function `digest`.</span>
<span class='doccomment'>/// A proof is a linked-list of `ProofBlock`s.</span>
<span class='doccomment'>/// TODO: Represent a proof as a vector of ProofBlock instead of a linked-list?</span>
<span class='kw'>pub</span> <span class='kw'>struct</span> <span class='ident'>Proof</span><span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> {
<span class='kw'>pub</span> <span class='ident'>digest</span>: <span class='ident'>D</span>,
<span class='kw'>pub</span> <span class='ident'>root_hash</span>: <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>,
<span class='kw'>pub</span> <span class='ident'>block</span>: <span class='ident'>ProofBlock</span>,
<span class='kw'>pub</span> <span class='ident'>value</span>: <span class='ident'>T</span>
}
<span class='kw'>impl</span> <span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> <span class='ident'>Proof</span><span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> <span class='kw'>where</span> <span class='ident'>D</span>: <span class='ident'>Digest</span> <span class='op'>+</span> <span class='ident'>Clone</span>, <span class='ident'>T</span>: <span class='ident'>Into</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span> <span class='op'>+</span> <span class='ident'>Clone</span> {
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>validate</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>, <span class='ident'>root_hash</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='ident'>bool</span> {
<span class='kw'>if</span> <span class='self'>self</span>.<span class='ident'>root_hash</span> <span class='op'>!=</span> <span class='op'>*</span><span class='ident'>root_hash</span> <span class='op'>||</span> <span class='self'>self</span>.<span class='ident'>block</span>.<span class='ident'>node_hash</span> <span class='op'>!=</span> <span class='op'>*</span><span class='ident'>root_hash</span> {
<span class='kw'>return</span> <span class='bool-val'>false</span>
}
<span class='self'>self</span>.<span class='ident'>validate_block</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>.<span class='ident'>block</span>, <span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='self'>self</span>.<span class='ident'>digest</span>.<span class='ident'>clone</span>())
}
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>validate_block</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>, <span class='ident'>block</span>: <span class='kw-2'>&amp;</span><span class='ident'>ProofBlock</span>, <span class='ident'>digest</span>: <span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='ident'>D</span>) <span class='op'>-&gt;</span> <span class='ident'>bool</span> {
<span class='kw'>match</span> <span class='ident'>block</span>.<span class='ident'>sub_proof</span> {
<span class='prelude-val'>None</span> <span class='op'>=&gt;</span>
<span class='ident'>block</span>.<span class='ident'>sibling_hash</span> <span class='op'>==</span> <span class='ident'>Positioned</span>::<span class='ident'>Nowhere</span>,
<span class='prelude-val'>Some</span>(<span class='kw-2'>ref</span> <span class='ident'>sub</span>) <span class='op'>=&gt;</span>
<span class='kw'>match</span> <span class='ident'>block</span>.<span class='ident'>sibling_hash</span> {
<span class='ident'>Positioned</span>::<span class='ident'>Nowhere</span> <span class='op'>=&gt;</span>
<span class='bool-val'>false</span>,
<span class='ident'>Positioned</span>::<span class='ident'>Left</span>(<span class='kw-2'>ref</span> <span class='ident'>hash</span>) <span class='op'>=&gt;</span> {
<span class='kw'>let</span> <span class='ident'>hashes_match</span> <span class='op'>=</span> <span class='ident'>digest</span>.<span class='ident'>combine_hashes</span>(<span class='kw-2'>&amp;</span><span class='ident'>hash</span>, <span class='kw-2'>&amp;</span><span class='ident'>sub</span>.<span class='ident'>node_hash</span>) <span class='op'>==</span> <span class='ident'>block</span>.<span class='ident'>node_hash</span>;
<span class='ident'>hashes_match</span> <span class='op'>&amp;&amp;</span> <span class='self'>self</span>.<span class='ident'>validate_block</span>(<span class='ident'>sub</span>, <span class='ident'>digest</span>)
}
<span class='ident'>Positioned</span>::<span class='ident'>Right</span>(<span class='kw-2'>ref</span> <span class='ident'>hash</span>) <span class='op'>=&gt;</span> {
<span class='kw'>let</span> <span class='ident'>hashes_match</span> <span class='op'>=</span> <span class='ident'>digest</span>.<span class='ident'>combine_hashes</span>(<span class='kw-2'>&amp;</span><span class='ident'>sub</span>.<span class='ident'>node_hash</span>, <span class='kw-2'>&amp;</span><span class='ident'>hash</span>) <span class='op'>==</span> <span class='ident'>block</span>.<span class='ident'>node_hash</span>;
<span class='ident'>hashes_match</span> <span class='op'>&amp;&amp;</span> <span class='self'>self</span>.<span class='ident'>validate_block</span>(<span class='ident'>sub</span>, <span class='ident'>digest</span>)
}
}
}
}
}
<span class='doccomment'>/// A `ProofBlock` is a linked-list holding the hash of the node, the hash of its sibling node,</span>
<span class='doccomment'>/// and the rest of the inclusion proof.</span>
<span class='kw'>pub</span> <span class='kw'>struct</span> <span class='ident'>ProofBlock</span> {
<span class='kw'>pub</span> <span class='ident'>node_hash</span>: <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>,
<span class='kw'>pub</span> <span class='ident'>sibling_hash</span>: <span class='ident'>Positioned</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span>,
<span class='kw'>pub</span> <span class='ident'>sub_proof</span>: <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>Box</span><span class='op'>&lt;</span><span class='ident'>ProofBlock</span><span class='op'>&gt;&gt;</span>
}
<span class='kw'>impl</span> <span class='ident'>ProofBlock</span> {
<span class='doccomment'>/// Attempt to generate a proof that the hash `needle` is a member of the given `tree`.</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>new</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>(<span class='ident'>tree</span>: <span class='kw-2'>&amp;</span><span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>, <span class='ident'>needle</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>ProofBlock</span><span class='op'>&gt;</span>
<span class='kw'>where</span> <span class='ident'>T</span>: <span class='ident'>Into</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span> <span class='op'>+</span> <span class='ident'>Clone</span>
{
<span class='kw'>match</span> <span class='op'>*</span><span class='ident'>tree</span> {
<span class='ident'>Tree</span>::<span class='ident'>Leaf</span> { <span class='kw-2'>ref</span> <span class='ident'>hash</span>, .. } <span class='op'>=&gt;</span>
<span class='ident'>ProofBlock</span>::<span class='ident'>new_leaf_proof</span>(<span class='ident'>hash</span>, <span class='ident'>needle</span>),
<span class='ident'>Tree</span>::<span class='ident'>Node</span> { <span class='kw-2'>ref</span> <span class='ident'>hash</span>, <span class='kw-2'>ref</span> <span class='ident'>left</span>, <span class='kw-2'>ref</span> <span class='ident'>right</span> } <span class='op'>=&gt;</span>
<span class='ident'>ProofBlock</span>::<span class='ident'>new_tree_proof</span>(<span class='ident'>hash</span>, <span class='ident'>needle</span>, <span class='ident'>left</span>, <span class='ident'>right</span>)
}
}
<span class='kw'>fn</span> <span class='ident'>new_leaf_proof</span>(<span class='ident'>hash</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>, <span class='ident'>needle</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>ProofBlock</span><span class='op'>&gt;</span> {
<span class='kw'>if</span> <span class='op'>*</span><span class='ident'>hash</span> <span class='op'>==</span> <span class='op'>*</span><span class='ident'>needle</span> {
<span class='prelude-val'>Some</span>(<span class='ident'>ProofBlock</span> {
<span class='ident'>node_hash</span>: <span class='ident'>hash</span>.<span class='ident'>clone</span>(),
<span class='ident'>sibling_hash</span>: <span class='ident'>Positioned</span>::<span class='ident'>Nowhere</span>,
<span class='ident'>sub_proof</span>: <span class='prelude-val'>None</span>
})
} <span class='kw'>else</span> {
<span class='prelude-val'>None</span>
}
}
<span class='kw'>fn</span> <span class='ident'>new_tree_proof</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>(<span class='ident'>hash</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>, <span class='ident'>needle</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>, <span class='ident'>left</span>: <span class='kw-2'>&amp;</span><span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>, <span class='ident'>right</span>: <span class='kw-2'>&amp;</span><span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>ProofBlock</span><span class='op'>&gt;</span>
<span class='kw'>where</span> <span class='ident'>T</span>: <span class='ident'>Into</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span> <span class='op'>+</span> <span class='ident'>Clone</span>
{
<span class='ident'>ProofBlock</span>::<span class='ident'>new</span>(<span class='ident'>left</span>, <span class='ident'>needle</span>)
.<span class='ident'>map</span>(<span class='op'>|</span><span class='ident'>block</span><span class='op'>|</span> {
<span class='kw'>let</span> <span class='ident'>right_hash</span> <span class='op'>=</span> <span class='ident'>right</span>.<span class='ident'>get_hash</span>().<span class='ident'>clone</span>();
<span class='kw'>let</span> <span class='ident'>sub_proof</span> <span class='op'>=</span> <span class='ident'>Positioned</span>::<span class='ident'>Right</span>(<span class='ident'>right_hash</span>);
(<span class='ident'>block</span>, <span class='ident'>sub_proof</span>)
})
.<span class='ident'>or_else</span>(<span class='op'>||</span> {
<span class='kw'>let</span> <span class='ident'>sub_proof</span> <span class='op'>=</span> <span class='ident'>ProofBlock</span>::<span class='ident'>new</span>(<span class='ident'>right</span>, <span class='ident'>needle</span>);
<span class='ident'>sub_proof</span>.<span class='ident'>map</span>(<span class='op'>|</span><span class='ident'>block</span><span class='op'>|</span> {
<span class='kw'>let</span> <span class='ident'>left_hash</span> <span class='op'>=</span> <span class='ident'>left</span>.<span class='ident'>get_hash</span>().<span class='ident'>clone</span>();
<span class='kw'>let</span> <span class='ident'>sub_proof</span> <span class='op'>=</span> <span class='ident'>Positioned</span>::<span class='ident'>Left</span>(<span class='ident'>left_hash</span>);
(<span class='ident'>block</span>, <span class='ident'>sub_proof</span>)
})
})
.<span class='ident'>map</span>(<span class='op'>|</span>(<span class='ident'>sub_proof</span>, <span class='ident'>sibling_hash</span>)<span class='op'>|</span> {
<span class='ident'>ProofBlock</span> {
<span class='ident'>node_hash</span>: <span class='ident'>hash</span>.<span class='ident'>clone</span>(),
<span class='ident'>sibling_hash</span>: <span class='ident'>sibling_hash</span>,
<span class='ident'>sub_proof</span>: <span class='prelude-val'>Some</span>(<span class='ident'>Box</span>::<span class='ident'>new</span>(<span class='ident'>sub_proof</span>))
}
})
}
}
<span class='doccomment'>/// Tags a value so that we know from in branch (if any) it was found.</span>
<span class='attribute'>#[<span class='ident'>derive</span>(<span class='ident'>PartialEq</span>)]</span>
<span class='kw'>pub</span> <span class='kw'>enum</span> <span class='ident'>Positioned</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span> {
<span class='doccomment'>/// No value was found</span>
<span class='ident'>Nowhere</span>,
<span class='doccomment'>/// The value was found in the left branch</span>
<span class='ident'>Left</span>(<span class='ident'>T</span>),
<span class='doccomment'>/// The value was found in the right branch</span>
<span class='ident'>Right</span>(<span class='ident'>T</span>)
}
</pre>
</section>
<section id='search' class="content hidden"></section>
<section class="footer"></section>
<aside id="help" class="hidden">
<div>
<h1 class="hidden">Help</h1>
<div class="shortcuts">
<h2>Keyboard Shortcuts</h2>
<dl>
<dt>?</dt>
<dd>Show this help dialog</dd>
<dt>S</dt>
<dd>Focus the search field</dd>
<dt>&larrb;</dt>
<dd>Move up in search results</dd>
<dt>&rarrb;</dt>
<dd>Move down in search results</dd>
<dt>&#9166;</dt>
<dd>Go to active search result</dd>
<dt>+</dt>
<dd>Collapse/expand all sections</dd>
</dl>
</div>
<div class="infos">
<h2>Search Tricks</h2>
<p>
Prefix searches with a type followed by a colon (e.g.
<code>fn:</code>) to restrict the search to a given type.
</p>
<p>
Accepted types are: <code>fn</code>, <code>mod</code>,
<code>struct</code>, <code>enum</code>,
<code>trait</code>, <code>type</code>, <code>macro</code>,
and <code>const</code>.
</p>
<p>
Search functions by type signature (e.g.
<code>vec -> usize</code> or <code>* -> vec</code>)
</p>
</div>
</div>
</aside>
<script>
window.rootPath = "../../../";
window.currentCrate = "merkle";
</script>
<script src="../../../jquery.js"></script>
<script src="../../../main.js"></script>
<script defer src="../../../search-index.js"></script>
</body>
</html>

View File

@ -84,12 +84,25 @@
<span id="40">40</span>
<span id="41">41</span>
<span id="42">42</span>
<span id="43">43</span>
<span id="44">44</span>
<span id="45">45</span>
<span id="46">46</span>
<span id="47">47</span>
<span id="48">48</span>
<span id="49">49</span>
<span id="50">50</span>
</pre><pre class='rust '>
<span class='kw'>use</span> <span class='ident'>crypto</span>::<span class='ident'>digest</span>::<span class='ident'>Digest</span>;
<span class='kw'>use</span> <span class='ident'>hashable</span>::{ <span class='ident'>Hashable</span> };
<span class='kw'>use</span> <span class='ident'>merkledigest</span>::{ <span class='ident'>MerkleDigest</span> };
<span class='kw'>pub</span> <span class='kw'>use</span> <span class='ident'>proof</span>::{
<span class='ident'>Proof</span>,
<span class='ident'>ProofBlock</span>,
<span class='ident'>Positioned</span>
};
<span class='doccomment'>/// Binary Tree where leaves hold a stand-alone value.</span>
<span class='kw'>pub</span> <span class='kw'>enum</span> <span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span> {
<span class='ident'>Leaf</span> {
@ -104,7 +117,8 @@
}
}
<span class='kw'>impl</span> <span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span> <span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span> <span class='kw'>where</span> <span class='ident'>T</span>: <span class='ident'>Hashable</span> {
<span class='kw'>impl</span> <span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span> <span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span> <span class='kw'>where</span> <span class='ident'>T</span>: <span class='ident'>Into</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span> <span class='op'>+</span> <span class='ident'>Clone</span> {
<span class='doccomment'>/// Create a new tree</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>new</span>(<span class='ident'>hash</span>: <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>, <span class='ident'>value</span>: <span class='ident'>T</span>) <span class='op'>-&gt;</span> <span class='self'>Self</span> {
<span class='ident'>Tree</span>::<span class='ident'>Leaf</span> {
@ -113,20 +127,22 @@
}
}
<span class='doccomment'>/// Create a new leaf</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>make_leaf</span><span class='op'>&lt;</span><span class='ident'>D</span>: <span class='ident'>Digest</span><span class='op'>&gt;</span>(<span class='ident'>digest</span>: <span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='ident'>D</span>, <span class='ident'>value</span>: <span class='ident'>T</span>) <span class='op'>-&gt;</span> <span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span> {
<span class='kw'>let</span> <span class='ident'>hash</span> <span class='op'>=</span> <span class='ident'>digest</span>.<span class='ident'>hash_bytes</span>(<span class='kw-2'>&amp;</span><span class='ident'>value</span>.<span class='ident'>clone</span>().<span class='ident'>into</span>());
<span class='ident'>Tree</span>::<span class='ident'>new</span>(<span class='ident'>hash</span>, <span class='ident'>value</span>)
}
<span class='doccomment'>/// Returns a hash from the tree.</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>get_hash</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span> {
<span class='kw'>match</span> <span class='op'>*</span><span class='self'>self</span> {
<span class='ident'>Tree</span>::<span class='ident'>Leaf</span> { <span class='kw-2'>ref</span> <span class='ident'>hash</span>, <span class='ident'>value</span>: _ } <span class='op'>=&gt;</span> <span class='ident'>hash</span>,
<span class='ident'>Tree</span>::<span class='ident'>Node</span> { <span class='kw-2'>ref</span> <span class='ident'>hash</span>, <span class='ident'>left</span>: _, <span class='ident'>right</span>: _ } <span class='op'>=&gt;</span> <span class='ident'>hash</span>
<span class='ident'>Tree</span>::<span class='ident'>Leaf</span> { <span class='kw-2'>ref</span> <span class='ident'>hash</span>, .. } <span class='op'>=&gt;</span> <span class='ident'>hash</span>,
<span class='ident'>Tree</span>::<span class='ident'>Node</span> { <span class='kw-2'>ref</span> <span class='ident'>hash</span>, .. } <span class='op'>=&gt;</span> <span class='ident'>hash</span>
}
}
<span class='doccomment'>/// Create a new leaf</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>make_leaf</span><span class='op'>&lt;</span><span class='ident'>D</span>: <span class='ident'>Digest</span><span class='op'>&gt;</span>(<span class='ident'>digest</span>: <span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='ident'>D</span>, <span class='ident'>value</span>: <span class='ident'>T</span>) <span class='op'>-&gt;</span> <span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span> {
<span class='kw'>let</span> <span class='ident'>hash</span> <span class='op'>=</span> <span class='ident'>digest</span>.<span class='ident'>hash_bytes</span>(<span class='kw-2'>&amp;</span><span class='ident'>value</span>.<span class='ident'>to_bytes</span>());
<span class='ident'>Tree</span>::<span class='ident'>new</span>(<span class='ident'>hash</span>, <span class='ident'>value</span>)
}
}
</pre>
</section>
<section id='search' class="content hidden"></section>
@ -184,11 +200,9 @@
<script>
window.rootPath = "../../../";
window.currentCrate = "merkle";
window.playgroundUrl = "";
</script>
<script src="../../../jquery.js"></script>
<script src="../../../main.js"></script>
<script defer src="../../../search-index.js"></script>
</body>
</html>

View File

@ -1,15 +1,19 @@
//! *merkle* implements a Merkle Tree in Rust.
#[doc(no_inline)]
pub extern crate crypto;
extern crate crypto;
mod tree;
pub use tree::{ Tree };
mod merkletree;
pub use merkletree::{ MerkleTree };
mod proof;
pub use proof::{ Proof, ProofBlock, Positioned };
mod merkledigest;
pub use merkledigest::{ MerkleDigest };
mod tree;
#[cfg(test)]
mod tests;

View File

@ -1,8 +1,13 @@
use crypto::digest::Digest;
/// Extends the standard `crypto::digest::Digest` to play nicely with our Merkle Tree
/// The sole purpose of this trait is to extend the standard
/// `crypto::digest::Digest` with a couple utility functions.
pub trait MerkleDigest {
/// Compute the hash the given byte array
fn hash_bytes(&mut self, bytes: &Vec<u8>) -> Vec<u8>;
/// Compute the hash of the concatenation of `left` and `right`
fn combine_hashes(&mut self, left: &Vec<u8>, right: &Vec<u8>) -> Vec<u8>;
}

View File

@ -3,17 +3,31 @@ use crypto::digest::Digest;
use tree::{ Tree };
use merkledigest::{ MerkleDigest };
/// The Merkle tree
pub use proof::{
Proof,
ProofBlock
};
/// 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> {
#[allow(dead_code)]
digest: D,
tree: Tree<T>,
/// The hashing function used by this Merkle tree
pub digest: D,
/// The inner binary tree
pub tree: Tree<T>,
/// The height of the tree
pub height: usize,
/// The number of leaf nodes in the tree
pub count: usize
}
impl <D, T> MerkleTree<D, T> where D: Digest, T: Into<Vec<u8>> + Clone {
/// Constructs a Merkle Tree from a vector of data blocks.
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 {
if values.is_empty() {
panic!("Cannot build a Merkle tree from an empty vector.");
@ -71,9 +85,26 @@ impl <D, T> MerkleTree<D, T> where D: Digest, T: Into<Vec<u8>> + Clone {
}
}
/// Returns the tree's root hash.
/// Returns the tree's root hash
pub fn root_hash(&self) -> &Vec<u8> {
self.tree.get_hash()
}
/// Generate an inclusion proof for the given value.
/// `None` is returned 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());
ProofBlock::new(&self.tree, &hash).map(|block|
Proof {
digest: digest,
root_hash: self.root_hash().clone(),
block: block,
value: value.clone()
}
)
}
}

132
src/proof.rs Normal file
View File

@ -0,0 +1,132 @@
use crypto::digest::Digest;
use merkledigest::{ MerkleDigest };
use tree::{ Tree };
/// An inclusion proof represent the fact that `value` is a member of a `MerkleTree`
/// with root hash `root_hash`, and hash function `digest`.
/// A proof is a linked-list of `ProofBlock`s.
/// TODO: Represent a proof as a vector of ProofBlock instead of a linked-list?
pub struct Proof<D, T> {
pub digest: D,
pub root_hash: Vec<u8>,
pub block: ProofBlock,
pub value: T
}
impl <D, T> Proof<D, T> where D: Digest + Clone, T: Into<Vec<u8>> + Clone {
pub fn validate(&self, root_hash: &Vec<u8>) -> bool {
if self.root_hash != *root_hash || self.block.node_hash != *root_hash {
return false
}
self.validate_block(&self.block, &mut self.digest.clone())
}
pub fn validate_block(&self, block: &ProofBlock, digest: &mut D) -> bool {
match block.sub_proof {
None =>
block.sibling_hash == Positioned::Nowhere,
Some(ref sub) =>
match block.sibling_hash {
Positioned::Nowhere =>
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)
}
Positioned::Right(ref hash) => {
let hashes_match = digest.combine_hashes(&sub.node_hash, &hash) == block.node_hash;
hashes_match && self.validate_block(sub, digest)
}
}
}
}
}
/// 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>>
}
impl ProofBlock {
/// 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
{
match *tree {
Tree::Leaf { ref hash, .. } =>
ProofBlock::new_leaf_proof(hash, needle),
Tree::Node { ref hash, ref left, ref right } =>
ProofBlock::new_tree_proof(hash, needle, left, right)
}
}
fn new_leaf_proof(hash: &Vec<u8>, needle: &Vec<u8>) -> Option<ProofBlock> {
if *hash == *needle {
Some(ProofBlock {
node_hash: hash.clone(),
sibling_hash: Positioned::Nowhere,
sub_proof: None
})
} else {
None
}
}
fn new_tree_proof<T>(hash: &Vec<u8>, needle: &Vec<u8>, left: &Tree<T>, right: &Tree<T>) -> Option<ProofBlock>
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)
})
.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)
})
})
.map(|(sub_proof, sibling_hash)| {
ProofBlock {
node_hash: hash.clone(),
sibling_hash: sibling_hash,
sub_proof: Some(Box::new(sub_proof))
}
})
}
}
/// Tags a value so that we know from in branch (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),
/// The value was found in the right branch
Right(T)
}

View File

@ -5,7 +5,7 @@ use crypto::sha3::Sha3;
use merkletree::{ MerkleTree };
use merkledigest::{ MerkleDigest };
use proof::{ Positioned };
#[test]
fn test_from_str_vec() {
@ -121,3 +121,77 @@ fn test_from_vec9() {
assert_eq!(tree.height, 4);
assert_eq!(tree.root_hash().as_slice(), root_hash.as_slice());
}
#[test]
fn test_valid_proof() {
let digest = Sha3::sha3_256();
let values: Vec<Vec<u8>> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9].iter().map(|x| vec![*x]).collect();
let tree = MerkleTree::from_vec(digest, values.clone());
let root_hash = tree.root_hash();
for value in values.iter() {
let proof = tree.gen_proof(value);
let is_valid = proof.map(|p| p.validate(&root_hash)).unwrap_or(false);
assert!(is_valid);
}
}
#[test]
fn test_valid_proof_str() {
let digest = Sha3::sha3_256();
let values = vec!["Hello", "my", "name", "is", "Rusty"];
let tree = MerkleTree::from_vec(digest, values.clone());
let root_hash = tree.root_hash();
let value = "Rusty";
let proof = tree.gen_proof(&value);
let is_valid = proof.map(|p| p.validate(&root_hash)).unwrap_or(false);
assert!(is_valid);
}
#[test]
fn test_wrong_proof() {
let digest1 = Sha3::sha3_256();
let values1 = vec![vec![1], vec![2], vec![3], vec![4]];
let tree1 = MerkleTree::from_vec(digest1, values1.clone());
let digest2 = Sha3::sha3_256();
let values2 = vec![vec![4], vec![5], vec![6], vec![7]];
let tree2 = MerkleTree::from_vec(digest2, values2.clone());
let root_hash = tree2.root_hash();
for value in values1.iter() {
let proof = tree1.gen_proof(value);
let is_valid = proof.map(|p| p.validate(root_hash)).unwrap_or(false);
assert_eq!(is_valid, false);
}
}
#[test]
fn test_mutate_proof_first_block() {
let digest = Sha3::sha3_256();
let values = vec![1, 2, 3, 4].iter().map(|x| vec![*x]).collect::<Vec<Vec<u8>>>();
let tree = MerkleTree::from_vec(digest, values.clone());
let root_hash = tree.root_hash();
let mut i = 0;
for value in values.iter() {
let mut proof = tree.gen_proof(value).unwrap();
if i % 2 == 0 {
proof.block.node_hash = vec![1,2,3];
} else {
proof.block.sibling_hash = Positioned::Left(vec![1,2,3]);
}
let is_valid = proof.validate(root_hash);
assert_eq!(is_valid, false);
i += 1;
}
}

View File

@ -2,6 +2,12 @@ use crypto::digest::Digest;
use merkledigest::{ MerkleDigest };
pub use proof::{
Proof,
ProofBlock,
Positioned
};
/// Binary Tree where leaves hold a stand-alone value.
pub enum Tree<T> {
Leaf {
@ -17,6 +23,7 @@ pub enum Tree<T> {
}
impl <T> Tree<T> where T: Into<Vec<u8>> + Clone {
/// Create a new tree
pub fn new(hash: Vec<u8>, value: T) -> Self {
Tree::Leaf {
@ -25,17 +32,19 @@ impl <T> Tree<T> where T: Into<Vec<u8>> + Clone {
}
}
/// Returns a hash from the tree.
pub fn get_hash(&self) -> &Vec<u8> {
match *self {
Tree::Leaf { ref hash, value: _ } => hash,
Tree::Node { ref hash, left: _, right: _ } => hash
}
}
/// Create a new leaf
pub fn make_leaf<D: Digest>(digest: &mut D, value: T) -> Tree<T> {
let hash = digest.hash_bytes(&value.clone().into());
Tree::new(hash, value)
}
/// Returns a hash from the tree.
pub fn get_hash(&self) -> &Vec<u8> {
match *self {
Tree::Leaf { ref hash, .. } => hash,
Tree::Node { ref hash, .. } => hash
}
}
}