github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/common/merkle_tree.go (about)

     1  package common
     2  
     3  import "crypto/sha256"
     4  
     5  // param hashes will be used as workspace
     6  func ComputeMerkleRoot(hashes []Hash) Hash {
     7  	if len(hashes) == 0 {
     8  		return Hash{}
     9  	}
    10  	sha := sha256.New()
    11  	var temp Hash
    12  	for len(hashes) != 1 {
    13  		n := len(hashes) / 2
    14  		for i := 0; i < n; i++ {
    15  			sha.Reset()
    16  			sha.Write(hashes[2*i][:])
    17  			sha.Write(hashes[2*i+1][:])
    18  			sha.Sum(temp[:0])
    19  			sha.Reset()
    20  			sha.Write(temp[:])
    21  			sha.Sum(hashes[i][:0])
    22  		}
    23  		if len(hashes) == 2*n+1 {
    24  			sha.Reset()
    25  			sha.Write(hashes[2*n][:])
    26  			sha.Write(hashes[2*n][:])
    27  
    28  			sha.Sum(temp[:0])
    29  			sha.Reset()
    30  			sha.Write(temp[:])
    31  			sha.Sum(hashes[n][:0])
    32  
    33  			hashes = hashes[:n+1]
    34  		} else {
    35  			hashes = hashes[:n]
    36  		}
    37  	}
    38  
    39  	return hashes[0]
    40  }