github.com/turingchain2020/turingchain@v1.1.21/common/merkle/merkle.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package merkle 实现默克尔树相关的hash计算
     6  package merkle
     7  
     8  import (
     9  	"bytes"
    10  	"runtime"
    11  
    12  	"github.com/turingchain2020/turingchain/common"
    13  	"github.com/turingchain2020/turingchain/types"
    14  )
    15  
    16  /*     WARNING! If you're reading this because you're learning about crypto
    17  and/or designing a new system that will use merkle trees, keep in mind
    18  that the following merkle tree algorithm has a serious flaw related to
    19  duplicate txids, resulting in a vulnerability (CVE-2012-2459).
    20  
    21  The reason is that if the number of hashes in the list at a given time
    22  is odd, the last one is duplicated before computing the next level (which
    23  is unusual in Merkle trees). This results in certain sequences of
    24  transactions leading to the same merkle root. For example, these two
    25  trees:
    26  
    27  A               A
    28  /  \            /   \
    29  B     C         B       C
    30  / \    |        / \     / \
    31  D   E   F       D   E   F   F
    32  / \ / \ / \     / \ / \ / \ / \
    33  1 2 3 4 5 6     1 2 3 4 5 6 5 6
    34  
    35  for transaction lists [1,2,3,4,5,6] and [1,2,3,4,5,6,5,6] (where 5 and
    36  6 are repeated) result in the same root hash A (because the hash of both
    37  of (F) and (F,F) is C).
    38  
    39  The vulnerability results from being able to send a block with such a
    40  transaction list, with the same merkle root, and the same block hash as
    41  the original without duplication, resulting in failed validation. If the
    42  receiving node proceeds to mark that block as permanently invalid
    43  however, it will fail to accept further unmodified (and thus potentially
    44  valid) versions of the same block. We defend against this by detecting
    45  the case where we would hash two identical hashes at the end of the list
    46  together, and treating that identically to the block having an invalid
    47  merkle root. Assuming no double-SHA256 collisions, this will detect all
    48  known ways of changing the transactions without affecting the merkle
    49  root.
    50  */
    51  
    52  /*GetMerkleRoot This implements a constant-space merkle root/path calculator, limited to 2^32 leaves. */
    53  //flage =1 只计算roothash  flage =2 只计算branch  flage =3 计算roothash 和 branch
    54  func getMerkleRoot(hashes [][]byte) []byte {
    55  	cache := make([]byte, 64)
    56  	level := 0
    57  	for len(hashes) > 1 {
    58  		if len(hashes)&1 != 0 { //奇数
    59  			hashes = append(hashes, hashes[len(hashes)-1])
    60  		}
    61  		index := 0
    62  		for i := 0; i < len(hashes); i += 2 {
    63  			hashes[index] = GetHashFromTwoHash(cache, hashes[i], hashes[i+1])
    64  			index++
    65  		}
    66  		level++
    67  		hashes = hashes[0:index]
    68  	}
    69  	if len(hashes) == 0 {
    70  		return nil
    71  	}
    72  	return hashes[0]
    73  }
    74  
    75  func log2(data int) int {
    76  	level := 1
    77  	if data <= 0 {
    78  		return 0
    79  	}
    80  	for {
    81  		data = data / 2
    82  		if data <= 1 {
    83  			return level
    84  		}
    85  		level++
    86  	}
    87  }
    88  
    89  func pow2(d int) (p int) {
    90  	if d <= 0 {
    91  		return 1
    92  	}
    93  	p = 1
    94  	for i := 0; i < d; i++ {
    95  		p *= 2
    96  	}
    97  	return p
    98  }
    99  
   100  func calcLevel(n int) int {
   101  	if n == 1 {
   102  		return 1
   103  	}
   104  	level := 0
   105  	for n > 1 {
   106  		if n&1 != 0 {
   107  			n++
   108  		}
   109  		n = n / 2
   110  		level++
   111  	}
   112  	return level
   113  }
   114  
   115  func getMerkleRootPad(hashes [][]byte, step int) []byte {
   116  	level1 := calcLevel(len(hashes))
   117  	level2 := log2(step)
   118  	var root []byte
   119  	cache := make([]byte, 64)
   120  	if len(hashes) == 1 {
   121  		root = GetHashFromTwoHash(cache, hashes[0], hashes[0])
   122  	} else {
   123  		root = getMerkleRoot(hashes)
   124  	}
   125  	for i := 0; i < level2-level1; i++ {
   126  		root = GetHashFromTwoHash(cache, root, root)
   127  	}
   128  	return root
   129  }
   130  
   131  type childstate struct {
   132  	hash  []byte
   133  	index int
   134  }
   135  
   136  //GetMerkleRoot 256构成一个组,进行计算
   137  // n * step = hashes
   138  // (hashes / n)
   139  func GetMerkleRoot(hashes [][]byte) []byte {
   140  	ncpu := runtime.NumCPU()
   141  	if len(hashes) <= 80 || ncpu <= 1 {
   142  		return getMerkleRoot(hashes)
   143  	}
   144  	step := log2(len(hashes) / ncpu)
   145  	if step < 1 {
   146  		step = 1
   147  	}
   148  	step = pow2(step)
   149  	if step > 256 {
   150  		step = 256
   151  	}
   152  	ch := make(chan *childstate, 10)
   153  	//pad to step
   154  	rem := len(hashes) % step
   155  	l := len(hashes) / step
   156  	if rem != 0 {
   157  		l++
   158  	}
   159  	for i := 0; i < l; i++ {
   160  		end := (i + 1) * step
   161  		if end > len(hashes) {
   162  			end = len(hashes)
   163  		}
   164  		child := hashes[i*step : end]
   165  		go func(index int, h [][]byte) {
   166  			var subhash []byte
   167  			if len(h) != step {
   168  				subhash = getMerkleRootPad(h, step)
   169  			} else {
   170  				subhash = getMerkleRoot(h)
   171  			}
   172  			ch <- &childstate{
   173  				hash:  subhash,
   174  				index: index,
   175  			}
   176  		}(i, child)
   177  	}
   178  	childlist := make([][]byte, l)
   179  	for i := 0; i < l; i++ {
   180  		sub := <-ch
   181  		childlist[sub.index] = sub.hash
   182  	}
   183  	return getMerkleRoot(childlist)
   184  }
   185  
   186  /*Computation This implements a constant-space merkle root/path calculator, limited to 2^32 leaves. */
   187  //flage =1 只计算roothash  flage =2 只计算branch  flage =3 计算roothash 和 branch
   188  func Computation(leaves [][]byte, flage int, branchpos uint32) (roothash []byte, mutated bool, pbranch [][]byte) {
   189  	if len(leaves) == 0 {
   190  		return nil, false, nil
   191  	}
   192  	if flage < 1 || flage > 3 {
   193  		return nil, false, nil
   194  	}
   195  
   196  	var count int
   197  	var branch [][]byte
   198  	var level uint32
   199  	var h []byte
   200  	inner := make([][]byte, 32)
   201  	var matchlevel uint32 = 0xff
   202  	mutated = false
   203  	var matchh bool
   204  	cache := make([]byte, 64)
   205  	for count, h = range leaves {
   206  
   207  		if (uint32(count) == branchpos) && (flage&2) != 0 {
   208  			matchh = true
   209  		} else {
   210  			matchh = false
   211  		}
   212  		count++
   213  		// 1左移level位
   214  		for level = 0; 0 == ((count) & (1 << level)); level++ {
   215  			//需要计算branch
   216  			if (flage & 2) != 0 {
   217  				if matchh {
   218  					branch = append(branch, inner[level])
   219  				} else if matchlevel == level {
   220  					branch = append(branch, h)
   221  					matchh = true
   222  				}
   223  			}
   224  			if bytes.Equal(inner[level], h) {
   225  				mutated = true
   226  			}
   227  			//计算inner[level] + h 的hash值
   228  			h = GetHashFromTwoHash(cache, inner[level], h)
   229  		}
   230  		inner[level] = h
   231  		if matchh {
   232  			matchlevel = level
   233  		}
   234  	}
   235  
   236  	for level = 0; 0 == (count & (1 << level)); level++ {
   237  	}
   238  	h = inner[level]
   239  	matchh = matchlevel == level
   240  	for count != (1 << level) {
   241  		if (flage&2) != 0 && matchh {
   242  			branch = append(branch, h)
   243  		}
   244  		h = GetHashFromTwoHash(cache, h, h)
   245  		count += (1 << level)
   246  		level++
   247  		// And propagate the result upwards accordingly.
   248  		for 0 == (count & (1 << level)) {
   249  			if (flage & 2) != 0 {
   250  				if matchh {
   251  					branch = append(branch, inner[level])
   252  				} else if matchlevel == level {
   253  					branch = append(branch, h)
   254  					matchh = true
   255  				}
   256  			}
   257  			h = GetHashFromTwoHash(cache, inner[level], h)
   258  			level++
   259  		}
   260  	}
   261  	return h, mutated, branch
   262  }
   263  
   264  //GetHashFromTwoHash 计算左右节点hash的父hash
   265  func GetHashFromTwoHash(parent []byte, left []byte, right []byte) []byte {
   266  	if left == nil || right == nil {
   267  		return nil
   268  	}
   269  	copy(parent, left)
   270  	copy(parent[32:], right)
   271  	return common.Sha2Sum(parent)
   272  }
   273  
   274  //GetMerkleBranch 获取指定txindex的branch position 从0开始
   275  func GetMerkleBranch(leaves [][]byte, position uint32) [][]byte {
   276  	_, _, branchs := Computation(leaves, 2, position)
   277  	return branchs
   278  }
   279  
   280  //GetMerkleRootFromBranch 通过branch 获取对应的roothash 用于指定txhash的proof证明
   281  func GetMerkleRootFromBranch(merkleBranch [][]byte, leaf []byte, Index uint32) []byte {
   282  	hash := leaf
   283  	hashcache := make([]byte, 64)
   284  	for _, branch := range merkleBranch {
   285  		if (Index & 1) != 0 {
   286  			hash = GetHashFromTwoHash(hashcache, branch, hash)
   287  		} else {
   288  			hash = GetHashFromTwoHash(hashcache, hash, branch)
   289  		}
   290  		Index >>= 1
   291  	}
   292  	return hash
   293  }
   294  
   295  //GetMerkleRootAndBranch 获取merkle roothash 以及指定tx index的branch,注释:position从0开始
   296  func GetMerkleRootAndBranch(leaves [][]byte, position uint32) (roothash []byte, branchs [][]byte) {
   297  	roothash, _, branchs = Computation(leaves, 3, position)
   298  	return
   299  }
   300  
   301  var zeroHash [32]byte
   302  
   303  //CalcMerkleRoot 计算merkle树根
   304  func CalcMerkleRoot(cfg *types.TuringchainConfig, height int64, txs []*types.Transaction) []byte {
   305  	if !cfg.IsFork(height, "ForkRootHash") {
   306  		return calcMerkleRoot(txs)
   307  	}
   308  	calcHash, _ := calcMultiLayerMerkleInfo(txs)
   309  	return calcHash
   310  }
   311  
   312  //calcMerkleRoot 计算merkle树根hash
   313  func calcMerkleRoot(txs []*types.Transaction) []byte {
   314  	var hashes [][]byte
   315  	for _, tx := range txs {
   316  		hashes = append(hashes, tx.Hash())
   317  	}
   318  	if hashes == nil {
   319  		return zeroHash[:]
   320  	}
   321  	merkleroot := GetMerkleRoot(hashes)
   322  	if merkleroot == nil {
   323  		panic("calc merkle root error")
   324  	}
   325  	return merkleroot
   326  }
   327  
   328  //calcSingleLayerMerkleRoot 计算单层merkle树根hash使用fullhash
   329  func calcSingleLayerMerkleRoot(txs []*types.Transaction) []byte {
   330  	var hashes [][]byte
   331  	for _, tx := range txs {
   332  		hashes = append(hashes, tx.FullHash())
   333  	}
   334  	if hashes == nil {
   335  		return zeroHash[:]
   336  	}
   337  	merkleroot := GetMerkleRoot(hashes)
   338  	if merkleroot == nil {
   339  		panic("calc merkle root error")
   340  	}
   341  	return merkleroot
   342  }
   343  
   344  //CalcMerkleRootCache 计算merkle树根缓存
   345  func CalcMerkleRootCache(txs []*types.TransactionCache) []byte {
   346  	var hashes [][]byte
   347  	for _, tx := range txs {
   348  		hashes = append(hashes, tx.Hash())
   349  	}
   350  	if hashes == nil {
   351  		return zeroHash[:]
   352  	}
   353  	merkleroot := GetMerkleRoot(hashes)
   354  	if merkleroot == nil {
   355  		panic("calc merkle root error")
   356  	}
   357  	return merkleroot
   358  }
   359  
   360  //CalcMultiLayerMerkleInfo 计算多层merkle树根hash以及子链根hash信息
   361  func CalcMultiLayerMerkleInfo(cfg *types.TuringchainConfig, height int64, txs []*types.Transaction) ([]byte, []types.ChildChain) {
   362  	if !cfg.IsFork(height, "ForkRootHash") {
   363  		return nil, nil
   364  	}
   365  	return calcMultiLayerMerkleInfo(txs)
   366  }
   367  
   368  //calcMultiLayerMerkleInfo 计算多层merkle树根hash使用fullhash
   369  //1,交易列表中都是主链的交易
   370  //2,交易列表中都是某个平行链的交易(平行链节点上的情况)
   371  //3,交易列表中是主链和平行链交易都存在,及混合交易
   372  func calcMultiLayerMerkleInfo(txs []*types.Transaction) ([]byte, []types.ChildChain) {
   373  	var fristParaTitle string
   374  	var childchains []types.ChildChain
   375  
   376  	txsCount := len(txs)
   377  	if txsCount == 0 {
   378  		return zeroHash[:], nil
   379  	}
   380  	//需要区分交易列表中是否是同一个链的交易,
   381  	//混合链的交易需要找到每个链的第一笔交易,方便子链roothash的并行计算
   382  	for i, tx := range txs {
   383  		paraTitle, haveParaTx := types.GetParaExecTitleName(string(tx.Execer))
   384  		//记录主链交易的index。主链交易肯定是从0开始的
   385  		if !haveParaTx && 0 == i {
   386  			childchains = append(childchains, types.ChildChain{Title: types.MainChainName, StartIndex: 0})
   387  		} else if (haveParaTx && 0 == len(fristParaTitle)) || (haveParaTx && paraTitle != fristParaTitle) {
   388  			//第一个平行链交易或者不同平行链的交易需要更新fristParaTitle以及子链信息
   389  			fristParaTitle = paraTitle
   390  			childchains = append(childchains, types.ChildChain{Title: paraTitle, StartIndex: int32(i)})
   391  		}
   392  	}
   393  	chainCount := len(childchains)
   394  
   395  	//全是主链或者全是同一个平行链的交易。
   396  	//直接调用calcSingleLayerMerkleRoot计算roothash即可
   397  	if chainCount <= 1 {
   398  		merkleRoot := calcSingleLayerMerkleRoot(txs)
   399  		childchains[0].ChildHash = merkleRoot
   400  		childchains[0].TxCount = int32(txsCount)
   401  		return merkleRoot, childchains
   402  	}
   403  
   404  	//并行计算每个子链的roothash
   405  	ch := make(chan *childstate, chainCount)
   406  	for index := 0; index < chainCount; index++ {
   407  
   408  		start := childchains[index].StartIndex
   409  		var end int
   410  		if index == chainCount-1 {
   411  			end = txsCount
   412  		} else {
   413  			end = int(childchains[index+1].StartIndex)
   414  		}
   415  		childchains[index].TxCount = int32(end) - start
   416  		go func(index int, subtxs []*types.Transaction) {
   417  			subChainRoot := calcSingleLayerMerkleRoot(subtxs)
   418  			ch <- &childstate{
   419  				hash:  subChainRoot,
   420  				index: index,
   421  			}
   422  		}(index, txs[start:end])
   423  	}
   424  
   425  	childlist := make([][]byte, chainCount)
   426  	for i := 0; i < chainCount; i++ {
   427  		sub := <-ch
   428  		childlist[sub.index] = sub.hash
   429  		childchains[sub.index].ChildHash = sub.hash
   430  	}
   431  	merkleroot := GetMerkleRoot(childlist)
   432  	if merkleroot == nil {
   433  		panic("calc merkle root is nil!")
   434  	}
   435  	return merkleroot, childchains
   436  }