Fabcoin Core  0.16.2
P2P Digital Currency
sign.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2017 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 "key.h"
9 #include "keystore.h"
10 #include "policy/policy.h"
11 #include "primitives/transaction.h"
12 #include "script/standard.h"
13 #include "uint256.h"
14 #include "coins.h"
15 
16 
17 typedef std::vector<unsigned char> valtype;
18 
19 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 bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
22 {
23  CKey key;
24  if (!keystore->GetKey(address, key))
25  return false;
26 
27  // Signing with uncompressed keys is disabled in witness scripts
28  if (sigversion == SIGVERSION_WITNESS_V0 && !key.IsCompressed())
29  return false;
30 
31  uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion);
32  if (!key.Sign(hash, vchSig))
33  return false;
34  vchSig.push_back((unsigned char)nHashType);
35  return true;
36 }
37 
38 static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
39 {
40  std::vector<unsigned char> vchSig;
41  if (!creator.CreateSig(vchSig, address, scriptCode, sigversion))
42  return false;
43  ret.push_back(vchSig);
44  return true;
45 }
46 
47 static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
48 {
49  int nSigned = 0;
50  int nRequired = multisigdata.front()[0];
51  for (unsigned int i = 1; i < multisigdata.size()-1 && nSigned < nRequired; i++)
52  {
53  const valtype& pubkey = multisigdata[i];
54  CKeyID keyID = CPubKey(pubkey).GetID();
55  if (Sign1(keyID, creator, scriptCode, ret, sigversion))
56  ++nSigned;
57  }
58  return nSigned==nRequired;
59 }
60 
67 static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey,
68  std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion)
69 {
70  CScript scriptRet;
71  uint160 h160;
72  ret.clear();
73 
74  std::vector<valtype> vSolutions;
75  if (!Solver(scriptPubKey, whichTypeRet, vSolutions))
76  return false;
77 
78  CKeyID keyID;
79  switch (whichTypeRet)
80  {
81  case TX_NONSTANDARD:
82  case TX_NULL_DATA:
83  return false;
84  case TX_PUBKEY:
85  keyID = CPubKey(vSolutions[0]).GetID();
86  return Sign1(keyID, creator, scriptPubKey, ret, sigversion);
87  case TX_PUBKEYHASH:
88  keyID = CKeyID(uint160(vSolutions[0]));
89  if (!Sign1(keyID, creator, scriptPubKey, ret, sigversion))
90  return false;
91  else
92  {
93  CPubKey vch;
94  creator.KeyStore().GetPubKey(keyID, vch);
95  ret.push_back(ToByteVector(vch));
96  }
97  return true;
98  case TX_SCRIPTHASH:
99  if (creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptRet)) {
100  ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
101  return true;
102  }
103  return false;
104 
105  case TX_MULTISIG:
106  ret.push_back(valtype()); // workaround CHECKMULTISIG bug
107  return (SignN(vSolutions, creator, scriptPubKey, ret, sigversion));
108 
110  ret.push_back(vSolutions[0]);
111  return true;
112 
114  CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160.begin());
115  if (creator.KeyStore().GetCScript(h160, scriptRet)) {
116  ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
117  return true;
118  }
119  return false;
120 
121  default:
122  return false;
123  }
124 }
125 
126 static CScript PushAll(const std::vector<valtype>& values)
127 {
128  CScript result;
129  for (const valtype& v : values) {
130  if (v.size() == 0) {
131  result << OP_0;
132  } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) {
133  result << CScript::EncodeOP_N(v[0]);
134  } else {
135  result << v;
136  }
137  }
138  return result;
139 }
140 
141 bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata)
142 {
143  CScript script = fromPubKey;
144  std::vector<valtype> result;
145  txnouttype whichType;
146  bool solved = SignStep(creator, script, result, whichType, SIGVERSION_BASE);
147  bool P2SH = false;
148  CScript subscript;
149  sigdata.scriptWitness.stack.clear();
150 
151  if (solved && whichType == TX_SCRIPTHASH)
152  {
153  // Solver returns the subscript that needs to be evaluated;
154  // the final scriptSig is the signatures from that
155  // and then the serialized subscript:
156  script = subscript = CScript(result[0].begin(), result[0].end());
157  solved = solved && SignStep(creator, script, result, whichType, SIGVERSION_BASE) && whichType != TX_SCRIPTHASH;
158  P2SH = true;
159  }
160 
161  if (solved && whichType == TX_WITNESS_V0_KEYHASH)
162  {
163  CScript witnessscript;
164  witnessscript << OP_DUP << OP_HASH160 << ToByteVector(result[0]) << OP_EQUALVERIFY << OP_CHECKSIG;
165  txnouttype subType;
166  solved = solved && SignStep(creator, witnessscript, result, subType, SIGVERSION_WITNESS_V0);
167  sigdata.scriptWitness.stack = result;
168  result.clear();
169  }
170  else if (solved && whichType == TX_WITNESS_V0_SCRIPTHASH)
171  {
172  CScript witnessscript(result[0].begin(), result[0].end());
173  txnouttype subType;
174  solved = solved && SignStep(creator, witnessscript, result, subType, SIGVERSION_WITNESS_V0) && subType != TX_SCRIPTHASH && subType != TX_WITNESS_V0_SCRIPTHASH && subType != TX_WITNESS_V0_KEYHASH;
175  result.push_back(std::vector<unsigned char>(witnessscript.begin(), witnessscript.end()));
176  sigdata.scriptWitness.stack = result;
177  result.clear();
178  }
179 
180  if (P2SH) {
181  result.push_back(std::vector<unsigned char>(subscript.begin(), subscript.end()));
182  }
183  sigdata.scriptSig = PushAll(result);
184 
185  // Test solution
186  return solved && VerifyScript(sigdata.scriptSig, fromPubKey, &sigdata.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker());
187 }
188 
190 {
192  assert(tx.vin.size() > nIn);
193  data.scriptSig = tx.vin[nIn].scriptSig;
194  data.scriptWitness = tx.vin[nIn].scriptWitness;
195  return data;
196 }
197 
199 {
200  assert(tx.vin.size() > nIn);
201  tx.vin[nIn].scriptSig = data.scriptSig;
202  tx.vin[nIn].scriptWitness = data.scriptWitness;
203 }
204 
205 bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType)
206 {
207  assert(nIn < txTo.vin.size());
208 
209  CTransaction txToConst(txTo);
210  TransactionSignatureCreator creator(&keystore, &txToConst, nIn, amount, nHashType);
211 
212  SignatureData sigdata;
213  bool ret = ProduceSignature(creator, fromPubKey, sigdata);
214  UpdateTransaction(txTo, nIn, sigdata);
215  return ret;
216 }
217 
218 bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
219 {
220  assert(nIn < txTo.vin.size());
221  CTxIn& txin = txTo.vin[nIn];
222  assert(txin.prevout.n < txFrom.vout.size());
223  const CTxOut& txout = txFrom.vout[txin.prevout.n];
224 
225  return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType);
226 }
227 
228 bool VerifySignature(const Coin& coin, const uint256 txFromHash, const CTransaction& txTo, unsigned int nIn, unsigned int flags)
229 {
230  TransactionSignatureChecker checker(&txTo, nIn, 0);
231 
232  const CTxIn& txin = txTo.vin[nIn];
233 // if (txin.prevout.n >= txFrom.vout.size())
234 // return false;
235 // const CTxOut& txout = txFrom.vout[txin.prevout.n];
236 
237  const CTxOut& txout = coin.out;
238 
239  if (txin.prevout.hash != txFromHash)
240  return false;
241 
242  return VerifyScript(txin.scriptSig, txout.scriptPubKey, NULL, flags, checker);
243 }
244 static std::vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
245  const std::vector<valtype>& vSolutions,
246  const std::vector<valtype>& sigs1, const std::vector<valtype>& sigs2, SigVersion sigversion)
247 {
248  // Combine all the signatures we've got:
249  std::set<valtype> allsigs;
250  for (const valtype& v : sigs1)
251  {
252  if (!v.empty())
253  allsigs.insert(v);
254  }
255  for (const valtype& v : sigs2)
256  {
257  if (!v.empty())
258  allsigs.insert(v);
259  }
260 
261  // Build a map of pubkey -> signature by matching sigs to pubkeys:
262  assert(vSolutions.size() > 1);
263  unsigned int nSigsRequired = vSolutions.front()[0];
264  unsigned int nPubKeys = vSolutions.size()-2;
265  std::map<valtype, valtype> sigs;
266  for (const valtype& sig : allsigs)
267  {
268  for (unsigned int i = 0; i < nPubKeys; i++)
269  {
270  const valtype& pubkey = vSolutions[i+1];
271  if (sigs.count(pubkey))
272  continue; // Already got a sig for this pubkey
273 
274  if (checker.CheckSig(sig, pubkey, scriptPubKey, sigversion))
275  {
276  sigs[pubkey] = sig;
277  break;
278  }
279  }
280  }
281  // Now build a merged CScript:
282  unsigned int nSigsHave = 0;
283  std::vector<valtype> result; result.push_back(valtype()); // pop-one-too-many workaround
284  for (unsigned int i = 0; i < nPubKeys && nSigsHave < nSigsRequired; i++)
285  {
286  if (sigs.count(vSolutions[i+1]))
287  {
288  result.push_back(sigs[vSolutions[i+1]]);
289  ++nSigsHave;
290  }
291  }
292  // Fill any missing with OP_0:
293  for (unsigned int i = nSigsHave; i < nSigsRequired; i++)
294  result.push_back(valtype());
295 
296  return result;
297 }
298 
299 namespace
300 {
301 struct Stacks
302 {
303  std::vector<valtype> script;
304  std::vector<valtype> witness;
305 
306  Stacks() {}
307  explicit Stacks(const std::vector<valtype>& scriptSigStack_) : script(scriptSigStack_), witness() {}
308  explicit Stacks(const SignatureData& data) : witness(data.scriptWitness.stack) {
310  }
311 
312  SignatureData Output() const {
313  SignatureData result;
314  result.scriptSig = PushAll(script);
315  result.scriptWitness.stack = witness;
316  return result;
317  }
318 };
319 }
320 
321 static Stacks CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
322  const txnouttype txType, const std::vector<valtype>& vSolutions,
323  Stacks sigs1, Stacks sigs2, SigVersion sigversion)
324 {
325  switch (txType)
326  {
327  case TX_NONSTANDARD:
328  case TX_NULL_DATA:
329  // Don't know anything about this, assume bigger one is correct:
330  if (sigs1.script.size() >= sigs2.script.size())
331  return sigs1;
332  return sigs2;
333  case TX_PUBKEY:
334  case TX_PUBKEYHASH:
335  // Signatures are bigger than placeholders or empty scripts:
336  if (sigs1.script.empty() || sigs1.script[0].empty())
337  return sigs2;
338  return sigs1;
340  // Signatures are bigger than placeholders or empty scripts:
341  if (sigs1.witness.empty() || sigs1.witness[0].empty())
342  return sigs2;
343  return sigs1;
344  case TX_SCRIPTHASH:
345  if (sigs1.script.empty() || sigs1.script.back().empty())
346  return sigs2;
347  else if (sigs2.script.empty() || sigs2.script.back().empty())
348  return sigs1;
349  else
350  {
351  // Recur to combine:
352  valtype spk = sigs1.script.back();
353  CScript pubKey2(spk.begin(), spk.end());
354 
355  txnouttype txType2;
356  std::vector<std::vector<unsigned char> > vSolutions2;
357  Solver(pubKey2, txType2, vSolutions2);
358  sigs1.script.pop_back();
359  sigs2.script.pop_back();
360  Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, sigversion);
361  result.script.push_back(spk);
362  return result;
363  }
364  case TX_MULTISIG:
365  return Stacks(CombineMultisig(scriptPubKey, checker, vSolutions, sigs1.script, sigs2.script, sigversion));
367  if (sigs1.witness.empty() || sigs1.witness.back().empty())
368  return sigs2;
369  else if (sigs2.witness.empty() || sigs2.witness.back().empty())
370  return sigs1;
371  else
372  {
373  // Recur to combine:
374  CScript pubKey2(sigs1.witness.back().begin(), sigs1.witness.back().end());
375  txnouttype txType2;
376  std::vector<valtype> vSolutions2;
377  Solver(pubKey2, txType2, vSolutions2);
378  sigs1.witness.pop_back();
379  sigs1.script = sigs1.witness;
380  sigs1.witness.clear();
381  sigs2.witness.pop_back();
382  sigs2.script = sigs2.witness;
383  sigs2.witness.clear();
384  Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, SIGVERSION_WITNESS_V0);
385  result.witness = result.script;
386  result.script.clear();
387  result.witness.push_back(valtype(pubKey2.begin(), pubKey2.end()));
388  return result;
389  }
390  default:
391  return Stacks();
392  }
393 }
394 
395 SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
396  const SignatureData& scriptSig1, const SignatureData& scriptSig2)
397 {
398  txnouttype txType;
399  std::vector<std::vector<unsigned char> > vSolutions;
400  Solver(scriptPubKey, txType, vSolutions);
401 
402  return CombineSignatures(scriptPubKey, checker, txType, vSolutions, Stacks(scriptSig1), Stacks(scriptSig2), SIGVERSION_BASE).Output();
403 }
404 
405 namespace {
407 class DummySignatureChecker : public BaseSignatureChecker
408 {
409 public:
410  DummySignatureChecker() {}
411 
412  bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override
413  {
414  return true;
415  }
416 };
417 const DummySignatureChecker dummyChecker;
418 } // namespace
419 
421 {
422  return dummyChecker;
423 }
424 
425 bool DummySignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const
426 {
427  // Create a dummy signature that is a valid DER-encoding
428  vchSig.assign(72, '\000');
429  vchSig[0] = 0x30;
430  vchSig[1] = 69;
431  vchSig[2] = 0x02;
432  vchSig[3] = 33;
433  vchSig[4] = 0x01;
434  vchSig[4 + 33] = 0x02;
435  vchSig[5 + 33] = 32;
436  vchSig[6 + 33] = 0x01;
437  vchSig[6 + 33 + 32] = SIGHASH_ALL;
438  return true;
439 }
void UpdateTransaction(CMutableTransaction &tx, unsigned int nIn, const SignatureData &data)
Definition: sign.cpp:198
SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn)
Extract signature data from a transaction, and insert it.
Definition: sign.cpp:189
bool Solver(const CScript &scriptPubKey, txnouttype &typeRet, std::vector< std::vector< unsigned char > > &vSolutionsRet, bool contractConsensus)
Return public keys or hashes from scriptPubKey, for &#39;standard&#39; transaction types. ...
Definition: standard.cpp:46
CScript scriptPubKey
Definition: transaction.h:135
A UTXO entry.
Definition: coins.h:29
bool SignSignature(const CKeyStore &keystore, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn, const CAmount &amount, int nHashType)
Produce a script signature for a transaction.
Definition: sign.cpp:205
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
const CKeyStore & KeyStore() const
Definition: sign.h:26
CScript scriptSig
Definition: sign.h:64
std::vector< CTxIn > vin
Definition: transaction.h:392
Virtual base class for signature creators.
Definition: sign.h:20
CTxOut out
unspent transaction output
Definition: coins.h:33
A signature creator for transactions.
Definition: sign.h:35
std::vector< std::vector< unsigned char > > stack
Definition: script.h:724
assert(len-trim+(2 *lenIndices)<=WIDTH)
unsigned char * begin()
Definition: uint256.h:65
bool ProduceSignature(const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
Definition: sign.cpp:141
const std::vector< CTxIn > vin
Definition: transaction.h:292
SignatureData CombineSignatures(const CScript &scriptPubKey, const BaseSignatureChecker &checker, const SignatureData &scriptSig1, const SignatureData &scriptSig2)
Combine two script signatures using a generic signature checker, intelligently, possibly with OP_0 pl...
Definition: sign.cpp:395
unsigned int nIn
Definition: sign.h:37
int64_t CAmount
Amount in lius (Can be negative)
Definition: amount.h:15
const CKeyStore * keystore
Definition: sign.h:22
iterator end()
Definition: prevector.h:292
uint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo, unsigned int nIn, int nHashType, const CAmount &amount, SigVersion sigversion, const PrecomputedTransactionData *cache)
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
Definition: key.h:95
const BaseSignatureChecker & Checker() const override
Definition: sign.cpp:420
An input of a transaction.
Definition: transaction.h:61
virtual bool CreateSig(std::vector< unsigned char > &vchSig, const CKeyID &keyid, const CScript &scriptCode, SigVersion sigversion) const =0
Create a singular (non-script) signature.
An encapsulated public key.
Definition: pubkey.h:39
const std::vector< CTxOut > vout
Definition: transaction.h:293
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const =0
TransactionSignatureCreator(const CKeyStore *keystoreIn, const CTransaction *txToIn, unsigned int nInIn, const CAmount &amountIn, int nHashTypeIn=SIGHASH_ALL)
Definition: sign.cpp:19
bool CreateSig(std::vector< unsigned char > &vchSig, const CKeyID &keyid, const CScript &scriptCode, SigVersion sigversion) const override
Create a singular (non-script) signature.
Definition: sign.cpp:21
An output of a transaction.
Definition: transaction.h:131
bool EvalScript(std::vector< std::vector< unsigned char > > &stack, const CScript &script, unsigned int flags, const BaseSignatureChecker &checker, SigVersion sigversion, ScriptError *serror)
CScriptWitness scriptWitness
Definition: sign.h:65
virtual bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const =0
const TransactionSignatureChecker checker
Definition: sign.h:40
CRIPEMD160 & Write(const unsigned char *data, size_t len)
Definition: ripemd160.cpp:247
CScript scriptSig
Definition: transaction.h:65
txnouttype
Definition: standard.h:51
256-bit opaque blob.
Definition: uint256.h:132
static opcodetype EncodeOP_N(int n)
Definition: script.h:610
uint8_t const size_t const size
Definition: sha3.h:20
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:417
A virtual base class for key stores.
Definition: keystore.h:18
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:29
160-bit opaque blob.
Definition: uint256.h:120
std::vector< unsigned char > valtype
Definition: sign.cpp:17
iterator begin()
Definition: prevector.h:290
bool VerifySignature(const Coin &coin, const uint256 txFromHash, const CTransaction &txTo, unsigned int nIn, unsigned int flags)
Definition: sign.cpp:228
A mutable version of CTransaction.
Definition: transaction.h:390
std::vector< unsigned char > valtype
Definition: fascstate.h:17
FixedHash< 20 > h160
Definition: FixedHash.h:341
struct evm_uint160be address(struct evm_env *env)
Definition: capi.c:13
An encapsulated private key.
Definition: key.h:35
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:275
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: ripemd160.cpp:273
bool CreateSig(std::vector< unsigned char > &vchSig, const CKeyID &keyid, const CScript &scriptCode, SigVersion sigversion) const override
Create a singular (non-script) signature.
Definition: sign.cpp:425
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:146
const CTransaction * txTo
Definition: sign.h:36
COutPoint prevout
Definition: transaction.h:64
Definition: script.h:51
uint8_t const * data
Definition: sha3.h:19
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig, uint32_t test_case=0) const
Create a DER-serialized signature.
Definition: key.cpp:160
virtual bool CheckSig(const std::vector< unsigned char > &scriptSig, const std::vector< unsigned char > &vchPubKey, const CScript &scriptCode, SigVersion sigversion) const
Definition: interpreter.h:135
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const =0
A hasher class for RIPEMD-160.
Definition: ripemd160.h:12
Definition: script.h:100
virtual const BaseSignatureChecker & Checker() const =0
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:42
SigVersion
Definition: interpreter.h:124
uint256 hash
Definition: transaction.h:21