You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
8.7 KiB

  1. /**
  2. * @file
  3. * @copyright defined in aergo/LICENSE.txt
  4. */
  5. package trie
  6. import (
  7. "bytes"
  8. )
  9. // MerkleProof generates a Merke proof of inclusion or non-inclusion
  10. // for the current trie root
  11. // returns the audit path, bool (key included), key, value, error
  12. // (key,value) can be 1- (nil, value), value of the included key, 2- the kv of a LeafNode
  13. // on the path of the non-included key, 3- (nil, nil) for a non-included key
  14. // with a DefaultLeaf on the path
  15. func (s *Trie) MerkleProof(key []byte) ([][]byte, bool, []byte, []byte, error) {
  16. s.lock.RLock()
  17. defer s.lock.RUnlock()
  18. s.atomicUpdate = false // so loadChildren doesnt return a copy
  19. return s.merkleProof(s.Root, key, nil, s.TrieHeight, 0)
  20. }
  21. // MerkleProofPast generates a Merke proof of inclusion or non-inclusion
  22. // for a given past trie root
  23. // returns the audit path, bool (key included), key, value, error
  24. // (key,value) can be 1- (nil, value), value of the included key, 2- the kv of a LeafNode
  25. // on the path of the non-included key, 3- (nil, nil) for a non-included key
  26. // with a DefaultLeaf on the path
  27. func (s *Trie) MerkleProofR(key, root []byte) ([][]byte, bool, []byte, []byte, error) {
  28. s.lock.RLock()
  29. defer s.lock.RUnlock()
  30. s.atomicUpdate = false // so loadChildren doesnt return a copy
  31. return s.merkleProof(root, key, nil, s.TrieHeight, 0)
  32. }
  33. // MerkleProofCompressed returns a compressed merkle proof in the given trie
  34. func (s *Trie) MerkleProofCompressedR(key, root []byte) ([]byte, [][]byte, int, bool, []byte, []byte, error) {
  35. return s.merkleProofCompressed(key, root)
  36. }
  37. // MerkleProofCompressed returns a compressed merkle proof
  38. func (s *Trie) MerkleProofCompressed(key []byte) ([]byte, [][]byte, int, bool, []byte, []byte, error) {
  39. return s.merkleProofCompressed(key, s.Root)
  40. }
  41. func (s *Trie) merkleProofCompressed(key, root []byte) ([]byte, [][]byte, int, bool, []byte, []byte, error) {
  42. s.lock.RLock()
  43. defer s.lock.RUnlock()
  44. s.atomicUpdate = false // so loadChildren doesnt return a copy
  45. // create a regular merkle proof and then compress it
  46. mpFull, included, proofKey, proofVal, err := s.merkleProof(root, key, nil, s.TrieHeight, 0)
  47. if err != nil {
  48. return nil, nil, 0, true, nil, nil, err
  49. }
  50. // the height of the shortcut in the tree will be needed for the proof verification
  51. height := len(mpFull)
  52. var mp [][]byte
  53. bitmap := make([]byte, len(mpFull)/8+1)
  54. for i, node := range mpFull {
  55. if !bytes.Equal(node, DefaultLeaf) {
  56. bitSet(bitmap, i)
  57. mp = append(mp, node)
  58. }
  59. }
  60. return bitmap, mp, height, included, proofKey, proofVal, nil
  61. }
  62. // merkleProof generates a Merke proof of inclusion or non-inclusion
  63. // for a given trie root.
  64. // returns the audit path, bool (key included), key, value, error
  65. // (key,value) can be 1- (nil, value), value of the included key, 2- the kv of a LeafNode
  66. // on the path of the non-included key, 3- (nil, nil) for a non-included key
  67. // with a DefaultLeaf on the path
  68. func (s *Trie) merkleProof(root, key []byte, batch [][]byte, height, iBatch int) ([][]byte, bool, []byte, []byte, error) {
  69. if len(root) == 0 {
  70. // proove that an empty subtree is on the path of the key
  71. return nil, false, nil, nil, nil
  72. }
  73. // Fetch the children of the node
  74. batch, iBatch, lnode, rnode, isShortcut, err := s.loadChildren(root, height, iBatch, batch)
  75. if err != nil {
  76. return nil, false, nil, nil, err
  77. }
  78. if isShortcut || height == 0 {
  79. if bytes.Equal(lnode[:HashLength], key) {
  80. // return the value so a call to trie.Get() is not needed.
  81. return nil, true, nil, rnode[:HashLength], nil
  82. }
  83. // Return the proof of the leaf key that is on the path of the non included key
  84. return nil, false, lnode[:HashLength], rnode[:HashLength], nil
  85. }
  86. // append the left or right node to the proof
  87. if bitIsSet(key, s.TrieHeight-height) {
  88. mp, included, proofKey, proofValue, err := s.merkleProof(rnode, key, batch, height-1, 2*iBatch+2)
  89. if err != nil {
  90. return nil, false, nil, nil, err
  91. }
  92. if len(lnode) != 0 {
  93. return append(mp, lnode[:HashLength]), included, proofKey, proofValue, nil
  94. } else {
  95. return append(mp, DefaultLeaf), included, proofKey, proofValue, nil
  96. }
  97. }
  98. mp, included, proofKey, proofValue, err := s.merkleProof(lnode, key, batch, height-1, 2*iBatch+1)
  99. if err != nil {
  100. return nil, false, nil, nil, err
  101. }
  102. if len(rnode) != 0 {
  103. return append(mp, rnode[:HashLength]), included, proofKey, proofValue, nil
  104. } else {
  105. return append(mp, DefaultLeaf), included, proofKey, proofValue, nil
  106. }
  107. }
  108. // VerifyInclusion verifies that key/value is included in the trie with latest root
  109. func (s *Trie) VerifyInclusion(ap [][]byte, key, value []byte) bool {
  110. leafHash := s.hash(key, value, []byte{byte(s.TrieHeight - len(ap))})
  111. return bytes.Equal(s.Root, s.verifyInclusion(ap, 0, key, leafHash))
  112. }
  113. // VerifyInclusionWithRoot verifies that key/value is included in the trie with provided root
  114. func (s *Trie) VerifyInclusionWithRoot(root []byte, ap [][]byte, key, value []byte) bool {
  115. leafHash := s.hash(key, value, []byte{byte(s.TrieHeight - len(ap))})
  116. return bytes.Equal(root, s.verifyInclusion(ap, 0, key, leafHash))
  117. }
  118. // verifyInclusion returns the merkle root by hashing the merkle proof items
  119. func (s *Trie) verifyInclusion(ap [][]byte, keyIndex int, key, leafHash []byte) []byte {
  120. if keyIndex == len(ap) {
  121. return leafHash
  122. }
  123. if bitIsSet(key, keyIndex) {
  124. return s.hash(ap[len(ap)-keyIndex-1], s.verifyInclusion(ap, keyIndex+1, key, leafHash))
  125. }
  126. return s.hash(s.verifyInclusion(ap, keyIndex+1, key, leafHash), ap[len(ap)-keyIndex-1])
  127. }
  128. // VerifyNonInclusion verifies a proof of non inclusion,
  129. // Returns true if the non-inclusion is verified
  130. func (s *Trie) VerifyNonInclusion(ap [][]byte, key, value, proofKey []byte) bool {
  131. // Check if an empty subtree is on the key path
  132. if len(proofKey) == 0 {
  133. // return true if a DefaultLeaf in the key path is included in the trie
  134. return bytes.Equal(s.Root, s.verifyInclusion(ap, 0, key, DefaultLeaf))
  135. }
  136. // Check if another kv leaf is on the key path in 2 steps
  137. // 1- Check the proof leaf exists
  138. if !s.VerifyInclusion(ap, proofKey, value) {
  139. // the proof leaf is not included in the trie
  140. return false
  141. }
  142. // 2- Check the proof leaf is on the key path
  143. var b int
  144. for b = 0; b < len(ap); b++ {
  145. if bitIsSet(key, b) != bitIsSet(proofKey, b) {
  146. // the proofKey leaf node is not on the path of the key
  147. return false
  148. }
  149. }
  150. // return true because we verified another leaf is on the key path
  151. return true
  152. }
  153. // VerifyInclusionC verifies that key/value is included in the trie with latest root
  154. func (s *Trie) VerifyInclusionC(bitmap, key, value []byte, ap [][]byte, length int) bool {
  155. leafHash := s.hash(key, value, []byte{byte(s.TrieHeight - length)})
  156. return bytes.Equal(s.Root, s.verifyInclusionC(bitmap, key, leafHash, ap, length, 0, 0))
  157. }
  158. // VerifyInclusionWithRootC verifies that key/value is included in the trie with latest root
  159. func (s *Trie) VerifyInclusionWithRootC(root, bitmap, key, value []byte, ap [][]byte, length int) bool {
  160. leafHash := s.hash(key, value, []byte{byte(s.TrieHeight - length)})
  161. return bytes.Equal(root, s.verifyInclusionC(bitmap, key, leafHash, ap, length, 0, 0))
  162. }
  163. // verifyInclusionC returns the merkle root by hashing the merkle proof items
  164. func (s *Trie) verifyInclusionC(bitmap, key, leafHash []byte, ap [][]byte, length, keyIndex, apIndex int) []byte {
  165. if keyIndex == length {
  166. return leafHash
  167. }
  168. if bitIsSet(key, keyIndex) {
  169. if bitIsSet(bitmap, length-keyIndex-1) {
  170. return s.hash(ap[len(ap)-apIndex-1], s.verifyInclusionC(bitmap, key, leafHash, ap, length, keyIndex+1, apIndex+1))
  171. }
  172. return s.hash(DefaultLeaf, s.verifyInclusionC(bitmap, key, leafHash, ap, length, keyIndex+1, apIndex))
  173. }
  174. if bitIsSet(bitmap, length-keyIndex-1) {
  175. return s.hash(s.verifyInclusionC(bitmap, key, leafHash, ap, length, keyIndex+1, apIndex+1), ap[len(ap)-apIndex-1])
  176. }
  177. return s.hash(s.verifyInclusionC(bitmap, key, leafHash, ap, length, keyIndex+1, apIndex), DefaultLeaf)
  178. }
  179. // VerifyNonInclusionC verifies a proof of non inclusion,
  180. // Returns true if the non-inclusion is verified
  181. func (s *Trie) VerifyNonInclusionC(ap [][]byte, length int, bitmap, key, value, proofKey []byte) bool {
  182. // Check if an empty subtree is on the key path
  183. if len(proofKey) == 0 {
  184. // return true if a DefaultLeaf in the key path is included in the trie
  185. return bytes.Equal(s.Root, s.verifyInclusionC(bitmap, key, DefaultLeaf, ap, length, 0, 0))
  186. }
  187. // Check if another kv leaf is on the key path in 2 steps
  188. // 1- Check the proof leaf exists
  189. if !s.VerifyInclusionC(bitmap, proofKey, value, ap, length) {
  190. // the proof leaf is not included in the trie
  191. return false
  192. }
  193. // 2- Check the proof leaf is on the key path
  194. var b int
  195. for b = 0; b < length; b++ {
  196. if bitIsSet(key, b) != bitIsSet(proofKey, b) {
  197. // the proofKey leaf node is not on the path of the key
  198. return false
  199. }
  200. }
  201. // return true because we verified another leaf is on the key path
  202. return true
  203. }