merkle_tree.rs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. use {solana_hash::Hash, solana_sha256_hasher::hashv};
  2. // We need to discern between leaf and intermediate nodes to prevent trivial second
  3. // pre-image attacks.
  4. // https://flawed.net.nz/2018/02/21/attacking-merkle-trees-with-a-second-preimage-attack
  5. const LEAF_PREFIX: &[u8] = &[0];
  6. const INTERMEDIATE_PREFIX: &[u8] = &[1];
  7. macro_rules! hash_leaf {
  8. {$d:ident} => {
  9. hashv(&[LEAF_PREFIX, $d])
  10. }
  11. }
  12. macro_rules! hash_intermediate {
  13. {$l:ident, $r:ident} => {
  14. hashv(&[INTERMEDIATE_PREFIX, $l.as_ref(), $r.as_ref()])
  15. }
  16. }
  17. #[derive(Debug)]
  18. pub struct MerkleTree {
  19. leaf_count: usize,
  20. nodes: Vec<Hash>,
  21. }
  22. #[derive(Debug, PartialEq, Eq)]
  23. pub struct ProofEntry<'a>(&'a Hash, Option<&'a Hash>, Option<&'a Hash>);
  24. impl<'a> ProofEntry<'a> {
  25. pub fn new(
  26. target: &'a Hash,
  27. left_sibling: Option<&'a Hash>,
  28. right_sibling: Option<&'a Hash>,
  29. ) -> Self {
  30. assert!(left_sibling.is_none() ^ right_sibling.is_none());
  31. Self(target, left_sibling, right_sibling)
  32. }
  33. }
  34. #[derive(Debug, Default, PartialEq, Eq)]
  35. pub struct Proof<'a>(Vec<ProofEntry<'a>>);
  36. impl<'a> Proof<'a> {
  37. pub fn push(&mut self, entry: ProofEntry<'a>) {
  38. self.0.push(entry)
  39. }
  40. pub fn verify(&self, candidate: Hash) -> bool {
  41. let result = self.0.iter().try_fold(candidate, |candidate, pe| {
  42. let lsib = pe.1.unwrap_or(&candidate);
  43. let rsib = pe.2.unwrap_or(&candidate);
  44. let hash = hash_intermediate!(lsib, rsib);
  45. if hash == *pe.0 {
  46. Some(hash)
  47. } else {
  48. None
  49. }
  50. });
  51. result.is_some()
  52. }
  53. }
  54. impl MerkleTree {
  55. #[inline]
  56. fn next_level_len(level_len: usize) -> usize {
  57. if level_len == 1 {
  58. 0
  59. } else {
  60. level_len.div_ceil(2)
  61. }
  62. }
  63. fn calculate_vec_capacity(leaf_count: usize) -> usize {
  64. // the most nodes consuming case is when n-1 is full balanced binary tree
  65. // then n will cause the previous tree add a left only path to the root
  66. // this cause the total nodes number increased by tree height, we use this
  67. // condition as the max nodes consuming case.
  68. // n is current leaf nodes number
  69. // assuming n-1 is a full balanced binary tree, n-1 tree nodes number will be
  70. // 2(n-1) - 1, n tree height is closed to log2(n) + 1
  71. // so the max nodes number is 2(n-1) - 1 + log2(n) + 1, finally we can use
  72. // 2n + log2(n+1) as a safe capacity value.
  73. // test results:
  74. // 8192 leaf nodes(full balanced):
  75. // computed cap is 16398, actually using is 16383
  76. // 8193 leaf nodes:(full balanced plus 1 leaf):
  77. // computed cap is 16400, actually using is 16398
  78. // about performance: current used fast_math log2 code is constant algo time
  79. if leaf_count > 0 {
  80. fast_math::log2_raw(leaf_count as f32) as usize + 2 * leaf_count + 1
  81. } else {
  82. 0
  83. }
  84. }
  85. pub fn new<T: AsRef<[u8]>>(items: &[T]) -> Self {
  86. let cap = MerkleTree::calculate_vec_capacity(items.len());
  87. let mut mt = MerkleTree {
  88. leaf_count: items.len(),
  89. nodes: Vec::with_capacity(cap),
  90. };
  91. for item in items {
  92. let item = item.as_ref();
  93. let hash = hash_leaf!(item);
  94. mt.nodes.push(hash);
  95. }
  96. let mut level_len = MerkleTree::next_level_len(items.len());
  97. let mut level_start = items.len();
  98. let mut prev_level_len = items.len();
  99. let mut prev_level_start = 0;
  100. while level_len > 0 {
  101. for i in 0..level_len {
  102. let prev_level_idx = 2 * i;
  103. let lsib = &mt.nodes[prev_level_start + prev_level_idx];
  104. let rsib = if prev_level_idx + 1 < prev_level_len {
  105. &mt.nodes[prev_level_start + prev_level_idx + 1]
  106. } else {
  107. // Duplicate last entry if the level length is odd
  108. &mt.nodes[prev_level_start + prev_level_idx]
  109. };
  110. let hash = hash_intermediate!(lsib, rsib);
  111. mt.nodes.push(hash);
  112. }
  113. prev_level_start = level_start;
  114. prev_level_len = level_len;
  115. level_start += level_len;
  116. level_len = MerkleTree::next_level_len(level_len);
  117. }
  118. mt
  119. }
  120. pub fn get_root(&self) -> Option<&Hash> {
  121. self.nodes.iter().last()
  122. }
  123. pub fn find_path(&self, index: usize) -> Option<Proof<'_>> {
  124. if index >= self.leaf_count {
  125. return None;
  126. }
  127. let mut level_len = self.leaf_count;
  128. let mut level_start = 0;
  129. let mut path = Proof::default();
  130. let mut node_index = index;
  131. let mut lsib = None;
  132. let mut rsib = None;
  133. while level_len > 0 {
  134. let level = &self.nodes[level_start..(level_start + level_len)];
  135. let target = &level[node_index];
  136. if lsib.is_some() || rsib.is_some() {
  137. path.push(ProofEntry::new(target, lsib, rsib));
  138. }
  139. if node_index % 2 == 0 {
  140. lsib = None;
  141. rsib = if node_index + 1 < level.len() {
  142. Some(&level[node_index + 1])
  143. } else {
  144. Some(&level[node_index])
  145. };
  146. } else {
  147. lsib = Some(&level[node_index - 1]);
  148. rsib = None;
  149. }
  150. node_index /= 2;
  151. level_start += level_len;
  152. level_len = MerkleTree::next_level_len(level_len);
  153. }
  154. Some(path)
  155. }
  156. }
  157. #[cfg(test)]
  158. mod tests {
  159. use {super::*, solana_hash::HASH_BYTES};
  160. const TEST: &[&[u8]] = &[
  161. b"my", b"very", b"eager", b"mother", b"just", b"served", b"us", b"nine", b"pizzas",
  162. b"make", b"prime",
  163. ];
  164. const BAD: &[&[u8]] = &[b"bad", b"missing", b"false"];
  165. #[test]
  166. fn test_tree_from_empty() {
  167. let mt = MerkleTree::new::<[u8; 0]>(&[]);
  168. assert_eq!(mt.get_root(), None);
  169. }
  170. #[test]
  171. fn test_tree_from_one() {
  172. let input = b"test";
  173. let mt = MerkleTree::new(&[input]);
  174. let expected = hash_leaf!(input);
  175. assert_eq!(mt.get_root(), Some(&expected));
  176. }
  177. #[test]
  178. fn test_tree_from_many() {
  179. let mt = MerkleTree::new(TEST);
  180. // This golden hash will need to be updated whenever the contents of `TEST` change in any
  181. // way, including addition, removal and reordering or any of the tree calculation algo
  182. // changes
  183. let bytes = hex::decode("b40c847546fdceea166f927fc46c5ca33c3638236a36275c1346d3dffb84e1bc")
  184. .unwrap();
  185. let expected = <[u8; HASH_BYTES]>::try_from(bytes)
  186. .map(Hash::new_from_array)
  187. .unwrap();
  188. assert_eq!(mt.get_root(), Some(&expected));
  189. }
  190. #[test]
  191. fn test_path_creation() {
  192. let mt = MerkleTree::new(TEST);
  193. for (i, _s) in TEST.iter().enumerate() {
  194. let _path = mt.find_path(i).unwrap();
  195. }
  196. }
  197. #[test]
  198. fn test_path_creation_bad_index() {
  199. let mt = MerkleTree::new(TEST);
  200. assert_eq!(mt.find_path(TEST.len()), None);
  201. }
  202. #[test]
  203. fn test_path_verify_good() {
  204. let mt = MerkleTree::new(TEST);
  205. for (i, s) in TEST.iter().enumerate() {
  206. let hash = hash_leaf!(s);
  207. let path = mt.find_path(i).unwrap();
  208. assert!(path.verify(hash));
  209. }
  210. }
  211. #[test]
  212. fn test_path_verify_bad() {
  213. let mt = MerkleTree::new(TEST);
  214. for (i, s) in BAD.iter().enumerate() {
  215. let hash = hash_leaf!(s);
  216. let path = mt.find_path(i).unwrap();
  217. assert!(!path.verify(hash));
  218. }
  219. }
  220. #[test]
  221. fn test_proof_entry_instantiation_lsib_set() {
  222. ProofEntry::new(&Hash::default(), Some(&Hash::default()), None);
  223. }
  224. #[test]
  225. fn test_proof_entry_instantiation_rsib_set() {
  226. ProofEntry::new(&Hash::default(), None, Some(&Hash::default()));
  227. }
  228. #[test]
  229. fn test_nodes_capacity_compute() {
  230. let iteration_count = |mut leaf_count: usize| -> usize {
  231. let mut capacity = 0;
  232. while leaf_count > 0 {
  233. capacity += leaf_count;
  234. leaf_count = MerkleTree::next_level_len(leaf_count);
  235. }
  236. capacity
  237. };
  238. // test max 64k leaf nodes compute
  239. for leaf_count in 0..65536 {
  240. let math_count = MerkleTree::calculate_vec_capacity(leaf_count);
  241. let iter_count = iteration_count(leaf_count);
  242. assert!(math_count >= iter_count);
  243. }
  244. }
  245. #[test]
  246. #[should_panic]
  247. fn test_proof_entry_instantiation_both_clear() {
  248. ProofEntry::new(&Hash::default(), None, None);
  249. }
  250. #[test]
  251. #[should_panic]
  252. fn test_proof_entry_instantiation_both_set() {
  253. ProofEntry::new(
  254. &Hash::default(),
  255. Some(&Hash::default()),
  256. Some(&Hash::default()),
  257. );
  258. }
  259. }