Dash Core  0.12.2.1
P2P Digital Currency
sign.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 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 
15 #include <boost/foreach.hpp>
16 
17 using namespace std;
18 
19 typedef std::vector<unsigned char> valtype;
20 
21 TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), checker(txTo, nIn) {}
22 
23 bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode) const
24 {
25  CKey key;
26  if (!keystore->GetKey(address, key))
27  return false;
28 
29  uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType);
30  if (!key.Sign(hash, vchSig))
31  return false;
32  vchSig.push_back((unsigned char)nHashType);
33  return true;
34 }
35 
36 static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, CScript& scriptSigRet)
37 {
38  vector<unsigned char> vchSig;
39  if (!creator.CreateSig(vchSig, address, scriptCode))
40  return false;
41  scriptSigRet << vchSig;
42  return true;
43 }
44 
45 static bool SignN(const vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, CScript& scriptSigRet)
46 {
47  int nSigned = 0;
48  int nRequired = multisigdata.front()[0];
49  for (unsigned int i = 1; i < multisigdata.size()-1 && nSigned < nRequired; i++)
50  {
51  const valtype& pubkey = multisigdata[i];
52  CKeyID keyID = CPubKey(pubkey).GetID();
53  if (Sign1(keyID, creator, scriptCode, scriptSigRet))
54  ++nSigned;
55  }
56  return nSigned==nRequired;
57 }
58 
65 static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey,
66  CScript& scriptSigRet, txnouttype& whichTypeRet)
67 {
68  scriptSigRet.clear();
69 
70  vector<valtype> vSolutions;
71  if (!Solver(scriptPubKey, whichTypeRet, vSolutions))
72  return false;
73 
74  CKeyID keyID;
75  switch (whichTypeRet)
76  {
77  case TX_NONSTANDARD:
78  case TX_NULL_DATA:
79  return false;
80  case TX_PUBKEY:
81  keyID = CPubKey(vSolutions[0]).GetID();
82  return Sign1(keyID, creator, scriptPubKey, scriptSigRet);
83  case TX_PUBKEYHASH:
84  keyID = CKeyID(uint160(vSolutions[0]));
85  if (!Sign1(keyID, creator, scriptPubKey, scriptSigRet))
86  return false;
87  else
88  {
89  CPubKey vch;
90  creator.KeyStore().GetPubKey(keyID, vch);
91  scriptSigRet << ToByteVector(vch);
92  }
93  return true;
94  case TX_SCRIPTHASH:
95  return creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptSigRet);
96 
97  case TX_MULTISIG:
98  scriptSigRet << OP_0; // workaround CHECKMULTISIG bug
99  return (SignN(vSolutions, creator, scriptPubKey, scriptSigRet));
100  }
101  return false;
102 }
103 
104 bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, CScript& scriptSig)
105 {
106  txnouttype whichType;
107  if (!SignStep(creator, fromPubKey, scriptSig, whichType))
108  return false;
109 
110  if (whichType == TX_SCRIPTHASH)
111  {
112  // Solver returns the subscript that need to be evaluated;
113  // the final scriptSig is the signatures from that
114  // and then the serialized subscript:
115  CScript subscript = scriptSig;
116 
117  txnouttype subType;
118  bool fSolved =
119  SignStep(creator, subscript, scriptSig, subType) && subType != TX_SCRIPTHASH;
120  // Append serialized subscript whether or not it is completely signed:
121  scriptSig << valtype(subscript.begin(), subscript.end());
122  if (!fSolved) return false;
123  }
124 
125  // Test solution
126  return VerifyScript(scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker());
127 }
128 
129 bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
130 {
131  assert(nIn < txTo.vin.size());
132  CTxIn& txin = txTo.vin[nIn];
133 
134  CTransaction txToConst(txTo);
135  TransactionSignatureCreator creator(&keystore, &txToConst, nIn, nHashType);
136 
137  return ProduceSignature(creator, fromPubKey, txin.scriptSig);
138 }
139 
140 bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
141 {
142  assert(nIn < txTo.vin.size());
143  CTxIn& txin = txTo.vin[nIn];
144  assert(txin.prevout.n < txFrom.vout.size());
145  const CTxOut& txout = txFrom.vout[txin.prevout.n];
146 
147  return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, nHashType);
148 }
149 
150 static CScript PushAll(const vector<valtype>& values)
151 {
152  CScript result;
153  BOOST_FOREACH(const valtype& v, values)
154  result << v;
155  return result;
156 }
157 
158 static CScript CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
159  const vector<valtype>& vSolutions,
160  const vector<valtype>& sigs1, const vector<valtype>& sigs2)
161 {
162  // Combine all the signatures we've got:
163  set<valtype> allsigs;
164  BOOST_FOREACH(const valtype& v, sigs1)
165  {
166  if (!v.empty())
167  allsigs.insert(v);
168  }
169  BOOST_FOREACH(const valtype& v, sigs2)
170  {
171  if (!v.empty())
172  allsigs.insert(v);
173  }
174 
175  // Build a map of pubkey -> signature by matching sigs to pubkeys:
176  assert(vSolutions.size() > 1);
177  unsigned int nSigsRequired = vSolutions.front()[0];
178  unsigned int nPubKeys = vSolutions.size()-2;
179  map<valtype, valtype> sigs;
180  BOOST_FOREACH(const valtype& sig, allsigs)
181  {
182  for (unsigned int i = 0; i < nPubKeys; i++)
183  {
184  const valtype& pubkey = vSolutions[i+1];
185  if (sigs.count(pubkey))
186  continue; // Already got a sig for this pubkey
187 
188  if (checker.CheckSig(sig, pubkey, scriptPubKey))
189  {
190  sigs[pubkey] = sig;
191  break;
192  }
193  }
194  }
195  // Now build a merged CScript:
196  unsigned int nSigsHave = 0;
197  CScript result; result << OP_0; // pop-one-too-many workaround
198  for (unsigned int i = 0; i < nPubKeys && nSigsHave < nSigsRequired; i++)
199  {
200  if (sigs.count(vSolutions[i+1]))
201  {
202  result << sigs[vSolutions[i+1]];
203  ++nSigsHave;
204  }
205  }
206  // Fill any missing with OP_0:
207  for (unsigned int i = nSigsHave; i < nSigsRequired; i++)
208  result << OP_0;
209 
210  return result;
211 }
212 
213 static CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
214  const txnouttype txType, const vector<valtype>& vSolutions,
215  vector<valtype>& sigs1, vector<valtype>& sigs2)
216 {
217  switch (txType)
218  {
219  case TX_NONSTANDARD:
220  case TX_NULL_DATA:
221  // Don't know anything about this, assume bigger one is correct:
222  if (sigs1.size() >= sigs2.size())
223  return PushAll(sigs1);
224  return PushAll(sigs2);
225  case TX_PUBKEY:
226  case TX_PUBKEYHASH:
227  // Signatures are bigger than placeholders or empty scripts:
228  if (sigs1.empty() || sigs1[0].empty())
229  return PushAll(sigs2);
230  return PushAll(sigs1);
231  case TX_SCRIPTHASH:
232  if (sigs1.empty() || sigs1.back().empty())
233  return PushAll(sigs2);
234  else if (sigs2.empty() || sigs2.back().empty())
235  return PushAll(sigs1);
236  else
237  {
238  // Recur to combine:
239  valtype spk = sigs1.back();
240  CScript pubKey2(spk.begin(), spk.end());
241 
242  txnouttype txType2;
243  vector<vector<unsigned char> > vSolutions2;
244  Solver(pubKey2, txType2, vSolutions2);
245  sigs1.pop_back();
246  sigs2.pop_back();
247  CScript result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2);
248  result << spk;
249  return result;
250  }
251  case TX_MULTISIG:
252  return CombineMultisig(scriptPubKey, checker, vSolutions, sigs1, sigs2);
253  }
254 
255  return CScript();
256 }
257 
258 CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
259  const CScript& scriptSig1, const CScript& scriptSig2)
260 {
261  TransactionSignatureChecker checker(&txTo, nIn);
262  return CombineSignatures(scriptPubKey, checker, scriptSig1, scriptSig2);
263 }
264 
265 CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
266  const CScript& scriptSig1, const CScript& scriptSig2)
267 {
268  txnouttype txType;
269  vector<vector<unsigned char> > vSolutions;
270  Solver(scriptPubKey, txType, vSolutions);
271 
272  vector<valtype> stack1;
274  vector<valtype> stack2;
276 
277  return CombineSignatures(scriptPubKey, checker, txType, vSolutions, stack1, stack2);
278 }
279 
280 namespace {
282 class DummySignatureChecker : public BaseSignatureChecker
283 {
284 public:
285  DummySignatureChecker() {}
286 
287  bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const
288  {
289  return true;
290  }
291 };
292 const DummySignatureChecker dummyChecker;
293 }
294 
296 {
297  return dummyChecker;
298 }
299 
300 bool DummySignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode) const
301 {
302  // Create a dummy signature that is a valid DER-encoding
303  vchSig.assign(72, '\000');
304  vchSig[0] = 0x30;
305  vchSig[1] = 69;
306  vchSig[2] = 0x02;
307  vchSig[3] = 33;
308  vchSig[4] = 0x01;
309  vchSig[4 + 33] = 0x02;
310  vchSig[5 + 33] = 32;
311  vchSig[6 + 33] = 0x01;
312  vchSig[6 + 33 + 32] = SIGHASH_ALL;
313  return true;
314 }
bool CreateSig(std::vector< unsigned char > &vchSig, const CKeyID &keyid, const CScript &scriptCode) const
Definition: sign.cpp:300
bool CreateSig(std::vector< unsigned char > &vchSig, const CKeyID &keyid, const CScript &scriptCode) const
Definition: sign.cpp:23
virtual bool CheckSig(const std::vector< unsigned char > &scriptSig, const std::vector< unsigned char > &vchPubKey, const CScript &scriptCode) const
Definition: interpreter.h:98
T & back()
Definition: prevector.h:402
iterator insert(iterator pos, const T &value)
Definition: prevector.h:323
TransactionSignatureCreator(const CKeyStore *keystoreIn, const CTransaction *txToIn, unsigned int nInIn, int nHashTypeIn=SIGHASH_ALL)
Definition: sign.cpp:21
static bool SignStep(const BaseSignatureCreator &creator, const CScript &scriptPubKey, CScript &scriptSigRet, txnouttype &whichTypeRet)
Definition: sign.cpp:65
static bool Sign1(const CKeyID &address, const BaseSignatureCreator &creator, const CScript &scriptCode, CScript &scriptSigRet)
Definition: sign.cpp:36
Definition: pubkey.h:27
std::vector< CTxIn > vin
Definition: transaction.h:306
virtual bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const =0
static CScript CombineSignatures(const CScript &scriptPubKey, const BaseSignatureChecker &checker, const txnouttype txType, const vector< valtype > &vSolutions, vector< valtype > &sigs1, vector< valtype > &sigs2)
Definition: sign.cpp:213
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const =0
static CScript PushAll(const vector< valtype > &values)
Definition: sign.cpp:150
static CScript CombineMultisig(const CScript &scriptPubKey, const BaseSignatureChecker &checker, const vector< valtype > &vSolutions, const vector< valtype > &sigs1, const vector< valtype > &sigs2)
Definition: sign.cpp:158
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:144
const CTransaction * txTo
Definition: sign.h:35
iterator end()
Definition: prevector.h:272
const BaseSignatureChecker & Checker() const
Definition: sign.cpp:295
def SignatureHash(script, txTo, inIdx, hashtype)
Definition: script.py:848
bool EvalScript(vector< vector< unsigned char > > &stack, const CScript &script, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
virtual bool CreateSig(std::vector< unsigned char > &vchSig, const CKeyID &keyid, const CScript &scriptCode) const =0
unsigned int nIn
Definition: sign.h:36
const CKeyStore * keystore
Definition: sign.h:21
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
txnouttype
Definition: standard.h:45
static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS
Definition: policy.h:35
vector< unsigned char > valtype
Definition: interpreter.cpp:18
virtual const BaseSignatureChecker & Checker() const =0
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const =0
const std::vector< CTxOut > vout
Definition: transaction.h:234
std::vector< unsigned char > valtype
Definition: sign.cpp:19
bool ProduceSignature(const BaseSignatureCreator &creator, const CScript &fromPubKey, CScript &scriptSig)
Definition: sign.cpp:104
iterator begin()
Definition: prevector.h:270
bool Solver(const CScript &scriptPubKey, txnouttype &typeRet, vector< vector< unsigned char > > &vSolutionsRet)
Definition: standard.cpp:41
Definition: pubkey.h:37
void clear()
Definition: script.h:639
Definition: key.h:35
Definition: script.h:44
bool SignSignature(const CKeyStore &keystore, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn, int nHashType)
Definition: sign.cpp:129
const CKeyStore & KeyStore() const
Definition: sign.h:25
result
Definition: rpcuser.py:37
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:35
static bool SignN(const vector< valtype > &multisigdata, const BaseSignatureCreator &creator, const CScript &scriptCode, CScript &scriptSigRet)
Definition: sign.cpp:45