1 // Copyright (c) 2011-2018 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <key.h>
6 #include <keystore.h>
7 #include <policy/policy.h>
8 #include <script/script.h>
9 #include <script/script_error.h>
10 #include <script/interpreter.h>
11 #include <script/sign.h>
12 #include <script/ismine.h>
13 #include <uint256.h>
14 #include <test/test_bitcoin.h>
15 
16 
17 #include <boost/test/unit_test.hpp>
18 
BOOST_FIXTURE_TEST_SUITE(multisig_tests,BasicTestingSetup)19 BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
20 
21 static CScript
22 sign_multisig(const CScript& scriptPubKey, const std::vector<CKey>& keys, const CTransaction& transaction, int whichIn)
23 {
24     uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, SigVersion::BASE);
25 
26     CScript result;
27     result << OP_0; // CHECKMULTISIG bug workaround
28     for (const CKey &key : keys)
29     {
30         std::vector<unsigned char> vchSig;
31         BOOST_CHECK(key.Sign(hash, vchSig));
32         vchSig.push_back((unsigned char)SIGHASH_ALL);
33         result << vchSig;
34     }
35     return result;
36 }
37 
BOOST_AUTO_TEST_CASE(multisig_verify)38 BOOST_AUTO_TEST_CASE(multisig_verify)
39 {
40     unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
41 
42     ScriptError err;
43     CKey key[4];
44     CAmount amount = 0;
45     for (int i = 0; i < 4; i++)
46         key[i].MakeNewKey(true);
47 
48     CScript a_and_b;
49     a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
50 
51     CScript a_or_b;
52     a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
53 
54     CScript escrow;
55     escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
56 
57     CMutableTransaction txFrom;  // Funding transaction
58     txFrom.vout.resize(3);
59     txFrom.vout[0].scriptPubKey = a_and_b;
60     txFrom.vout[1].scriptPubKey = a_or_b;
61     txFrom.vout[2].scriptPubKey = escrow;
62 
63     CMutableTransaction txTo[3]; // Spending transaction
64     for (int i = 0; i < 3; i++)
65     {
66         txTo[i].vin.resize(1);
67         txTo[i].vout.resize(1);
68         txTo[i].vin[0].prevout.n = i;
69         txTo[i].vin[0].prevout.hash = txFrom.GetHash();
70         txTo[i].vout[0].nValue = 1;
71     }
72 
73     std::vector<CKey> keys;
74     CScript s;
75 
76     // Test a AND b:
77     keys.assign(1,key[0]);
78     keys.push_back(key[1]);
79     s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
80     BOOST_CHECK(VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err));
81     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
82 
83     for (int i = 0; i < 4; i++)
84     {
85         keys.assign(1,key[i]);
86         s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
87         BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 1: %d", i));
88         BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
89 
90         keys.assign(1,key[1]);
91         keys.push_back(key[i]);
92         s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
93         BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 2: %d", i));
94         BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
95     }
96 
97     // Test a OR b:
98     for (int i = 0; i < 4; i++)
99     {
100         keys.assign(1,key[i]);
101         s = sign_multisig(a_or_b, keys, CTransaction(txTo[1]), 0);
102         if (i == 0 || i == 1)
103         {
104             BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i));
105             BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
106         }
107         else
108         {
109             BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i));
110             BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
111         }
112     }
113     s.clear();
114     s << OP_0 << OP_1;
115     BOOST_CHECK(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err));
116     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
117 
118 
119     for (int i = 0; i < 4; i++)
120         for (int j = 0; j < 4; j++)
121         {
122             keys.assign(1,key[i]);
123             keys.push_back(key[j]);
124             s = sign_multisig(escrow, keys, CTransaction(txTo[2]), 0);
125             if (i < j && i < 3 && j < 3)
126             {
127                 BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 1: %d %d", i, j));
128                 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
129             }
130             else
131             {
132                 BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 2: %d %d", i, j));
133                 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
134             }
135         }
136 }
137 
BOOST_AUTO_TEST_CASE(multisig_IsStandard)138 BOOST_AUTO_TEST_CASE(multisig_IsStandard)
139 {
140     CKey key[4];
141     for (int i = 0; i < 4; i++)
142         key[i].MakeNewKey(true);
143 
144     txnouttype whichType;
145 
146     CScript a_and_b;
147     a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
148     BOOST_CHECK(::IsStandard(a_and_b, whichType));
149 
150     CScript a_or_b;
151     a_or_b  << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
152     BOOST_CHECK(::IsStandard(a_or_b, whichType));
153 
154     CScript escrow;
155     escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
156     BOOST_CHECK(::IsStandard(escrow, whichType));
157 
158     CScript one_of_four;
159     one_of_four << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << ToByteVector(key[3].GetPubKey()) << OP_4 << OP_CHECKMULTISIG;
160     BOOST_CHECK(!::IsStandard(one_of_four, whichType));
161 
162     CScript malformed[6];
163     malformed[0] << OP_3 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
164     malformed[1] << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
165     malformed[2] << OP_0 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
166     malformed[3] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_0 << OP_CHECKMULTISIG;
167     malformed[4] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_CHECKMULTISIG;
168     malformed[5] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey());
169 
170     for (int i = 0; i < 6; i++)
171         BOOST_CHECK(!::IsStandard(malformed[i], whichType));
172 }
173 
BOOST_AUTO_TEST_CASE(multisig_Sign)174 BOOST_AUTO_TEST_CASE(multisig_Sign)
175 {
176     // Test SignSignature() (and therefore the version of Solver() that signs transactions)
177     CBasicKeyStore keystore;
178     CKey key[4];
179     for (int i = 0; i < 4; i++)
180     {
181         key[i].MakeNewKey(true);
182         BOOST_CHECK(keystore.AddKey(key[i]));
183     }
184 
185     CScript a_and_b;
186     a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
187 
188     CScript a_or_b;
189     a_or_b  << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
190 
191     CScript escrow;
192     escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
193 
194     CMutableTransaction txFrom;  // Funding transaction
195     txFrom.vout.resize(3);
196     txFrom.vout[0].scriptPubKey = a_and_b;
197     txFrom.vout[1].scriptPubKey = a_or_b;
198     txFrom.vout[2].scriptPubKey = escrow;
199 
200     CMutableTransaction txTo[3]; // Spending transaction
201     for (int i = 0; i < 3; i++)
202     {
203         txTo[i].vin.resize(1);
204         txTo[i].vout.resize(1);
205         txTo[i].vin[0].prevout.n = i;
206         txTo[i].vin[0].prevout.hash = txFrom.GetHash();
207         txTo[i].vout[0].nValue = 1;
208     }
209 
210     for (int i = 0; i < 3; i++)
211     {
212         BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom), txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i));
213     }
214 }
215 
216 
217 BOOST_AUTO_TEST_SUITE_END()
218