Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2014 The Bitcoin developers
3 : // Copyright (c) 2016-2022 The PIVX Core developers
4 : // Distributed under the MIT software license, see the accompanying
5 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 :
7 : #include "script/sign.h"
8 :
9 : #include "key.h"
10 : #include "keystore.h"
11 : #include "policy/policy.h"
12 : #include "primitives/transaction.h"
13 : #include "script/standard.h"
14 : #include "uint256.h"
15 : #include "util/system.h"
16 :
17 : typedef std::vector<unsigned char> valtype;
18 :
19 211377 : TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
20 :
21 211391 : bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
22 : {
23 422782 : CKey key;
24 211391 : if (!keystore->GetKey(address, key))
25 : return false;
26 :
27 211383 : uint256 hash;
28 211383 : try {
29 211383 : hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion);
30 0 : } catch (const std::logic_error& ex) {
31 0 : return false;
32 : }
33 :
34 211383 : if (!key.Sign(hash, vchSig))
35 : return false;
36 211383 : vchSig.push_back((unsigned char)nHashType);
37 211383 : return true;
38 : }
39 :
40 3533307 : static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
41 : {
42 7066604 : std::vector<unsigned char> vchSig;
43 3533307 : if (!creator.CreateSig(vchSig, address, scriptCode, sigversion))
44 : return false;
45 3533295 : ret.emplace_back(vchSig);
46 : return true;
47 : }
48 :
49 278 : static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
50 : {
51 278 : int nSigned = 0;
52 278 : int nRequired = multisigdata.front()[0];
53 845 : for (unsigned int i = 1; i < multisigdata.size()-1 && nSigned < nRequired; i++)
54 : {
55 567 : const valtype& pubkey = multisigdata[i];
56 567 : CKeyID keyID = CPubKey(pubkey).GetID();
57 567 : if (Sign1(keyID, creator, scriptCode, ret, sigversion))
58 561 : ++nSigned;
59 : }
60 278 : return nSigned==nRequired;
61 : }
62 :
63 : /**
64 : * Sign scriptPubKey using signature made with creator.
65 : * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
66 : * unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
67 : * Returns false if scriptPubKey could not be completely satisfied.
68 : */
69 3533454 : static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey,
70 : std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion, bool fColdStake)
71 : {
72 7066918 : CScript scriptRet;
73 3533454 : uint160 h160;
74 3533454 : ret.clear();
75 :
76 7066918 : std::vector<valtype> vSolutions;
77 3533454 : if (!Solver(scriptPubKey, whichTypeRet, vSolutions))
78 : return false;
79 :
80 3533454 : CKeyID keyID;
81 3533454 : switch (whichTypeRet)
82 : {
83 : case TX_NONSTANDARD:
84 : case TX_NULL_DATA:
85 : return false;
86 8351 : case TX_PUBKEY:
87 8351 : keyID = CPubKey(vSolutions[0]).GetID();
88 8351 : return Sign1(keyID, creator, scriptPubKey, ret, sigversion);
89 3524180 : case TX_PUBKEYHASH:
90 3524180 : case TX_EXCHANGEADDR:
91 3524180 : keyID = CKeyID(uint160(vSolutions[0]));
92 3524180 : if (!Sign1(keyID, creator, scriptPubKey, ret, sigversion))
93 : return false;
94 : else
95 : {
96 3524170 : CPubKey vch;
97 3524170 : creator.KeyStore().GetPubKey(keyID, vch);
98 7048350 : ret.push_back(ToByteVector(vch));
99 : }
100 3524170 : return true;
101 441 : case TX_SCRIPTHASH:
102 441 : if (creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptRet)) {
103 839 : ret.emplace_back(scriptRet.begin(), scriptRet.end());
104 281 : return true;
105 : }
106 : return false;
107 :
108 278 : case TX_MULTISIG:
109 278 : ret.push_back(valtype()); // workaround CHECKMULTISIG bug
110 278 : return (SignN(vSolutions, creator, scriptPubKey, ret, sigversion));
111 :
112 210 : case TX_COLDSTAKE:
113 210 : if (fColdStake) {
114 : // sign with the cold staker key
115 80 : keyID = CKeyID(uint160(vSolutions[0]));
116 : } else {
117 : // sign with the owner key
118 130 : keyID = CKeyID(uint160(vSolutions[1]));
119 : }
120 210 : if (!Sign1(keyID, creator, scriptPubKey, ret, sigversion))
121 0 : return error("*** %s: failed to sign with the %s key.",
122 0 : __func__, fColdStake ? "cold staker" : "owner");
123 210 : CPubKey vch;
124 210 : if (!creator.KeyStore().GetPubKey(keyID, vch))
125 0 : return error("%s : Unable to get public key from keyID", __func__);
126 :
127 3533664 : valtype oper;
128 210 : oper.reserve(4);
129 340 : oper.emplace_back((fColdStake ? (int) OP_TRUE : OP_FALSE));
130 210 : ret.emplace_back(oper);
131 210 : ret.emplace_back(ToByteVector(vch));
132 210 : return true;
133 : }
134 0 : LogPrintf("*** solver no case met \n");
135 : return false;
136 : }
137 :
138 3736082 : static CScript PushAll(const std::vector<valtype>& values)
139 : {
140 3736082 : CScript result;
141 11200371 : for (const valtype& v : values) {
142 7464289 : if (v.size() == 0) {
143 298 : result << OP_0;
144 7463995 : } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) {
145 0 : result << CScript::EncodeOP_N(v[0]);
146 : } else {
147 7463995 : result << v;
148 : }
149 : }
150 3736082 : return result;
151 : }
152 :
153 3533171 : bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata, SigVersion sigversion, bool fColdStake, ScriptError* serror)
154 : {
155 3533171 : CScript script = fromPubKey;
156 3533171 : bool solved = true;
157 7066352 : std::vector<valtype> result;
158 3533171 : txnouttype whichType;
159 3533171 : solved = SignStep(creator, script, result, whichType, sigversion, fColdStake);
160 7066352 : CScript subscript;
161 :
162 3533171 : if (solved && whichType == TX_SCRIPTHASH)
163 : {
164 : // Solver returns the subscript that needs to be evaluated;
165 : // the final scriptSig is the signatures from that
166 : // and then the serialized subscript:
167 281 : script = subscript = CScript(result[0].begin(), result[0].end());
168 281 : solved = solved && SignStep(creator, script, result, whichType, sigversion, fColdStake) && whichType != TX_SCRIPTHASH;
169 839 : result.emplace_back(subscript.begin(), subscript.end());
170 : }
171 :
172 3533171 : sigdata.scriptSig = PushAll(result);
173 :
174 : // Test solution
175 7066432 : return solved && VerifyScript(sigdata.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker(), sigversion, serror);
176 : }
177 :
178 202885 : SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn)
179 : {
180 202885 : SignatureData data;
181 202885 : assert(tx.vin.size() > nIn);
182 202885 : data.scriptSig = tx.vin[nIn].scriptSig;
183 202885 : return data;
184 : }
185 :
186 214987 : void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const SignatureData& data)
187 : {
188 214987 : assert(tx.vin.size() > nIn);
189 214987 : tx.vin[nIn].scriptSig = data.scriptSig;
190 214987 : }
191 :
192 6560 : bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType, bool fColdStake)
193 : {
194 6560 : assert(nIn < txTo.vin.size());
195 :
196 6560 : CTransaction txToConst(txTo);
197 13120 : TransactionSignatureCreator creator(&keystore, &txToConst, nIn, amount, nHashType);
198 :
199 13120 : SignatureData sigdata;
200 8566 : bool ret = ProduceSignature(creator, fromPubKey, sigdata, txToConst.GetRequiredSigVersion(), fColdStake);
201 6560 : UpdateTransaction(txTo, nIn, sigdata);
202 13120 : return ret;
203 : }
204 :
205 2060 : bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType, bool fColdStake)
206 : {
207 2060 : assert(nIn < txTo.vin.size());
208 2060 : CTxIn& txin = txTo.vin[nIn];
209 2060 : assert(txin.prevout.n < txFrom.vout.size());
210 2060 : const CTxOut& txout = txFrom.vout[txin.prevout.n];
211 :
212 2060 : return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType, fColdStake);
213 : }
214 :
215 11 : static std::vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
216 : const std::vector<valtype>& vSolutions,
217 : const std::vector<valtype>& sigs1, const std::vector<valtype>& sigs2, SigVersion sigversion)
218 : {
219 : // Combine all the signatures we've got:
220 11 : std::set<valtype> allsigs;
221 38 : for (const valtype& v : sigs1)
222 : {
223 27 : if (!v.empty())
224 38 : allsigs.insert(v);
225 : }
226 33 : for (const valtype& v : sigs2)
227 : {
228 22 : if (!v.empty())
229 33 : allsigs.insert(v);
230 : }
231 :
232 : // Build a map of pubkey -> signature by matching sigs to pubkeys:
233 11 : assert(vSolutions.size() > 1);
234 11 : unsigned int nSigsRequired = vSolutions.front()[0];
235 11 : unsigned int nPubKeys = vSolutions.size()-2;
236 22 : std::map<valtype, valtype> sigs;
237 31 : for (const valtype& sig : allsigs)
238 : {
239 36 : for (unsigned int i = 0; i < nPubKeys; i++)
240 : {
241 36 : const valtype& pubkey = vSolutions[i+1];
242 36 : if (sigs.count(pubkey))
243 6 : continue; // Already got a sig for this pubkey
244 :
245 30 : if (checker.CheckSig(sig, pubkey, scriptPubKey, sigversion))
246 : {
247 20 : sigs[pubkey] = sig;
248 : break;
249 : }
250 : }
251 : }
252 : // Now build a merged CScript:
253 11 : unsigned int nSigsHave = 0;
254 11 : std::vector<valtype> result; result.emplace_back(); // pop-one-too-many workaround
255 38 : for (unsigned int i = 0; i < nPubKeys && nSigsHave < nSigsRequired; i++)
256 : {
257 34 : if (sigs.count(vSolutions[i+1]))
258 : {
259 20 : result.push_back(sigs[vSolutions[i+1]]);
260 20 : ++nSigsHave;
261 : }
262 : }
263 : // Fill any missing with OP_0:
264 13 : for (unsigned int i = nSigsHave; i < nSigsRequired; i++)
265 2 : result.push_back(valtype());
266 :
267 22 : return result;
268 : }
269 :
270 : namespace
271 : {
272 202908 : struct Stacks
273 : {
274 : std::vector<valtype> script;
275 :
276 0 : Stacks() {}
277 11 : explicit Stacks(const std::vector<valtype>& scriptSigStack_) : script(scriptSigStack_) {}
278 405808 : explicit Stacks(const SignatureData& data, SigVersion sigversion) {
279 405808 : EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), sigversion);
280 405808 : }
281 :
282 202904 : SignatureData Output() const {
283 202904 : SignatureData result;
284 202904 : result.scriptSig = PushAll(script);
285 202904 : return result;
286 : }
287 : };
288 : }
289 :
290 202908 : static Stacks CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
291 : const txnouttype txType, const std::vector<valtype>& vSolutions,
292 : Stacks sigs1, Stacks sigs2, SigVersion sigversion)
293 : {
294 202908 : switch (txType)
295 : {
296 1 : case TX_NONSTANDARD:
297 1 : case TX_NULL_DATA:
298 : // Don't know anything about this, assume bigger one is correct:
299 1 : if (sigs1.script.size() >= sigs2.script.size())
300 1 : return sigs1;
301 0 : return sigs2;
302 202883 : case TX_PUBKEY:
303 202883 : case TX_PUBKEYHASH:
304 202883 : case TX_EXCHANGEADDR:
305 202883 : case TX_COLDSTAKE:
306 : // Signatures are bigger than placeholders or empty scripts:
307 202883 : if (sigs1.script.empty() || sigs1.script[0].empty())
308 5 : return sigs2;
309 202878 : return sigs1;
310 13 : case TX_SCRIPTHASH:
311 13 : if (sigs1.script.empty() || sigs1.script.back().empty())
312 2 : return sigs2;
313 11 : else if (sigs2.script.empty() || sigs2.script.back().empty())
314 7 : return sigs1;
315 : else
316 : {
317 : // Recur to combine:
318 8 : valtype spk = sigs1.script.back();
319 8 : CScript pubKey2(spk.begin(), spk.end());
320 :
321 4 : txnouttype txType2;
322 8 : std::vector<std::vector<unsigned char> > vSolutions2;
323 4 : Solver(pubKey2, txType2, vSolutions2);
324 4 : sigs1.script.pop_back();
325 4 : sigs2.script.pop_back();
326 12 : Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, sigversion);
327 4 : result.script.push_back(spk);
328 4 : return result;
329 : }
330 11 : case TX_MULTISIG:
331 11 : return Stacks(CombineMultisig(scriptPubKey, checker, vSolutions, sigs1.script, sigs2.script, sigversion));
332 : }
333 :
334 202908 : return Stacks();
335 : }
336 :
337 202904 : SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
338 : const SignatureData& scriptSig1, const SignatureData& scriptSig2)
339 : {
340 202904 : txnouttype txType;
341 202904 : std::vector<std::vector<unsigned char> > vSolutions;
342 202904 : Solver(scriptPubKey, txType, vSolutions);
343 :
344 405808 : return CombineSignatures(scriptPubKey, checker, txType, vSolutions, Stacks(scriptSig1, SIGVERSION_BASE), Stacks(scriptSig2, SIGVERSION_BASE), SIGVERSION_BASE).Output();
345 : }
346 :
347 : namespace {
348 : /** Dummy signature checker which accepts all signatures. */
349 : class DummySignatureChecker : public BaseSignatureChecker
350 : {
351 : public:
352 : DummySignatureChecker() {}
353 :
354 6640058 : bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const
355 : {
356 6640058 : return true;
357 : }
358 : };
359 : const DummySignatureChecker dummyChecker;
360 : }
361 :
362 6639598 : const BaseSignatureChecker& DummySignatureCreator::Checker() const
363 : {
364 6639598 : return dummyChecker;
365 : }
366 :
367 3321950 : bool DummySignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const
368 : {
369 : // Create a dummy signature that is a valid DER-encoding
370 3321950 : vchSig.assign(72, '\000');
371 3321950 : vchSig[0] = 0x30;
372 3321950 : vchSig[1] = 69;
373 3321950 : vchSig[2] = 0x02;
374 3321950 : vchSig[3] = 33;
375 3321950 : vchSig[4] = 0x01;
376 3321950 : vchSig[4 + 33] = 0x02;
377 3321950 : vchSig[5 + 33] = 32;
378 3321950 : vchSig[6 + 33] = 0x01;
379 3321950 : vchSig[6 + 33 + 32] = SIGHASH_ALL;
380 3321950 : return true;
381 : }
382 :
383 : template<typename M, typename K, typename V>
384 9012 : bool LookupHelper(const M& map, const K& key, V& value)
385 : {
386 9012 : auto it = map.find(key);
387 9012 : if (it != map.end()) {
388 9012 : value = it->second;
389 9012 : return true;
390 : }
391 : return false;
392 : }
393 :
394 3318188 : bool IsSolvable(const CKeyStore& store, const CScript& script, bool fColdStaking)
395 : {
396 : // This check is to make sure that the script we created can actually be solved for and signed by us
397 : // if we were to have the private keys. This is just to make sure that the script is valid and that,
398 : // if found in a transaction, we would still accept and relay that transaction. In particular,
399 6636376 : DummySignatureCreator creator(&store);
400 6636376 : SignatureData sigs;
401 3318188 : if (ProduceSignature(creator, script, sigs, SIGVERSION_BASE, fColdStaking)) {
402 : // VerifyScript check is just defensive, and should never fail.
403 3317958 : assert(VerifyScript(sigs.scriptSig, script, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker(), SIGVERSION_BASE));
404 : return true;
405 : }
406 : return false;
407 : }
408 :
409 0 : bool PublicOnlySigningProvider::GetCScript(const CScriptID &scriptid, CScript& script) const
410 : {
411 0 : return m_provider->GetCScript(scriptid, script);
412 : }
413 :
414 0 : bool PublicOnlySigningProvider::GetPubKey(const CKeyID &address, CPubKey& pubkey) const
415 : {
416 0 : return m_provider->GetPubKey(address, pubkey);
417 : }
418 :
419 0 : bool FlatSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const { return LookupHelper(scripts, scriptid, script); }
420 0 : bool FlatSigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const { return LookupHelper(pubkeys, keyid, pubkey); }
421 9012 : bool FlatSigningProvider::GetKey(const CKeyID& keyid, CKey& key) const { return LookupHelper(keys, keyid, key); }
422 :
423 0 : FlatSigningProvider Merge(const FlatSigningProvider& a, const FlatSigningProvider& b)
424 : {
425 0 : FlatSigningProvider ret;
426 0 : ret.scripts = a.scripts;
427 0 : ret.scripts.insert(b.scripts.begin(), b.scripts.end());
428 0 : ret.pubkeys = a.pubkeys;
429 0 : ret.pubkeys.insert(b.pubkeys.begin(), b.pubkeys.end());
430 0 : ret.keys = a.keys;
431 0 : ret.keys.insert(b.keys.begin(), b.keys.end());
432 0 : return ret;
433 : }
|