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.
251return (HashWriter{HASHER_TAPTWEAK} << m_keydata).GetSHA256();252} else {253return (HashWriter{HASHER_TAPTWEAK} << m_keydata << *merkle_root).GetSHA256();254}255}257bool XOnlyPubKey::CheckTapTweak(const XOnlyPubKey& internal, const uint256& merkle_root, bool parity) const258{259secp256k1_xonly_pubkey internal_key;260if (!secp256k1_xonly_pubkey_parse(secp256k1_context_static, &internal_key, internal.data())) return false;261uint256 tweak = internal.ComputeTapTweakHash(&merkle_root);262return secp256k1_xonly_pubkey_tweak_add_check(secp256k1_context_static, m_keydata.begin(), parity, &internal_key, tweak.begin());263}265std::optional<std::pair<XOnlyPubKey, bool>> XOnlyPubKey::CreateTapTweak(const uint256* merkle_root) const266{267secp256k1_xonly_pubkey base_point;268if (!secp256k1_xonly_pubkey_parse(secp256k1_context_static, &base_point, data())) return std::nullopt;269secp256k1_pubkey out;270uint256 tweak = ComputeTapTweakHash(merkle_root);271if (!secp256k1_xonly_pubkey_tweak_add(secp256k1_context_static, &out, &base_point, tweak.data())) return std::nullopt;272int parity = -1;273std::pair<XOnlyPubKey, bool> ret;274secp256k1_xonly_pubkey out_xonly;275if (!secp256k1_xonly_pubkey_from_pubkey(secp256k1_context_static, &out_xonly, &parity, &out)) return std::nullopt;276secp256k1_xonly_pubkey_serialize(secp256k1_context_static, ret.first.begin(), &out_xonly);277assert(parity == 0 || parity == 1);278ret.second = parity;279return ret;280}283bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {284if (!IsValid())285return false;286secp256k1_pubkey pubkey;287secp256k1_ecdsa_signature sig;288if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) {289return false;290}291if (!ecdsa_signature_parse_der_lax(&sig, vchSig.data(), vchSig.size())) {292return false;293}294/* libsecp256k1's ECDSA verification requires lower-S signatures, which have295* not historically been enforced in Bitcoin, so normalize them first. */296secp256k1_ecdsa_signature_normalize(secp256k1_context_static, &sig, &sig);297return secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pubkey);298}300bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {301if (vchSig.size() != COMPACT_SIGNATURE_SIZE)302return false;303int recid = (vchSig[0] - 27) & 3;304bool fComp = ((vchSig[0] - 27) & 4) != 0;305secp256k1_pubkey pubkey;306secp256k1_ecdsa_recoverable_signature sig;307if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_static, &sig, &vchSig[1], recid)) {308return false;309}310if (!secp256k1_ecdsa_recover(secp256k1_context_static, &pubkey, &sig, hash.begin())) {311return false;312}313unsigned char pub[SIZE];314size_t publen = SIZE;315secp256k1_ec_pubkey_serialize(secp256k1_context_static, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);316Set(pub, pub + publen);317return true;318}320bool CPubKey::IsFullyValid() const {321if (!IsValid())322return false;323secp256k1_pubkey pubkey;324return secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size());325}327bool CPubKey::Decompress() {328if (!IsValid())329return false;330secp256k1_pubkey pubkey;331if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) {332return false;333}334unsigned char pub[SIZE];335size_t publen = SIZE;336secp256k1_ec_pubkey_serialize(secp256k1_context_static, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);337Set(pub, pub + publen);338return true;339}341bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc, uint256* bip32_tweak_out) const {342assert(IsValid());343assert((nChild >> 31) == 0);344assert(size() == COMPRESSED_SIZE);345unsigned char out[64];346BIP32Hash(cc, nChild, *begin(), begin()+1, out);347memcpy(ccChild.begin(), out+32, 32);348if (bip32_tweak_out) {349memcpy(bip32_tweak_out->begin(), out, 32);350}351secp256k1_pubkey pubkey;352if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) {353return false;354}355if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_static, &pubkey, out)) {356return false;357}358unsigned char pub[COMPRESSED_SIZE];359size_t publen = COMPRESSED_SIZE;360secp256k1_ec_pubkey_serialize(secp256k1_context_static, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);361pubkeyChild.Set(pub, pub + publen);362return true;363}365EllSwiftPubKey::EllSwiftPubKey(std::span<const std::byte> ellswift) noexcept366{367assert(ellswift.size() == SIZE);368std::copy(ellswift.begin(), ellswift.end(), m_pubkey.begin());369}371CPubKey EllSwiftPubKey::Decode() const372{373secp256k1_pubkey pubkey;374secp256k1_ellswift_decode(secp256k1_context_static, &pubkey, UCharCast(m_pubkey.data()));376size_t sz = CPubKey::COMPRESSED_SIZE;377std::array<uint8_t, CPubKey::COMPRESSED_SIZE> vch_bytes;379secp256k1_ec_pubkey_serialize(secp256k1_context_static, vch_bytes.data(), &sz, &pubkey, SECP256K1_EC_COMPRESSED);380assert(sz == vch_bytes.size());382return CPubKey{vch_bytes.begin(), vch_bytes.end()};383}385void CExtPubKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {386code[0] = nDepth;387std::ranges::copy(fingerprint, code+1);388WriteBE32(code+5, nChild);389memcpy(code+9, chaincode.begin(), 32);390assert(pubkey.size() == CPubKey::COMPRESSED_SIZE);391memcpy(code+41, pubkey.begin(), CPubKey::COMPRESSED_SIZE);392}394void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {395nDepth = code[0];396std::copy_n(code + 1, fingerprint.size(), fingerprint.begin());397nChild = ReadBE32(code+5);398memcpy(chaincode.begin(), code+9, 32);399pubkey.Set(code+41, code+BIP32_EXTKEY_SIZE);400if ((nDepth == 0 && (nChild != 0 || ReadLE32(fingerprint.data()) != 0)) || !pubkey.IsFullyValid()) pubkey = CPubKey();401}403void CExtPubKey::EncodeWithVersion(unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]) const404{405memcpy(code, version, 4);406Encode(&code[4]);407}409void CExtPubKey::DecodeWithVersion(const unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE])410{411memcpy(version, code, 4);412Decode(&code[4]);413}415bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild, uint256* bip32_tweak_out) const {416if (nDepth == std::numeric_limits<unsigned char>::max()) return false;417out.nDepth = nDepth + 1;418out.fingerprint = id_key_fingerprint();419out.nChild = _nChild;420return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode, bip32_tweak_out);421}423/* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) {424secp256k1_ecdsa_signature sig;425if (!ecdsa_signature_parse_der_lax(&sig, vchSig.data(), vchSig.size())) {426return false;427}428return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_static, nullptr, &sig));429}
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.