github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/crypto/merkle.go (about)

     1  // Copyright 2017-2018 DERO Project. All rights reserved.
     2  // Use of this source code in any form is governed by RESEARCH license.
     3  // license can be found in the LICENSE file.
     4  // GPG: 0F39 E425 8C65 3947 702A  8234 08B2 0360 A03A 9DE8
     5  //
     6  //
     7  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
     8  // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     9  // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
    10  // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    11  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    12  // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    13  // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    14  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
    15  // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    16  
    17  package crypto
    18  
    19  // this file must be moved to crypto package
    20  
    21  //import "fmt"
    22  import "math"
    23  
    24  //import "encoding/binary"
    25  
    26  //import log "github.com/sirupsen/logrus"
    27  
    28  //import "github.com/deroproject/derosuite/block"
    29  //import "github.com/deroproject/derosuite/crypto"
    30  //import "github.com/deroproject/derosuite/globals"
    31  //import "github.com/deroproject/derosuite/transaction"
    32  
    33  /* this file implements the  merkle tree hash
    34   * this is used to build a a hash of sorted Tips
    35   * this is also used build merkle hash of transactions within hash
    36   */
    37  // this merkle is not compatible with treehash that exists in block package
    38  // reason for using this version, as it has been battle tested in bitcoin, cryptonote  treehash on the otherhand is less tested
    39  
    40  // nextPowerOfTwo returns the next highest power of two from a given number if
    41  // it is not already a power of two.  This is a helper function used during the
    42  // calculation of a merkle tree.
    43  func nextPowerOfTwo(n int) int {
    44  	// Return the number if it's already a power of 2.
    45  	if n&(n-1) == 0 {
    46  		return n
    47  	}
    48  
    49  	// Figure out and return the next power of two.
    50  	exponent := uint(math.Log2(float64(n))) + 1
    51  	return 1 << exponent // 2^exponent
    52  }
    53  
    54  // HashMerkleBranches takes two hashes, treated as the left and right tree
    55  // nodes, and returns the hash of their concatenation.  This is a helper
    56  // function used to aid in the generation of a merkle tree.
    57  func HashMerkleBranches(left *Hash, right *Hash) *Hash {
    58  	// Concatenate the left and right nodes.
    59  	var hash [len(left) * 2]byte
    60  	copy(hash[:len(left)], left[:])
    61  	copy(hash[len(left):], right[:])
    62  
    63  	hash2 := Keccak256(hash[:])
    64  	return &hash2
    65  
    66  }
    67  
    68  // BuildMerkleTreeStore creates a merkle tree from a slice of transaction hashes or tips hashes,
    69  // stores it using a linear array, and returns a slice of the backing array.  A
    70  // linear array was chosen as opposed to an actual tree structure since it uses
    71  // about half as much memory.  The following describes a merkle tree and how it
    72  // is stored in a linear array.
    73  //
    74  // A merkle tree is a tree in which every non-leaf node is the hash of its
    75  // children nodes.  A diagram depicting how this works for Decred transactions
    76  // where h(x) is a blake256 hash follows:
    77  //
    78  //	         root = h1234 = h(h12 + h34)
    79  //	        /                           \
    80  //	  h12 = h(h1 + h2)            h34 = h(h3 + h4)
    81  //	   /            \              /            \
    82  //	h1 = h(tx1)  h2 = h(tx2)    h3 = h(tx3)  h4 = h(tx4)
    83  //
    84  // The above stored as a linear array is as follows:
    85  //
    86  // 	[h1 h2 h3 h4 h12 h34 root]
    87  //
    88  // As the above shows, the merkle root is always the last element in the array.
    89  //
    90  // The number of inputs is not always a power of two which results in a
    91  // balanced tree structure as above.  In that case, parent nodes with no
    92  // children are also zero and parent nodes with only a single left node
    93  // are calculated by concatenating the left node with itself before hashing.
    94  // Since this function uses nodes that are pointers to the hashes, empty nodes
    95  // will be nil.
    96  func BuildMerkleTreeStore(hashes []Hash) []*Hash {
    97  	// If there's an empty stake tree, return totally zeroed out merkle tree root
    98  	// only.
    99  	if len(hashes) == 0 {
   100  		merkles := make([]*Hash, 1)
   101  		merkles[0] = &Hash{}
   102  		return merkles
   103  	}
   104  
   105  	// Calculate how many entries are required to hold the binary merkle
   106  	// tree as a linear array and create an array of that size.
   107  	nextPoT := nextPowerOfTwo(len(hashes))
   108  	arraySize := nextPoT*2 - 1
   109  	merkles := make([]*Hash, arraySize)
   110  
   111  	// Create the base transaction hashes and populate the array with them.
   112  	for i := range hashes {
   113  		merkles[i] = &hashes[i]
   114  	}
   115  
   116  	// Start the array offset after the last transaction and adjusted to the
   117  	// next power of two.
   118  	offset := nextPoT
   119  	for i := 0; i < arraySize-1; i += 2 {
   120  		switch {
   121  		// When there is no left child node, the parent is nil too.
   122  		case merkles[i] == nil:
   123  			merkles[offset] = nil
   124  
   125  		// When there is no right child, the parent is generated by
   126  		// hashing the concatenation of the left child with itself.
   127  		case merkles[i+1] == nil:
   128  			newHash := HashMerkleBranches(merkles[i], merkles[i])
   129  			merkles[offset] = newHash
   130  
   131  		// The normal case sets the parent node to the hash of the
   132  		// concatentation of the left and right children.
   133  		default:
   134  			newHash := HashMerkleBranches(merkles[i], merkles[i+1])
   135  			merkles[offset] = newHash
   136  		}
   137  		offset++
   138  	}
   139  	return merkles
   140  }
   141  
   142  func MerkleRoot(hashes []Hash) Hash {
   143  
   144  	merkles := BuildMerkleTreeStore(hashes)
   145  	return *merkles[len(merkles)-1] //return last element
   146  }