github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/btcutil/blockchain/merkle.go (about) 1 // Copyright (c) 2013-2016 The btcsuite developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package blockchain 6 7 import ( 8 "bytes" 9 "fmt" 10 "math" 11 12 "github.com/mit-dci/lit/btcutil" 13 "github.com/mit-dci/lit/btcutil/chaincfg/chainhash" 14 "github.com/mit-dci/lit/btcutil/txscript" 15 ) 16 17 const ( 18 // CoinbaseWitnessDataLen is the required length of the only element within 19 // the coinbase's witness data if the coinbase transaction contains a 20 // witness commitment. 21 CoinbaseWitnessDataLen = 32 22 23 // CoinbaseWitnessPkScriptLength is the length of the public key script 24 // containing an OP_RETURN, the WitnessMagicBytes, and the witness 25 // commitment itself. In order to be a valid candidate for the output 26 // containing the witness commitment 27 CoinbaseWitnessPkScriptLength = 38 28 ) 29 30 var ( 31 // WitnessMagicBytes is the prefix marker within a public key script to 32 // indicate that this output holds the witness commitment for a block. 33 // The prefix breaks down down: OP_RETURN OP_DATA_36 34 WitnessMagicBytes = []byte{ 35 txscript.OP_RETURN, 36 txscript.OP_DATA_36, 37 0xaa, 38 0x21, 39 0xa9, 40 0xed, 41 } 42 ) 43 44 // nextPowerOfTwo returns the next highest power of two from a given number if 45 // it is not already a power of two. This is a helper function used during the 46 // calculation of a merkle tree. 47 func nextPowerOfTwo(n int) int { 48 // Return the number if it's already a power of 2. 49 if n&(n-1) == 0 { 50 return n 51 } 52 53 // Figure out and return the next power of two. 54 exponent := uint(math.Log2(float64(n))) + 1 55 return 1 << exponent // 2^exponent 56 } 57 58 // HashMerkleBranches takes two hashes, treated as the left and right tree 59 // nodes, and returns the hash of their concatenation. This is a helper 60 // function used to aid in the generation of a merkle tree. 61 func HashMerkleBranches(left *chainhash.Hash, right *chainhash.Hash) *chainhash.Hash { 62 // Concatenate the left and right nodes. 63 var hash [chainhash.HashSize * 2]byte 64 copy(hash[:chainhash.HashSize], left[:]) 65 copy(hash[chainhash.HashSize:], right[:]) 66 67 newHash := chainhash.DoubleHashH(hash[:]) 68 return &newHash 69 } 70 71 // BuildMerkleTreeStore creates a merkle tree from a slice of transactions, 72 // stores it using a linear array, and returns a slice of the backing array. A 73 // linear array was chosen as opposed to an actual tree structure since it uses 74 // about half as much memory. The following describes a merkle tree and how it 75 // is stored in a linear array. 76 // 77 // A merkle tree is a tree in which every non-leaf node is the hash of its 78 // children nodes. A diagram depicting how this works for bitcoin transactions 79 // where h(x) is a double sha256 follows: 80 // 81 // root = h1234 = h(h12 + h34) 82 // / \ 83 // h12 = h(h1 + h2) h34 = h(h3 + h4) 84 // / \ / \ 85 // h1 = h(tx1) h2 = h(tx2) h3 = h(tx3) h4 = h(tx4) 86 // 87 // The above stored as a linear array is as follows: 88 // 89 // [h1 h2 h3 h4 h12 h34 root] 90 // 91 // As the above shows, the merkle root is always the last element in the array. 92 // 93 // The number of inputs is not always a power of two which results in a 94 // balanced tree structure as above. In that case, parent nodes with no 95 // children are also zero and parent nodes with only a single left node 96 // are calculated by concatenating the left node with itself before hashing. 97 // Since this function uses nodes that are pointers to the hashes, empty nodes 98 // will be nil. 99 // 100 // The additional bool parameter indicates if we are generating the merkle tree 101 // using witness transaction id's rather than regular transaction id's. This 102 // also presents an additional case wherein the wtxid of the coinbase transaction 103 // is the zeroHash. 104 func BuildMerkleTreeStore(transactions []*btcutil.Tx, witness bool) []*chainhash.Hash { 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(transactions)) 108 arraySize := nextPoT*2 - 1 109 merkles := make([]*chainhash.Hash, arraySize) 110 111 // Create the base transaction hashes and populate the array with them. 112 for i, tx := range transactions { 113 // If we're computing a witness merkle root, instead of the 114 // regular txid, we use the modified wtxid which includes a 115 // transaction's witness data within the digest. Additionally, 116 // the coinbase's wtxid is all zeroes. 117 switch { 118 case witness && i == 0: 119 var zeroHash chainhash.Hash 120 merkles[i] = &zeroHash 121 case witness: 122 wSha := tx.MsgTx().WitnessHash() 123 merkles[i] = &wSha 124 default: 125 merkles[i] = tx.Hash() 126 } 127 128 } 129 130 // Start the array offset after the last transaction and adjusted to the 131 // next power of two. 132 offset := nextPoT 133 for i := 0; i < arraySize-1; i += 2 { 134 switch { 135 // When there is no left child node, the parent is nil too. 136 case merkles[i] == nil: 137 merkles[offset] = nil 138 139 // When there is no right child, the parent is generated by 140 // hashing the concatenation of the left child with itself. 141 case merkles[i+1] == nil: 142 newHash := HashMerkleBranches(merkles[i], merkles[i]) 143 merkles[offset] = newHash 144 145 // The normal case sets the parent node to the double sha256 146 // of the concatentation of the left and right children. 147 default: 148 newHash := HashMerkleBranches(merkles[i], merkles[i+1]) 149 merkles[offset] = newHash 150 } 151 offset++ 152 } 153 154 return merkles 155 } 156 157 // ExtractWitnessCommitment attempts to locate, and return the witness 158 // commitment for a block. The witness commitment is of the form: 159 // SHA256(witness root || witness nonce). The function additionally returns a 160 // boolean indicating if the witness root was located within any of the txOut's 161 // in the passed transaction. The witness commitment is stored as the data push 162 // for an OP_RETURN with special magic bytes to aide in location. 163 func ExtractWitnessCommitment(tx *btcutil.Tx) ([]byte, bool) { 164 var witnessCommitment []byte 165 166 // The witness commitment *must* be located within one of the coinbase 167 // transaction's outputs. 168 if !IsCoinBase(tx) { 169 return witnessCommitment, false 170 } 171 172 msgTx := tx.MsgTx() 173 witFound := false 174 for i := len(msgTx.TxOut) - 1; i >= 0; i-- { 175 // The public key script that contains the witness commitment 176 // must shared a prefix with the WitnessMagicBytes, and be at 177 // least 38 bytes. 178 pkScript := msgTx.TxOut[i].PkScript 179 if len(pkScript) >= 38 && 180 bytes.HasPrefix(pkScript, WitnessMagicBytes) { 181 182 // The witness commitment itself is a 32-byte hash 183 // directly after the WitnessMagicBytes. The remaining 184 // bytes beyond the 38th byte currently have no consensus 185 // meaning. 186 witnessCommitment = msgTx.TxOut[i].PkScript[6:38] 187 witFound = true 188 break 189 } 190 } 191 192 return witnessCommitment, witFound 193 } 194 195 // ValidateWitnessCommitment validates the witness commitment (if any) found 196 // within the coinbase transaction of the passed block. 197 func ValidateWitnessCommitment(blk *btcutil.Block) error { 198 coinbaseTx := blk.Transactions()[0] 199 witnessCommitment, witnessFound := ExtractWitnessCommitment(coinbaseTx) 200 201 // If we can't find a witness commitment in any of the coinbase's 202 // outputs, then the block MUST NOT contain any transactions with 203 // witness data. 204 if !witnessFound { 205 for _, tx := range blk.Transactions() { 206 msgTx := tx.MsgTx() 207 if msgTx.HasWitness() { 208 str := fmt.Sprintf("block contains transaction with witness" + 209 " data, yet no witness commitment present") 210 return ruleError(ErrUnexpectedWitness, str) 211 } 212 } 213 return nil 214 } 215 216 // At this point the block contains a witness commitment, so the 217 // coinbase transaction MUST have exactly one witness element within 218 // its witness data and that element must be exactly 219 // CoinbaseWitnessDataLen bytes. 220 coinbaseWitness := coinbaseTx.MsgTx().TxIn[0].Witness 221 if len(coinbaseWitness) != 1 { 222 str := fmt.Sprintf("the coinbase transaction has %d items in "+ 223 "its witness stack when only one is allowed", 224 len(coinbaseWitness)) 225 return ruleError(ErrInvalidWitnessCommitment, str) 226 } 227 witnessNonce := coinbaseWitness[0] 228 if len(witnessNonce) != CoinbaseWitnessDataLen { 229 str := fmt.Sprintf("the coinbase transaction witness nonce "+ 230 "has %d bytes when it must be %d bytes", 231 len(witnessNonce), CoinbaseWitnessDataLen) 232 return ruleError(ErrInvalidWitnessCommitment, str) 233 } 234 235 // Finally, with the preliminary checks out of the way, we can check if 236 // the extracted witnessCommitment is equal to: 237 // SHA256(witnessMerkleRoot || witnessNonce). Where witnessNonce is the 238 // coinbase transaction's only witness item. 239 witnessMerkleTree := BuildMerkleTreeStore(blk.Transactions(), true) 240 witnessMerkleRoot := witnessMerkleTree[len(witnessMerkleTree)-1] 241 242 witnessPreimage := make([]byte, 64) 243 copy(witnessPreimage[:], witnessMerkleRoot[:]) 244 copy(witnessPreimage[32:], witnessNonce) 245 246 if !bytes.Equal(chainhash.DoubleHashB(witnessPreimage), witnessCommitment) { 247 str := "witness commitment does not match" 248 return ruleError(ErrWitnessCommitmentMismatch, str) 249 } 250 251 return nil 252 }