1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
use crate::*;
use serde::{Deserialize, Serialize};
use thiserror::Error;

/// A Merkle tree that is created once but never modified.
///
/// This is useful for per-block data such as transaction lists.
pub struct OneshotMerkleTree {
    hash_list: Vec<Hash256>,
}

impl OneshotMerkleTree {
    pub const EMPTY_HASH: Hash256 = Hash256::zero();

    /// Creates a new OneshotMerkleTree from the given data.
    pub fn create(data: Vec<Hash256>) -> Self {
        OneshotMerkleTree { hash_list: data }
    }

    /// Creates a Merkle proof for a given data in the tree.
    ///
    /// Returns `None` if the data is not in the tree.
    ///
    /// Given a tree [[1, 2, 3], [4, 5], [6]],
    /// Merkle proof for 2 is [1, 5] and Merkle proof for 3 is [OnlyChild, 4].
    ///
    /// For `LeftChild` and `RightChild`, pair hash of the sibling node is given.
    /// For `OnlyChild`, only the instruction is given.
    pub fn create_merkle_proof(&self, key: Hash256) -> Option<MerkleProof> {
        if !self.hash_list.contains(&key) {
            return None;
        }
        let mut merkle_proof: MerkleProof = MerkleProof { proof: Vec::new() };
        let mut merkle_tree: Vec<Vec<Hash256>> = Self::merkle_tree(&self.hash_list);
        let mut target_hash: Hash256 = key;
        // Pop because the root is never included in the Merkle proof
        merkle_tree.pop();
        for level in merkle_tree {
            for pair in level.chunks(2) {
                if pair.contains(&target_hash) {
                    if pair.len() == 2 {
                        let is_right_node: bool = pair[0] == target_hash;
                        if is_right_node {
                            merkle_proof
                                .proof
                                .push(MerkleProofEntry::RightChild(pair[is_right_node as usize]))
                        } else {
                            merkle_proof
                                .proof
                                .push(MerkleProofEntry::LeftChild(pair[is_right_node as usize]))
                        }
                        target_hash = Hash256::aggregate(&pair[0], &pair[1]);
                    } else {
                        merkle_proof.proof.push(MerkleProofEntry::OnlyChild);
                        target_hash = Hash256::hash(pair[0]);
                    };
                }
            }
        }
        Some(merkle_proof)
    }

    /// Creates a merkle tree from the given hash list.
    ///
    /// Merkle tree is returned in the form of Vec of Vec of Hash256.
    ///
    /// Given a hash list [1, 2, 3], merkle tree will be built as below,
    ///
    /// ``` text
    ///     6
    ///   4   5
    ///  1 2  3
    /// ```
    ///
    /// which is represented as [[1, 2, 3], [4, 5], [6]].
    ///
    /// For nodes with siblings, their concatenated hash value is hashed up.
    /// For nodes without siblings, its hash value is hashed up.
    fn merkle_tree(hash_list: &[Hash256]) -> Vec<Vec<Hash256>> {
        let mut merkle_tree: Vec<Vec<Hash256>> = vec![hash_list.to_vec()];
        while !Self::is_fully_created(&merkle_tree) {
            let mut upper_level_hash_list: Vec<Hash256> = Vec::new();
            for pair in merkle_tree.last().unwrap().chunks(2) {
                if pair.len() == 2 {
                    upper_level_hash_list.push(Hash256::aggregate(&pair[0], &pair[1]));
                } else {
                    upper_level_hash_list.push(Hash256::hash(pair[0]));
                }
            }
            merkle_tree.push(upper_level_hash_list);
        }
        merkle_tree
    }

    /// Checks if a given merkle tree is fully created or is in progress.
    ///
    /// Is fully created if root exists and returns `true`.
    /// Is in progress if root does not exist and returns `false`.
    ///
    /// Note that root exists in the last element of a merkle tree with length 1.
    fn is_fully_created(merkle_tree: &[Vec<Hash256>]) -> bool {
        merkle_tree.last().unwrap().len() == 1
    }

    /// Returns the root of the tree.
    ///
    /// If the tree is empty, this returns a `Self::EMPTY_HASH`.
    ///
    /// Never panics on unwrap because merkle_tree is initialized with `vec![hash_list.to_vec()]` where `hash_list` is not empty.
    pub fn root(&self) -> Hash256 {
        if self.hash_list.is_empty() {
            Self::EMPTY_HASH
        } else {
            Self::merkle_tree(&self.hash_list)
                .last()
                .unwrap()
                .last()
                .unwrap()
                .to_owned()
        }
    }
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct MerkleProof {
    pub proof: Vec<MerkleProofEntry>,
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub enum MerkleProofEntry {
    LeftChild(Hash256),
    RightChild(Hash256),
    OnlyChild,
}

#[derive(Error, Debug, Serialize, Deserialize, Clone)]
pub enum MerkleProofError {
    /// When the proof is malformed.
    #[error("malformed proof: {0}")]
    MalformedProof(String),
    /// When the root doesn't match
    #[error("unmatched string: expected {0} but found {1}")]
    UnmatchedRoot(String, String),
}

impl MerkleProof {
    /// Verifies whether the given data is in the block.
    pub fn verify(&self, root: Hash256, data: &[u8]) -> Result<(), MerkleProofError> {
        let mut calculated_root: Hash256 = Hash256::hash(data);
        for node in &self.proof {
            calculated_root = match node {
                MerkleProofEntry::LeftChild(pair_hash) => {
                    Hash256::aggregate(pair_hash, &calculated_root)
                }
                MerkleProofEntry::RightChild(pair_hash) => {
                    Hash256::aggregate(&calculated_root, pair_hash)
                }
                MerkleProofEntry::OnlyChild => Hash256::hash(calculated_root),
            };
        }
        if root == calculated_root {
            Ok(())
        } else {
            Err(MerkleProofError::UnmatchedRoot(
                root.to_string(),
                calculated_root.to_string(),
            ))
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    /// Returns a hash list with `number` elements
    ///
    /// Hash list consists of hashes of 8-bit unsigned integer from 0 to `number - 1`.
    fn create_hash_list(number: u8) -> Vec<Hash256> {
        let mut hash_list: Vec<Hash256> = Vec::new();
        for n in 0..number {
            hash_list.push(Hash256::hash([n]));
        }
        hash_list
    }

    #[test]
    /// Test if `None` is returned for merkle proof of data not in the tree.
    fn create_merkle_proof_for_data_not_in_the_tree() {
        let hash_list: Vec<Hash256> = create_hash_list(16);
        let merkle_tree: OneshotMerkleTree = OneshotMerkleTree::create(hash_list);
        let key: Hash256 = Hash256::hash([42]);

        assert!(OneshotMerkleTree::create_merkle_proof(&merkle_tree, key).is_none());
    }

    #[test]
    /// Test if `OneshotMerkleTree::EMPTY_HASH` is returned for root hash of empty tree
    fn root_of_empty_tree() {
        let merkle_tree: OneshotMerkleTree = OneshotMerkleTree::create(Vec::new());

        assert_eq!(
            OneshotMerkleTree::root(&merkle_tree),
            OneshotMerkleTree::EMPTY_HASH
        );
    }

    #[test]
    /// Test if verification fails for data not in the tree.
    fn verification_failure() {
        let hash_list: Vec<Hash256> = create_hash_list(16);
        let merkle_tree: OneshotMerkleTree = OneshotMerkleTree::create(hash_list);
        let key: Hash256 = Hash256::hash([2]);
        let merkle_proof: Option<MerkleProof> =
            OneshotMerkleTree::create_merkle_proof(&merkle_tree, key);
        let root_hash: Hash256 = OneshotMerkleTree::root(&merkle_tree);

        assert!(merkle_proof.is_some());
        assert!(root_hash != OneshotMerkleTree::EMPTY_HASH);
        assert!(MerkleProof::verify(&merkle_proof.unwrap(), root_hash, &[42]).is_err());
    }

    #[test]
    /// Test if Merkle proof generation and verification work well with a tree with an even number of leaves that is 2^n.
    fn even_number_of_leaves_pow_of_two() {
        let hash_list: Vec<Hash256> = create_hash_list(16);
        let merkle_tree: OneshotMerkleTree = OneshotMerkleTree::create(hash_list);
        let data: [u8; 1] = [2];
        let key: Hash256 = Hash256::hash(data);
        let merkle_proof: Option<MerkleProof> =
            OneshotMerkleTree::create_merkle_proof(&merkle_tree, key);
        let root_hash: Hash256 = OneshotMerkleTree::root(&merkle_tree);

        assert!(merkle_proof.is_some());
        assert!(root_hash != OneshotMerkleTree::EMPTY_HASH);
        assert!(MerkleProof::verify(&merkle_proof.unwrap(), root_hash, &data).is_ok());
    }

    #[test]
    /// Test if Merkle proof generation and verification work well with a tree with an even number of leaves that is not 2^n.
    fn even_number_of_leaves_not_pow_of_two() {
        let hash_list: Vec<Hash256> = create_hash_list(10);
        let merkle_tree: OneshotMerkleTree = OneshotMerkleTree::create(hash_list);
        let key: Hash256 = Hash256::hash([9]);
        let merkle_proof: Option<MerkleProof> =
            OneshotMerkleTree::create_merkle_proof(&merkle_tree, key);
        let root_hash: Hash256 = OneshotMerkleTree::root(&merkle_tree);

        assert!(merkle_proof.is_some());
        assert!(root_hash != OneshotMerkleTree::EMPTY_HASH);
        assert!(MerkleProof::verify(&merkle_proof.unwrap(), root_hash, &[9]).is_ok());
    }

    #[test]
    /// Test if Merkle proof generation and verification work well with an odd number of leaves.
    fn odd_number_of_leaves() {
        let hash_list: Vec<Hash256> = create_hash_list(11);
        let merkle_tree: OneshotMerkleTree = OneshotMerkleTree::create(hash_list);
        let key: Hash256 = Hash256::hash([10]);
        let merkle_proof: Option<MerkleProof> =
            OneshotMerkleTree::create_merkle_proof(&merkle_tree, key);
        let root_hash: Hash256 = OneshotMerkleTree::root(&merkle_tree);

        assert!(merkle_proof.is_some());
        assert!(root_hash != OneshotMerkleTree::EMPTY_HASH);
        assert!(MerkleProof::verify(&merkle_proof.unwrap(), root_hash, &[10]).is_ok());
    }
}