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.

242 lines
6.6 KiB

  1. /*
  2. Computes a deterministic minimal height merkle tree hash.
  3. If the number of items is not a power of two, some leaves
  4. will be at different levels. Tries to keep both sides of
  5. the tree the same size, but the left may be one greater.
  6. Use this for short deterministic trees, such as the validator list.
  7. For larger datasets, use IAVLTree.
  8. *
  9. / \
  10. / \
  11. / \
  12. / \
  13. * *
  14. / \ / \
  15. / \ / \
  16. / \ / \
  17. * * * h6
  18. / \ / \ / \
  19. h0 h1 h2 h3 h4 h5
  20. */
  21. package merkle
  22. import (
  23. "bytes"
  24. "crypto/sha256"
  25. "fmt"
  26. "github.com/tendermint/tendermint/binary"
  27. )
  28. func SimpleHashFromTwoHashes(left []byte, right []byte) []byte {
  29. var n int64
  30. var err error
  31. var hasher = sha256.New()
  32. binary.WriteByteSlice(left, hasher, &n, &err)
  33. binary.WriteByteSlice(right, hasher, &n, &err)
  34. if err != nil {
  35. panic(err)
  36. }
  37. return hasher.Sum(nil)
  38. }
  39. func SimpleHashFromHashes(hashes [][]byte) []byte {
  40. // Recursive impl.
  41. switch len(hashes) {
  42. case 0:
  43. return nil
  44. case 1:
  45. return hashes[0]
  46. default:
  47. left := SimpleHashFromHashes(hashes[:(len(hashes)+1)/2])
  48. right := SimpleHashFromHashes(hashes[(len(hashes)+1)/2:])
  49. return SimpleHashFromTwoHashes(left, right)
  50. }
  51. }
  52. // Convenience for SimpleHashFromHashes.
  53. func SimpleHashFromBinaries(items []interface{}) []byte {
  54. hashes := [][]byte{}
  55. for _, item := range items {
  56. hashes = append(hashes, SimpleHashFromBinary(item))
  57. }
  58. return SimpleHashFromHashes(hashes)
  59. }
  60. // General Convenience
  61. func SimpleHashFromBinary(item interface{}) []byte {
  62. hasher, n, err := sha256.New(), new(int64), new(error)
  63. binary.WriteBinary(item, hasher, n, err)
  64. if *err != nil {
  65. panic(err)
  66. }
  67. return hasher.Sum(nil)
  68. }
  69. // Convenience for SimpleHashFromHashes.
  70. func SimpleHashFromHashables(items []Hashable) []byte {
  71. hashes := [][]byte{}
  72. for _, item := range items {
  73. hash := item.Hash()
  74. hashes = append(hashes, hash)
  75. }
  76. return SimpleHashFromHashes(hashes)
  77. }
  78. //--------------------------------------------------------------------------------
  79. type SimpleProof struct {
  80. Index uint `json:"index"`
  81. Total uint `json:"total"`
  82. LeafHash []byte `json:"leaf_hash"`
  83. InnerHashes [][]byte `json:"inner_hashes"` // Hashes from leaf's sibling to a root's child.
  84. RootHash []byte `json:"root_hash"`
  85. }
  86. // proofs[0] is the proof for items[0].
  87. func SimpleProofsFromHashables(items []Hashable) (proofs []*SimpleProof) {
  88. trails, root := trailsFromHashables(items)
  89. proofs = make([]*SimpleProof, len(items))
  90. for i, trail := range trails {
  91. proofs[i] = &SimpleProof{
  92. Index: uint(i),
  93. Total: uint(len(items)),
  94. LeafHash: trail.Hash,
  95. InnerHashes: trail.FlattenInnerHashes(),
  96. RootHash: root.Hash,
  97. }
  98. }
  99. return
  100. }
  101. // Verify that leafHash is a leaf hash of the simple-merkle-tree
  102. // which hashes to rootHash.
  103. func (sp *SimpleProof) Verify(leafHash []byte, rootHash []byte) bool {
  104. if !bytes.Equal(leafHash, sp.LeafHash) {
  105. return false
  106. }
  107. if !bytes.Equal(rootHash, sp.RootHash) {
  108. return false
  109. }
  110. computedHash := computeHashFromInnerHashes(sp.Index, sp.Total, sp.LeafHash, sp.InnerHashes)
  111. if computedHash == nil {
  112. return false
  113. }
  114. if !bytes.Equal(computedHash, rootHash) {
  115. return false
  116. }
  117. return true
  118. }
  119. func (sp *SimpleProof) String() string {
  120. return sp.StringIndented("")
  121. }
  122. func (sp *SimpleProof) StringIndented(indent string) string {
  123. return fmt.Sprintf(`SimpleProof{
  124. %s Index: %v
  125. %s Total: %v
  126. %s LeafHash: %X
  127. %s InnerHashes: %X
  128. %s RootHash: %X
  129. %s}`,
  130. indent, sp.Index,
  131. indent, sp.Total,
  132. indent, sp.LeafHash,
  133. indent, sp.InnerHashes,
  134. indent, sp.RootHash,
  135. indent)
  136. }
  137. // Use the leafHash and innerHashes to get the root merkle hash.
  138. // If the length of the innerHashes slice isn't exactly correct, the result is nil.
  139. func computeHashFromInnerHashes(index uint, total uint, leafHash []byte, innerHashes [][]byte) []byte {
  140. // Recursive impl.
  141. if index >= total {
  142. return nil
  143. }
  144. switch total {
  145. case 0:
  146. panic("Cannot call computeHashFromInnerHashes() with 0 total")
  147. case 1:
  148. if len(innerHashes) != 0 {
  149. return nil
  150. }
  151. return leafHash
  152. default:
  153. if len(innerHashes) == 0 {
  154. return nil
  155. }
  156. numLeft := (total + 1) / 2
  157. if index < numLeft {
  158. leftHash := computeHashFromInnerHashes(index, numLeft, leafHash, innerHashes[:len(innerHashes)-1])
  159. if leftHash == nil {
  160. return nil
  161. }
  162. return SimpleHashFromTwoHashes(leftHash, innerHashes[len(innerHashes)-1])
  163. } else {
  164. rightHash := computeHashFromInnerHashes(index-numLeft, total-numLeft, leafHash, innerHashes[:len(innerHashes)-1])
  165. if rightHash == nil {
  166. return nil
  167. }
  168. return SimpleHashFromTwoHashes(innerHashes[len(innerHashes)-1], rightHash)
  169. }
  170. }
  171. }
  172. // Helper structure to construct merkle proof.
  173. // The node and the tree is thrown away afterwards.
  174. // Exactly one of node.Left and node.Right is nil, unless node is the root, in which case both are nil.
  175. // node.Parent.Hash = hash(node.Hash, node.Right.Hash) or
  176. // hash(node.Left.Hash, node.Hash), depending on whether node is a left/right child.
  177. type SimpleProofNode struct {
  178. Hash []byte
  179. Parent *SimpleProofNode
  180. Left *SimpleProofNode // Left sibling (only one of Left,Right is set)
  181. Right *SimpleProofNode // Right sibling (only one of Left,Right is set)
  182. }
  183. // Starting from a leaf SimpleProofNode, FlattenInnerHashes() will return
  184. // the inner hashes for the item corresponding to the leaf.
  185. func (spn *SimpleProofNode) FlattenInnerHashes() [][]byte {
  186. // Nonrecursive impl.
  187. innerHashes := [][]byte{}
  188. for spn != nil {
  189. if spn.Left != nil {
  190. innerHashes = append(innerHashes, spn.Left.Hash)
  191. } else if spn.Right != nil {
  192. innerHashes = append(innerHashes, spn.Right.Hash)
  193. } else {
  194. break
  195. }
  196. spn = spn.Parent
  197. }
  198. return innerHashes
  199. }
  200. // trails[0].Hash is the leaf hash for items[0].
  201. // trails[i].Parent.Parent....Parent == root for all i.
  202. func trailsFromHashables(items []Hashable) (trails []*SimpleProofNode, root *SimpleProofNode) {
  203. // Recursive impl.
  204. switch len(items) {
  205. case 0:
  206. return nil, nil
  207. case 1:
  208. trail := &SimpleProofNode{items[0].Hash(), nil, nil, nil}
  209. return []*SimpleProofNode{trail}, trail
  210. default:
  211. lefts, leftRoot := trailsFromHashables(items[:(len(items)+1)/2])
  212. rights, rightRoot := trailsFromHashables(items[(len(items)+1)/2:])
  213. rootHash := SimpleHashFromTwoHashes(leftRoot.Hash, rightRoot.Hash)
  214. root := &SimpleProofNode{rootHash, nil, nil, nil}
  215. leftRoot.Parent = root
  216. leftRoot.Right = rightRoot
  217. rightRoot.Parent = root
  218. rightRoot.Left = leftRoot
  219. return append(lefts, rights...), root
  220. }
  221. }