UltrafastSecp256k1 3.50.0
Ultra high-performance secp256k1 elliptic curve cryptography library
Loading...
Searching...
No Matches
segwit.hpp
Go to the documentation of this file.
1#ifndef SECP256K1_SEGWIT_HPP
2#define SECP256K1_SEGWIT_HPP
3
4// ============================================================================
5// BIP-141: Segregated Witness (Consensus Layer)
6// ============================================================================
7// Implements witness program creation and validation as defined in BIP-141.
8//
9// A witness program is defined by:
10// - A version byte (0–16, encoded as OP_0 to OP_16)
11// - A data push of 2–40 bytes
12//
13// Standard witness programs:
14// v0, 20 bytes → P2WPKH (BIP-141 §4.1)
15// v0, 32 bytes → P2WSH (BIP-141 §4.2)
16// v1, 32 bytes → P2TR (BIP-341)
17//
18// This module provides:
19// - scriptPubKey construction for witness outputs
20// - Witness program extraction from scriptPubKey
21// - Witness program type classification
22// - P2WPKH and P2WSH script code generation for signing
23//
24// Reference: BIP-141, https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki
25// ============================================================================
26
27#include <array>
28#include <cstdint>
29#include <cstddef>
30#include <vector>
31
32namespace secp256k1 {
33
34// Witness program type classification
35enum class WitnessProgramType : std::uint8_t {
36 NONE = 0, // Not a witness program
37 P2WPKH = 1, // v0, 20-byte program (BIP-141 §4.1)
38 P2WSH = 2, // v0, 32-byte program (BIP-141 §4.2)
39 P2TR = 3, // v1, 32-byte program (BIP-341)
40 UNKNOWN = 4, // Valid witness program but unknown type (v2-v16, or non-standard length)
41};
42
43// Parsed witness program
45 int version; // -1 = not a witness program, 0-16 otherwise
46 std::vector<std::uint8_t> program; // 2-40 bytes
48};
49
50// Create a P2WPKH scriptPubKey from a 20-byte pubkey hash.
51// Output: OP_0 <20 bytes> = [0x00, 0x14, ...20 bytes...]
52std::array<std::uint8_t, 22> segwit_scriptpubkey_p2wpkh(
53 const std::uint8_t pubkey_hash[20]) noexcept;
54
55// Create a P2WSH scriptPubKey from a 32-byte witness script hash.
56// Output: OP_0 <32 bytes> = [0x00, 0x20, ...32 bytes...]
57std::array<std::uint8_t, 34> segwit_scriptpubkey_p2wsh(
58 const std::uint8_t script_hash[32]) noexcept;
59
60// Create a P2TR scriptPubKey from a 32-byte x-only output key.
61// Output: OP_1 <32 bytes> = [0x51, 0x20, ...32 bytes...]
62std::array<std::uint8_t, 34> segwit_scriptpubkey_p2tr(
63 const std::uint8_t output_key[32]) noexcept;
64
65// Create a general witness scriptPubKey from version & program.
66// version: 0-16
67// program: 2-40 bytes
68// Returns: [OP_n, push_len, ...program...]
69std::vector<std::uint8_t> segwit_scriptpubkey(
70 std::uint8_t version,
71 const std::uint8_t* program,
72 std::size_t program_len) noexcept;
73
74// Check if a scriptPubKey is a witness program.
75// BIP-141: A scriptPubKey is a witness program if:
76// - Its length is 4-42 bytes
77// - First byte is OP_0 (0x00) or OP_1..OP_16 (0x51..0x60)
78// - Second byte is a direct data push of 2-40 bytes equal to remaining length
80 const std::uint8_t* script, std::size_t script_len) noexcept;
81
82// Extract and classify a witness program from a scriptPubKey.
83// Returns a WitnessProgram struct. If not a valid witness program,
84// version = -1 and type = NONE.
86 const std::uint8_t* script, std::size_t script_len) noexcept;
87
88// Compute the witness script hash (SHA256) for P2WSH.
89// This is the raw SHA256 (not double-SHA256) of the witness script.
90std::array<std::uint8_t, 32> witness_script_hash(
91 const std::uint8_t* script, std::size_t script_len) noexcept;
92
93// Compute the P2WPKH scriptCode for BIP-143 signing from a 20-byte pubkey hash.
94// Returns: OP_DUP OP_HASH160 <20 bytes> OP_EQUALVERIFY OP_CHECKSIG (25 bytes)
95// This is the script that replaces the witness program in the sighash preimage.
96std::array<std::uint8_t, 25> p2wpkh_script_code(
97 const std::uint8_t pubkey_hash[20]) noexcept;
98
99// Validate P2WPKH witness (BIP-141 §4.1):
100// Witness must be exactly [<signature>, <pubkey>]
101// pubkey must be 33 bytes (compressed), hash160(pubkey) must match program
103 const std::vector<std::vector<std::uint8_t>>& witness,
104 const std::uint8_t program[20]) noexcept;
105
106// Validate P2WSH witness (BIP-141 §4.2):
107// Last witness item is the witness script.
108// SHA256(witnessScript) must match the 32-byte program.
110 const std::vector<std::vector<std::uint8_t>>& witness,
111 const std::uint8_t program[32]) noexcept;
112
113// Compute witness weight contribution for a single input.
114// witness items count + all items with their lengths.
115std::size_t witness_weight(
116 const std::vector<std::vector<std::uint8_t>>& witness) noexcept;
117
118} // namespace secp256k1
119
120#endif // SECP256K1_SEGWIT_HPP
WitnessProgramType
Definition segwit.hpp:35
bool validate_p2wsh_witness(const std::vector< std::vector< std::uint8_t > > &witness, const std::uint8_t program[32]) noexcept
WitnessProgram parse_witness_program(const std::uint8_t *script, std::size_t script_len) noexcept
std::array< std::uint8_t, 34 > segwit_scriptpubkey_p2wsh(const std::uint8_t script_hash[32]) noexcept
std::size_t witness_weight(const std::vector< std::vector< std::uint8_t > > &witness) noexcept
std::array< std::uint8_t, 32 > witness_script_hash(const std::uint8_t *script, std::size_t script_len) noexcept
bool validate_p2wpkh_witness(const std::vector< std::vector< std::uint8_t > > &witness, const std::uint8_t program[20]) noexcept
std::vector< std::uint8_t > segwit_scriptpubkey(std::uint8_t version, const std::uint8_t *program, std::size_t program_len) noexcept
std::array< std::uint8_t, 22 > segwit_scriptpubkey_p2wpkh(const std::uint8_t pubkey_hash[20]) noexcept
std::array< std::uint8_t, 25 > p2wpkh_script_code(const std::uint8_t pubkey_hash[20]) noexcept
std::array< std::uint8_t, 34 > segwit_scriptpubkey_p2tr(const std::uint8_t output_key[32]) noexcept
bool is_witness_program(const std::uint8_t *script, std::size_t script_len) noexcept
std::vector< std::uint8_t > program
Definition segwit.hpp:46
WitnessProgramType type
Definition segwit.hpp:47