mirror of
https://github.com/dashpay/dash.git
synced 2024-12-29 05:49:11 +01:00
90154c6074
e306be742932d4ea5aca0ea4768e54b2fc3dc6a0 Use 72 byte dummy signatures when watching only inputs may be used (Andrew Chow) 48b1473c898129a99212e2db36c61cf93625ea17 Use 71 byte signature for DUMMY_SIGNATURE_CREATOR (Andrew Chow) 18dfea0dd082af18dfb02981b7ee1cd44d514388 Always create 70 byte signatures with low R values (Andrew Chow) Pull request description: When creating signatures for transactions, always make one which has a 32 byte or smaller R and 32 byte or smaller S value. This results in signatures that are always less than 71 bytes (32 byte R + 32 byte S + 6 bytes DER + 1 byte sighash) with low R values. In most cases, the signature will be 71 bytes. Because R is not mutable in the same way that S is, a low R value can only be found by trying different nonces. RFC 6979 for deterministic nonce generation has the option to specify additional entropy, so we simply use that and add a uin32_t counter which we increment in order to try different nonces. Nonces are sill deterministically generated as the nonce used will the be the first one where the counter results in a nonce that results in a low R value. Because different nonces need to be tried, time to produce a signature does increase. On average, it takes twice as long to make a signature as two signatures need to be created, on average, to find one with a low R. Having a fixed size signature makes size calculations easier and also saves half a byte of transaction size, on average. DUMMY_SIGNATURE_CREATOR has been modified to produce 71 byte dummy signatures instead of 72 byte signatures. Tree-SHA512: 3cd791505126ce92da7c631856a97ba0b59e87d9c132feff6e0eef1dc47768e81fbb38bfbe970371bedf9714b7f61a13a5fe9f30f962c81734092a4d19a4ef33
94 lines
4.4 KiB
C++
94 lines
4.4 KiB
C++
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
|
// Copyright (c) 2009-2015 The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#ifndef BITCOIN_SCRIPT_SIGN_H
|
|
#define BITCOIN_SCRIPT_SIGN_H
|
|
|
|
#include <script/interpreter.h>
|
|
|
|
class CKey;
|
|
class CKeyID;
|
|
class CScript;
|
|
class CScriptID;
|
|
class CTransaction;
|
|
|
|
struct CMutableTransaction;
|
|
|
|
/** An interface to be implemented by keystores that support signing. */
|
|
class SigningProvider
|
|
{
|
|
public:
|
|
virtual ~SigningProvider() {}
|
|
virtual bool GetCScript(const CScriptID &scriptid, CScript& script) const { return false; }
|
|
virtual bool GetPubKey(const CKeyID &address, CPubKey& pubkey) const { return false; }
|
|
virtual bool GetKey(const CKeyID &address, CKey& key) const { return false; }
|
|
};
|
|
|
|
extern const SigningProvider& DUMMY_SIGNING_PROVIDER;
|
|
|
|
/** Interface for signature creators. */
|
|
class BaseSignatureCreator {
|
|
public:
|
|
virtual ~BaseSignatureCreator() {}
|
|
virtual const BaseSignatureChecker& Checker() const =0;
|
|
|
|
/** Create a singular (non-script) signature. */
|
|
virtual bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const =0;
|
|
};
|
|
|
|
/** A signature creator for transactions. */
|
|
class MutableTransactionSignatureCreator : public BaseSignatureCreator {
|
|
const CMutableTransaction* txTo;
|
|
unsigned int nIn;
|
|
int nHashType;
|
|
CAmount amount;
|
|
const MutableTransactionSignatureChecker checker;
|
|
|
|
public:
|
|
MutableTransactionSignatureCreator(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn = SIGHASH_ALL);
|
|
const BaseSignatureChecker& Checker() const override{ return checker; }
|
|
bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override;
|
|
};
|
|
|
|
/** A signature creator that just produces 71-byte empty signatures. */
|
|
extern const BaseSignatureCreator& DUMMY_SIGNATURE_CREATOR;
|
|
/** A signature creator that just produces 72-byte empty signatures. */
|
|
extern const BaseSignatureCreator& DUMMY_MAXIMUM_SIGNATURE_CREATOR;
|
|
|
|
typedef std::pair<CPubKey, std::vector<unsigned char>> SigPair;
|
|
|
|
// This struct contains information from a transaction input and also contains signatures for that input.
|
|
// The information contained here can be used to create a signature and is also filled by ProduceSignature
|
|
// in order to construct final scriptSigs and scriptWitnesses.
|
|
struct SignatureData {
|
|
bool complete = false; ///< Stores whether the scriptSig is complete
|
|
CScript scriptSig; ///< The scriptSig of an input. Contains complete signatures or the traditional partial signatures format
|
|
CScript redeem_script; ///< The redeemScript (if any) for the input
|
|
std::map<CKeyID, SigPair> signatures; ///< BIP 174 style partial signatures for the input. May contain all signatures necessary for producing a final scriptSig.
|
|
|
|
SignatureData() {}
|
|
explicit SignatureData(const CScript& script) : scriptSig(script) {}
|
|
void MergeSignatureData(SignatureData sigdata);
|
|
};
|
|
|
|
/** Produce a script signature using a generic signature creator. */
|
|
bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata);
|
|
|
|
/** Produce a script signature for a transaction. */
|
|
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType);
|
|
bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType);
|
|
|
|
/** Extract signature data from a transaction input, and insert it. */
|
|
SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout);
|
|
void UpdateInput(CTxIn& input, const SignatureData& data);
|
|
|
|
/* Check whether we know how to sign for an output like this, assuming we
|
|
* have all private keys. While this function does not need private keys, the passed
|
|
* provider is used to look up public keys and redeemscripts by hash.
|
|
* Solvability is unrelated to whether we consider this output to be ours. */
|
|
bool IsSolvable(const SigningProvider& provider, const CScript& script);
|
|
|
|
#endif // BITCOIN_SCRIPT_SIGN_H
|