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) 2026-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <boost/test/unit_test.hpp>7#include <key.h>8#include <key_io.h>9#include <musig.h>10#include <test/util/setup_common.h>11#include <util/strencodings.h>12#include <crypto/hex_base.h>14#include <string>15#include <vector>17namespace {19struct BIP328TestVector {20std::vector<std::string> pubkeys;21std::string expected_aggregate_pubkey;22std::string expected_aggregate_xpub;23};25BOOST_FIXTURE_TEST_SUITE(bip328_tests, BasicTestingSetup)27BOOST_AUTO_TEST_CASE(valid_keys)28{29// BIP 328 test vectors30std::vector<BIP328TestVector> test_vectors = {31// Test vector 032{33.pubkeys = {34"03935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9",35"02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9"36},37.expected_aggregate_pubkey = "0354240c76b8f2999143301a99c7f721ee57eee0bce401df3afeaa9ae218c70f23",38.expected_aggregate_xpub = "xpub661MyMwAqRbcFt6tk3uaczE1y6EvM1TqXvawXcYmFEWijEM4PDBnuCXwwXEKGEouzXE6QLLRxjatMcLLzJ5LV5Nib1BN7vJg6yp45yHHRbm"39},40// Test vector 141{42.pubkeys = {43"02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9",44"03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659",45"023590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D038CA66"46},47.expected_aggregate_pubkey = "0290539eede565f5d054f32cc0c220126889ed1e5d193baf15aef344fe59d4610c",48.expected_aggregate_xpub = "xpub661MyMwAqRbcFt6tk3uaczE1y6EvM1TqXvawXcYmFEWijEM4PDBnuCXwwVk5TFJk8Tw5WAdV3DhrGfbFA216sE9BsQQiSFTdudkETnKdg8k"49},50// Test vector 251{52.pubkeys = {53"02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659",54"023590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D038CA66",55"02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9",56"03935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9"57},58.expected_aggregate_pubkey = "022479f134cdb266141dab1a023cbba30a870f8995b95a91fc8464e56a7d41f8ea",59.expected_aggregate_xpub = "xpub661MyMwAqRbcFt6tk3uaczE1y6EvM1TqXvawXcYmFEWijEM4PDBnuCXwwUvaZYpysLX4wN59tjwU5pBuDjNrPEJbfxjLwn7ruzbXTcUTHkZ"60}61};63// Iterate through all test vectors64for (int i = 0; i < (int) test_vectors.size(); ++i) {65const auto& test = test_vectors[i];67// Parse public keys68std::vector<CPubKey> pubkeys;69for (const auto& hex_pubkey : test.pubkeys) {70std::vector<unsigned char> data = ParseHex(hex_pubkey);71CPubKey pubkey(data.begin(), data.end());72pubkeys.push_back(pubkey);73}75// Aggregate public keys76std::optional<CPubKey> m_aggregate_pubkey = MuSig2AggregatePubkeys(pubkeys);77BOOST_CHECK_MESSAGE(m_aggregate_pubkey.has_value(), "Test vector " << i << ": Failed to aggregate pubkeys");79// Check aggregate pubkey80std::string combined_keys = HexStr(m_aggregate_pubkey.value());81BOOST_CHECK_MESSAGE(combined_keys == test.expected_aggregate_pubkey, "Test vector " << i << ": Aggregate pubkey mismatch");83// Create extended public key84CExtPubKey extpub = CreateMuSig2SyntheticXpub(m_aggregate_pubkey.value());86// Check xpub87std::string xpub = EncodeExtPubKey(extpub);88BOOST_CHECK_MESSAGE(xpub == test.expected_aggregate_xpub, "Test vector " << i << ": Synthetic xpub mismatch");89}90}92BOOST_AUTO_TEST_CASE(empty_pubkey_list)93{94const std::optional<CPubKey> aggregate_pubkey{MuSig2AggregatePubkeys({})};95BOOST_CHECK(!aggregate_pubkey.has_value());96}98BOOST_AUTO_TEST_CASE(invalid_key)99{100std::vector<std::string> test_vectors = {101"00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",102"02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"103};105// Parse public keys106std::vector<CPubKey> pubkeys;107for (const auto& hex_pubkey : test_vectors) {108std::vector<unsigned char> data = ParseHex(hex_pubkey);109CPubKey pubkey(data.begin(), data.end());110pubkeys.push_back(pubkey);111}113// Aggregate public keys114std::optional<CPubKey> m_aggregate_pubkey = MuSig2AggregatePubkeys(pubkeys);115BOOST_CHECK_MESSAGE(!m_aggregate_pubkey.has_value(), "Aggregate key with an invalid public key is null");116}118BOOST_AUTO_TEST_SUITE_END()120}
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.