1 // Copyright (c) 2011-2020 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 <policy/policy.h>
7 #include <script/interpreter.h>
8 #include <script/script.h>
9 #include <script/script_error.h>
10 #include <script/sign.h>
11 #include <script/signingprovider.h>
12 #include <test/util/setup_common.h>
13 #include <tinyformat.h>
14 #include <uint256.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 TxoutType 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 FillableSigningProvider 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