UltrafastSecp256k1 3.50.0
Ultra high-performance secp256k1 elliptic curve cryptography library
Loading...
Searching...
No Matches
address.hpp
Go to the documentation of this file.
1#ifndef SECP256K1_ADDRESS_HPP
2#define SECP256K1_ADDRESS_HPP
3#pragma once
4
5// ============================================================================
6// Bitcoin Address Generation + Encoding for secp256k1
7// ============================================================================
8// Address types:
9// P2PKH -- Pay-to-Public-Key-Hash (1..., legacy, Base58Check)
10// P2WPKH -- Pay-to-Witness-Public-Key-Hash (bc1q..., SegWit v0, Bech32)
11// P2TR -- Pay-to-Taproot (bc1p..., SegWit v1, Bech32m)
12//
13// Encoding:
14// Base58Check -- P2PKH addresses + WIF private keys
15// Bech32 -- SegWit v0 (BIP-173)
16// Bech32m -- SegWit v1+ (BIP-350)
17//
18// BIP-352 Silent Payments:
19// Privacy-preserving addresses. Sender computes unique output from
20// public scan/spend keys; only recipient can detect and spend.
21// ============================================================================
22
23#include <array>
24#include <cstdint>
25#include <cstddef>
26#include <string>
27#include <vector>
28#include <utility>
29#include "secp256k1/scalar.hpp"
30#include "secp256k1/point.hpp"
31
32namespace secp256k1 {
33
34// -- Network ------------------------------------------------------------------
35
36enum class Network : std::uint8_t {
37 Mainnet = 0,
38 Testnet = 1
39};
40
41// -- Base58Check Encoding -----------------------------------------------------
42
43// Encode data with 4-byte SHA256d checksum in Base58
44std::string base58check_encode(const std::uint8_t* data, std::size_t len);
45
46// Decode Base58Check, returns pair of (data, valid)
47std::pair<std::vector<std::uint8_t>, bool>
48base58check_decode(const std::string& encoded);
49
50// -- Bech32 / Bech32m Encoding (BIP-173 / BIP-350) ---------------------------
51
52enum class Bech32Encoding {
53 BECH32, // SegWit v0 (BIP-173)
54 BECH32M // SegWit v1+ (BIP-350)
55};
56
57// Encode a witness program to bech32/bech32m address
58// hrp: "bc" for mainnet, "tb" for testnet
59// witness_version: 0 for P2WPKH, 1 for P2TR
60// witness_program: 20 bytes (v0) or 32 bytes (v1)
61std::string bech32_encode(const std::string& hrp,
62 std::uint8_t witness_version,
63 const std::uint8_t* witness_program,
64 std::size_t prog_len);
65
66// Decode bech32/bech32m address
67// Returns: {hrp, witness_version, witness_program, valid}
69 std::string hrp;
70 int witness_version; // -1 if invalid
71 std::vector<std::uint8_t> witness_program;
72 bool valid;
73};
74Bech32DecodeResult bech32_decode(const std::string& addr);
75
76// -- HASH160 ------------------------------------------------------------------
77
78// HASH160: RIPEMD160 applied to SHA256 digest
79std::array<std::uint8_t, 20> hash160(const std::uint8_t* data, std::size_t len);
80
81// -- Address Derivation -------------------------------------------------------
82
83// P2PKH address from public key (compressed 33 bytes or uncompressed 65 bytes)
84// Returns: "1..." (mainnet) or "m/n..." (testnet)
85std::string address_p2pkh(const fast::Point& pubkey,
87
88// P2WPKH address from public key (native SegWit v0)
89// Returns: "bc1q..." (mainnet) or "tb1q..." (testnet)
90std::string address_p2wpkh(const fast::Point& pubkey,
92
93// P2TR address from x-only public key (Taproot, SegWit v1)
94// Returns: "bc1p..." (mainnet) or "tb1p..." (testnet)
95// If internal_key only (no script tree): uses untwisted key
96std::string address_p2tr(const fast::Point& internal_key,
98
99// P2TR address from x-only output key bytes (32 bytes)
100std::string address_p2tr_raw(const std::array<std::uint8_t, 32>& output_key_x,
102
103// P2SH-P2WPKH address (nested/wrapped SegWit, "3..." on mainnet)
104// Wraps P2WPKH witness program inside P2SH for backward compatibility
105std::string address_p2sh_p2wpkh(const fast::Point& pubkey,
107
108// P2SH address from a 20-byte script hash (generic)
109std::string address_p2sh(const std::array<std::uint8_t, 20>& script_hash,
111
112// P2WSH address from a 32-byte witness script hash (SegWit v0)
113std::string address_p2wsh(const std::array<std::uint8_t, 32>& witness_script_hash,
115
116// -- CashAddr (Bitcoin Cash BIP-0185) -----------------------------------------
117
118// Encode a hash160 as CashAddr address
119// type: 0 = P2PKH, 1 = P2SH
120std::string cashaddr_encode(const std::array<std::uint8_t, 20>& hash,
121 const std::string& prefix,
122 std::uint8_t type = 0);
123
124// CashAddr P2PKH from public key
125std::string address_cashaddr(const fast::Point& pubkey,
126 const std::string& prefix = "bitcoincash");
127
128// -- WIF (Wallet Import Format) -----------------------------------------------
129
130// Encode private key as WIF string
131std::string wif_encode(const fast::Scalar& private_key,
132 bool compressed = true,
134
135// Decode WIF string to private key
136// Returns: {scalar, compressed, network, valid}
143WIFDecodeResult wif_decode(const std::string& wif);
144
145// -- BIP-352 Silent Payments --------------------------------------------------
146
147// Silent payment address: (scan_pubkey, spend_pubkey) pair
151
152 // Encode to sp1q... address (mainnet) or tsp1q... (testnet)
153 std::string encode(Network net = Network::Mainnet) const;
154};
155
156// Generate silent payment address from scan and spend private keys
159 const fast::Scalar& spend_privkey);
160
161// Sender: Compute output public key for a silent payment
162// input_privkeys: sender's input private keys (for ECDH)
163// input_pubkeys: corresponding public keys
164// recipient: recipient's silent payment address
165// k: output index (for multiple outputs to same recipient)
166// Returns: {output_pubkey, output_tweaked_key}
167std::pair<fast::Point, fast::Scalar>
168silent_payment_create_output(const std::vector<fast::Scalar>& input_privkeys,
169 const SilentPaymentAddress& recipient,
170 std::uint32_t k = 0);
171
172// Receiver: Scan transaction to detect silent payment outputs
173// scan_privkey: receiver's scan private key
174// spend_privkey: receiver's spend private key
175// input_pubkeys: all input public keys from the transaction
176// output_pubkeys: all output x-only public keys to check
177// Returns: vector of {output_index, tweaked_privkey} for detected outputs
178std::vector<std::pair<std::uint32_t, fast::Scalar>>
180 const fast::Scalar& spend_privkey,
181 const std::vector<fast::Point>& input_pubkeys,
182 const std::vector<std::array<std::uint8_t, 32>>& output_pubkeys);
183
184} // namespace secp256k1
185
186#endif // SECP256K1_ADDRESS_HPP
Bech32DecodeResult bech32_decode(const std::string &addr)
std::string base58check_encode(const std::uint8_t *data, std::size_t len)
std::string address_p2sh(const std::array< std::uint8_t, 20 > &script_hash, Network net=Network::Mainnet)
std::string address_p2tr(const fast::Point &internal_key, Network net=Network::Mainnet)
std::string address_p2wsh(const std::array< std::uint8_t, 32 > &witness_script_hash, Network net=Network::Mainnet)
std::string address_p2tr_raw(const std::array< std::uint8_t, 32 > &output_key_x, Network net=Network::Mainnet)
std::string address_p2sh_p2wpkh(const fast::Point &pubkey, Network net=Network::Mainnet)
std::string address_cashaddr(const fast::Point &pubkey, const std::string &prefix="bitcoincash")
std::pair< fast::Point, fast::Scalar > silent_payment_create_output(const std::vector< fast::Scalar > &input_privkeys, const SilentPaymentAddress &recipient, std::uint32_t k=0)
std::pair< std::vector< std::uint8_t >, bool > base58check_decode(const std::string &encoded)
WIFDecodeResult wif_decode(const std::string &wif)
std::array< std::uint8_t, 20 > hash160(const std::uint8_t *data, std::size_t len)
std::array< std::uint8_t, 32 > witness_script_hash(const std::uint8_t *script, std::size_t script_len) noexcept
std::string address_p2wpkh(const fast::Point &pubkey, Network net=Network::Mainnet)
std::string address_p2pkh(const fast::Point &pubkey, Network net=Network::Mainnet)
std::string bech32_encode(const std::string &hrp, std::uint8_t witness_version, const std::uint8_t *witness_program, std::size_t prog_len)
std::string cashaddr_encode(const std::array< std::uint8_t, 20 > &hash, const std::string &prefix, std::uint8_t type=0)
std::string wif_encode(const fast::Scalar &private_key, bool compressed=true, Network net=Network::Mainnet)
std::vector< std::pair< std::uint32_t, fast::Scalar > > silent_payment_scan(const fast::Scalar &scan_privkey, const fast::Scalar &spend_privkey, const std::vector< fast::Point > &input_pubkeys, const std::vector< std::array< std::uint8_t, 32 > > &output_pubkeys)
SilentPaymentAddress silent_payment_address(const fast::Scalar &scan_privkey, const fast::Scalar &spend_privkey)
std::vector< std::uint8_t > witness_program
Definition address.hpp:71
std::string encode(Network net=Network::Mainnet) const