<commit_before>// Copyright (c) 2013-2015 The btcsuite developers
// Copyright (c) 2015-2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package txscript

import (
	"errors"
	"fmt"

	"github.com/decred/dcrd/chaincfg"
	"github.com/decred/dcrd/chaincfg/chainec"
	"github.com/decred/dcrd/dcrec"
	"github.com/decred/dcrd/dcrutil"
	"github.com/decred/dcrd/wire"
)

// RawTxInSignature returns the serialized ECDSA signature for the input idx of
// the given transaction, with hashType appended to it.
//
// NOTE: This function is only valid for version 0 scripts.  Since the function
// does not accept a script version, the results are undefined for other script
// versions.
func RawTxInSignature(tx *wire.MsgTx, idx int, subScript []byte,
	hashType SigHashType, key chainec.PrivateKey) ([]byte, error) {

	hash, err := CalcSignatureHash(subScript, hashType, tx, idx, nil)
	if err != nil {
		return nil, err
	}

	r, s, err := chainec.Secp256k1.Sign(key, hash)
	if err != nil {
		return nil, fmt.Errorf("cannot sign tx input: %s", err)
	}
	sig := chainec.Secp256k1.NewSignature(r, s)

	return append(sig.Serialize(), byte(hashType)), nil
}

// RawTxInSignatureAlt returns the serialized ECDSA signature for the input idx of
// the given transaction, with hashType appended to it.
//
// NOTE: This function is only valid for version 0 scripts.  Since the function
// does not accept a script version, the results are undefined for other script
// versions.
func RawTxInSignatureAlt(tx *wire.MsgTx, idx int, subScript []byte,
	hashType SigHashType, key chainec.PrivateKey, sigType dcrec.SignatureType) ([]byte,
	error) {

	hash, err := CalcSignatureHash(subScript, hashType, tx, idx, nil)
	if err != nil {
		return nil, err
	}

	var sig chainec.Signature
	switch sigType {
	case dcrec.STEd25519:
		r, s, err := chainec.Edwards.Sign(key, hash)
		if err != nil {
			return nil, fmt.Errorf("cannot sign tx input: %s", err)
		}
		sig = chainec.Edwards.NewSignature(r, s)
	case dcrec.STSchnorrSecp256k1:
		r, s, err := chainec.SecSchnorr.Sign(key, hash)
		if err != nil {
			return nil, fmt.Errorf("cannot sign tx input: %s", err)
		}
		sig = chainec.SecSchnorr.NewSignature(r, s)
	default:
		return nil, fmt.Errorf("unknown alt sig type %v", sigType)
	}

	return append(sig.Serialize(), byte(hashType)), nil
}

// SignatureScript creates an input signature script for tx to spend coins sent
// from a previous output to the owner of privKey. tx must include all
// transaction inputs and outputs, however txin scripts are allowed to be filled
// or empty. The returned script is calculated to be used as the idx'th txin
// sigscript for tx. subscript is the PkScript of the previous output being used
// as the idx'th input. privKey is serialized in either a compressed or
// uncompressed format based on compress. This format must match the same format
// used to generate the payment address, or the script validation will fail.
func SignatureScript(tx *wire.MsgTx, idx int, subscript []byte,
	hashType SigHashType, privKey chainec.PrivateKey, compress bool) ([]byte,
	error) {
	sig, err := RawTxInSignature(tx, idx, subscript, hashType, privKey)
	if err != nil {
		return nil, err
	}

	pubx, puby := privKey.Public()
	pub := chainec.Secp256k1.NewPublicKey(pubx, puby)
	var pkData []byte
	if compress {
		pkData = pub.SerializeCompressed()
	} else {
		pkData = pub.SerializeUncompressed()
	}

	return NewScriptBuilder().AddData(sig).AddData(pkData).Script()
}

// SignatureScriptAlt creates an input signature script for tx to spend coins sent
// from a previous output to the owner of privKey. tx must include all
// transaction inputs and outputs, however txin scripts are allowed to be filled
// or empty. The returned script is calculated to be used as the idx'th txin
// sigscript for tx. subscript is the PkScript of the previous output being used
// as the idx'th input. privKey is serialized in the respective format for the
// ECDSA type. This format must match the same format used to generate the payment
// address, or the script validation will fail.
func SignatureScriptAlt(tx *wire.MsgTx, idx int, subscript []byte,
	hashType SigHashType, privKey chainec.PrivateKey, compress bool,
	sigType dcrec.SignatureType) ([]byte,
	error) {
	sig, err := RawTxInSignatureAlt(tx, idx, subscript, hashType, privKey,
		sigType)
	if err != nil {
		return nil, err
	}

	pubx, puby := privKey.Public()
	var pub chainec.PublicKey
	switch sigType {
	case dcrec.STEd25519:
		pub = chainec.Edwards.NewPublicKey(pubx, puby)
	case dcrec.STSchnorrSecp256k1:
		pub = chainec.SecSchnorr.NewPublicKey(pubx, puby)
	}
	pkData := pub.Serialize()

	return NewScriptBuilder().AddData(sig).AddData(pkData).Script()
}

// p2pkSignatureScript constructs a pay-to-pubkey signature script.
func p2pkSignatureScript(tx *wire.MsgTx, idx int, subScript []byte,
	hashType SigHashType, privKey chainec.PrivateKey) ([]byte, error) {
	sig, err := RawTxInSignature(tx, idx, subScript, hashType, privKey)
	if err != nil {
		return nil, err
	}

	return NewScriptBuilder().AddData(sig).Script()
}

// p2pkSignatureScript constructs a pay-to-pubkey signature script for alternative
// ECDSA types.
func p2pkSignatureScriptAlt(tx *wire.MsgTx, idx int, subScript []byte,
	hashType SigHashType, privKey chainec.PrivateKey, sigType dcrec.SignatureType) ([]byte,
	error) {
	sig, err := RawTxInSignatureAlt(tx, idx, subScript, hashType, privKey,
		sigType)
	if err != nil {
		return nil, err
	}

	return NewScriptBuilder().AddData(sig).Script()
}

// signMultiSig signs as many of the outputs in the provided multisig script as
// possible. It returns the generated script and a boolean if the script fulfils
// the contract (i.e. nrequired signatures are provided).  Since it is arguably
// legal to not be able to sign any of the outputs, no error is returned.
func signMultiSig(tx *wire.MsgTx, idx int, subScript []byte, hashType SigHashType,
	addresses []dcrutil.Address, nRequired int, kdb KeyDB) ([]byte, bool) {
	// No need to add dummy in Decred.
	builder := NewScriptBuilder()
	signed := 0
	for _, addr := range addresses {
		key, _, err := kdb.GetKey(addr)
		if err != nil {
			continue
		}
		sig, err := RawTxInSignature(tx, idx, subScript, hashType, key)<commit_msg>txscript: Correct p2pkSignatureScriptAlt comment.<commit_after>// Copyright (c) 2013-2015 The btcsuite developers
// Copyright (c) 2015-2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package txscript

import (
	"errors"
	"fmt"

	"github.com/decred/dcrd/chaincfg"
	"github.com/decred/dcrd/chaincfg/chainec"
	"github.com/decred/dcrd/dcrec"
	"github.com/decred/dcrd/dcrutil"
	"github.com/decred/dcrd/wire"
)

// RawTxInSignature returns the serialized ECDSA signature for the input idx of
// the given transaction, with hashType appended to it.
//
// NOTE: This function is only valid for version 0 scripts.  Since the function
// does not accept a script version, the results are undefined for other script
// versions.
func RawTxInSignature(tx *wire.MsgTx, idx int, subScript []byte,
	hashType SigHashType, key chainec.PrivateKey) ([]byte, error) {

	hash, err := CalcSignatureHash(subScript, hashType, tx, idx, nil)
	if err != nil {
		return nil, err
	}

	r, s, err := chainec.Secp256k1.Sign(key, hash)
	if err != nil {
		return nil, fmt.Errorf("cannot sign tx input: %s", err)
	}
	sig := chainec.Secp256k1.NewSignature(r, s)

	return append(sig.Serialize(), byte(hashType)), nil
}

// RawTxInSignatureAlt returns the serialized ECDSA signature for the input idx of
// the given transaction, with hashType appended to it.
//
// NOTE: This function is only valid for version 0 scripts.  Since the function
// does not accept a script version, the results are undefined for other script
// versions.
func RawTxInSignatureAlt(tx *wire.MsgTx, idx int, subScript []byte,
	hashType SigHashType, key chainec.PrivateKey, sigType dcrec.SignatureType) ([]byte,
	error) {

	hash, err := CalcSignatureHash(subScript, hashType, tx, idx, nil)
	if err != nil {
		return nil, err
	}

	var sig chainec.Signature
	switch sigType {
	case dcrec.STEd25519:
		r, s, err := chainec.Edwards.Sign(key, hash)
		if err != nil {
			return nil, fmt.Errorf("cannot sign tx input: %s", err)
		}
		sig = chainec.Edwards.NewSignature(r, s)
	case dcrec.STSchnorrSecp256k1:
		r, s, err := chainec.SecSchnorr.Sign(key, hash)
		if err != nil {
			return nil, fmt.Errorf("cannot sign tx input: %s", err)
		}
		sig = chainec.SecSchnorr.NewSignature(r, s)
	default:
		return nil, fmt.Errorf("unknown alt sig type %v", sigType)
	}

	return append(sig.Serialize(), byte(hashType)), nil
}

// SignatureScript creates an input signature script for tx to spend coins sent
// from a previous output to the owner of privKey. tx must include all
// transaction inputs and outputs, however txin scripts are allowed to be filled
// or empty. The returned script is calculated to be used as the idx'th txin
// sigscript for tx. subscript is the PkScript of the previous output being used
// as the idx'th input. privKey is serialized in either a compressed or
// uncompressed format based on compress. This format must match the same format
// used to generate the payment address, or the script validation will fail.
func SignatureScript(tx *wire.MsgTx, idx int, subscript []byte,
	hashType SigHashType, privKey chainec.PrivateKey, compress bool) ([]byte,
	error) {
	sig, err := RawTxInSignature(tx, idx, subscript, hashType, privKey)
	if err != nil {
		return nil, err
	}

	pubx, puby := privKey.Public()
	pub := chainec.Secp256k1.NewPublicKey(pubx, puby)
	var pkData []byte
	if compress {
		pkData = pub.SerializeCompressed()
	} else {
		pkData = pub.SerializeUncompressed()
	}

	return NewScriptBuilder().AddData(sig).AddData(pkData).Script()
}

// SignatureScriptAlt creates an input signature script for tx to spend coins sent
// from a previous output to the owner of privKey. tx must include all
// transaction inputs and outputs, however txin scripts are allowed to be filled
// or empty. The returned script is calculated to be used as the idx'th txin
// sigscript for tx. subscript is the PkScript of the previous output being used
// as the idx'th input. privKey is serialized in the respective format for the
// ECDSA type. This format must match the same format used to generate the payment
// address, or the script validation will fail.
func SignatureScriptAlt(tx *wire.MsgTx, idx int, subscript []byte,
	hashType SigHashType, privKey chainec.PrivateKey, compress bool,
	sigType dcrec.SignatureType) ([]byte,
	error) {
	sig, err := RawTxInSignatureAlt(tx, idx, subscript, hashType, privKey,
		sigType)
	if err != nil {
		return nil, err
	}

	pubx, puby := privKey.Public()
	var pub chainec.PublicKey
	switch sigType {
	case dcrec.STEd25519:
		pub = chainec.Edwards.NewPublicKey(pubx, puby)
	case dcrec.STSchnorrSecp256k1:
		pub = chainec.SecSchnorr.NewPublicKey(pubx, puby)
	}
	pkData := pub.Serialize()

	return NewScriptBuilder().AddData(sig).AddData(pkData).Script()
}

// p2pkSignatureScript constructs a pay-to-pubkey signature script.
func p2pkSignatureScript(tx *wire.MsgTx, idx int, subScript []byte,
	hashType SigHashType, privKey chainec.PrivateKey) ([]byte, error) {
	sig, err := RawTxInSignature(tx, idx, subScript, hashType, privKey)
	if err != nil {
		return nil, err
	}

	return NewScriptBuilder().AddData(sig).Script()
}

// p2pkSignatureScriptAlt constructs a pay-to-pubkey signature script for
// alternative ECDSA types.
func p2pkSignatureScriptAlt(tx *wire.MsgTx, idx int, subScript []byte,
	hashType SigHashType, privKey chainec.PrivateKey, sigType dcrec.SignatureType) ([]byte,
	error) {

	sig, err := RawTxInSignatureAlt(tx, idx, subScript, hashType, privKey,
		sigType)
	if err != nil {
		return nil, err
	}

	return NewScriptBuilder().AddData(sig).Script()
}

// signMultiSig signs as many of the outputs in the provided multisig script as
// possible. It returns the generated script and a boolean if the script fulfils
// the contract (i.e. nrequired signatures are provided).  Since it is arguably
// legal to not be able to sign any of the outputs, no error is returned.
func signMultiSig(tx *wire.MsgTx, idx int, subScript []byte, hashType SigHashType,
	addresses []dcrutil.Address, nRequired int, kdb KeyDB) ([]byte, bool) {
	// No need to add dummy in Decred.
	builder := NewScriptBuilder()
	signed := 0
	for _, addr := range addresses {
		key, _, err := kdb.GetKey(addr)
		if err != nil {
			continue
		}
		sig, err := RawTxInSignature(tx, idx, subScript, hashType, key)
{'fraction_non_alphanumeric': 0.10145385587863463, 'fraction_numerical': 0.00845448798988622, 'mean_word_length': 4.204358552631579, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6840073', 'n_tokens_mistral': 4190, 'n_tokens_neox': 3994, 'n_words': 1484}