Bitcoin Core 32.99.0
P2P Digital Currency
Loading...
Searching...
No Matches
bip352_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2026-present 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 <common/bip352.h>
6#include <chainparams.h>
7#include <coins.h>
8#include <span.h>
9#include <addresstype.h>
10#include <policy/policy.h>
11#include <script/interpreter.h>
12#include <script/script.h>
13#include <script/script_error.h>
14#include <script/solver.h>
15#include <test/data/bip352_send_and_receive_vectors.json.h>
16
17#include <test/util/common.h>
19
20#include <boost/test/unit_test.hpp>
21#include <test/util/json.h>
22#include <vector>
23#include <util/chaintype.h>
24#include <util/strencodings.h>
25#include <streams.h>
26
27namespace bip352 {
29
31 CKey output;
32 std::vector<unsigned char> hex_data = ParseHex(hex);
33 output.Set(hex_data.begin(), hex_data.end(), true);
34 return output;
35};
36
38{
40 BOOST_REQUIRE(tests.read(json_tests::bip352_send_and_receive_vectors));
41
42 for (const auto& vec : tests.getValues()) {
43 // run sending tests
44 BOOST_TEST_MESSAGE(vec["comment"].get_str());
45
46 for (const auto& sender : vec["sending"].getValues()) {
47 const UniValue& given = sender["given"];
48 const UniValue& expected = sender["expected"];
49
50 std::vector<COutPoint> outpoints;
51 std::vector<CKey> keys;
52 std::vector<KeyPair> taproot_keys;
53 for (const auto& input : given["vin"].getValues()) {
54 COutPoint outpoint{Txid::FromHex(input["txid"].get_str()).value(), input["vout"].getInt<uint32_t>()};
55 outpoints.push_back(outpoint);
56 const auto& spk_bytes = ParseHex(input["prevout"]["scriptPubKey"]["hex"].get_str());
57 CScript spk = CScript(spk_bytes.begin(), spk_bytes.end());
58 const auto& script_sig_bytes = ParseHex(input["scriptSig"].get_str());
60 CTxIn txin{outpoint, script_sig};
61 // read the field txWitness as a stream and write txWitness >> witness.stack;
62 const auto witness_str = ParseHex(input["txinwitness"].get_str());
63 if (!witness_str.empty()) {
64 SpanReader(witness_str) >> txin.scriptWitness.stack;
65 }
66
67 // check if this is a silent payments input by trying to extract the public key
68 const auto& pubkey = GetPubKeyFromInput(txin, spk);
69 if (pubkey.has_value()) {
70 std::vector<std::vector<unsigned char>> solutions;
73 taproot_keys.emplace_back(ParseHexToCKey(input["private_key"].get_str()).ComputeKeyPair(nullptr));
74 } else {
75 keys.emplace_back(ParseHexToCKey(input["private_key"].get_str()));
76 }
77 }
78 }
79 if (taproot_keys.empty() && keys.empty()) {
80 BOOST_CHECK(expected["outputs"].getValues()[0].empty());
81 continue;
82 }
83 // silent payments logic
84 auto smallest_outpoint = std::min_element(outpoints.begin(), outpoints.end(), BIP352Comparator());
85 std::map<size_t, SilentPaymentsDestination> sp_dests;
86 const std::vector<UniValue>& silent_payments_addresses = given["recipients"].getValues();
87 size_t sp_index = 0;
88 for (size_t i = 0; i < silent_payments_addresses.size(); ++i) {
89 auto sp = DecodeSilentPaymentsAddress(silent_payments_addresses[i]["address"].get_str(), Params());
90 BOOST_REQUIRE(sp.has_value());
91 if (!silent_payments_addresses[i]["scan_pub_key"].isNull()) {
92 BOOST_CHECK_EQUAL(HexStr(sp->GetScanPubKey()), silent_payments_addresses[i]["scan_pub_key"].get_str());
93 BOOST_CHECK_EQUAL(HexStr(sp->GetSpendPubKey()), silent_payments_addresses[i]["spend_pub_key"].get_str());
94 }
95 size_t count = silent_payments_addresses[i]["count"].isNull() ? 1 : (size_t)silent_payments_addresses[i]["count"].getInt<int>();
96 for (size_t j = 0; j < count; ++j) {
97 sp_dests.emplace(sp_index++, *sp);
98 }
99 }
101 // This means the inputs summed to zero, which realistically would only happen maliciously. In this case, just move on
102 if (!sp_tr_dests.has_value()) {
103 // Check that we actually expect zero outputs to be generated for this test
104 BOOST_CHECK(expected["outputs"].getValues()[0].empty());
105 continue;
106 }
107 bool match = false;
108 for (const auto& candidate_set : expected["outputs"].getValues()) {
109 BOOST_CHECK(sp_tr_dests->size() == candidate_set.size());
110 std::vector<WitnessV1Taproot> expected_spks;
111 for (const auto& output : candidate_set.getValues()) {
112 const WitnessV1Taproot tap{XOnlyPubKey(ParseHex(output.get_str()))};
113 expected_spks.push_back(tap);
114 }
115 match = std::all_of(sp_tr_dests->begin(), sp_tr_dests->end(), [&](const auto& entry) {
116 return std::find(expected_spks.begin(), expected_spks.end(), entry.second) != expected_spks.end();
117 });
118 if (match) break;
119 }
121 }
122
123 // Test receiving
124 for (const auto& recipient : vec["receiving"].getValues()) {
125
126 const UniValue& given = recipient["given"];
127 const UniValue& expected = recipient["expected"];
128
129 std::vector<CTxIn> vin;
130 std::map<COutPoint, Coin> coins;
131 for (const auto& input : given["vin"].getValues()) {
132 COutPoint outpoint{Txid::FromHex(input["txid"].get_str()).value(), input["vout"].getInt<uint32_t>()};
133 const auto& spk_bytes = ParseHex(input["prevout"]["scriptPubKey"]["hex"].get_str());
134 CScript spk = CScript(spk_bytes.begin(), spk_bytes.end());
135 const auto& script_sig_bytes = ParseHex(input["scriptSig"].get_str());
137 CTxIn txin{outpoint, script_sig};
138 // read the field txWitness as a stream and write txWitness >> witness.stack;
139 const auto witness_str = ParseHex(input["txinwitness"].get_str());
140 if (!witness_str.empty()) {
141 SpanReader(witness_str) >> txin.scriptWitness.stack;
142 }
143 vin.push_back(txin);
144 coins[outpoint] = Coin{CTxOut{{}, spk}, 0, false};
145 }
147 // If we don't get any tweak data from the transaction inputs, it is not a silent payment
148 // transaction, so we skip it.
149 if (!pub_tweak_data.has_value()) {
150 // Make sure this is expected and not just a failure of the GetSilentPaymentsPrevoutsSummary func
151 BOOST_CHECK(expected["outputs"].empty());
152 continue;
153 }
154 std::vector<XOnlyPubKey> output_pub_keys;
155 for (const auto& pubkey : given["outputs"].getValues()) {
156 output_pub_keys.emplace_back(ParseHex(pubkey.get_str()));
157 }
158
159 CKey scan_priv_key = ParseHexToCKey(given["key_material"]["scan_priv_key"].get_str());
160 CKey spend_priv_key = ParseHexToCKey(given["key_material"]["spend_priv_key"].get_str());
162 auto expected_address = DecodeSilentPaymentsAddress(expected["addresses"][0].get_str(), Params());
163 BOOST_REQUIRE(expected_address.has_value());
165
166 // The change label is registered automatically; only non-change labels need registering.
167 SilentPaymentsReceiver receiver{scan_priv_key, sp_address.GetSpendPubKey()};
168 auto given_labels{given["labels"].getValues()};
169 for (size_t i = 0; i < given_labels.size(); i++) {
170 const uint32_t m = given_labels[i].getInt<uint32_t>();
171 const SilentPaymentsDestination labeled_addr = (m == 0) ? receiver.GetChangeDestination() : receiver.GenerateLabeledAddress(m);
172 // expected["addresses"] contains the base silent payments address (at index 0)
173 // followed by the labeled addresses
174 auto sp = DecodeSilentPaymentsAddress(expected["addresses"][i+1].get_str(), Params());
175 BOOST_REQUIRE(sp.has_value());
177 }
178
179 // Scanning
180 const auto& found_outputs = receiver.Scan(*pub_tweak_data, output_pub_keys);
181 BOOST_REQUIRE(found_outputs.has_value());
182 // The transaction may be a silent payments transaction, but it does not contain any outputs for us,
183 // so we continue to the next transaction.
184 if (found_outputs->empty()) {
185 BOOST_CHECK(expected["outputs"].empty());
186 continue;
187 }
188 if (!expected["n_outputs"].isNull()) {
189 BOOST_CHECK_EQUAL(found_outputs->size(), (size_t)expected["n_outputs"].getInt<int>());
190 } else {
191 std::map<XOnlyPubKey, uint256> expected_outputs;
192 for (const auto& output : expected["outputs"].getValues()) {
193 expected_outputs.emplace(
194 XOnlyPubKey{ParseHex(output["pub_key"].get_str())},
195 uint256{ParseHex(output["priv_key_tweak"].get_str())});
196 }
197 BOOST_TEST_MESSAGE(found_outputs->size());
198 BOOST_REQUIRE_EQUAL(found_outputs->size(), expected_outputs.size());
199 for (const auto& output : *found_outputs) {
200 const auto expected_output = expected_outputs.find(output.output);
201 BOOST_REQUIRE(expected_output != expected_outputs.end());
202 BOOST_CHECK(output.tweak == expected_output->second);
203 }
204 }
205 }
206 }
207}
208
210{
211 CKey sender_key = ParseHexToCKey("0000000000000000000000000000000000000000000000000000000000000001");
212 CKey scan_key = ParseHexToCKey("0000000000000000000000000000000000000000000000000000000000000002");
213 CKey spend_key = ParseHexToCKey("0000000000000000000000000000000000000000000000000000000000000003");
215 std::map<size_t, SilentPaymentsDestination> sp_dests{{2, sp_dest}, {5, sp_dest}};
216 COutPoint smallest_outpoint{Txid::FromHex("0000000000000000000000000000000000000000000000000000000000000001").value(), 0};
217
219
220 BOOST_REQUIRE(generated.has_value());
221 BOOST_CHECK_EQUAL(generated->size(), sp_dests.size());
222 BOOST_CHECK_EQUAL(generated->count(0), 0);
223 BOOST_CHECK_EQUAL(generated->count(1), 0);
224 BOOST_CHECK_EQUAL(generated->count(2), 1);
225 BOOST_CHECK_EQUAL(generated->count(5), 1);
226}
227
229{
230 CKey key = ParseHexToCKey("0000000000000000000000000000000000000000000000000000000000000001");
231 CPubKey pubkey = key.GetPubKey();
232 COutPoint eligible_outpoint{Txid::FromHex("0000000000000000000000000000000000000000000000000000000000000001").value(), 0};
233 COutPoint unknown_segwit_outpoint{Txid::FromHex("0000000000000000000000000000000000000000000000000000000000000002").value(), 0};
234
236 eligible_input.scriptWitness.stack.emplace_back(64, 0);
237 eligible_input.scriptWitness.stack.emplace_back(pubkey.begin(), pubkey.end());
238
239 std::map<COutPoint, Coin> coins;
240 coins[eligible_outpoint] = Coin{CTxOut{{}, GetScriptForDestination(WitnessV0KeyHash{pubkey})}, 0, false};
241 coins[unknown_segwit_outpoint] = Coin{CTxOut{{}, GetScriptForDestination(WitnessUnknown{2, std::vector<unsigned char>(32, 1)})}, 0, false};
242
245}
246
248{
249 CKey sender_key = ParseHexToCKey("0000000000000000000000000000000000000000000000000000000000000001");
250 CKey scan_key = ParseHexToCKey("0000000000000000000000000000000000000000000000000000000000000002");
251 CKey spend_key = ParseHexToCKey("0000000000000000000000000000000000000000000000000000000000000003");
252 const COutPoint outpoint{Txid::FromHex("0000000000000000000000000000000000000000000000000000000000000001").value(), 0};
253
254 std::map<size_t, SilentPaymentsDestination> sp_dests;
255 sp_dests.emplace(0, SilentPaymentsDestination::From(scan_key.GetPubKey(), spend_key.GetPubKey()).value());
257 BOOST_REQUIRE(sp_tr_dests.has_value());
258 const XOnlyPubKey expected_output{sp_tr_dests->begin()->second};
259
260 CTxIn txin{outpoint};
261 const CPubKey sender_pubkey{sender_key.GetPubKey()};
262 txin.scriptWitness.stack.emplace_back();
263 txin.scriptWitness.stack.emplace_back(sender_pubkey.begin(), sender_pubkey.end());
264
265 std::map<COutPoint, Coin> coins;
266 coins[outpoint] = Coin{CTxOut{{}, GetScriptForDestination(WitnessV0KeyHash{sender_pubkey})}, 0, false};
268 BOOST_REQUIRE(prevouts_summary.has_value());
269
270 std::vector<XOnlyPubKey> output_pub_keys;
271 output_pub_keys.emplace_back(ParseHex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
272 output_pub_keys.push_back(expected_output);
273
274 SilentPaymentsReceiver receiver{scan_key, spend_key.GetPubKey()};
275 const auto found_outputs = receiver.Scan(*prevouts_summary, output_pub_keys);
276 BOOST_REQUIRE(found_outputs.has_value());
277 BOOST_REQUIRE_EQUAL(found_outputs->size(), 1);
278 BOOST_CHECK_EQUAL(found_outputs->front().output, expected_output);
279}
280
282{
283 // P2PKH scriptSigs are third-party malleable. Construct one that contains an OP_CHECKSIG with a
284 // bogus (but strictly DER-encoded) signature, followed by a conditional push of a wrong pubkey:
285 //
286 // <sig> <pubkey> <bogus_sig> OP_OVER OP_CHECKSIG OP_IF <wrong_pubkey> OP_ENDIF
287 //
288 // In real validation the OP_CHECKSIG fails, the OP_IF branch is skipped and the final stack is
289 // <sig> <pubkey>, i.e. the spend is still valid and the pubkey must be extracted from it.
290 const CKey key = ParseHexToCKey("0000000000000000000000000000000000000000000000000000000000000001");
291 const CPubKey pubkey = key.GetPubKey();
292 const CPubKey wrong_pubkey = ParseHexToCKey("0000000000000000000000000000000000000000000000000000000000000002").GetPubKey();
294
296 tx.vin.emplace_back(COutPoint{Txid::FromHex("0000000000000000000000000000000000000000000000000000000000000001").value(), 0});
297 std::vector<unsigned char> sig;
298 BOOST_REQUIRE(key.Sign(SignatureHash(spk, tx, 0, SIGHASH_ALL, /*amount=*/0, SigVersion::BASE), sig));
299 sig.push_back(SIGHASH_ALL);
300 const std::vector<unsigned char> bogus_sig{ParseHex("300602010102010101")}; // r=1, s=1, SIGHASH_ALL
301 tx.vin[0].scriptSig = CScript() << sig << ToByteVector(pubkey) << bogus_sig << OP_OVER << OP_CHECKSIG
303 const CTxIn& txin{tx.vin[0]};
304
305 // Verify that the malleated spend is consensus-valid
310
312 BOOST_REQUIRE(extracted_pubkey.has_value());
313 BOOST_CHECK_EQUAL(std::get<CPubKey>(*extracted_pubkey), pubkey);
314}
315
317{
318 CKey scan_key = ParseHexToCKey("0000000000000000000000000000000000000000000000000000000000000002");
319 CPubKey spend_pubkey = ParseHexToCKey("0000000000000000000000000000000000000000000000000000000000000003").GetPubKey();
320 SilentPaymentsReceiver receiver{scan_key, spend_pubkey};
321
322 BOOST_REQUIRE_EQUAL(receiver.GetLabels().size(), 1);
323 const SilentPaymentsLabel& label = receiver.GetLabels().begin()->first;
324
326 label.Serialize(stream);
328 BOOST_REQUIRE(roundtripped.has_value());
329 BOOST_CHECK(*roundtripped == label);
330 BOOST_CHECK(stream.empty());
331}
332
334{
335 struct ValidVector {
336 ChainType chain;
337 std::string address;
338 std::string scan_pubkey;
339 std::string spend_pubkey;
340 std::string extension_data;
341 uint8_t version;
342 };
345 "sp1qq22l5s6l9460ww6t4tkzsy2a7zejurcmzz35pt0ffrzk5erlaykdcqugecjjnjqf7ggq39vl6wexjlm00n66z94v675n7wcux6d2krr68gdjvfn2",
346 "0295fa435f2d74f73b4baaec28115df0b32e0f1b10a340ade948c56a647fe92cdc",
347 "0388ce2529c809f21008959fd3b2697f6f7cf5a116acd7a93f3b1c369aab0c7a3a",
348 "", 0},
350 "sp1pq22l5s6l9460ww6t4tkzsy2a7zejurcmzz35pt0ffrzk5erlaykdcqugecjjnjqf7ggq39vl6wexjlm00n66z94v675n7wcux6d2krr68t02m0h0s8cwhy",
351 "0295fa435f2d74f73b4baaec28115df0b32e0f1b10a340ade948c56a647fe92cdc",
352 "0388ce2529c809f21008959fd3b2697f6f7cf5a116acd7a93f3b1c369aab0c7a3a",
353 "deadbeef", 1},
355 "tsp1qqthpye3hdcnydp9temp7yduy6uw5h2nw8u9fz677ccrna280qwj3uq60zeqs3zfpj3age62h4ljq2lyawwdecmk8a545yysk4x3tu3skjqm2thu6",
356 "02ee1266376e264684abcec3e23784d71d4baa6e3f0a916bdec6073ea8ef03a51e",
357 "034f1641088921947a8ce957afe4057c9d739b9c6ec7ed2b421216a9a2be461690",
358 "", 0},
360 "tsp1qqvrl2accqtatgtkllv5fdsfapq6vqnrr0uf2whhmjyas4teg7ljfqqlpec0ze90m97t3stv92p5ekzkcwzmpx0x8p7ljj9xqcjjpvnfurc00tjn9",
361 "0307f5771802fab42edffb2896c13d0834c04c637f12a75efb913b0aaf28f7e490",
362 "03e1ce1e2c95fb2f97182d8550699b0ad870b6133cc70fbf2914c0c4a4164d3c1e",
363 "", 0},
365 "sprt1qq04xgllnqqfdlxjkr355rmsahfn9t8l6sd0k20t4uka4c73nvvpnwqu4kvg0nm62d5jtmqp54lkc7tul0dzt25ejtn4f80505z3u0h5jag59rdg4",
366 "03ea647ff30012df9a561c6941ee1dba66559ffa835f653d75e5bb5c7a33630337",
367 "0395b310f9ef4a6d24bd8034afed8f2f9f7b44b553325cea93be8fa0a3c7de92ea",
368 "", 0},
369 };
370
371 for (const auto& vec : valid_vectors) {
372 SelectParams(vec.chain);
373
374 auto sp = DecodeSilentPaymentsAddress(vec.address, Params());
375 BOOST_REQUIRE_MESSAGE(sp.has_value(), vec.address);
376 BOOST_CHECK_EQUAL(sp->GetVersion(), vec.version);
377 BOOST_CHECK_EQUAL(HexStr(sp->GetScanPubKey()), vec.scan_pubkey);
378 BOOST_CHECK_EQUAL(HexStr(sp->GetSpendPubKey()), vec.spend_pubkey);
379 BOOST_CHECK_EQUAL(HexStr(sp->GetExtensionData()), vec.extension_data);
380
381 // Bech32(m) is case-insensitive as a whole; an all-uppercase address must decode identically.
382 std::string flipped = ToUpper(vec.address);
386 }
387
388 // `chain` is the one chain (if any) whose HRP matches the address, where `expected_error`
389 // applies; on every other chain the HRP check itself is expected to fail first.
390 // `chain_independent` addresses fail bech32m checksum verification before the HRP is even
391 // compared, so `expected_error` applies on every chain instead.
392 struct InvalidVector {
393 std::string address;
394 std::string expected_error;
395 std::optional<ChainType> chain = std::nullopt;
396 bool chain_independent = false;
397 };
399 {"spx1qq22l5s6l9460ww6t4tkzsy2a7zejurcmzz35pt0ffrzk5erlaykdcqugecjjnjqf7ggq39vl6wexjlm00n66z94v675n7wcux6d2krr68g37pn04",
400 "Invalid or unsupported prefix for Silent Payments address (expected sp, got spx)."}, // wrong HRP; never matches any chain
401 {"sp1qq22l5s6l9460ww6t4tkzsy2a7zejurcmzz35pt0ffrzk5erlaykdcqugecjjnjqf7ggq39vl6wexjlm00n66z94v675n7wcux6d2krr68gcwu9kg",
402 "Silent Payments address must use Bech32m checksum", std::nullopt, /*chain_independent=*/true}, // bad checksum
403 {"sp1qqgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq2qugecjjnjqf7ggq39vl6wexjlm00n66z94v675n7wcux6d2krr68g25havg",
404 "Invalid Silent payments address", ChainType::MAIN}, // invalid scan pubkey
405 {"sp1qq22l5s6l9460ww6t4tkzsy2a7zejurcmzz35pt0ffrzk5erlaykdcqsqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq57qc9nf",
406 "Invalid Silent payments address", ChainType::MAIN}, // invalid spend pubkey
407 {"sp1lq22l5s6l9460ww6t4tkzsy2a7zejurcmzz35pt0ffrzk5erlaykdcqugecjjnjqf7ggq39vl6wexjlm00n66z94v675n7wcux6d2krr68gaafydt",
408 "This implementation only supports Silent payments addresses v0 through v30 (got 31).", ChainType::MAIN}, // reserved version 31
409 {"sp1qq22l5s6l9460ww6t4tkzsy2a7zejurcmzz35pt0ffrzk5erlaykdcznsxsn",
410 "Silent payments data payload is too small (expected at least 66, got 33).", ChainType::MAIN}, // payload too small
411 {"tsp1qqthpye3hdcnydp9temp7yduy6uw5h2nw8u9fz677ccrna280qwj3uq60zeqs3zfpj3age62h4ljq2lyawwdecmk8a545yysk4x3tu3skjqm2thum",
412 "Silent Payments address must use Bech32m checksum", std::nullopt, /*chain_independent=*/true}, // bad checksum
413 {"sp1qqgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqf26rn7",
414 "Silent Payments address must use Bech32m checksum", std::nullopt, /*chain_independent=*/true}, // bad checksum
415 {"sprt1qqgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq2qu4kvg0nm62d5jtmqp54lkc7tul0dzt25ejtn4f80505z3u0h5jagf9zkp5",
416 "Invalid Silent payments address", ChainType::REGTEST}, // invalid scan pubkey
417 };
418
419 for (const auto& vec : invalid_vectors) {
421 SelectParams(chain);
422 auto sp = DecodeSilentPaymentsAddress(vec.address, Params());
423 BOOST_REQUIRE_MESSAGE(!sp.has_value(), vec.address);
424 if (vec.chain_independent || chain == vec.chain) {
425 BOOST_CHECK_EQUAL(sp.error(), vec.expected_error);
426 } else {
427 BOOST_CHECK_MESSAGE(sp.error().starts_with("Invalid or unsupported prefix for Silent Payments address"), sp.error());
428 }
429 }
430 }
431
433}
434
436} // namespace bip352
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
void SelectParams(const ChainType chain)
Sets the params returned by Params() to those for the given chain type.
const CChainParams & Params()
Return the currently selected parameters.
ChainType
Definition chaintype.h:12
An encapsulated private key.
Definition key.h:46
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig, bool grind=true, uint32_t test_case=0) const
Create a DER-serialized signature.
Definition key.cpp:210
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition key.cpp:184
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition key.h:114
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition transaction.h:30
An encapsulated public key.
Definition pubkey.h:43
const unsigned char * end() const
Definition pubkey.h:124
const unsigned char * begin() const
Definition pubkey.h:123
Serialized script, used inside transaction inputs and outputs.
Definition script.h:406
An input of a transaction.
Definition transaction.h:63
CScriptWitness scriptWitness
Only serialized through CTransaction.
Definition transaction.h:68
An output of a transaction.
A UTXO entry.
Definition coins.h:46
Double ended buffer combining vector and stream-like interfaces.
Definition streams.h:165
Minimal stream for reading from an existing byte array by std::span.
Definition streams.h:83
const std::vector< UniValue > & getValues() const
Int getInt() const
Definition univalue.h:143
const unsigned char * begin() const
Definition pubkey.h:304
static std::optional< SilentPaymentsLabel > Unserialize(Stream &s)
Definition bip352.h:150
void Serialize(Stream &s) const
Definition bip352.h:144
A silent payments recipient's scanning identity.
Definition bip352.h:239
static std::optional< transaction_identifier > FromHex(std::string_view hex)
256-bit opaque blob.
Definition uint256.h:196
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition hex_base.cpp:30
uint256 SignatureHash(const CScript &scriptCode, const T &txTo, unsigned int nIn, int32_t nHashType, const CAmount &amount, SigVersion sigversion, const PrecomputedTransactionData *cache, SigHashCache *sighash_cache)
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, script_verify_flags flags, const BaseSignatureChecker &checker, ScriptError *serror)
@ BASE
Bare scripts and BIP16 P2SH-wrapped redeemscripts.
@ SIGHASH_ALL
Definition interpreter.h:32
@ ASSERT_FAIL
Abort execution through assertion failure (for consensus code)
util::Expected< PrevoutsSummary, PrevoutsSummaryError > GetSilentPaymentsPrevoutsSummary(const std::vector< CTxIn > &vin, const std::map< COutPoint, Coin > &coins)
Get silent payments public data from transaction inputs.
Definition bip352.cpp:274
std::optional< PubKey > GetPubKeyFromInput(const CTxIn &txin, const CScript &spk)
Get the public key from an input.
Definition bip352.cpp:144
std::optional< std::map< size_t, WitnessV1Taproot > > GenerateSilentPaymentsTaprootDestinations(const std::map< size_t, SilentPaymentsDestination > &sp_dests, const std::vector< CKey > &plain_keys, const std::vector< KeyPair > &taproot_keys, const COutPoint &smallest_outpoint)
Generate silent payments taproot destinations.
Definition bip352.cpp:372
CKey ParseHexToCKey(std::string_view hex)
util::Expected< SilentPaymentsDestination, std::string > DecodeSilentPaymentsAddress(const std::string &str, const CChainParams &params)
Decode a BIP352 "sp1..." address. Returns the destination, or an error message on failure.
Definition bip352.cpp:68
BOOST_AUTO_TEST_CASE(bip352_send_and_receive_test_vectors)
#define BOOST_CHECK_EQUAL(v1, v2)
Definition object.cpp:17
#define BOOST_CHECK(expr)
Definition object.cpp:16
constexpr script_verify_flags MANDATORY_SCRIPT_VERIFY_FLAGS
Mandatory script verification flags that all new transactions must comply with for them to be valid.
Definition policy.h:98
@ OP_IF
Definition script.h:105
@ OP_CHECKSIG
Definition script.h:191
@ OP_ENDIF
Definition script.h:110
@ OP_OVER
Definition script.h:128
std::vector< unsigned char > ToByteVector(const T &in)
Definition script.h:68
std::string ScriptErrorString(const ScriptError serror)
enum ScriptError_t ScriptError
@ SCRIPT_ERR_OK
static unsigned char smallest_outpoint[36]
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition solver.cpp:141
TxoutType
Definition solver.h:22
@ WITNESS_V1_TAPROOT
Utilities for converting data from/to strings.
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
Basic testing setup.
A mutable version of CTransaction.
std::vector< CTxIn > vin
std::vector< std::vector< unsigned char > > stack
Definition script.h:581
CTxDestination subtype to encode any future Witness version.
Definition addresstype.h:95
static std::optional< SilentPaymentsDestination > From(const CPubKey &scan_pubkey, const CPubKey &spend_pubkey, uint8_t version=0, std::span< const unsigned char > extension_data={})
Definition bip352.cpp:52
std::vector< uint16_t > keys
static int count
constexpr std::array tests
std::string ToUpper(std::string_view str)
Returns the uppercase equivalent of the given string.
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:82