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  }