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