github.com/lbryio/lbcd@v0.22.119/txscript/sign.go (about) 1 // Copyright (c) 2013-2015 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 txscript 6 7 import ( 8 "errors" 9 "fmt" 10 11 "github.com/lbryio/lbcd/btcec" 12 "github.com/lbryio/lbcd/chaincfg" 13 "github.com/lbryio/lbcd/wire" 14 btcutil "github.com/lbryio/lbcutil" 15 ) 16 17 // RawTxInWitnessSignature returns the serialized ECDA signature for the input 18 // idx of the given transaction, with the hashType appended to it. This 19 // function is identical to RawTxInSignature, however the signature generated 20 // signs a new sighash digest defined in BIP0143. 21 func RawTxInWitnessSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int, 22 amt int64, subScript []byte, hashType SigHashType, 23 key *btcec.PrivateKey) ([]byte, error) { 24 25 hash, err := calcWitnessSignatureHashRaw(subScript, sigHashes, hashType, tx, 26 idx, amt) 27 if err != nil { 28 return nil, err 29 } 30 31 signature, err := key.Sign(hash) 32 if err != nil { 33 return nil, fmt.Errorf("cannot sign tx input: %s", err) 34 } 35 36 return append(signature.Serialize(), byte(hashType)), nil 37 } 38 39 // WitnessSignature creates an input witness stack for tx to spend BTC sent 40 // from a previous output to the owner of privKey using the p2wkh script 41 // template. The passed transaction must contain all the inputs and outputs as 42 // dictated by the passed hashType. The signature generated observes the new 43 // transaction digest algorithm defined within BIP0143. 44 func WitnessSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int, amt int64, 45 subscript []byte, hashType SigHashType, privKey *btcec.PrivateKey, 46 compress bool) (wire.TxWitness, error) { 47 48 sig, err := RawTxInWitnessSignature(tx, sigHashes, idx, amt, subscript, 49 hashType, privKey) 50 if err != nil { 51 return nil, err 52 } 53 54 pk := (*btcec.PublicKey)(&privKey.PublicKey) 55 var pkData []byte 56 if compress { 57 pkData = pk.SerializeCompressed() 58 } else { 59 pkData = pk.SerializeUncompressed() 60 } 61 62 // A witness script is actually a stack, so we return an array of byte 63 // slices here, rather than a single byte slice. 64 return wire.TxWitness{sig, pkData}, nil 65 } 66 67 // RawTxInSignature returns the serialized ECDSA signature for the input idx of 68 // the given transaction, with hashType appended to it. 69 func RawTxInSignature(tx *wire.MsgTx, idx int, subScript []byte, 70 hashType SigHashType, key *btcec.PrivateKey) ([]byte, error) { 71 72 hash, err := CalcSignatureHash(subScript, hashType, tx, idx) 73 if err != nil { 74 return nil, err 75 } 76 signature, err := key.Sign(hash) 77 if err != nil { 78 return nil, fmt.Errorf("cannot sign tx input: %s", err) 79 } 80 81 return append(signature.Serialize(), byte(hashType)), nil 82 } 83 84 // SignatureScript creates an input signature script for tx to spend BTC sent 85 // from a previous output to the owner of privKey. tx must include all 86 // transaction inputs and outputs, however txin scripts are allowed to be filled 87 // or empty. The returned script is calculated to be used as the idx'th txin 88 // sigscript for tx. subscript is the PkScript of the previous output being used 89 // as the idx'th input. privKey is serialized in either a compressed or 90 // uncompressed format based on compress. This format must match the same format 91 // used to generate the payment address, or the script validation will fail. 92 func SignatureScript(tx *wire.MsgTx, idx int, subscript []byte, hashType SigHashType, privKey *btcec.PrivateKey, compress bool) ([]byte, error) { 93 sig, err := RawTxInSignature(tx, idx, subscript, hashType, privKey) 94 if err != nil { 95 return nil, err 96 } 97 98 pk := (*btcec.PublicKey)(&privKey.PublicKey) 99 var pkData []byte 100 if compress { 101 pkData = pk.SerializeCompressed() 102 } else { 103 pkData = pk.SerializeUncompressed() 104 } 105 106 return NewScriptBuilder().AddData(sig).AddData(pkData).Script() 107 } 108 109 func p2pkSignatureScript(tx *wire.MsgTx, idx int, subScript []byte, hashType SigHashType, privKey *btcec.PrivateKey) ([]byte, error) { 110 sig, err := RawTxInSignature(tx, idx, subScript, hashType, privKey) 111 if err != nil { 112 return nil, err 113 } 114 115 return NewScriptBuilder().AddData(sig).Script() 116 } 117 118 // signMultiSig signs as many of the outputs in the provided multisig script as 119 // possible. It returns the generated script and a boolean if the script fulfils 120 // the contract (i.e. nrequired signatures are provided). Since it is arguably 121 // legal to not be able to sign any of the outputs, no error is returned. 122 func signMultiSig(tx *wire.MsgTx, idx int, subScript []byte, hashType SigHashType, 123 addresses []btcutil.Address, nRequired int, kdb KeyDB) ([]byte, bool) { 124 // We start with a single OP_FALSE to work around the (now standard) 125 // but in the reference implementation that causes a spurious pop at 126 // the end of OP_CHECKMULTISIG. 127 builder := NewScriptBuilder().AddOp(OP_FALSE) 128 signed := 0 129 for _, addr := range addresses { 130 key, _, err := kdb.GetKey(addr) 131 if err != nil { 132 continue 133 } 134 sig, err := RawTxInSignature(tx, idx, subScript, hashType, key) 135 if err != nil { 136 continue 137 } 138 139 builder.AddData(sig) 140 signed++ 141 if signed == nRequired { 142 break 143 } 144 145 } 146 147 script, _ := builder.Script() 148 return script, signed == nRequired 149 } 150 151 func sign(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, 152 subScript []byte, hashType SigHashType, kdb KeyDB, sdb ScriptDB) ([]byte, 153 ScriptClass, []btcutil.Address, int, error) { 154 155 class, addresses, nrequired, err := ExtractPkScriptAddrs(subScript, 156 chainParams) 157 if err != nil { 158 return nil, NonStandardTy, nil, 0, err 159 } 160 161 switch class { 162 case PubKeyTy: 163 // look up key for address 164 key, _, err := kdb.GetKey(addresses[0]) 165 if err != nil { 166 return nil, class, nil, 0, err 167 } 168 169 script, err := p2pkSignatureScript(tx, idx, subScript, hashType, 170 key) 171 if err != nil { 172 return nil, class, nil, 0, err 173 } 174 175 return script, class, addresses, nrequired, nil 176 case PubKeyHashTy: 177 // look up key for address 178 key, compressed, err := kdb.GetKey(addresses[0]) 179 if err != nil { 180 return nil, class, nil, 0, err 181 } 182 183 script, err := SignatureScript(tx, idx, subScript, hashType, 184 key, compressed) 185 if err != nil { 186 return nil, class, nil, 0, err 187 } 188 189 return script, class, addresses, nrequired, nil 190 case ScriptHashTy: 191 script, err := sdb.GetScript(addresses[0]) 192 if err != nil { 193 return nil, class, nil, 0, err 194 } 195 196 return script, class, addresses, nrequired, nil 197 case MultiSigTy: 198 script, _ := signMultiSig(tx, idx, subScript, hashType, 199 addresses, nrequired, kdb) 200 return script, class, addresses, nrequired, nil 201 case NullDataTy: 202 return nil, class, nil, 0, 203 errors.New("can't sign NULLDATA transactions") 204 default: 205 return nil, class, nil, 0, 206 errors.New("can't sign unknown transactions") 207 } 208 } 209 210 // mergeMultiSig combines the two signature scripts sigScript and prevScript 211 // that both provide signatures for pkScript in output idx of tx. addresses 212 // and nRequired should be the results from extracting the addresses from 213 // pkScript. Since this function is internal only we assume that the arguments 214 // have come from other functions internally and thus are all consistent with 215 // each other, behaviour is undefined if this contract is broken. 216 // 217 // NOTE: This function is only valid for version 0 scripts. Since the function 218 // does not accept a script version, the results are undefined for other script 219 // versions. 220 func mergeMultiSig(tx *wire.MsgTx, idx int, addresses []btcutil.Address, 221 nRequired int, pkScript, sigScript, prevScript []byte) []byte { 222 223 // Nothing to merge if either the new or previous signature scripts are 224 // empty. 225 if len(sigScript) == 0 { 226 return prevScript 227 } 228 if len(prevScript) == 0 { 229 return sigScript 230 } 231 232 // Convenience function to avoid duplication. 233 var possibleSigs [][]byte 234 extractSigs := func(script []byte) error { 235 const scriptVersion = 0 236 tokenizer := MakeScriptTokenizer(scriptVersion, script) 237 for tokenizer.Next() { 238 if data := tokenizer.Data(); len(data) != 0 { 239 possibleSigs = append(possibleSigs, data) 240 } 241 } 242 return tokenizer.Err() 243 } 244 245 // Attempt to extract signatures from the two scripts. Return the other 246 // script that is intended to be merged in the case signature extraction 247 // fails for some reason. 248 if err := extractSigs(sigScript); err != nil { 249 return prevScript 250 } 251 if err := extractSigs(prevScript); err != nil { 252 return sigScript 253 } 254 255 // Now we need to match the signatures to pubkeys, the only real way to 256 // do that is to try to verify them all and match it to the pubkey 257 // that verifies it. we then can go through the addresses in order 258 // to build our script. Anything that doesn't parse or doesn't verify we 259 // throw away. 260 addrToSig := make(map[string][]byte) 261 sigLoop: 262 for _, sig := range possibleSigs { 263 264 // can't have a valid signature that doesn't at least have a 265 // hashtype, in practise it is even longer than this. but 266 // that'll be checked next. 267 if len(sig) < 1 { 268 continue 269 } 270 tSig := sig[:len(sig)-1] 271 hashType := SigHashType(sig[len(sig)-1]) 272 273 pSig, err := btcec.ParseDERSignature(tSig, btcec.S256()) 274 if err != nil { 275 continue 276 } 277 278 // We have to do this each round since hash types may vary 279 // between signatures and so the hash will vary. We can, 280 // however, assume no sigs etc are in the script since that 281 // would make the transaction nonstandard and thus not 282 // MultiSigTy, so we just need to hash the full thing. 283 hash := calcSignatureHash(pkScript, hashType, tx, idx) 284 285 for _, addr := range addresses { 286 // All multisig addresses should be pubkey addresses 287 // it is an error to call this internal function with 288 // bad input. 289 pkaddr := addr.(*btcutil.AddressPubKey) 290 291 pubKey := pkaddr.PubKey() 292 293 // If it matches we put it in the map. We only 294 // can take one signature per public key so if we 295 // already have one, we can throw this away. 296 if pSig.Verify(hash, pubKey) { 297 aStr := addr.EncodeAddress() 298 if _, ok := addrToSig[aStr]; !ok { 299 addrToSig[aStr] = sig 300 } 301 continue sigLoop 302 } 303 } 304 } 305 306 // Extra opcode to handle the extra arg consumed (due to previous bugs 307 // in the reference implementation). 308 builder := NewScriptBuilder().AddOp(OP_FALSE) 309 doneSigs := 0 310 // This assumes that addresses are in the same order as in the script. 311 for _, addr := range addresses { 312 sig, ok := addrToSig[addr.EncodeAddress()] 313 if !ok { 314 continue 315 } 316 builder.AddData(sig) 317 doneSigs++ 318 if doneSigs == nRequired { 319 break 320 } 321 } 322 323 // padding for missing ones. 324 for i := doneSigs; i < nRequired; i++ { 325 builder.AddOp(OP_0) 326 } 327 328 script, _ := builder.Script() 329 return script 330 } 331 332 // mergeScripts merges sigScript and prevScript assuming they are both 333 // partial solutions for pkScript spending output idx of tx. class, addresses 334 // and nrequired are the result of extracting the addresses from pkscript. 335 // The return value is the best effort merging of the two scripts. Calling this 336 // function with addresses, class and nrequired that do not match pkScript is 337 // an error and results in undefined behaviour. 338 // 339 // NOTE: This function is only valid for version 0 scripts. Since the function 340 // does not accept a script version, the results are undefined for other script 341 // versions. 342 func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, 343 pkScript []byte, class ScriptClass, addresses []btcutil.Address, 344 nRequired int, sigScript, prevScript []byte) []byte { 345 346 // TODO(oga) the scripthash and multisig paths here are overly 347 // inefficient in that they will recompute already known data. 348 // some internal refactoring could probably make this avoid needless 349 // extra calculations. 350 const scriptVersion = 0 351 switch class { 352 case ScriptHashTy: 353 // Nothing to merge if either the new or previous signature 354 // scripts are empty or fail to parse. 355 if len(sigScript) == 0 || 356 checkScriptParses(scriptVersion, sigScript) != nil { 357 358 return prevScript 359 } 360 if len(prevScript) == 0 || 361 checkScriptParses(scriptVersion, prevScript) != nil { 362 363 return sigScript 364 } 365 366 // Remove the last push in the script and then recurse. 367 // this could be a lot less inefficient. 368 // 369 // Assume that final script is the correct one since it was just 370 // made and it is a pay-to-script-hash. 371 script := finalOpcodeData(scriptVersion, sigScript) 372 373 // We already know this information somewhere up the stack, 374 // therefore the error is ignored. 375 class, addresses, nrequired, _ := 376 ExtractPkScriptAddrs(script, chainParams) 377 378 // Merge 379 mergedScript := mergeScripts(chainParams, tx, idx, script, 380 class, addresses, nrequired, sigScript, prevScript) 381 382 // Reappend the script and return the result. 383 builder := NewScriptBuilder() 384 builder.AddOps(mergedScript) 385 builder.AddData(script) 386 finalScript, _ := builder.Script() 387 return finalScript 388 389 case MultiSigTy: 390 return mergeMultiSig(tx, idx, addresses, nRequired, pkScript, 391 sigScript, prevScript) 392 393 // It doesn't actually make sense to merge anything other than multiig 394 // and scripthash (because it could contain multisig). Everything else 395 // has either zero signature, can't be spent, or has a single signature 396 // which is either present or not. The other two cases are handled 397 // above. In the conflict case here we just assume the longest is 398 // correct (this matches behaviour of the reference implementation). 399 default: 400 if len(sigScript) > len(prevScript) { 401 return sigScript 402 } 403 return prevScript 404 } 405 } 406 407 // KeyDB is an interface type provided to SignTxOutput, it encapsulates 408 // any user state required to get the private keys for an address. 409 type KeyDB interface { 410 GetKey(btcutil.Address) (*btcec.PrivateKey, bool, error) 411 } 412 413 // KeyClosure implements KeyDB with a closure. 414 type KeyClosure func(btcutil.Address) (*btcec.PrivateKey, bool, error) 415 416 // GetKey implements KeyDB by returning the result of calling the closure. 417 func (kc KeyClosure) GetKey(address btcutil.Address) (*btcec.PrivateKey, bool, error) { 418 return kc(address) 419 } 420 421 // ScriptDB is an interface type provided to SignTxOutput, it encapsulates any 422 // user state required to get the scripts for an pay-to-script-hash address. 423 type ScriptDB interface { 424 GetScript(btcutil.Address) ([]byte, error) 425 } 426 427 // ScriptClosure implements ScriptDB with a closure. 428 type ScriptClosure func(btcutil.Address) ([]byte, error) 429 430 // GetScript implements ScriptDB by returning the result of calling the closure. 431 func (sc ScriptClosure) GetScript(address btcutil.Address) ([]byte, error) { 432 return sc(address) 433 } 434 435 // SignTxOutput signs output idx of the given tx to resolve the script given in 436 // pkScript with a signature type of hashType. Any keys required will be 437 // looked up by calling getKey() with the string of the given address. 438 // Any pay-to-script-hash signatures will be similarly looked up by calling 439 // getScript. If previousScript is provided then the results in previousScript 440 // will be merged in a type-dependent manner with the newly generated. 441 // signature script. 442 // 443 // NOTE: This function is only valid for version 0 scripts. Since the function 444 // does not accept a script version, the results are undefined for other script 445 // versions. 446 func SignTxOutput(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, 447 pkScript []byte, hashType SigHashType, kdb KeyDB, sdb ScriptDB, 448 previousScript []byte) ([]byte, error) { 449 450 sigScript, class, addresses, nrequired, err := sign(chainParams, tx, 451 idx, pkScript, hashType, kdb, sdb) 452 if err != nil { 453 return nil, err 454 } 455 456 if class == ScriptHashTy { 457 // TODO keep the sub addressed and pass down to merge. 458 realSigScript, _, _, _, err := sign(chainParams, tx, idx, 459 sigScript, hashType, kdb, sdb) 460 if err != nil { 461 return nil, err 462 } 463 464 // Append the p2sh script as the last push in the script. 465 builder := NewScriptBuilder() 466 builder.AddOps(realSigScript) 467 builder.AddData(sigScript) 468 469 sigScript, _ = builder.Script() 470 // TODO keep a copy of the script for merging. 471 } 472 473 // Merge scripts. with any previous data, if any. 474 mergedScript := mergeScripts(chainParams, tx, idx, pkScript, class, 475 addresses, nrequired, sigScript, previousScript) 476 return mergedScript, nil 477 }