github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/merkle/merkle_tree.go (about) 1 /* 2 * Copyright (C) 2018 The ontology Authors 3 * This file is part of The ontology library. 4 * 5 * The ontology is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * The ontology is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with The ontology. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 package merkle 20 21 import ( 22 "encoding/binary" 23 "errors" 24 "fmt" 25 26 "github.com/sixexorg/magnetic-ring/common" 27 "github.com/sixexorg/magnetic-ring/log" 28 ) 29 30 // const UINT256_SIZE int = 32 31 32 // type common.Uint256 [UINT256_SIZE]byte 33 34 var EMPTY_HASH = common.Hash{} 35 36 // CompactMerkleTree calculate merkle tree with compact hash store in HashStore 37 type CompactMerkleTree struct { 38 mintree_h uint 39 hashes []common.Hash 40 hasher TreeHasher 41 hashStore HashStore 42 rootHash common.Hash 43 treeSize uint64 44 } 45 46 // NewTree returns a CompactMerkleTree instance 47 func NewTree(tree_size uint64, hashes []common.Hash, store HashStore) *CompactMerkleTree { 48 49 tree := &CompactMerkleTree{ 50 mintree_h: 0, 51 hashes: nil, 52 hasher: TreeHasher{}, 53 hashStore: store, 54 rootHash: EMPTY_HASH, 55 } 56 57 tree._update(tree_size, hashes) 58 return tree 59 } 60 61 func (self *CompactMerkleTree) Hashes() []common.Hash { 62 return self.hashes 63 } 64 65 func (self *CompactMerkleTree) TreeSize() uint64 { 66 return self.treeSize 67 } 68 69 func (self *CompactMerkleTree) Marshal() ([]byte, error) { 70 length := 8 + len(self.hashes)*common.HashLength 71 buf := make([]byte, 8, length) 72 binary.BigEndian.PutUint64(buf[0:], self.treeSize) 73 for _, h := range self.hashes { 74 buf = append(buf, h[:]...) 75 } 76 return buf, nil 77 } 78 79 func (self *CompactMerkleTree) UnMarshal(buf []byte) error { 80 tree_size := binary.BigEndian.Uint64(buf[0:8]) 81 nhashes := countBit(tree_size) 82 if len(buf) < 8+int(nhashes)*common.HashLength { 83 return errors.New("Too short input buf length") 84 } 85 hashes := make([]common.Hash, nhashes, nhashes) 86 for i := 0; i < int(nhashes); i++ { 87 copy(hashes[i][:], buf[8+i*common.HashLength:]) 88 } 89 self._update(tree_size, hashes) 90 return nil 91 } 92 93 func (self *CompactMerkleTree) _update(tree_size uint64, hashes []common.Hash) { 94 numBit := countBit(tree_size) 95 if len(hashes) != int(numBit) { 96 panic("number of hashes != num bit in tree_size") 97 } 98 self.treeSize = tree_size 99 self.hashes = hashes 100 self.mintree_h = lowBit(tree_size) 101 self.rootHash = EMPTY_HASH 102 103 } 104 105 // Root returns root hash of merkle tree 106 func (self *CompactMerkleTree) Root() common.Hash { 107 if self.rootHash == EMPTY_HASH { 108 if len(self.hashes) != 0 { 109 self.rootHash = self.hasher._hash_fold(self.hashes) 110 } else { 111 self.rootHash = self.hasher.hash_empty() 112 } 113 } 114 return self.rootHash 115 } 116 117 // GetRootWithNewLeaf returns the new root hash if newLeaf is appended to the merkle tree 118 func (self *CompactMerkleTree) GetRootWithNewLeaf(newLeaf common.Hash) common.Hash { 119 hashes := append(self.hashes, newLeaf) 120 root := self.hasher._hash_fold(hashes) 121 122 return root 123 } 124 125 // Append appends a leaf to the merkle tree and returns the audit path 126 func (self *CompactMerkleTree) Append(leafv []byte) []common.Hash { 127 leaf := self.hasher.hash_leaf(leafv) 128 129 return self.AppendHash(leaf) 130 } 131 132 // AppendHash appends a leaf hash to the merkle tree and returns the audit path 133 func (self *CompactMerkleTree) AppendHash(leaf common.Hash) []common.Hash { 134 size := len(self.hashes) 135 auditPath := make([]common.Hash, size, size) 136 storehashes := make([]common.Hash, 0) 137 // reverse 138 for i, v := range self.hashes { 139 auditPath[size-i-1] = v 140 } 141 142 storehashes = append(storehashes, leaf) 143 self.mintree_h = 1 144 for s := self.treeSize; s%2 == 1; s = s >> 1 { 145 self.mintree_h += 1 146 leaf = self.hasher.hash_children(self.hashes[size-1], leaf) 147 storehashes = append(storehashes, leaf) 148 size -= 1 149 } 150 if self.hashStore != nil { 151 self.hashStore.Append(storehashes) 152 self.hashStore.Flush() 153 } 154 self.treeSize += 1 155 self.hashes = self.hashes[0:size] 156 self.hashes = append(self.hashes, leaf) 157 self.rootHash = EMPTY_HASH 158 159 return auditPath 160 } 161 162 func (self *CompactMerkleTree) Subtract() { 163 164 } 165 166 func (self *CompactMerkleTree) DumpStatus() { 167 log.Error("tree root:", self.rootHash) 168 log.Error("tree size:", self.treeSize) 169 log.Error("hashes size:", len(self.hashes)) 170 log.Error("hashes ", self.hashes) 171 log.Error("mintree_h ", self.mintree_h) 172 } 173 174 // 1 based n 175 func getSubTreeSize(n uint64) []uint64 { 176 nhashes := countBit(n) 177 subtreesize := make([]uint64, nhashes, nhashes) 178 for i, id := nhashes-1, uint64(1); n != 0; n = n >> 1 { 179 id = id * 2 180 if n%2 == 1 { 181 subtreesize[i] = id - 1 182 i -= 1 183 } 184 } 185 186 return subtreesize 187 } 188 189 // 1-based n and return value 190 func getSubTreePos(n uint64) []uint64 { 191 nhashes := countBit(n) 192 hashespos := make([]uint64, nhashes, nhashes) 193 for i, id := nhashes-1, uint64(1); n != 0; n = n >> 1 { 194 id = id * 2 195 if n%2 == 1 { 196 hashespos[i] = id - 1 197 i -= 1 198 } 199 } 200 201 for i := uint(1); i < nhashes; i++ { 202 hashespos[i] += hashespos[i-1] 203 } 204 205 return hashespos 206 } 207 208 // return merkle root of D[0:n] not include n 209 func (self *CompactMerkleTree) merkleRoot(n uint64) common.Hash { 210 hashespos := getSubTreePos(n) 211 nhashes := uint(len(hashespos)) 212 213 hashes := make([]common.Hash, nhashes, nhashes) 214 for i := uint(0); i < nhashes; i++ { 215 hashes[i], _ = self.hashStore.GetHash(hashespos[i] - 1) 216 } 217 return self.hasher._hash_fold(hashes) 218 } 219 220 // ConsistencyProof returns consistency proof 221 func (self *CompactMerkleTree) ConsistencyProof(m, n uint64) []common.Hash { 222 if m > n || self.treeSize < n || self.hashStore == nil { 223 return nil 224 } 225 226 return self.subproof(m, n, true) 227 } 228 229 // m, n 1-based 230 func (self *CompactMerkleTree) subproof(m, n uint64, b bool) []common.Hash { 231 offset := uint64(0) 232 var hashes []common.Hash 233 for m < n { 234 k := uint64(1 << (highBit(n-1) - 1)) 235 if m <= k { 236 pos := getSubTreePos(n - k) 237 subhashes := make([]common.Hash, len(pos), len(pos)) 238 for p := range pos { 239 pos[p] += offset + k*2 - 1 240 subhashes[p], _ = self.hashStore.GetHash(pos[p] - 1) 241 } 242 rootk2n := self.hasher._hash_fold(subhashes) 243 hashes = append(hashes, rootk2n) 244 n = k 245 } else { 246 offset += k*2 - 1 247 root02k, _ := self.hashStore.GetHash(offset - 1) 248 hashes = append(hashes, root02k) 249 m -= k 250 n -= k 251 b = false 252 } 253 } 254 255 //assert m == n 256 if b == false { 257 pos := getSubTreePos(n) 258 //assert len(pos) == 1 259 if len(pos) != 1 { 260 panic("assert error") 261 } 262 root02n, _ := self.hashStore.GetHash(pos[0] + offset - 1) 263 hashes = append(hashes, root02n) 264 } 265 266 length := len(hashes) 267 reverse := make([]common.Hash, length, length) 268 for k, _ := range reverse { 269 reverse[k] = hashes[length-k-1] 270 } 271 272 return reverse 273 } 274 275 // InclusionProof returns the proof d[m] in D[0:n] 276 // m zero based index, n size 1-based 277 func (self *CompactMerkleTree) InclusionProof(m, n uint64) ([]common.Hash, error) { 278 if m >= n { 279 return nil, errors.New("wrong parameters") 280 } else if self.treeSize < n { 281 return nil, errors.New("not available yet") 282 } else if self.hashStore == nil { 283 return nil, errors.New("hash store not available") 284 } 285 286 offset := uint64(0) 287 var hashes []common.Hash 288 for n != 1 { 289 k := uint64(1 << (highBit(n-1) - 1)) 290 if m < k { 291 pos := getSubTreePos(n - k) 292 subhashes := make([]common.Hash, len(pos), len(pos)) 293 for p := range pos { 294 pos[p] += offset + k*2 - 1 295 subhashes[p], _ = self.hashStore.GetHash(pos[p] - 1) 296 } 297 rootk2n := self.hasher._hash_fold(subhashes) 298 hashes = append(hashes, rootk2n) 299 n = k 300 } else { 301 offset += k*2 - 1 302 root02k, _ := self.hashStore.GetHash(offset - 1) 303 hashes = append(hashes, root02k) 304 m -= k 305 n -= k 306 } 307 } 308 309 length := len(hashes) 310 reverse := make([]common.Hash, length, length) 311 for k := range reverse { 312 reverse[k] = hashes[length-k-1] 313 } 314 315 return reverse, nil 316 } 317 318 // MerkleVerifier verify inclusion and consist proof 319 type MerkleVerifier struct { 320 hasher TreeHasher 321 } 322 323 func NewMerkleVerifier() *MerkleVerifier { 324 return &MerkleVerifier{ 325 hasher: TreeHasher{}, 326 } 327 } 328 329 /* 330 Verify a Merkle Audit PATH. 331 332 leaf_hash: The hash of the leaf for which the proof was provided. 333 leaf_index: Index of the leaf in the tree. 334 proof: A list of SHA-256 hashes representing the Merkle audit path. 335 tree_size: The size of the tree 336 root_hash: The root hash of the tree 337 338 Returns: 339 nil when the proof is valid 340 */ 341 func (self *MerkleVerifier) VerifyLeafHashInclusion(leaf_hash common.Hash, 342 leaf_index uint64, proof []common.Hash, root_hash common.Hash, tree_size uint64) error { 343 344 if tree_size <= leaf_index { 345 return errors.New("Wrong params: the tree size is smaller than the leaf index") 346 } 347 348 calculated_root_hash, err := self.calculate_root_hash_from_audit_path(leaf_hash, 349 leaf_index, proof, tree_size) 350 if err != nil { 351 return err 352 } 353 if calculated_root_hash != root_hash { 354 return errors.New(fmt.Sprintf("Constructed root hash differs from provided root hash. Constructed: %x, Expected: %x", 355 calculated_root_hash, root_hash)) 356 } 357 358 return nil 359 } 360 361 /* 362 Verify a Merkle Audit PATH. 363 364 leaf: The leaf for which the proof is provided 365 leaf_index: Index of the leaf in the tree. 366 proof: A list of SHA-256 hashes representing the Merkle audit path. 367 tree_size: The size of the tree 368 root_hash: The root hash of the tree 369 370 Returns: 371 nil when the proof is valid 372 */ 373 func (self *MerkleVerifier) VerifyLeafInclusion(leaf []byte, 374 leaf_index uint64, proof []common.Hash, root_hash common.Hash, tree_size uint64) error { 375 leaf_hash := self.hasher.hash_leaf(leaf) 376 return self.VerifyLeafHashInclusion(leaf_hash, leaf_index, proof, root_hash, tree_size) 377 } 378 379 func (self *MerkleVerifier) calculate_root_hash_from_audit_path(leaf_hash common.Hash, 380 node_index uint64, audit_path []common.Hash, tree_size uint64) (common.Hash, error) { 381 calculated_hash := leaf_hash 382 last_node := tree_size - 1 383 pos := 0 384 path_len := len(audit_path) 385 for last_node > 0 { 386 if pos >= path_len { 387 return EMPTY_HASH, errors.New(fmt.Sprintf("Proof too short. expected %d, got %d", 388 audit_path_length(node_index, tree_size), path_len)) 389 } 390 391 if node_index%2 == 1 { 392 calculated_hash = self.hasher.hash_children(audit_path[pos], calculated_hash) 393 pos += 1 394 } else if node_index < last_node { 395 calculated_hash = self.hasher.hash_children(calculated_hash, audit_path[pos]) 396 pos += 1 397 } 398 node_index /= 2 399 last_node /= 2 400 } 401 402 if pos < path_len { 403 return EMPTY_HASH, errors.New("Proof too long") 404 } 405 return calculated_hash, nil 406 } 407 408 func audit_path_length(index, tree_size uint64) int { 409 length := 0 410 last_node := tree_size - 1 411 for last_node > 0 { 412 if index%2 == 1 || index < last_node { 413 length += 1 414 } 415 index /= 2 416 last_node /= 2 417 } 418 return length 419 } 420 421 /* 422 Verify the consistency between two root hashes. 423 424 old_tree_size must be <= new_tree_size. 425 426 Args: 427 old_tree_size: size of the older tree. 428 new_tree_size: size of the newer_tree. 429 old_root: the root hash of the older tree. 430 new_root: the root hash of the newer tree. 431 proof: the consistency proof. 432 433 Returns: 434 True. The return value is enforced by a decorator and need not be 435 checked by the caller. 436 437 Raises: 438 ConsistencyError: the proof indicates an inconsistency 439 (this is usually really serious!). 440 ProofError: the proof is invalid. 441 ValueError: supplied tree sizes are invalid. 442 */ 443 func (self *MerkleVerifier) VerifyConsistency(old_tree_size, 444 new_tree_size uint64, old_root, new_root common.Hash, proof []common.Hash) error { 445 old_size := old_tree_size 446 new_size := new_tree_size 447 448 if old_size > new_size { 449 return errors.New(fmt.Sprintf("Older tree has bigger size %d vs %d", old_size, new_size)) 450 } 451 if old_root == new_root { 452 return nil 453 } 454 if old_size == 0 { 455 return nil 456 } 457 //assert o < old_size < new_size 458 /* 459 A consistency proof is essentially an audit proof for the node with 460 index old_size - 1 in the newer tree. The sole difference is that 461 the path is already hashed together into a single hash up until the 462 first audit node that occurs in the newer tree only. 463 */ 464 node := old_size - 1 465 last_node := new_size - 1 466 467 // while we are the right child, everything is in both trees, so move one level up 468 for node%2 == 1 { 469 node /= 2 470 last_node /= 2 471 } 472 473 lenp := len(proof) 474 pos := 0 475 var new_hash, old_hash common.Hash 476 477 if pos >= lenp { 478 return errors.New("Wrong proof length") 479 } 480 if node != 0 { 481 // compute the two root hashes in parallel. 482 new_hash = proof[pos] 483 old_hash = proof[pos] 484 pos += 1 485 } else { 486 // The old tree was balanced (2^k nodes), so we already have the first root hash 487 new_hash = old_root 488 old_hash = old_root 489 } 490 491 for node != 0 { 492 if node%2 == 1 { 493 if pos >= lenp { 494 return errors.New("Wrong proof length") 495 } 496 // node is a right child: left sibling exists in both trees 497 next_node := proof[pos] 498 pos += 1 499 old_hash = self.hasher.hash_children(next_node, old_hash) 500 new_hash = self.hasher.hash_children(next_node, new_hash) 501 } else if node < last_node { 502 if pos >= lenp { 503 return errors.New("Wrong proof length") 504 } 505 // node is a left child: right sibling only exists inthe newer tree 506 next_node := proof[pos] 507 pos += 1 508 new_hash = self.hasher.hash_children(new_hash, next_node) 509 } 510 // else node == last_node: node is a left child with no sibling in either tree 511 512 node /= 2 513 last_node /= 2 514 } 515 516 // Now old_hash is the hash of the first subtree. If the two trees have different 517 // height, continue the path until the new root. 518 for last_node != 0 { 519 if pos >= lenp { 520 return errors.New("Wrong proof length") 521 } 522 next_node := proof[pos] 523 pos += 1 524 new_hash = self.hasher.hash_children(new_hash, next_node) 525 last_node /= 2 526 } 527 528 /* If the second hash does not match, the proof is invalid for the given pair 529 If, on the other hand, the newer hash matches but the older one does not, then 530 the proof (together with the signatures on the hashes) is proof of inconsistency. 531 */ 532 if new_hash != new_root { 533 return errors.New(fmt.Sprintf(`Bad Merkle proof: second root hash does not match. 534 Expected hash:%x, computed hash: %x`, new_root, new_hash)) 535 } else if old_hash != old_root { 536 return errors.New(fmt.Sprintf(`Inconsistency: first root hash does not match." 537 "Expected hash: %x, computed hash:%x`, old_root, old_hash)) 538 } 539 540 if pos != lenp { 541 return errors.New("Proof too long") 542 } 543 544 return nil 545 }