mirror of
https://github.com/mii443/merkle.rs.git
synced 2025-08-22 16:05:30 +00:00
Rustfmt
This commit is contained in:
@ -1,15 +1,14 @@
|
||||
|
||||
#![feature(test)]
|
||||
#![feature(rand)]
|
||||
|
||||
extern crate test;
|
||||
extern crate rand;
|
||||
extern crate test;
|
||||
|
||||
extern crate merkle;
|
||||
extern crate ring;
|
||||
|
||||
use test::Bencher;
|
||||
use rand::Rng;
|
||||
use test::Bencher;
|
||||
|
||||
use ring::digest::{Algorithm, SHA512};
|
||||
|
||||
@ -30,9 +29,11 @@ fn bench_small_str_proof_gen(b: &mut Bencher) {
|
||||
let values = vec!["one", "two", "three", "four"];
|
||||
let tree = MerkleTree::from_vec(digest, values.clone());
|
||||
|
||||
b.iter(|| for value in &values {
|
||||
let proof = tree.gen_proof(value);
|
||||
test::black_box(proof);
|
||||
b.iter(|| {
|
||||
for value in &values {
|
||||
let proof = tree.gen_proof(value);
|
||||
test::black_box(proof);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -45,8 +46,10 @@ fn bench_small_str_proof_check(b: &mut Bencher) {
|
||||
.map(|v| tree.gen_proof(v).unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
b.iter(|| for proof in &proofs {
|
||||
test::black_box(proof.validate(tree.root_hash()));
|
||||
b.iter(|| {
|
||||
for proof in &proofs {
|
||||
test::black_box(proof.validate(tree.root_hash()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -76,9 +79,11 @@ fn bench_big_rnd_proof_gen(b: &mut Bencher) {
|
||||
|
||||
let tree = MerkleTree::from_vec(digest, values.clone());
|
||||
|
||||
b.iter(|| for value in &values {
|
||||
let proof = tree.gen_proof(value.clone());
|
||||
test::black_box(proof);
|
||||
b.iter(|| {
|
||||
for value in &values {
|
||||
let proof = tree.gen_proof(value.clone());
|
||||
test::black_box(proof);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -97,8 +102,10 @@ fn bench_big_rnd_proof_check(b: &mut Bencher) {
|
||||
.map(|v| tree.gen_proof(v).unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
b.iter(|| for proof in &proofs {
|
||||
test::black_box(proof.validate(tree.root_hash()));
|
||||
b.iter(|| {
|
||||
for proof in &proofs {
|
||||
test::black_box(proof.validate(tree.root_hash()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -113,7 +120,9 @@ fn bench_big_rnd_iter(b: &mut Bencher) {
|
||||
|
||||
let tree = MerkleTree::from_vec(digest, values.clone());
|
||||
|
||||
b.iter(|| for value in &tree {
|
||||
test::black_box(value);
|
||||
b.iter(|| {
|
||||
for value in &tree {
|
||||
test::black_box(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
|
||||
use ring::digest::{Algorithm, Context, Digest, digest};
|
||||
use ring::digest::{digest, Algorithm, Context, Digest};
|
||||
|
||||
/// The type of values stored in a `MerkleTree` must implement
|
||||
/// this trait, in order for them to be able to be fed
|
||||
|
12
src/lib.rs
12
src/lib.rs
@ -1,10 +1,6 @@
|
||||
#![deny(
|
||||
missing_docs, unused_qualifications,
|
||||
missing_debug_implementations, missing_copy_implementations,
|
||||
trivial_casts, trivial_numeric_casts,
|
||||
unsafe_code, unstable_features,
|
||||
unused_import_braces
|
||||
)]
|
||||
#![deny(missing_docs, unused_qualifications, missing_debug_implementations,
|
||||
missing_copy_implementations, trivial_casts, trivial_numeric_casts, unsafe_code,
|
||||
unstable_features, unused_import_braces)]
|
||||
|
||||
//! *merkle* implements a Merkle Tree in Rust.
|
||||
|
||||
@ -29,7 +25,7 @@ mod hashutils;
|
||||
pub use hashutils::Hashable;
|
||||
|
||||
mod tree;
|
||||
pub use tree::{LeavesIterator, LeavesIntoIterator};
|
||||
pub use tree::{LeavesIntoIterator, LeavesIterator};
|
||||
|
||||
#[cfg(feature = "serialization-protobuf")]
|
||||
#[allow(unused_qualifications)]
|
||||
|
@ -1,13 +1,12 @@
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::cmp::Ordering;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use ring::digest::Algorithm;
|
||||
|
||||
use tree::{Tree, LeavesIterator, LeavesIntoIterator};
|
||||
use hashutils::{Hashable, HashUtils};
|
||||
use hashutils::{HashUtils, Hashable};
|
||||
use tree::{LeavesIntoIterator, LeavesIterator, Tree};
|
||||
|
||||
use proof::{Proof, Lemma};
|
||||
use proof::{Lemma, Proof};
|
||||
|
||||
/// A Merkle tree is a binary tree, with values of type `T` at the leafs,
|
||||
/// and where every internal node holds the hash of the concatenation of the hashes of its children nodes.
|
||||
@ -29,8 +28,8 @@ pub struct MerkleTree<T> {
|
||||
impl<T: PartialEq> PartialEq for MerkleTree<T> {
|
||||
#[allow(trivial_casts)]
|
||||
fn eq(&self, other: &MerkleTree<T>) -> bool {
|
||||
self.root == other.root && self.height == other.height && self.count == other.count &&
|
||||
(self.algorithm as *const Algorithm) == (other.algorithm as *const Algorithm)
|
||||
self.root == other.root && self.height == other.height && self.count == other.count
|
||||
&& (self.algorithm as *const Algorithm) == (other.algorithm as *const Algorithm)
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,10 +47,7 @@ impl<T: Ord> Ord for MerkleTree<T> {
|
||||
self.height
|
||||
.cmp(&other.height)
|
||||
.then(self.count.cmp(&other.count))
|
||||
.then((self.algorithm as *const Algorithm).cmp(
|
||||
&(other.algorithm as
|
||||
*const Algorithm),
|
||||
))
|
||||
.then((self.algorithm as *const Algorithm).cmp(&(other.algorithm as *const Algorithm)))
|
||||
.then_with(|| self.root.cmp(&other.root))
|
||||
}
|
||||
}
|
||||
@ -73,7 +69,6 @@ impl<T> MerkleTree<T> {
|
||||
where
|
||||
T: Hashable,
|
||||
{
|
||||
|
||||
if values.is_empty() {
|
||||
return MerkleTree {
|
||||
algorithm: algorithm,
|
||||
@ -156,13 +151,11 @@ impl<T> MerkleTree<T> {
|
||||
where
|
||||
T: Hashable,
|
||||
{
|
||||
|
||||
let root_hash = self.root_hash().clone();
|
||||
let leaf_hash = self.algorithm.hash_leaf(&value);
|
||||
|
||||
Lemma::new(&self.root, leaf_hash.as_ref()).map(|lemma| {
|
||||
Proof::new(self.algorithm, root_hash, lemma, value)
|
||||
})
|
||||
Lemma::new(&self.root, leaf_hash.as_ref())
|
||||
.map(|lemma| Proof::new(self.algorithm, root_hash, lemma, value))
|
||||
}
|
||||
|
||||
/// Creates an `Iterator` over the values contained in this Merkle tree.
|
||||
|
54
src/proof.rs
54
src/proof.rs
@ -1,11 +1,10 @@
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::cmp::Ordering;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use ring::digest::Algorithm;
|
||||
|
||||
use tree::Tree;
|
||||
use hashutils::HashUtils;
|
||||
use tree::Tree;
|
||||
|
||||
/// An inclusion proof represent the fact that a `value` is a member
|
||||
/// of a `MerkleTree` with root hash `root_hash`, and hash function `algorithm`.
|
||||
@ -29,11 +28,13 @@ pub struct Proof<T> {
|
||||
#[cfg(feature = "serialization-serde")]
|
||||
mod algorithm_serde {
|
||||
use ring::digest::{self, Algorithm};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde::de::Error;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
pub fn serialize<S: Serializer>(algorithm: &&'static Algorithm, se: S)
|
||||
-> Result<S::Ok, S::Error> {
|
||||
pub fn serialize<S: Serializer>(
|
||||
algorithm: &&'static Algorithm,
|
||||
se: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
// The `Debug` implementation of `Algorithm` prints its ID.
|
||||
format!("{:?}", algorithm).serialize(se)
|
||||
}
|
||||
@ -104,32 +105,27 @@ impl<T> Proof<T> {
|
||||
|
||||
fn validate_lemma(&self, lemma: &Lemma) -> bool {
|
||||
match lemma.sub_lemma {
|
||||
|
||||
None => lemma.sibling_hash.is_none(),
|
||||
|
||||
Some(ref sub) => {
|
||||
match lemma.sibling_hash {
|
||||
None => false,
|
||||
|
||||
Some(Positioned::Left(ref hash)) => {
|
||||
let combined = self.algorithm.hash_nodes(hash, &sub.node_hash);
|
||||
let hashes_match = combined.as_ref() == lemma.node_hash.as_slice();
|
||||
hashes_match && self.validate_lemma(sub)
|
||||
}
|
||||
|
||||
Some(Positioned::Right(ref hash)) => {
|
||||
let combined = self.algorithm.hash_nodes(&sub.node_hash, hash);
|
||||
let hashes_match = combined.as_ref() == lemma.node_hash.as_slice();
|
||||
hashes_match && self.validate_lemma(sub)
|
||||
}
|
||||
Some(ref sub) => match lemma.sibling_hash {
|
||||
None => false,
|
||||
|
||||
Some(Positioned::Left(ref hash)) => {
|
||||
let combined = self.algorithm.hash_nodes(hash, &sub.node_hash);
|
||||
let hashes_match = combined.as_ref() == lemma.node_hash.as_slice();
|
||||
hashes_match && self.validate_lemma(sub)
|
||||
}
|
||||
}
|
||||
|
||||
Some(Positioned::Right(ref hash)) => {
|
||||
let combined = self.algorithm.hash_nodes(&sub.node_hash, hash);
|
||||
let hashes_match = combined.as_ref() == lemma.node_hash.as_slice();
|
||||
hashes_match && self.validate_lemma(sub)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A `Lemma` holds the hash of a node, the hash of its sibling node,
|
||||
/// and a sub lemma, whose `node_hash`, when combined with this `sibling_hash`
|
||||
/// must be equal to this `node_hash`.
|
||||
@ -189,12 +185,10 @@ impl Lemma {
|
||||
(lemma, sub_lemma)
|
||||
})
|
||||
})
|
||||
.map(|(sub_lemma, sibling_hash)| {
|
||||
Lemma {
|
||||
node_hash: hash.into(),
|
||||
sibling_hash: sibling_hash,
|
||||
sub_lemma: Some(Box::new(sub_lemma)),
|
||||
}
|
||||
.map(|(sub_lemma, sibling_hash)| Lemma {
|
||||
node_hash: hash.into(),
|
||||
sibling_hash: sibling_hash,
|
||||
sub_lemma: Some(Box::new(sub_lemma)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
|
||||
mod proof;
|
||||
|
||||
use ring::digest::Algorithm;
|
||||
|
||||
use proof::{Proof, Lemma, Positioned};
|
||||
pub use self::proof::{ProofProto, LemmaProto};
|
||||
pub use self::proof::{LemmaProto, ProofProto};
|
||||
use proof::{Lemma, Positioned, Proof};
|
||||
|
||||
use protobuf::Message;
|
||||
use protobuf::error::ProtobufResult;
|
||||
@ -16,7 +15,6 @@ impl<T> Proof<T> {
|
||||
where
|
||||
T: From<Vec<u8>>,
|
||||
{
|
||||
|
||||
proto.into_proof(algorithm)
|
||||
}
|
||||
|
||||
@ -25,7 +23,6 @@ impl<T> Proof<T> {
|
||||
where
|
||||
T: Into<Vec<u8>>,
|
||||
{
|
||||
|
||||
ProofProto::from_proof(self)
|
||||
}
|
||||
|
||||
@ -37,7 +34,6 @@ impl<T> Proof<T> {
|
||||
where
|
||||
T: From<Vec<u8>>,
|
||||
{
|
||||
|
||||
parse_from_bytes::<ProofProto>(bytes).map(|proto| proto.into_proof(algorithm))
|
||||
}
|
||||
|
||||
@ -46,7 +42,6 @@ impl<T> Proof<T> {
|
||||
where
|
||||
T: Into<Vec<u8>>,
|
||||
{
|
||||
|
||||
self.into_protobuf().write_to_bytes()
|
||||
}
|
||||
}
|
||||
@ -56,7 +51,6 @@ impl ProofProto {
|
||||
where
|
||||
T: Into<Vec<u8>>,
|
||||
{
|
||||
|
||||
let mut proto = Self::new();
|
||||
|
||||
match proof {
|
||||
@ -79,7 +73,6 @@ impl ProofProto {
|
||||
where
|
||||
T: From<Vec<u8>>,
|
||||
{
|
||||
|
||||
if self.root_hash.is_empty() || !self.has_lemma() {
|
||||
return None;
|
||||
}
|
||||
@ -143,12 +136,10 @@ impl LemmaProto {
|
||||
// If a `sub_lemma` is present is the Protobuf,
|
||||
// then we expect it to unserialize to a valid `Lemma`,
|
||||
// otherwise we return `None`
|
||||
self.take_sub_lemma().into_lemma().map(|sub_lemma| {
|
||||
Lemma {
|
||||
node_hash: node_hash,
|
||||
sibling_hash: sibling_hash,
|
||||
sub_lemma: Some(Box::new(sub_lemma)),
|
||||
}
|
||||
self.take_sub_lemma().into_lemma().map(|sub_lemma| Lemma {
|
||||
node_hash: node_hash,
|
||||
sibling_hash: sibling_hash,
|
||||
sub_lemma: Some(Box::new(sub_lemma)),
|
||||
})
|
||||
} else {
|
||||
// We might very well not have a sub_lemma,
|
||||
|
21
src/tests.rs
21
src/tests.rs
@ -1,10 +1,9 @@
|
||||
|
||||
#![cfg(test)]
|
||||
|
||||
use ring::digest::{Algorithm, Context, SHA512};
|
||||
|
||||
use hashutils::{HashUtils, Hashable};
|
||||
use merkletree::MerkleTree;
|
||||
use hashutils::{Hashable, HashUtils};
|
||||
use proof::Positioned;
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
@ -34,7 +33,6 @@ fn test_from_str_vec() {
|
||||
assert_eq!(tree.root_hash().as_slice(), root_hash.as_ref());
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_from_vec_empty() {
|
||||
let values: Vec<Vec<u8>> = vec![];
|
||||
@ -57,7 +55,6 @@ fn test_from_vec1() {
|
||||
assert_eq!(tree.root_hash().as_slice(), root_hash.as_ref());
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_from_vec3() {
|
||||
let values = vec![vec![1], vec![2], vec![3]];
|
||||
@ -228,7 +225,6 @@ fn test_tree_into_iter_loop_borrow() {
|
||||
assert_eq!(refs, collected);
|
||||
}
|
||||
|
||||
|
||||
pub struct PublicKey {
|
||||
zero_values: Vec<Vec<u8>>,
|
||||
one_values: Vec<Vec<u8>>,
|
||||
@ -243,13 +239,13 @@ impl PublicKey {
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
self.zero_values.iter().chain(self.one_values.iter()).fold(
|
||||
Vec::new(),
|
||||
|mut acc, i| {
|
||||
self.zero_values
|
||||
.iter()
|
||||
.chain(self.one_values.iter())
|
||||
.fold(Vec::new(), |mut acc, i| {
|
||||
acc.append(&mut i.clone());
|
||||
acc
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,5 +281,8 @@ fn test_serialize_proof_with_serde() {
|
||||
let tree = MerkleTree::from_vec(digest, values);
|
||||
let proof = tree.gen_proof(vec![5]);
|
||||
let serialized = serde_json::to_string(&proof).expect("serialize proof");
|
||||
assert_eq!(proof, serde_json::from_str(&serialized).expect("deserialize proof"));
|
||||
assert_eq!(
|
||||
proof,
|
||||
serde_json::from_str(&serialized).expect("deserialize proof")
|
||||
);
|
||||
}
|
||||
|
19
src/tree.rs
19
src/tree.rs
@ -1,16 +1,20 @@
|
||||
|
||||
use ring::digest::{Algorithm, Digest};
|
||||
|
||||
use hashutils::{Hashable, HashUtils};
|
||||
use hashutils::{HashUtils, Hashable};
|
||||
|
||||
pub use proof::{Proof, Lemma, Positioned};
|
||||
pub use proof::{Lemma, Positioned, Proof};
|
||||
|
||||
/// Binary Tree where leaves hold a stand-alone value.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum Tree<T> {
|
||||
Empty { hash: Vec<u8> },
|
||||
Empty {
|
||||
hash: Vec<u8>,
|
||||
},
|
||||
|
||||
Leaf { hash: Vec<u8>, value: T },
|
||||
Leaf {
|
||||
hash: Vec<u8>,
|
||||
value: T,
|
||||
},
|
||||
|
||||
Node {
|
||||
hash: Vec<u8>,
|
||||
@ -22,7 +26,9 @@ pub enum Tree<T> {
|
||||
impl<T> Tree<T> {
|
||||
/// Create an empty tree
|
||||
pub fn empty(hash: Digest) -> Self {
|
||||
Tree::Empty { hash: hash.as_ref().into() }
|
||||
Tree::Empty {
|
||||
hash: hash.as_ref().into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new tree
|
||||
@ -38,7 +44,6 @@ impl<T> Tree<T> {
|
||||
where
|
||||
T: Hashable,
|
||||
{
|
||||
|
||||
let hash = algo.hash_leaf(&value);
|
||||
Tree::new(hash, value)
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
#![cfg(feature = "serialization-protobuf")]
|
||||
|
||||
#![cfg(feature="serialization-protobuf")]
|
||||
|
||||
extern crate ring;
|
||||
extern crate merkle;
|
||||
extern crate protobuf;
|
||||
extern crate ring;
|
||||
|
||||
use ring::digest::{Algorithm, Context, SHA512};
|
||||
|
||||
use merkle::{MerkleTree, Proof, Hashable};
|
||||
use merkle::{Hashable, MerkleTree, Proof};
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
static digest: &'static Algorithm = &SHA512;
|
||||
|
Reference in New Issue
Block a user