Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
sign.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2016 The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include <script/sign.h>
7
8#include <consensus/amount.h>
9#include <key.h>
10#include <policy/policy.h>
13#include <script/standard.h>
14#include <uint256.h>
15
16typedef std::vector<uint8_t> valtype;
17
23
25 const SigningProvider &provider, std::vector<uint8_t> &vchSig,
26 const CKeyID &address, const CScript &scriptCode) const {
27 CKey key;
28 if (!provider.GetKey(address, key)) {
29 return false;
30 }
31
32 uint256 hash = SignatureHash(scriptCode, *txTo, nIn, sigHashType, amount);
33 if (!key.SignECDSA(hash, vchSig)) {
34 return false;
35 }
36
38 return true;
39}
40
41static bool GetCScript(const SigningProvider &provider,
42 const SignatureData &sigdata, const CScriptID &scriptid,
43 CScript &script) {
44 if (provider.GetCScript(scriptid, script)) {
45 return true;
46 }
47 // Look for scripts in SignatureData
48 if (CScriptID(sigdata.redeem_script) == scriptid) {
49 script = sigdata.redeem_script;
50 return true;
51 }
52 return false;
53}
54
55static bool GetPubKey(const SigningProvider &provider,
56 const SignatureData &sigdata, const CKeyID &address,
57 CPubKey &pubkey) {
58 // Look for pubkey in all partial sigs
59 const auto it = sigdata.signatures.find(address);
60 if (it != sigdata.signatures.end()) {
61 pubkey = it->second.first;
62 return true;
63 }
64 // Look for pubkey in pubkey list
65 const auto &pk_it = sigdata.misc_pubkeys.find(address);
66 if (pk_it != sigdata.misc_pubkeys.end()) {
67 pubkey = pk_it->second.first;
68 return true;
69 }
70 // Query the underlying provider
71 return provider.GetPubKey(address, pubkey);
72}
73
75 SignatureData &sigdata, const SigningProvider &provider,
76 std::vector<uint8_t> &sig_out, const CPubKey &pubkey,
77 const CScript &scriptcode) {
78 CKeyID keyid = pubkey.GetID();
79 const auto it = sigdata.signatures.find(keyid);
80 if (it != sigdata.signatures.end()) {
81 sig_out = it->second.second;
82 return true;
83 }
84 KeyOriginInfo info;
85 if (provider.GetKeyOrigin(keyid, info)) {
86 sigdata.misc_pubkeys.emplace(keyid,
87 std::make_pair(pubkey, std::move(info)));
88 }
89 if (creator.CreateSig(provider, sig_out, keyid, scriptcode)) {
90 auto i = sigdata.signatures.emplace(keyid, SigPair(pubkey, sig_out));
91 assert(i.second);
92 return true;
93 }
94 // Could not make signature or signature not found, add keyid to missing
95 sigdata.missing_sigs.push_back(keyid);
96 return false;
97}
98
106static bool SignStep(const SigningProvider &provider,
108 const CScript &scriptPubKey, std::vector<valtype> &ret,
112 ret.clear();
113 std::vector<uint8_t> sig;
114
115 std::vector<valtype> vSolutions;
116 whichTypeRet = Solver(scriptPubKey, vSolutions);
117
118 switch (whichTypeRet) {
121 return false;
123 if (!CreateSig(creator, sigdata, provider, sig,
124 CPubKey(vSolutions[0]), scriptPubKey)) {
125 return false;
126 }
127 ret.push_back(std::move(sig));
128 return true;
131 CPubKey pubkey;
132 if (!GetPubKey(provider, sigdata, keyID, pubkey)) {
133 // Pubkey could not be found, add to missing
134 sigdata.missing_pubkeys.push_back(keyID);
135 return false;
136 }
137 if (!CreateSig(creator, sigdata, provider, sig, pubkey,
138 scriptPubKey)) {
139 return false;
140 }
141 ret.push_back(std::move(sig));
142 ret.push_back(ToByteVector(pubkey));
143 return true;
144 }
146 h160 = uint160(vSolutions[0]);
147 if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) {
148 ret.push_back(
149 std::vector<uint8_t>(scriptRet.begin(), scriptRet.end()));
150 return true;
151 }
152 // Could not find redeemScript, add to missing
153 sigdata.missing_redeem_script = h160;
154 return false;
155 case TxoutType::MULTISIG: {
156 size_t required = vSolutions.front()[0];
157 // workaround CHECKMULTISIG bug
158 ret.push_back(valtype());
159 for (size_t i = 1; i < vSolutions.size() - 1; ++i) {
160 CPubKey pubkey = CPubKey(vSolutions[i]);
161 // We need to always call CreateSig in order to fill sigdata
162 // with all possible signatures that we can create. This will
163 // allow further PSBT processing to work as it needs all
164 // possible signature and pubkey pairs
165 if (CreateSig(creator, sigdata, provider, sig, pubkey,
166 scriptPubKey)) {
167 if (ret.size() < required + 1) {
168 ret.push_back(std::move(sig));
169 }
170 }
171 }
172 bool ok = ret.size() == required + 1;
173 for (size_t i = 0; i + ret.size() < required + 1; ++i) {
174 ret.push_back(valtype());
175 }
176 return ok;
177 }
178 default:
179 return false;
180 }
181}
182
183static CScript PushAll(const std::vector<valtype> &values) {
184 CScript result;
185 for (const valtype &v : values) {
186 if (v.size() == 0) {
187 result << OP_0;
188 } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) {
189 result << CScript::EncodeOP_N(v[0]);
190 } else {
191 result << v;
192 }
193 }
194
195 return result;
196}
197
200 const CScript &fromPubKey, SignatureData &sigdata) {
201 if (sigdata.complete) {
202 return true;
203 }
204
205 std::vector<valtype> result;
207 bool solved =
208 SignStep(provider, creator, fromPubKey, result, whichType, sigdata);
210
212 // Solver returns the subscript that needs to be evaluated; the final
213 // scriptSig is the signatures from that and then the serialized
214 // subscript:
215 subscript = CScript(result[0].begin(), result[0].end());
216 sigdata.redeem_script = subscript;
217
218 solved = solved &&
219 SignStep(provider, creator, subscript, result, whichType,
220 sigdata) &&
222 result.push_back(
223 std::vector<uint8_t>(subscript.begin(), subscript.end()));
224 }
225
226 sigdata.scriptSig = PushAll(result);
227
228 // Test solution
229 sigdata.complete =
232 return sigdata.complete;
233}
234
235namespace {
236class SignatureExtractorChecker final : public BaseSignatureChecker {
237private:
238 SignatureData &sigdata;
239 BaseSignatureChecker &checker;
240
241public:
242 SignatureExtractorChecker(SignatureData &sigdata_,
244 : sigdata(sigdata_), checker(checker_) {}
245 bool CheckSig(const std::vector<uint8_t> &scriptSig,
246 const std::vector<uint8_t> &vchPubKey,
247 const CScript &scriptCode, uint32_t flags) const override {
248 if (checker.CheckSig(scriptSig, vchPubKey, scriptCode, flags)) {
249 CPubKey pubkey(vchPubKey);
250
251 sigdata.signatures.emplace(pubkey.GetID(),
252 SigPair(pubkey, scriptSig));
253 return true;
254 }
255 return false;
256 }
257};
258
259struct Stacks {
260 std::vector<valtype> script;
261
262 Stacks() = delete;
263 Stacks(const Stacks &) = delete;
264 explicit Stacks(const SignatureData &data) {
265 if (data.scriptSig.IsPushOnly()) {
268 }
269 }
270};
271} // namespace
272
273// Extracts signatures and scripts from incomplete scriptSigs. Please do not
274// extend this, use PSBT instead
276 unsigned int nIn, const CTxOut &txout) {
277 SignatureData data;
278 assert(tx.vin.size() > nIn);
279 data.scriptSig = tx.vin[nIn].scriptSig;
280 Stacks stack(data);
281
282 // Get signatures
284 SignatureExtractorChecker extractor_checker(data, tx_checker);
285 if (VerifyScript(data.scriptSig, txout.scriptPubKey,
287 data.complete = true;
288 return data;
289 }
290
291 // Get scripts
292 std::vector<std::vector<uint8_t>> solutions;
295
296 if (script_type == TxoutType::SCRIPTHASH && !stack.script.empty() &&
297 !stack.script.back().empty()) {
298 // Get the redeemScript
299 CScript redeem_script(stack.script.back().begin(),
300 stack.script.back().end());
301 data.redeem_script = redeem_script;
302 next_script = std::move(redeem_script);
303
304 // Get redeemScript type
306 stack.script.pop_back();
307 }
308 if (script_type == TxoutType::MULTISIG && !stack.script.empty()) {
309 // Build a map of pubkey -> signature by matching sigs to pubkeys:
310 assert(solutions.size() > 1);
311 unsigned int num_pubkeys = solutions.size() - 2;
312 unsigned int last_success_key = 0;
313 for (const valtype &sig : stack.script) {
314 for (unsigned int i = last_success_key; i < num_pubkeys; ++i) {
315 const valtype &pubkey = solutions[i + 1];
316 // We either have a signature for this pubkey, or we have found
317 // a signature and it is valid
318 if (data.signatures.count(CPubKey(pubkey).GetID()) ||
319 extractor_checker.CheckSig(sig, pubkey, next_script,
321 last_success_key = i + 1;
322 break;
323 }
324 }
325 }
326 }
327
328 return data;
329}
330
331void UpdateInput(CTxIn &input, const SignatureData &data) {
332 input.scriptSig = data.scriptSig;
333}
334
336 if (complete) {
337 return;
338 }
339 if (sigdata.complete) {
340 *this = std::move(sigdata);
341 return;
342 }
343 if (redeem_script.empty() && !sigdata.redeem_script.empty()) {
345 }
346 signatures.insert(std::make_move_iterator(sigdata.signatures.begin()),
347 std::make_move_iterator(sigdata.signatures.end()));
348}
349
350bool SignSignature(const SigningProvider &provider, const CScript &fromPubKey,
351 CMutableTransaction &txTo, unsigned int nIn,
352 const Amount amount, SigHashType sigHashType) {
353 assert(nIn < txTo.vin.size());
354
355 MutableTransactionSignatureCreator creator(&txTo, nIn, amount, sigHashType);
356
357 SignatureData sigdata;
358 bool ret = ProduceSignature(provider, creator, fromPubKey, sigdata);
359 UpdateInput(txTo.vin.at(nIn), sigdata);
360 return ret;
361}
362
364 CMutableTransaction &txTo, unsigned int nIn,
365 SigHashType sigHashType) {
366 assert(nIn < txTo.vin.size());
367 const CTxIn &txin = txTo.vin[nIn];
368 assert(txin.prevout.GetN() < txFrom.vout.size());
369 const CTxOut &txout = txFrom.vout[txin.prevout.GetN()];
370
371 return SignSignature(provider, txout.scriptPubKey, txTo, nIn, txout.nValue,
372 sigHashType);
373}
374
375namespace {
377class DummySignatureChecker final : public BaseSignatureChecker {
378public:
379 DummySignatureChecker() {}
380 bool CheckSig(const std::vector<uint8_t> &scriptSig,
381 const std::vector<uint8_t> &vchPubKey,
382 const CScript &scriptCode, uint32_t flags) const override {
383 return true;
384 }
385};
386const DummySignatureChecker DUMMY_CHECKER;
387
388class DummySignatureCreator final : public BaseSignatureCreator {
389private:
390 char m_r_len = 32;
391 char m_s_len = 32;
392
393public:
394 DummySignatureCreator(char r_len, char s_len)
395 : m_r_len(r_len), m_s_len(s_len) {}
396 const BaseSignatureChecker &Checker() const override {
397 return DUMMY_CHECKER;
398 }
399 bool CreateSig(const SigningProvider &provider,
400 std::vector<uint8_t> &vchSig, const CKeyID &keyid,
401 const CScript &scriptCode) const override {
402 // Create a dummy signature that is a valid DER-encoding
403 vchSig.assign(m_r_len + m_s_len + 7, '\000');
404 vchSig[0] = 0x30;
405 vchSig[1] = m_r_len + m_s_len + 4;
406 vchSig[2] = 0x02;
407 vchSig[3] = m_r_len;
408 vchSig[4] = 0x01;
409 vchSig[4 + m_r_len] = 0x02;
410 vchSig[5 + m_r_len] = m_s_len;
411 vchSig[6 + m_r_len] = 0x01;
412 vchSig[6 + m_r_len + m_s_len] = SIGHASH_ALL | SIGHASH_FORKID;
413 return true;
414 }
415};
416
417} // namespace
418
420 DummySignatureCreator(32, 32);
422 DummySignatureCreator(33, 32);
423
424bool IsSolvable(const SigningProvider &provider, const CScript &script) {
425 // This check is to make sure that the script we created can actually be
426 // solved for and signed by us if we were to have the private keys. This is
427 // just to make sure that the script is valid and that, if found in a
428 // transaction, we would still accept and relay that transaction.
429 SignatureData sigs;
430 if (ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, script, sigs)) {
431 // VerifyScript check is just defensive, and should never fail.
432 bool verified =
436 return true;
437 }
438 return false;
439}
440
442 const std::map<COutPoint, Coin> &coins,
443 SigHashType sigHashType,
444 std::map<int, std::string> &input_errors) {
445 // Use CTransaction for the constant parts of the
446 // transaction to avoid rehashing.
447 const CTransaction txConst(mtx);
448 // Sign what we can:
449 for (size_t i = 0; i < mtx.vin.size(); i++) {
450 CTxIn &txin = mtx.vin[i];
451 auto coin = coins.find(txin.prevout);
452 if (coin == coins.end() || coin->second.IsSpent()) {
453 input_errors[i] = "Input not found or already spent";
454 continue;
455 }
456 const CScript &prevPubKey = coin->second.GetTxOut().scriptPubKey;
457 const Amount amount = coin->second.GetTxOut().nValue;
458
459 SignatureData sigdata =
460 DataFromTransaction(mtx, i, coin->second.GetTxOut());
461 // Only sign SIGHASH_SINGLE if there's a corresponding output:
462 if ((sigHashType.getBaseType() != BaseSigHashType::SINGLE) ||
463 (i < mtx.vout.size())) {
466 sigHashType),
467 prevPubKey, sigdata);
468 }
469
470 UpdateInput(txin, sigdata);
471
472 // amount must be specified for valid signature
473 if (amount == MAX_MONEY) {
474 input_errors[i] = "Missing amount";
475 continue;
476 }
477
479 if (!VerifyScript(
483 // Unable to sign input and verification failed (possible
484 // attempt to partially sign).
485 input_errors[i] = "Unable to sign input, invalid stack size "
486 "(possibly missing key)";
487 } else {
489 }
490 } else {
491 // If this input succeeds, make sure there is no error set for it
492 input_errors.erase(i);
493 }
494 }
495 return input_errors.empty();
496}
static constexpr Amount MAX_MONEY
No amount larger than this (in satoshi) is valid.
Definition amount.h:165
int flags
virtual bool CheckSig(const std::vector< uint8_t > &vchSigIn, const std::vector< uint8_t > &vchPubKey, const CScript &scriptCode, uint32_t flags) const
Definition interpreter.h:40
Interface for signature creators.
Definition sign.h:26
virtual bool CreateSig(const SigningProvider &provider, std::vector< uint8_t > &vchSig, const CKeyID &keyid, const CScript &scriptCode) const =0
Create a singular (non-script) signature.
virtual const BaseSignatureChecker & Checker() const =0
An encapsulated secp256k1 private key.
Definition key.h:28
bool SignECDSA(const uint256 &hash, std::vector< uint8_t > &vchSig, bool grind=true, uint32_t test_case=0) const
Create a DER-serialized ECDSA signature.
Definition key.cpp:242
A reference to a CKey: the Hash160 of its serialized public key.
Definition pubkey.h:22
A mutable version of CTransaction.
std::vector< CTxIn > vin
An encapsulated public key.
Definition pubkey.h:31
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition pubkey.h:137
Serialized script, used inside transaction inputs and outputs.
Definition script.h:431
bool IsPushOnly(const_iterator pc) const
Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical).
Definition script.cpp:404
static opcodetype EncodeOP_N(int n)
Definition script.h:520
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition standard.h:24
The basic transaction that is broadcasted on the network and contained in blocks.
An input of a transaction.
Definition transaction.h:59
CScript scriptSig
Definition transaction.h:62
An output of a transaction.
CScript scriptPubKey
Amount nValue
A signature creator for transactions.
Definition sign.h:38
MutableTransactionSignatureCreator(const CMutableTransaction *txToIn, unsigned int nInIn, const Amount &amountIn, SigHashType sigHashTypeIn=SigHashType())
Definition sign.cpp:18
bool CreateSig(const SigningProvider &provider, std::vector< uint8_t > &vchSig, const CKeyID &keyid, const CScript &scriptCode) const override
Create a singular (non-script) signature.
Definition sign.cpp:24
const CMutableTransaction * txTo
Definition sign.h:39
Signature hash type wrapper class.
Definition sighashtype.h:37
uint32_t getRawSigHashType() const
Definition sighashtype.h:83
BaseSigHashType getBaseType() const
Definition sighashtype.h:64
An interface to be implemented by keystores that support signing.
virtual bool GetCScript(const CScriptID &scriptid, CScript &script) const
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
virtual bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const
bool empty() const
Definition prevector.h:396
iterator insert(iterator pos, const T &value)
Definition prevector.h:451
void push_back(const T &value)
Definition prevector.h:539
160-bit opaque blob.
Definition uint256.h:117
256-bit opaque blob.
Definition uint256.h:129
uint256 SignatureHash(const CScript &scriptCode, const T &txTo, unsigned int nIn, SigHashType sigHashType, const Amount amount, const PrecomputedTransactionData *cache, uint32_t flags)
bool EvalScript(std::vector< valtype > &stack, const CScript &script, uint32_t flags, const BaseSignatureChecker &checker, ScriptExecutionMetrics &metrics, ScriptError *serror)
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, uint32_t flags, const BaseSignatureChecker &checker, ScriptExecutionMetrics &metricsOut, ScriptError *serror)
Execute an unlocking and locking script together.
static constexpr uint32_t STANDARD_SCRIPT_VERIFY_FLAGS
Standard script verification flags that standard transactions will comply with.
Definition policy.h:91
SchnorrSig sig
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition random.h:85
@ OP_0
Definition script.h:49
std::vector< uint8_t > ToByteVector(const T &in)
Definition script.h:42
std::string ScriptErrorString(const ScriptError serror)
ScriptError
@ INVALID_STACK_OPERATION
@ SCRIPT_VERIFY_NONE
std::vector< uint8_t > valtype
Definition sigencoding.h:16
@ SIGHASH_FORKID
Definition sighashtype.h:18
@ SIGHASH_ALL
Definition sighashtype.h:15
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
Definition sign.cpp:198
std::vector< uint8_t > valtype
Definition sign.cpp:16
void UpdateInput(CTxIn &input, const SignatureData &data)
Definition sign.cpp:331
static bool CreateSig(const BaseSignatureCreator &creator, SignatureData &sigdata, const SigningProvider &provider, std::vector< uint8_t > &sig_out, const CPubKey &pubkey, const CScript &scriptcode)
Definition sign.cpp:74
static bool SignStep(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &scriptPubKey, std::vector< valtype > &ret, TxoutType &whichTypeRet, SignatureData &sigdata)
Sign scriptPubKey using signature made with creator.
Definition sign.cpp:106
bool IsSolvable(const SigningProvider &provider, const CScript &script)
Check whether we know how to sign for an output like this, assuming we have all private keys.
Definition sign.cpp:424
const BaseSignatureCreator & DUMMY_MAXIMUM_SIGNATURE_CREATOR
A signature creator that just produces 72-byte empty signatures.
Definition sign.cpp:421
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
Definition sign.cpp:55
bool SignTransaction(CMutableTransaction &mtx, const SigningProvider *keystore, const std::map< COutPoint, Coin > &coins, SigHashType sigHashType, std::map< int, std::string > &input_errors)
Sign the CMutableTransaction.
Definition sign.cpp:441
SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn, const CTxOut &txout)
Extract signature data from a transaction input, and insert it.
Definition sign.cpp:275
static CScript PushAll(const std::vector< valtype > &values)
Definition sign.cpp:183
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR
A signature creator that just produces 71-byte empty signatures.
Definition sign.cpp:419
bool SignSignature(const SigningProvider &provider, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn, const Amount amount, SigHashType sigHashType)
Produce a script signature for a transaction.
Definition sign.cpp:350
static bool GetCScript(const SigningProvider &provider, const SignatureData &sigdata, const CScriptID &scriptid, CScript &script)
Definition sign.cpp:41
std::pair< CPubKey, std::vector< uint8_t > > SigPair
Definition sign.h:60
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< uint8_t > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition standard.cpp:108
TxoutType
Definition standard.h:38
uint160 missing_redeem_script
ScriptID of the missing redeemScript (if any)
Definition sign.h:83
std::vector< CKeyID > missing_sigs
KeyIDs of pubkeys for signatures which could not be found.
Definition sign.h:81
void MergeSignatureData(SignatureData sigdata)
Definition sign.cpp:335
std::map< CKeyID, SigPair > signatures
BIP 174 style partial signatures for the input.
Definition sign.h:76
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > misc_pubkeys
Definition sign.h:77
CScript scriptSig
The scriptSig of an input.
Definition sign.h:71
CScript redeem_script
The redeemScript (if any) for the input.
Definition sign.h:73
std::vector< CKeyID > missing_pubkeys
KeyIDs of pubkeys which could not be found.
Definition sign.h:79
bool complete
Stores whether the scriptSig are complete.
Definition sign.h:68
assert(!tx.IsCoinBase())