Skip to content

Commit 8f69409

Browse files
committed
merkle tree module created
remove comments remove test comments
1 parent bfe2a88 commit 8f69409

File tree

9 files changed

+483
-447
lines changed

9 files changed

+483
-447
lines changed

mithril-stm/src/eligibility_check.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,6 @@ mod tests {
126126
q < phi
127127
}
128128

129-
// ---------------------------------------------------------------------
130-
// Property test: `test_precision_approximation`
131-
// Property test: `early_break_taylor`
132-
// ---------------------------------------------------------------------
133129
proptest! {
134130
#![proptest_config(ProptestConfig::with_cases(50))]
135131

mithril-stm/src/error.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Crate specific errors
22
3-
use crate::merkle_tree::{BatchPath, Path};
3+
use crate::merkle_tree::basic::Path;
4+
use crate::merkle_tree::batch_compatible::BatchPath;
45
use blake2::digest::{Digest, FixedOutput};
56
use {
67
crate::multi_sig::{Signature, VerificationKey, VerificationKeyPoP},

mithril-stm/src/key_reg.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
//! Key registration functionality.
22
use super::stm::Stake;
33
use crate::error::RegisterError;
4-
use crate::merkle_tree::{MTLeaf, MerkleTree};
4+
use crate::merkle_tree::leaf::MTLeaf;
5+
use crate::merkle_tree::tree::MerkleTree;
56
use crate::multi_sig::{VerificationKey, VerificationKeyPoP};
67
use blake2::digest::{Digest, FixedOutput};
78
use std::collections::hash_map::Entry;
@@ -88,9 +89,6 @@ mod tests {
8889
use rand_chacha::ChaCha20Rng;
8990
use rand_core::SeedableRng;
9091

91-
// ---------------------------------------------------------------------
92-
// Property test: `test_keyreg`
93-
// ---------------------------------------------------------------------
9492
proptest! {
9593
#[test]
9694
fn test_keyreg(stake in vec(1..1u64 << 60, 2..=10),
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
use crate::error::MerkleTreeError;
2+
use crate::merkle_tree::leaf::MTLeaf;
3+
use blake2::digest::{Digest, FixedOutput};
4+
use serde::{Deserialize, Serialize};
5+
use std::marker::PhantomData;
6+
7+
/// Path of hashes from root to leaf in a Merkle Tree.
8+
/// Contains all hashes on the path, and the index of the leaf.
9+
/// Used to verify that signatures come from eligible signers.
10+
#[derive(Default, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
11+
pub struct Path<D: Digest> {
12+
pub(crate) values: Vec<Vec<u8>>,
13+
pub(crate) index: usize,
14+
hasher: PhantomData<D>,
15+
}
16+
17+
impl<D: Digest + FixedOutput> Path<D> {
18+
pub(crate) fn new(values: Vec<Vec<u8>>, index: usize) -> Self {
19+
Self {
20+
values,
21+
index,
22+
hasher: Default::default(),
23+
}
24+
}
25+
26+
/// Convert to bytes
27+
/// # Layout
28+
/// * Index representing the position in the Merkle Tree
29+
/// * Size of the Path
30+
/// * Path of hashes
31+
pub fn to_bytes(&self) -> Vec<u8> {
32+
let mut output = Vec::new();
33+
output.extend_from_slice(&u64::try_from(self.index).unwrap().to_be_bytes());
34+
output.extend_from_slice(&u64::try_from(self.values.len()).unwrap().to_be_bytes());
35+
for value in &self.values {
36+
output.extend_from_slice(value)
37+
}
38+
39+
output
40+
}
41+
42+
/// Extract a `Path` from a byte slice.
43+
/// # Error
44+
/// This function fails if the bytes cannot retrieve path.
45+
pub fn from_bytes(bytes: &[u8]) -> Result<Path<D>, MerkleTreeError<D>> {
46+
let mut u64_bytes = [0u8; 8];
47+
u64_bytes.copy_from_slice(&bytes[..8]);
48+
let index = usize::try_from(u64::from_be_bytes(u64_bytes))
49+
.map_err(|_| MerkleTreeError::SerializationError)?;
50+
u64_bytes.copy_from_slice(&bytes[8..16]);
51+
let len = usize::try_from(u64::from_be_bytes(u64_bytes))
52+
.map_err(|_| MerkleTreeError::SerializationError)?;
53+
let mut values = Vec::with_capacity(len);
54+
for i in 0..len {
55+
values.push(
56+
bytes[16 + i * <D as Digest>::output_size()
57+
..16 + (i + 1) * <D as Digest>::output_size()]
58+
.to_vec(),
59+
);
60+
}
61+
62+
Ok(Path {
63+
values,
64+
index,
65+
hasher: PhantomData,
66+
})
67+
}
68+
}
69+
70+
/// `MerkleTree` commitment.
71+
/// This structure differs from `MerkleTree` in that it does not contain all elements, which are not always necessary.
72+
/// Instead, it only contains the root of the tree.
73+
#[derive(Debug, Clone, Serialize, Deserialize)]
74+
pub struct MerkleTreeCommitment<D: Digest> {
75+
/// Root of the merkle commitment.
76+
pub root: Vec<u8>,
77+
hasher: PhantomData<D>,
78+
}
79+
80+
impl<D: Digest + FixedOutput> MerkleTreeCommitment<D> {
81+
pub(crate) fn new(root: Vec<u8>) -> Self {
82+
MerkleTreeCommitment {
83+
root,
84+
hasher: PhantomData,
85+
}
86+
}
87+
88+
/// Check an inclusion proof that `val` is part of the tree by traveling the whole path until the root.
89+
/// # Error
90+
/// If the merkle tree path is invalid, then the function fails.
91+
pub fn check(&self, val: &MTLeaf, proof: &Path<D>) -> Result<(), MerkleTreeError<D>> where D: FixedOutput + Clone, {
92+
let mut idx = proof.index;
93+
94+
let mut h = D::digest(val.to_bytes()).to_vec();
95+
for p in &proof.values {
96+
if (idx & 0b1) == 0 {
97+
h = D::new().chain_update(h).chain_update(p).finalize().to_vec();
98+
} else {
99+
h = D::new().chain_update(p).chain_update(h).finalize().to_vec();
100+
}
101+
idx >>= 1;
102+
}
103+
104+
if h == self.root {
105+
return Ok(());
106+
}
107+
Err(MerkleTreeError::PathInvalid(proof.clone()))
108+
}
109+
110+
/// Serializes the Merkle Tree commitment together with a message in a single vector of bytes.
111+
/// Outputs `msg || self` as a vector of bytes.
112+
pub fn concat_with_msg(&self, msg: &[u8]) -> Vec<u8>
113+
where
114+
D: Digest,
115+
{
116+
let mut msgp = msg.to_vec();
117+
let mut bytes = self.root.clone();
118+
msgp.append(&mut bytes);
119+
120+
msgp
121+
}
122+
}

0 commit comments

Comments
 (0)