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 }