Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b3295ab
refactor: define BIP32_HARDENED and BIP32_UNHARDENED constants
pythcoiner Apr 14, 2026
4e2e42c
refactor: deduplicate keypath element parsing
pythcoiner Apr 14, 2026
57a1f30
crypto: add NonceFromBytes/NonceToBytes helpers
Sjors Jan 14, 2026
349877e
util: ParseHDKeypath allow h as hardened indicator
pythcoiner Jan 15, 2026
4eb416f
wallet: add WalletDescriptorInfo helper for descriptor serialization
pythcoiner Jan 14, 2026
5741144
wallet: BIP-xxxx key normalization primitives
pythcoiner Jan 14, 2026
def4852
wallet: BIP-xxxx secret computation
pythcoiner Jan 14, 2026
b1b417e
wallet: BIP-xxxx derivation path encoding
pythcoiner Jan 14, 2026
f49aec6
wallet: BIP-xxxx individual secrets encoding
pythcoiner Jan 14, 2026
c0ead9d
wallet: BIP-xxxx content type encoding
pythcoiner Apr 15, 2026
4bd2060
wallet: BIP-xxxx ChaCha20-Poly1305 encryption helpers
pythcoiner Apr 15, 2026
eb707e4
wallet: BIP-xxxx backup struct and binary encoding
pythcoiner Apr 15, 2026
c6eb02d
wallet: BIP-xxxx encrypted backup creation and decryption
pythcoiner Apr 15, 2026
ff68bc8
rpc: add encryptdescriptor RPC
pythcoiner Apr 16, 2026
ba26860
rpc: add decryptdescriptor RPC
pythcoiner Apr 16, 2026
c096923
rpc: add importencrypteddescriptor RPC
pythcoiner Apr 16, 2026
9318afa
rpc: add inspectencryptedbackup RPC
pythcoiner Apr 16, 2026
364ba88
wallet-tool: add encryptdescriptor command
pythcoiner Apr 16, 2026
1d32e68
wallet-tool: add decryptdescriptor command
pythcoiner Apr 16, 2026
b9ede35
wallet-tool: add importencrypteddescriptor command
pythcoiner Apr 16, 2026
10fa834
wallet-tool: add inspectencryptedbackup command
pythcoiner Jan 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ if(ENABLE_WALLET)
bitcoin_wallet
bitcoin_common
bitcoin_util
univalue
Boost::headers
)
install_binary_component(bitcoin-wallet HAS_MANPAGE)
endif()
Expand Down
7 changes: 7 additions & 0 deletions src/bitcoin-wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,18 @@ static void SetupWalletToolArgs(ArgsManager& argsman)
argsman.AddArg("-dumpfile=<file name>", "When used with 'dump', writes out the records to this file. When used with 'createfromdump', loads the records into a new wallet.", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS);
argsman.AddArg("-debug=<category>", "Output debugging information (default: 0).", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -debug is true, 0 otherwise).", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-descriptor=<descriptor>", "Descriptor string to encrypt (with checksum)", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS);
argsman.AddArg("-xpub=<key>", "Extended public key (xpub/tpub) for decrypting a backup", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS);
argsman.AddArg("-backupfile=<file name>", "When used with 'encryptdescriptor', writes the raw binary backup to this file (no base64). When used with 'decryptdescriptor' or 'inspectencryptedbackup', reads the raw binary backup from this file.", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS);

argsman.AddCommand("info", "Get wallet info");
argsman.AddCommand("create", "Create a new descriptor wallet file");
argsman.AddCommand("dump", "Print out all of the wallet key-value records");
argsman.AddCommand("createfromdump", "Create new wallet file from dumped records");
argsman.AddCommand("encryptdescriptor", "Encrypt a descriptor string (outputs base64 to stdout, or raw binary to -backupfile)");
argsman.AddCommand("decryptdescriptor", "Decrypt an encrypted backup and output the descriptor string (reads base64 from stdin or raw binary from -backupfile, requires -xpub)");
argsman.AddCommand("importencrypteddescriptor", "Decrypt an encrypted backup and import the descriptor into a wallet (requires -wallet, -xpub; reads base64 from stdin or raw binary from -backupfile)");
argsman.AddCommand("inspectencryptedbackup", "Show metadata from an encrypted backup (reads base64 from stdin or raw binary from -backupfile)");
}

static std::optional<int> WalletAppInit(ArgsManager& args, int argc, char* argv[])
Expand Down
37 changes: 37 additions & 0 deletions src/crypto/chacha20poly1305.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,43 @@ class AEADChaCha20Poly1305
/** 96-bit nonce type. */
using Nonce96 = ChaCha20::Nonce96;

/** Size of the nonce in bytes. */
static constexpr unsigned NONCE_SIZE = 12;

/** Convert a 12-byte array to a Nonce96.
*
* RFC8439 defines the nonce as 96 opaque bits. This helper converts
* a byte array (big-endian) to the internal {uint32_t, uint64_t} representation.
*/
static Nonce96 NonceFromBytes(std::span<const std::byte, NONCE_SIZE> nonce_bytes) noexcept
{
return {
(uint32_t(uint8_t(nonce_bytes[0])) << 24) | (uint32_t(uint8_t(nonce_bytes[1])) << 16) |
(uint32_t(uint8_t(nonce_bytes[2])) << 8) | uint32_t(uint8_t(nonce_bytes[3])),
(uint64_t(uint8_t(nonce_bytes[4])) << 56) | (uint64_t(uint8_t(nonce_bytes[5])) << 48) |
(uint64_t(uint8_t(nonce_bytes[6])) << 40) | (uint64_t(uint8_t(nonce_bytes[7])) << 32) |
(uint64_t(uint8_t(nonce_bytes[8])) << 24) | (uint64_t(uint8_t(nonce_bytes[9])) << 16) |
(uint64_t(uint8_t(nonce_bytes[10])) << 8) | uint64_t(uint8_t(nonce_bytes[11]))
};
}

/** Convert a Nonce96 back to a 12-byte array (big-endian). */
static void NonceToBytes(Nonce96 nonce, std::span<std::byte, NONCE_SIZE> nonce_bytes) noexcept
{
nonce_bytes[0] = std::byte((nonce.first >> 24) & 0xFF);
nonce_bytes[1] = std::byte((nonce.first >> 16) & 0xFF);
nonce_bytes[2] = std::byte((nonce.first >> 8) & 0xFF);
nonce_bytes[3] = std::byte(nonce.first & 0xFF);
nonce_bytes[4] = std::byte((nonce.second >> 56) & 0xFF);
nonce_bytes[5] = std::byte((nonce.second >> 48) & 0xFF);
nonce_bytes[6] = std::byte((nonce.second >> 40) & 0xFF);
nonce_bytes[7] = std::byte((nonce.second >> 32) & 0xFF);
nonce_bytes[8] = std::byte((nonce.second >> 24) & 0xFF);
nonce_bytes[9] = std::byte((nonce.second >> 16) & 0xFF);
nonce_bytes[10] = std::byte((nonce.second >> 8) & 0xFF);
nonce_bytes[11] = std::byte(nonce.second & 0xFF);
}

/** Encrypt a message with a specified 96-bit nonce and aad.
*
* Requires cipher.size() = plain.size() + EXPANSION.
Expand Down
40 changes: 19 additions & 21 deletions src/script/descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ class BIP32PubkeyProvider final : public PubkeyProvider
std::copy(keyid.begin(), keyid.begin() + sizeof(info.fingerprint), info.fingerprint);
info.path = m_path;
if (m_derive == DeriveType::UNHARDENED_RANGED) info.path.push_back((uint32_t)pos);
if (m_derive == DeriveType::HARDENED_RANGED) info.path.push_back(((uint32_t)pos) | 0x80000000L);
if (m_derive == DeriveType::HARDENED_RANGED) info.path.push_back(((uint32_t)pos) | BIP32_HARDENED);

// Derive keys or fetch them from cache
CExtPubKey final_extkey = m_root_extkey;
Expand All @@ -450,7 +450,7 @@ class BIP32PubkeyProvider final : public PubkeyProvider
if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return std::nullopt;
parent_extkey = xprv.Neuter();
if (m_derive == DeriveType::UNHARDENED_RANGED) der = xprv.Derive(xprv, pos);
if (m_derive == DeriveType::HARDENED_RANGED) der = xprv.Derive(xprv, pos | 0x80000000UL);
if (m_derive == DeriveType::HARDENED_RANGED) der = xprv.Derive(xprv, pos | BIP32_HARDENED);
final_extkey = xprv.Neuter();
if (lh_xprv.key.IsValid()) {
last_hardened_extkey = lh_xprv.Neuter();
Expand Down Expand Up @@ -576,7 +576,7 @@ class BIP32PubkeyProvider final : public PubkeyProvider
CExtKey dummy;
if (!GetDerivedExtKey(arg, extkey, dummy)) return;
if (m_derive == DeriveType::UNHARDENED_RANGED && !extkey.Derive(extkey, pos)) return;
if (m_derive == DeriveType::HARDENED_RANGED && !extkey.Derive(extkey, pos | 0x80000000UL)) return;
if (m_derive == DeriveType::HARDENED_RANGED && !extkey.Derive(extkey, pos | BIP32_HARDENED)) return;
out.keys.emplace(extkey.key.GetPubKey().GetID(), extkey.key);
}
std::optional<CPubKey> GetRootPubKey() const override
Expand Down Expand Up @@ -1754,25 +1754,13 @@ enum class ParseScriptContext {
std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem, bool& apostrophe, std::string& error, bool& has_hardened)
{
bool hardened = false;
if (elem.size() > 0) {
const char last = elem[elem.size() - 1];
if (last == '\'' || last == 'h') {
elem = elem.first(elem.size() - 1);
hardened = true;
apostrophe = last == '\'';
}
const auto index{ParseKeyPathElement(elem, hardened, error)};
if (!index.has_value()) return std::nullopt;
if (hardened) {
has_hardened = true;
apostrophe = elem.back() == '\'';
}
const auto p{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
if (!p) {
error = strprintf("Key path value '%s' is not a valid uint32", std::string_view{elem.begin(), elem.end()});
return std::nullopt;
} else if (*p > 0x7FFFFFFFUL) {
error = strprintf("Key path value %u is out of range", *p);
return std::nullopt;
}
has_hardened = has_hardened || hardened;

return std::make_optional<uint32_t>(*p | (((uint32_t)hardened) << 31));
return *index | (hardened ? BIP32_HARDENED : BIP32_UNHARDENED);
}

/**
Expand Down Expand Up @@ -3004,3 +2992,13 @@ ExtPubKeyMap DescriptorCache::GetCachedLastHardenedExtPubKeys() const
{
return m_last_hardened_xpubs;
}

std::optional<CExtPubKey> ParseExtPubKeyExpression(const std::string& str, std::string& error)
{
FlatSigningProvider out;
uint32_t key_exp_index = 0;
const std::span<const char> sp{str.data(), str.size()};
auto providers = ParsePubkey(key_exp_index, sp, ParseScriptContext::P2WPKH, out, error);
if (providers.empty()) return std::nullopt;
return providers[0]->GetRootExtPubKey();
}
5 changes: 5 additions & 0 deletions src/script/descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ struct Descriptor {
virtual size_t GetKeyCount() const = 0;
};

/** Parse a key expression (optionally with origin and derivation path) and return the extended public key.
* Accepts formats like: xpub..., [fingerprint/path]xpub..., [fingerprint/path]xpub.../0/wildcard
*/
std::optional<CExtPubKey> ParseExtPubKeyExpression(const std::string& str, std::string& error);

/** Parse a `descriptor` string. Included private keys are put in `out`.
*
* If the descriptor has a checksum, it must be valid. If `require_checksum`
Expand Down
7 changes: 7 additions & 0 deletions src/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,13 @@ include(TargetDataSources)
target_json_data_sources(test_bitcoin
data/base58_encode_decode.json
data/bip341_wallet_vectors.json
data/bip_encrypted_backup_chacha20poly1305_encryption.json
data/bip_encrypted_backup_content_type.json
data/bip_encrypted_backup_derivation_path.json
data/bip_encrypted_backup_encrypted_backup.json
data/bip_encrypted_backup_encryption_secret.json
data/bip_encrypted_backup_individual_secrets.json
data/bip_encrypted_backup_keys_types.json
data/blockfilters.json
data/key_io_invalid.json
data/key_io_valid.json
Expand Down
13 changes: 7 additions & 6 deletions src/test/bip32_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <key_io.h>
#include <streams.h>
#include <test/util/setup_common.h>
#include <util/bip32.h>
#include <util/strencodings.h>

#include <string>
Expand Down Expand Up @@ -42,13 +43,13 @@ TestVector test1 =
TestVector("000102030405060708090a0b0c0d0e0f")
("xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
"xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
0x80000000)
BIP32_HARDENED)
("xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw",
"xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7",
1)
("xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ",
"xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs",
0x80000002)
BIP32_HARDENED | 2)
("xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5",
"xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM",
2)
Expand Down Expand Up @@ -84,7 +85,7 @@ TestVector test3 =
TestVector("4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be")
("xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13",
"xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6",
0x80000000)
BIP32_HARDENED)
("xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y",
"xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L",
0);
Expand All @@ -93,10 +94,10 @@ TestVector test4 =
TestVector("3ddd5602285899a946114506157c7997e5444528f3003f6134712147db19b678")
("xpub661MyMwAqRbcGczjuMoRm6dXaLDEhW1u34gKenbeYqAix21mdUKJyuyu5F1rzYGVxyL6tmgBUAEPrEz92mBXjByMRiJdba9wpnN37RLLAXa",
"xprv9s21ZrQH143K48vGoLGRPxgo2JNkJ3J3fqkirQC2zVdk5Dgd5w14S7fRDyHH4dWNHUgkvsvNDCkvAwcSHNAQwhwgNMgZhLtQC63zxwhQmRv",
0x80000000)
BIP32_HARDENED)
("xpub69AUMk3qDBi3uW1sXgjCmVjJ2G6WQoYSnNHyzkmdCHEhSZ4tBok37xfFEqHd2AddP56Tqp4o56AePAgCjYdvpW2PU2jbUPFKsav5ut6Ch1m",
"xprv9vB7xEWwNp9kh1wQRfCCQMnZUEG21LpbR9NPCNN1dwhiZkjjeGRnaALmPXCX7SgjFTiCTT6bXes17boXtjq3xLpcDjzEuGLQBM5ohqkao9G",
0x80000001)
BIP32_HARDENED | 1)
("xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt",
"xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJeHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1",
0);
Expand Down Expand Up @@ -144,7 +145,7 @@ void RunTest(const TestVector& test)
CExtKey keyNew;
BOOST_CHECK(key.Derive(keyNew, derive.nChild));
CExtPubKey pubkeyNew = keyNew.Neuter();
if (!(derive.nChild & 0x80000000)) {
if (!(derive.nChild & BIP32_HARDENED)) {
// Compare with public derivation
CExtPubKey pubkeyNew2;
BOOST_CHECK(pubkey.Derive(pubkeyNew2, derive.nChild));
Expand Down
29 changes: 29 additions & 0 deletions src/test/crypto_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <util/strencodings.h>

#include <algorithm>
#include <ranges>
#include <vector>

#include <boost/test/unit_test.hpp>
Expand Down Expand Up @@ -1051,6 +1052,34 @@ BOOST_AUTO_TEST_CASE(chacha20poly1305_testvectors)
"14b94829deb27f0b1923a2af704ae5d6");
}

BOOST_AUTO_TEST_CASE(chacha20poly1305_nonce_conversion)
{
// Test NonceFromBytes/NonceToBytes roundtrip
auto key = ParseHex<std::byte>("808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f");
auto nonce_bytes = ParseHex<std::byte>("000000000001020304050607");

// Convert bytes to Nonce96
auto nonce = AEADChaCha20Poly1305::NonceFromBytes(std::span<const std::byte, 12>{nonce_bytes.data(), 12});
// Expected: first 4 bytes = 0x00000000, next 8 bytes = 0x0001020304050607
BOOST_CHECK_EQUAL(nonce.first, 0x00000000U);
BOOST_CHECK_EQUAL(nonce.second, 0x0001020304050607ULL);

// Convert back to bytes and check roundtrip
std::array<std::byte, 12> roundtrip_bytes;
AEADChaCha20Poly1305::NonceToBytes(nonce, roundtrip_bytes);
BOOST_CHECK(std::ranges::equal(nonce_bytes, roundtrip_bytes));

// Test with different values to ensure byte ordering is correct
auto nonce_bytes2 = ParseHex<std::byte>("aabbccdd11223344556677ff");
auto nonce2 = AEADChaCha20Poly1305::NonceFromBytes(std::span<const std::byte, 12>{nonce_bytes2.data(), 12});
BOOST_CHECK_EQUAL(nonce2.first, 0xaabbccddU);
BOOST_CHECK_EQUAL(nonce2.second, 0x11223344556677ffULL);

std::array<std::byte, 12> roundtrip_bytes2;
AEADChaCha20Poly1305::NonceToBytes(nonce2, roundtrip_bytes2);
BOOST_CHECK(std::ranges::equal(nonce_bytes2, roundtrip_bytes2));
}

BOOST_AUTO_TEST_CASE(hkdf_hmac_sha256_l32_tests)
{
// Use rfc5869 test vectors but truncated to 32 bytes (our implementation only support length 32)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[
{
"description": "Basic encryption with short plaintext",
"nonce": "000102030405060708090a0b",
"plaintext": "48656c6c6f",
"secret": "0000000000000000000000000000000000000000000000000000000000000000",
"ciphertext": "7df9cb9a0ac5851cc054b14d05f781127b2b0d31fa"
},
{
"description": "Empty plaintext should fail",
"nonce": "000102030405060708090a0b",
"plaintext": "",
"secret": "0000000000000000000000000000000000000000000000000000000000000000",
"ciphertext": null
},
{
"description": "Encryption with zeroed nonce should fail",
"nonce": "000000000000000000000000",
"plaintext": "00000000000000000000000000000000",
"secret": "0000000000000000000000000000000000000000000000000000000000000000",
"ciphertext": null
},
{
"description": "Encryption with all FFs",
"nonce": "ffffffffffffffffffffffff",
"plaintext": "ffffffffffffffffffffffffffffffff",
"secret": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"ciphertext": "22d8bfc313e141bd692c82cec7785b29a0e5d5014c0d3b2d3a8b00548cd8d221"
},
{
"description": "Longer plaintext",
"nonce": "0f1e2d3c4b5a69788796a5b4",
"plaintext": "546869732069732061206c6f6e67657220706c61696e746578742074686174207368756c6420626520656e637279707465642070726f7065726c792e",
"secret": "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
"ciphertext": "2af094190e2b43a02b8dd6bfc25a8833f84f81bc6f690d75f0214e466ef392616c4644bee65118c444a926e1e365b3a7ba0509a5636524eb4e5722f5926938f32e4df79237acb6dd4a6ccbc4"
}
]
67 changes: 67 additions & 0 deletions src/test/data/bip_encrypted_backup_content_type.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
[
{
"description": "Bip 380",
"valid": true,
"content": "01017c"
},
{
"description": "Bip 388",
"valid": true,
"content": "010184"
},
{
"description": "Bip 329",
"valid": true,
"content": "010149"
},
{
"description": "Bip 999",
"valid": true,
"content": "0103e7"
},
{
"description": "Bip max",
"valid": true,
"content": "01ffff"
},
{
"description": "Bip min",
"valid": true,
"content": "010000"
},
{
"description": "Propietary 00010203",
"valid": true,
"content": "020400010203"
},
{
"description": "TYPE 0x00 is reserved",
"valid": false,
"content": "00"
},
{
"description": "Invalid BIP (insufficient bytes)",
"valid": false,
"content": "0100"
},
{
"description": "Invalid proprietary (missing data)",
"valid": false,
"content": "0201"
},
{
"description": "Invalid proprietary (LENGTH exceeds payload)",
"valid": false,
"content": "020500"
},
{
"description": "TYPE >= 0x80 stops parsing",
"valid": false,
"content": "ff"
},
{
"description": "TYPE >= 0x80 stops parsing",
"valid": false,
"content": "ff000000"
}
]
Loading
Loading