Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2009-present The Bitcoin Core developers2// Copyright (c) 2017 The Zcash developers3// Distributed under the MIT software license, see the accompanying4// file COPYING or http://www.opensource.org/licenses/mit-license.php.6#include <pubkey.h>8#include <hash.h>9#include <secp256k1.h>10#include <secp256k1_ellswift.h>11#include <secp256k1_extrakeys.h>12#include <secp256k1_recovery.h>13#include <secp256k1_schnorrsig.h>14#include <span.h>15#include <uint256.h>16#include <util/strencodings.h>18#include <algorithm>19#include <cassert>21using namespace util::hex_literals;23namespace {25struct Secp256k1SelfTester26{27Secp256k1SelfTester() {28/* Run libsecp256k1 self-test before using the secp256k1_context_static. */29secp256k1_selftest();30}31} SECP256K1_SELFTESTER;33} // namespace35/** This function is taken from the libsecp256k1 distribution and implements36* DER parsing for ECDSA signatures, while supporting an arbitrary subset of37* format violations.38*39* Supported violations include negative integers, excessive padding, garbage40* at the end, and overly long length descriptors. This is safe to use in41* Bitcoin because since the activation of BIP66, signatures are verified to be42* strict DER before being passed to this module, and we know it supports all43* violations present in the blockchain before that point.44*/45int ecdsa_signature_parse_der_lax(secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {46size_t rpos, rlen, spos, slen;47size_t pos = 0;48size_t lenbyte;49unsigned char tmpsig[64] = {0};50int overflow = 0;52/* Hack to initialize sig with a correctly-parsed but invalid signature. */53secp256k1_ecdsa_signature_parse_compact(secp256k1_context_static, sig, tmpsig);55/* Sequence tag byte */56if (pos == inputlen || input[pos] != 0x30) {57return 0;58}59pos++;61/* Sequence length bytes */62if (pos == inputlen) {63return 0;64}65lenbyte = input[pos++];66if (lenbyte & 0x80) {67lenbyte -= 0x80;68if (lenbyte > inputlen - pos) {69return 0;70}71pos += lenbyte;72}74/* Integer tag byte for R */75if (pos == inputlen || input[pos] != 0x02) {76return 0;77}78pos++;80/* Integer length for R */81if (pos == inputlen) {82return 0;83}84lenbyte = input[pos++];85if (lenbyte & 0x80) {86lenbyte -= 0x80;87if (lenbyte > inputlen - pos) {88return 0;89}90while (lenbyte > 0 && input[pos] == 0) {91pos++;92lenbyte--;93}94static_assert(sizeof(size_t) >= 4, "size_t too small");95if (lenbyte >= 4) {96return 0;97}98rlen = 0;99while (lenbyte > 0) {100rlen = (rlen << 8) + input[pos];101pos++;102lenbyte--;103}104} else {105rlen = lenbyte;106}107if (rlen > inputlen - pos) {108return 0;109}110rpos = pos;111pos += rlen;113/* Integer tag byte for S */114if (pos == inputlen || input[pos] != 0x02) {115return 0;116}117pos++;119/* Integer length for S */120if (pos == inputlen) {121return 0;122}123lenbyte = input[pos++];124if (lenbyte & 0x80) {125lenbyte -= 0x80;126if (lenbyte > inputlen - pos) {127return 0;128}129while (lenbyte > 0 && input[pos] == 0) {130pos++;131lenbyte--;132}133static_assert(sizeof(size_t) >= 4, "size_t too small");134if (lenbyte >= 4) {135return 0;136}137slen = 0;138while (lenbyte > 0) {139slen = (slen << 8) + input[pos];140pos++;141lenbyte--;142}143} else {144slen = lenbyte;145}146if (slen > inputlen - pos) {147return 0;148}149spos = pos;151/* Ignore leading zeroes in R */152while (rlen > 0 && input[rpos] == 0) {153rlen--;154rpos++;155}156/* Copy R value */157if (rlen > 32) {158overflow = 1;159} else {160memcpy(tmpsig + 32 - rlen, input + rpos, rlen);161}163/* Ignore leading zeroes in S */164while (slen > 0 && input[spos] == 0) {165slen--;166spos++;167}168/* Copy S value */169if (slen > 32) {170overflow = 1;171} else {172memcpy(tmpsig + 64 - slen, input + spos, slen);173}175if (!overflow) {176overflow = !secp256k1_ecdsa_signature_parse_compact(secp256k1_context_static, sig, tmpsig);177}178if (overflow) {179/* Overwrite the result again with a correctly-parsed but invalid180signature if parsing failed. */181memset(tmpsig, 0, 64);182secp256k1_ecdsa_signature_parse_compact(secp256k1_context_static, sig, tmpsig);183}184return 1;185}187/** Nothing Up My Sleeve (NUMS) point188*189* NUMS_H is a point with an unknown discrete logarithm, constructed by taking the sha256 of 'g'190* (uncompressed encoding), which happens to be a point on the curve.191*192* For an example script for calculating H, refer to the unit tests in193* ./test/functional/test_framework/crypto/secp256k1.py194*/195constexpr XOnlyPubKey XOnlyPubKey::NUMS_H{196// Use immediate lambda to work around GCC-14 bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117966197[]() consteval { return XOnlyPubKey{"50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0"_hex_u8}; }(),198};200std::vector<CPubKey> XOnlyPubKey::GetCPubKeys() const201{202std::vector<CPubKey> out;203unsigned char b[33] = {0x02};204std::copy(m_keydata.begin(), m_keydata.end(), b + 1);205CPubKey fullpubkey;206fullpubkey.Set(b, b + 33);207out.push_back(fullpubkey);208b[0] = 0x03;209fullpubkey.Set(b, b + 33);210out.push_back(fullpubkey);211return out;212}214std::vector<CKeyID> XOnlyPubKey::GetKeyIDs() const215{216std::vector<CKeyID> out;217for (const CPubKey& pk : GetCPubKeys()) {218out.push_back(pk.GetID());219}220return out;221}223CPubKey XOnlyPubKey::GetEvenCorrespondingCPubKey() const224{225unsigned char full_key[CPubKey::COMPRESSED_SIZE] = {0x02};226std::copy(begin(), end(), full_key + 1);227return CPubKey{full_key};228}230bool XOnlyPubKey::IsFullyValid() const231{232secp256k1_xonly_pubkey pubkey;233return secp256k1_xonly_pubkey_parse(secp256k1_context_static, &pubkey, m_keydata.data());234}236bool XOnlyPubKey::VerifySchnorr(const uint256& msg, std::span<const unsigned char> sigbytes) const237{238assert(sigbytes.size() == 64);239secp256k1_xonly_pubkey pubkey;240if (!secp256k1_xonly_pubkey_parse(secp256k1_context_static, &pubkey, m_keydata.data())) return false;241return secp256k1_schnorrsig_verify(secp256k1_context_static, sigbytes.data(), msg.begin(), 32, &pubkey);242}244static const HashWriter HASHER_TAPTWEAK{TaggedHash("TapTweak")};246uint256 XOnlyPubKey::ComputeTapTweakHash(const uint256* merkle_root) const247{248if (merkle_root == nullptr) {249// We have no scripts. The actual tweak does not matter, but follow BIP341 here to250// allow for reproducible tweaking.
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.