Bitcoin Core 32.99.0
P2P Digital Currency
bip352.h
Go to the documentation of this file.
1// Copyright (c) 2023 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#ifndef BITCOIN_COMMON_BIP352_H
6#define BITCOIN_COMMON_BIP352_H
7
8#include <addresstype.h>
9#include <attributes.h>
10#include <compat/byteswap.h>
11#include <key.h>
13#include <pubkey.h>
14#include <uint256.h>
15#include <util/expected.h>
16
17#include <array>
18#include <compare>
19#include <cstdint>
20#include <cstring>
21#include <functional>
22#include <map>
23#include <memory>
24#include <optional>
25#include <span>
26#include <string>
27#include <variant>
28#include <vector>
29
32struct secp256k1_pubkey;
33class CChainParams;
34class CScript;
35class Coin;
36
37namespace bip352 {
38
39using PubKey = std::variant<CPubKey, XOnlyPubKey>;
40
42{
43private:
44 std::unique_ptr<secp256k1_silentpayments_prevouts_summary> m_prevouts_summary;
45
46public:
49 PrevoutsSummary& operator=(PrevoutsSummary&&) noexcept;
51
52 // Delete copy constructors
54 PrevoutsSummary& operator=(const PrevoutsSummary&) = delete;
55
57};
58
60 bool operator()(const COutPoint& a, const COutPoint& b) const {
61 // BIP352 defines the "smallest outpoint" based on a lexicographic
62 // sort of the outpoints, using the 36-byte serialization:
63 // <txid, 32-bytes little-endian>:<vout, 4-bytes little-endian>
64 if (a.hash != b.hash) return a.hash < b.hash;
66 }
67};
68
70{
71private:
72 uint8_t m_version;
75 std::vector<unsigned char> m_extension_data;
76
78 uint8_t version,
79 const CPubKey& scan_pubkey,
80 const CPubKey& spend_pubkey,
81 std::span<const unsigned char> extension_data = {}
82 ) : m_version(version), m_scan_pubkey(scan_pubkey),
83 m_spend_pubkey(spend_pubkey),
84 m_extension_data(extension_data.begin(), extension_data.end()) {};
85public:
86 static std::optional<SilentPaymentsDestination> From(
87 const CPubKey& scan_pubkey,
88 const CPubKey& spend_pubkey,
89 uint8_t version = 0,
90 std::span<const unsigned char> extension_data = {}
91 );
92
93 uint8_t GetVersion() const { return m_version; }
94 const CPubKey& GetScanPubKey() const { return m_scan_pubkey; }
95 const CPubKey& GetSpendPubKey() const { return m_spend_pubkey; }
96 std::span<const unsigned char> GetExtensionData() const { return m_extension_data; }
97
98 bool operator==(const SilentPaymentsDestination&) const = default;
99};
100
103 const std::string& str, const CChainParams& params);
104
106private:
107 std::unique_ptr<secp256k1_silentpayments_label> m_label;
108 unsigned char m_vch[CPubKey::COMPRESSED_SIZE];
109
112 static std::optional<SilentPaymentsLabel> FromBytes(std::span<const unsigned char, CPubKey::COMPRESSED_SIZE> vch);
113
114public:
116
120 SilentPaymentsLabel& operator=(const SilentPaymentsLabel&);
121
123
124 friend bool operator==(const SilentPaymentsLabel& a, const SilentPaymentsLabel& b) {
125 return memcmp(a.m_vch, b.m_vch, CPubKey::COMPRESSED_SIZE) == 0;
126 }
127 friend bool operator<(const SilentPaymentsLabel& a, const SilentPaymentsLabel& b) {
128 return memcmp(a.m_vch, b.m_vch, CPubKey::COMPRESSED_SIZE) < 0;
129 }
130 friend bool operator>(const SilentPaymentsLabel& a, const SilentPaymentsLabel& b) {
131 return b < a;
132 }
136 friend bool operator<(const SilentPaymentsLabel& a, std::span<const unsigned char, CPubKey::COMPRESSED_SIZE> b) {
137 return memcmp(a.m_vch, b.data(), CPubKey::COMPRESSED_SIZE) < 0;
138 }
139 friend bool operator<(std::span<const unsigned char, CPubKey::COMPRESSED_SIZE> a, const SilentPaymentsLabel& b) {
140 return memcmp(a.data(), b.m_vch, CPubKey::COMPRESSED_SIZE) < 0;
141 }
142
143 template <typename Stream>
144 void Serialize(Stream& s) const
145 {
146 s << std::span{m_vch, CPubKey::COMPRESSED_SIZE};
147 }
148
149 template <typename Stream>
150 static std::optional<SilentPaymentsLabel> Unserialize(Stream& s)
151 {
152 std::array<unsigned char, CPubKey::COMPRESSED_SIZE> vch;
153 s >> std::span{vch};
154 return FromBytes(std::span{vch});
155 }
156
158};
159
163 std::optional<SilentPaymentsLabel> label;
164};
165
178std::optional<PubKey> GetPubKeyFromInput(const CTxIn& txin, const CScript& spk);
179
198std::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);
199
207};
208
225util::Expected<PrevoutsSummary, PrevoutsSummaryError> GetSilentPaymentsPrevoutsSummary(const std::vector<CTxIn>& vin, const std::map<COutPoint, Coin>& coins);
226
227using LabelTweakMap = std::map<SilentPaymentsLabel, uint256, std::less<>>;
228
240private:
243 std::unique_ptr<secp256k1_pubkey> m_spend_pubkey_obj;
245 LabelTweakMap::const_iterator m_change_it;
246
247 SilentPaymentsDestination BuildLabeledDestination(const SilentPaymentsLabel& label) const;
248
249public:
250 SilentPaymentsReceiver(const CKey& scan_key, const CPubKey& spend_pubkey, const LabelTweakMap& labels = {});
252
253 // Default move would leave m_scan_key and m_labels empty while
254 // m_spend_pubkey remains fully populated, leaving the
255 // SilentPaymentsReceiver object in an inconsistent state.
258
261
267 const LabelTweakMap& GetLabels() const;
268
279 SilentPaymentsDestination GenerateLabeledAddress(uint32_t m);
280
287 SilentPaymentsDestination GetChangeDestination() const;
288
302 std::optional<std::vector<SilentPaymentsOutput>> Scan(const PrevoutsSummary& prevouts_summary, const std::vector<XOnlyPubKey>& tx_outputs) const;
303};
304}; // namespace bip352
305#endif // BITCOIN_COMMON_BIP352_H
#define LIFETIMEBOUND
Definition: attributes.h:16
BSWAP_CONSTEXPR uint32_t internal_bswap_32(uint32_t x)
Definition: byteswap.h:53
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Definition: chainparams.h:77
An encapsulated private key.
Definition: key.h:46
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:30
uint32_t n
Definition: transaction.h:33
Txid hash
Definition: transaction.h:32
An encapsulated public key.
Definition: pubkey.h:43
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:49
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:406
An input of a transaction.
Definition: transaction.h:63
A UTXO entry.
Definition: coins.h:46
std::unique_ptr< secp256k1_silentpayments_prevouts_summary > m_prevouts_summary
Definition: bip352.h:44
PrevoutsSummary(const secp256k1_silentpayments_prevouts_summary &prevouts_summary)
Definition: bip352.cpp:38
PrevoutsSummary(PrevoutsSummary &&) noexcept
const secp256k1_silentpayments_prevouts_summary * Get() const LIFETIMEBOUND
Definition: bip352.cpp:46
std::unique_ptr< secp256k1_silentpayments_label > m_label
Definition: bip352.h:107
static std::optional< SilentPaymentsLabel > Unserialize(Stream &s)
Definition: bip352.h:150
unsigned char m_vch[CPubKey::COMPRESSED_SIZE]
Definition: bip352.h:108
friend bool operator<(const SilentPaymentsLabel &a, std::span< const unsigned char, CPubKey::COMPRESSED_SIZE > b)
Transparent comparisons against a raw 33-byte compressed label key, so a LabelTweakMap can be looked ...
Definition: bip352.h:136
friend bool operator<(std::span< const unsigned char, CPubKey::COMPRESSED_SIZE > a, const SilentPaymentsLabel &b)
Definition: bip352.h:139
SilentPaymentsLabel(SilentPaymentsLabel &&) noexcept
friend bool operator>(const SilentPaymentsLabel &a, const SilentPaymentsLabel &b)
Definition: bip352.h:130
void Serialize(Stream &s) const
Definition: bip352.h:144
friend bool operator<(const SilentPaymentsLabel &a, const SilentPaymentsLabel &b)
Definition: bip352.h:127
A silent payments recipient's scanning identity.
Definition: bip352.h:239
SilentPaymentsReceiver(SilentPaymentsReceiver &&)=delete
LabelTweakMap::const_iterator m_change_it
Definition: bip352.h:245
SilentPaymentsReceiver & operator=(SilentPaymentsReceiver &&)=delete
SilentPaymentsReceiver(const SilentPaymentsReceiver &)=delete
SilentPaymentsReceiver & operator=(const SilentPaymentsReceiver &)=delete
std::unique_ptr< secp256k1_pubkey > m_spend_pubkey_obj
Definition: bip352.h:243
256-bit opaque blob.
Definition: uint256.h:196
The util::Expected class provides a standard way for low-level functions to return either error value...
Definition: expected.h:44
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:255
std::optional< PubKey > GetPubKeyFromInput(const CTxIn &txin, const CScript &spk)
Get the public key from an input.
Definition: bip352.cpp:143
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:353
PrevoutsSummaryError
Definition: bip352.h:200
@ NOT_ELIGIBLE
This transaction is not eligible to be scanned for silent payments outputs: either none of its inputs...
@ MISSING_COIN
A prevout referenced by an input in vin has no corresponding entry in coins.
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:67
std::map< SilentPaymentsLabel, uint256, std::less<> > LabelTweakMap
Definition: bip352.h:227
std::variant< CPubKey, XOnlyPubKey > PubKey
Definition: bip352.h:39
SocketId Stream
Definition: util.h:30
static unsigned char smallest_outpoint[36]
bool operator()(const COutPoint &a, const COutPoint &b) const
Definition: bip352.h:60
bool operator==(const SilentPaymentsDestination &) const =default
const CPubKey & GetSpendPubKey() const
Definition: bip352.h:95
uint8_t GetVersion() const
Definition: bip352.h:93
std::span< const unsigned char > GetExtensionData() const
Definition: bip352.h:96
SilentPaymentsDestination(uint8_t version, const CPubKey &scan_pubkey, const CPubKey &spend_pubkey, std::span< const unsigned char > extension_data={})
Definition: bip352.h:77
std::vector< unsigned char > m_extension_data
Definition: bip352.h:75
const CPubKey & GetScanPubKey() const
Definition: bip352.h:94
std::optional< SilentPaymentsLabel > label
Definition: bip352.h:163
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1.h:62
Opaque data structure that holds a Silent Payments label.
Opaque data structure that holds Silent Payments prevouts summary data.