merkle.move 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. module pyth::merkle {
  2. use std::vector;
  3. use pyth::keccak160;
  4. use pyth::keccak160::Hash;
  5. const LEAF_PREFIX: u8 = 0;
  6. const NODE_PREFIX: u8 = 1;
  7. fun hash_leaf(leaf: vector<u8>): Hash {
  8. let leaf_data: vector<u8> = vector[LEAF_PREFIX];
  9. vector::append(&mut leaf_data, leaf);
  10. keccak160::from_data(leaf_data)
  11. }
  12. fun hash_node(node1: &Hash, node2: &Hash): Hash {
  13. let node_data: vector<u8> = vector[NODE_PREFIX];
  14. if (keccak160::is_smaller(node2, node1)) {
  15. vector::append(&mut node_data, keccak160::get_data(node2));
  16. vector::append(&mut node_data, keccak160::get_data(node1));
  17. }
  18. else {
  19. vector::append(&mut node_data, keccak160::get_data(node1));
  20. vector::append(&mut node_data, keccak160::get_data(node2));
  21. };
  22. keccak160::from_data(node_data)
  23. }
  24. public fun check(path: &vector<Hash>, root: &Hash, leaf: vector<u8>): bool {
  25. let i = 0;
  26. let current = hash_leaf(leaf);
  27. while (i < vector::length(path)) {
  28. current = hash_node(&current, vector::borrow(path, i));
  29. i = i + 1;
  30. };
  31. &current == root
  32. }
  33. #[test]
  34. fun test_hash_leaf() {
  35. let data: vector<u8> = x"00640000000000000000000000000000000000000000000000000000000000000000000000000000640000000000000064000000640000000000000064000000000000006400000000000000640000000000000064";
  36. let hash = hash_leaf(data);
  37. let expected = keccak160::new(x"afc6a8ac466430f35895055f8a4c951785dad5ce");
  38. assert!(&hash == &expected, 1);
  39. }
  40. #[test]
  41. fun test_hash_node() {
  42. let h1 = keccak160::new(x"05c51b04b820c0f704e3fdd2e4fc1e70aff26dff");
  43. let h2 = keccak160::new(x"1e108841c8d21c7a5c4860c8c3499c918ea9e0ac");
  44. let hash = hash_node(&h1, &h2);
  45. let expected = keccak160::new(x"2d0e4fde68184c7ce8af426a0865bd41ef84dfa4");
  46. assert!(&hash == &expected, 1);
  47. }
  48. #[test_only]
  49. fun setup_tree(): (Hash, Hash, Hash, Hash, Hash, Hash, Hash) {
  50. // h1 h2 h3 h4
  51. // \ / \ /
  52. // h5 h6
  53. // \ /
  54. // h7
  55. let h1 = hash_leaf(x"adad11");
  56. let h2 = hash_leaf(x"adad12");
  57. let h3 = hash_leaf(x"adad13");
  58. let h4 = hash_leaf(x"adad14");
  59. let h5 = hash_node(&h1, &h2);
  60. let h6 = hash_node(&h3, &h4);
  61. let h7 = hash_node(&h5, &h6);
  62. (h1, h2, h3, h4, h5, h6, h7)
  63. }
  64. #[test]
  65. fun test_check_valid_proofs() {
  66. let (h1, h2, h3, h4, h5, h6, h7) = setup_tree();
  67. assert!(check(&vector[h2, h6], &h7, x"adad11"), 1);
  68. assert!(check(&vector[h3, h5], &h7, x"adad14"), 1);
  69. assert!(!check(&vector[h1, h4], &h7, x"adad14"), 1);
  70. }
  71. #[test]
  72. fun test_check_valid_proofs_subtree() {
  73. let (h1, h2, h3, h4, h5, h6, _) = setup_tree();
  74. assert!(check(&vector[h1], &h5, x"adad12"), 1);
  75. assert!(check(&vector[h2], &h5, x"adad11"), 1);
  76. assert!(check(&vector[h3], &h6, x"adad14"), 1);
  77. assert!(check(&vector[h4], &h6, x"adad13"), 1);
  78. }
  79. #[test]
  80. fun test_check_invalid_proofs() {
  81. let (h1, h2, h3, h4, h5, h6, h7) = setup_tree();
  82. assert!(!check(&vector[h2, h6], &h7, x"dead"), 1);
  83. assert!(!check(&vector[h3, h5], &h7, x"dead"), 1);
  84. assert!(!check(&vector[h1, h4], &h7, x"dead"), 1);
  85. }
  86. }