diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b37f3c8ca5cf..3ecbaf8693ec 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -168,6 +168,8 @@ if(ENABLE_WALLET) bitcoin_wallet bitcoin_common bitcoin_util + univalue + Boost::headers ) install_binary_component(bitcoin-wallet HAS_MANPAGE) endif() diff --git a/src/bitcoin-wallet.cpp b/src/bitcoin-wallet.cpp index 9b0136da4c48..01201b87726b 100644 --- a/src/bitcoin-wallet.cpp +++ b/src/bitcoin-wallet.cpp @@ -40,11 +40,18 @@ static void SetupWalletToolArgs(ArgsManager& argsman) argsman.AddArg("-dumpfile=", "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=", "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 string to encrypt (with checksum)", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS); + argsman.AddArg("-xpub=", "Extended public key (xpub/tpub) for decrypting a backup", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS); + argsman.AddArg("-backupfile=", "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 WalletAppInit(ArgsManager& args, int argc, char* argv[]) diff --git a/src/crypto/chacha20poly1305.h b/src/crypto/chacha20poly1305.h index 9a863dda97b4..7b21aca54ed9 100644 --- a/src/crypto/chacha20poly1305.h +++ b/src/crypto/chacha20poly1305.h @@ -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 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 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. diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index 19315dd6a30f..682b8b8c675c 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -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; @@ -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(); @@ -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 GetRootPubKey() const override @@ -1754,25 +1754,13 @@ enum class ParseScriptContext { std::optional ParseKeyPathNum(std::span 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(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(*p | (((uint32_t)hardened) << 31)); + return *index | (hardened ? BIP32_HARDENED : BIP32_UNHARDENED); } /** @@ -3004,3 +2992,13 @@ ExtPubKeyMap DescriptorCache::GetCachedLastHardenedExtPubKeys() const { return m_last_hardened_xpubs; } + +std::optional ParseExtPubKeyExpression(const std::string& str, std::string& error) +{ + FlatSigningProvider out; + uint32_t key_exp_index = 0; + const std::span 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(); +} diff --git a/src/script/descriptor.h b/src/script/descriptor.h index 3ac748a1746e..da792f5ec66f 100644 --- a/src/script/descriptor.h +++ b/src/script/descriptor.h @@ -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 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` diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 1365d6c147a6..2093b6c3c379 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -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 diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 1df368ade744..dbbe5d15a015 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -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) @@ -84,7 +85,7 @@ TestVector test3 = TestVector("4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be") ("xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13", "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6", - 0x80000000) + BIP32_HARDENED) ("xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y", "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L", 0); @@ -93,10 +94,10 @@ TestVector test4 = TestVector("3ddd5602285899a946114506157c7997e5444528f3003f6134712147db19b678") ("xpub661MyMwAqRbcGczjuMoRm6dXaLDEhW1u34gKenbeYqAix21mdUKJyuyu5F1rzYGVxyL6tmgBUAEPrEz92mBXjByMRiJdba9wpnN37RLLAXa", "xprv9s21ZrQH143K48vGoLGRPxgo2JNkJ3J3fqkirQC2zVdk5Dgd5w14S7fRDyHH4dWNHUgkvsvNDCkvAwcSHNAQwhwgNMgZhLtQC63zxwhQmRv", - 0x80000000) + BIP32_HARDENED) ("xpub69AUMk3qDBi3uW1sXgjCmVjJ2G6WQoYSnNHyzkmdCHEhSZ4tBok37xfFEqHd2AddP56Tqp4o56AePAgCjYdvpW2PU2jbUPFKsav5ut6Ch1m", "xprv9vB7xEWwNp9kh1wQRfCCQMnZUEG21LpbR9NPCNN1dwhiZkjjeGRnaALmPXCX7SgjFTiCTT6bXes17boXtjq3xLpcDjzEuGLQBM5ohqkao9G", - 0x80000001) + BIP32_HARDENED | 1) ("xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt", "xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJeHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1", 0); @@ -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)); diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index b348793bfb63..d128eafd978e 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -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("808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f"); + auto nonce_bytes = ParseHex("000000000001020304050607"); + + // Convert bytes to Nonce96 + auto nonce = AEADChaCha20Poly1305::NonceFromBytes(std::span{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 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("aabbccdd11223344556677ff"); + auto nonce2 = AEADChaCha20Poly1305::NonceFromBytes(std::span{nonce_bytes2.data(), 12}); + BOOST_CHECK_EQUAL(nonce2.first, 0xaabbccddU); + BOOST_CHECK_EQUAL(nonce2.second, 0x11223344556677ffULL); + + std::array 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) diff --git a/src/test/data/bip_encrypted_backup_chacha20poly1305_encryption.json b/src/test/data/bip_encrypted_backup_chacha20poly1305_encryption.json new file mode 100644 index 000000000000..625862d177eb --- /dev/null +++ b/src/test/data/bip_encrypted_backup_chacha20poly1305_encryption.json @@ -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" + } +] \ No newline at end of file diff --git a/src/test/data/bip_encrypted_backup_content_type.json b/src/test/data/bip_encrypted_backup_content_type.json new file mode 100644 index 000000000000..f688fd47fca7 --- /dev/null +++ b/src/test/data/bip_encrypted_backup_content_type.json @@ -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" + } +] diff --git a/src/test/data/bip_encrypted_backup_derivation_path.json b/src/test/data/bip_encrypted_backup_derivation_path.json new file mode 100644 index 000000000000..05402f1d7981 --- /dev/null +++ b/src/test/data/bip_encrypted_backup_derivation_path.json @@ -0,0 +1,146 @@ +[ + { + "description": "Empty derivation paths", + "paths": [], + "expected": "00" + }, + { + "description": "Single path with one child: m/0", + "paths": ["m/0"], + "expected": "010100000000" + }, + { + "description": "Single path with hardened child: m/44'", + "paths": ["m/44'"], + "expected": "01018000002c" + }, + { + "description": "Standard BIP-84 path: m/84'/0'/0'", + "paths": ["m/84'/0'/0'"], + "expected": "0103800000548000000080000000" + }, + { + "description": "Mixed hardened and normal: m/0/1'/2/3'", + "paths": ["m/0/1'/2/3'"], + "expected": "010400000000800000010000000280000003" + }, + { + "description": "Multiple paths: m/0/1'/2/3' and m/84'/0'/0'/2'", + "paths": ["m/0/1'/2/3'", "m/84'/0'/0'/2'"], + "expected": "0204000000008000000100000002800000030480000054800000008000000080000002" + }, + { + "description": "Path with large indices: m/2147483647'/2147483646", + "paths": ["m/2147483647'/2147483646"], + "expected": "0102ffffffff7ffffffe" + }, + { + "description": "Single child path: m/1", + "paths": ["m/1"], + "expected": "010100000001" + }, + { + "description": "Path with max normal index: m/2147483647", + "paths": ["m/2147483647"], + "expected": "01017fffffff" + }, + { + "description": "Path with multiple normal indices: m/0/1/2/3/4", + "paths": ["m/0/1/2/3/4"], + "expected": "01050000000000000001000000020000000300000004" + }, + { + "description": "Path with all hardened: m/0'/1'/2'", + "paths": ["m/0'/1'/2'"], + "expected": "0103800000008000000180000002" + }, + { + "description": "Two different single-child paths: m/0 and m/1", + "paths": ["m/0", "m/1"], + "expected": "0201000000000100000001" + }, + { + "description": "BIP-44 account 0: m/44'/0'/0'", + "paths": ["m/44'/0'/0'"], + "expected": "01038000002c8000000080000000" + }, + { + "description": "BIP-49 account 0: m/49'/0'/0'", + "paths": ["m/49'/0'/0'"], + "expected": "0103800000318000000080000000" + }, + { + "description": "Single path with 255 children (maximum depth, success)", + "paths": ["m/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0"], + "expected": "01ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "description": "256 paths should fail (exceeds u8::MAX)", + "paths": [ + "m/0", "m/1", "m/2", "m/3", "m/4", "m/5", "m/6", "m/7", "m/8", "m/9", + "m/10", "m/11", "m/12", "m/13", "m/14", "m/15", "m/16", "m/17", "m/18", "m/19", + "m/20", "m/21", "m/22", "m/23", "m/24", "m/25", "m/26", "m/27", "m/28", "m/29", + "m/30", "m/31", "m/32", "m/33", "m/34", "m/35", "m/36", "m/37", "m/38", "m/39", + "m/40", "m/41", "m/42", "m/43", "m/44", "m/45", "m/46", "m/47", "m/48", "m/49", + "m/50", "m/51", "m/52", "m/53", "m/54", "m/55", "m/56", "m/57", "m/58", "m/59", + "m/60", "m/61", "m/62", "m/63", "m/64", "m/65", "m/66", "m/67", "m/68", "m/69", + "m/70", "m/71", "m/72", "m/73", "m/74", "m/75", "m/76", "m/77", "m/78", "m/79", + "m/80", "m/81", "m/82", "m/83", "m/84", "m/85", "m/86", "m/87", "m/88", "m/89", + "m/90", "m/91", "m/92", "m/93", "m/94", "m/95", "m/96", "m/97", "m/98", "m/99", + "m/100", "m/101", "m/102", "m/103", "m/104", "m/105", "m/106", "m/107", "m/108", "m/109", + "m/110", "m/111", "m/112", "m/113", "m/114", "m/115", "m/116", "m/117", "m/118", "m/119", + "m/120", "m/121", "m/122", "m/123", "m/124", "m/125", "m/126", "m/127", "m/128", "m/129", + "m/130", "m/131", "m/132", "m/133", "m/134", "m/135", "m/136", "m/137", "m/138", "m/139", + "m/140", "m/141", "m/142", "m/143", "m/144", "m/145", "m/146", "m/147", "m/148", "m/149", + "m/150", "m/151", "m/152", "m/153", "m/154", "m/155", "m/156", "m/157", "m/158", "m/159", + "m/160", "m/161", "m/162", "m/163", "m/164", "m/165", "m/166", "m/167", "m/168", "m/169", + "m/170", "m/171", "m/172", "m/173", "m/174", "m/175", "m/176", "m/177", "m/178", "m/179", + "m/180", "m/181", "m/182", "m/183", "m/184", "m/185", "m/186", "m/187", "m/188", "m/189", + "m/190", "m/191", "m/192", "m/193", "m/194", "m/195", "m/196", "m/197", "m/198", "m/199", + "m/200", "m/201", "m/202", "m/203", "m/204", "m/205", "m/206", "m/207", "m/208", "m/209", + "m/210", "m/211", "m/212", "m/213", "m/214", "m/215", "m/216", "m/217", "m/218", "m/219", + "m/220", "m/221", "m/222", "m/223", "m/224", "m/225", "m/226", "m/227", "m/228", "m/229", + "m/230", "m/231", "m/232", "m/233", "m/234", "m/235", "m/236", "m/237", "m/238", "m/239", + "m/240", "m/241", "m/242", "m/243", "m/244", "m/245", "m/246", "m/247", "m/248", "m/249", + "m/250", "m/251", "m/252", "m/253", "m/254", "m/255" + ], + "expected": null + }, + { + "description": "Path with 256 children should fail (exceeds u8::MAX)", + "paths": ["m/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0"], + "expected": null + }, + { + "description": "255 paths should succeed (maximum allowed)", + "paths": [ + "m/0", "m/1", "m/2", "m/3", "m/4", "m/5", "m/6", "m/7", "m/8", "m/9", + "m/10", "m/11", "m/12", "m/13", "m/14", "m/15", "m/16", "m/17", "m/18", "m/19", + "m/20", "m/21", "m/22", "m/23", "m/24", "m/25", "m/26", "m/27", "m/28", "m/29", + "m/30", "m/31", "m/32", "m/33", "m/34", "m/35", "m/36", "m/37", "m/38", "m/39", + "m/40", "m/41", "m/42", "m/43", "m/44", "m/45", "m/46", "m/47", "m/48", "m/49", + "m/50", "m/51", "m/52", "m/53", "m/54", "m/55", "m/56", "m/57", "m/58", "m/59", + "m/60", "m/61", "m/62", "m/63", "m/64", "m/65", "m/66", "m/67", "m/68", "m/69", + "m/70", "m/71", "m/72", "m/73", "m/74", "m/75", "m/76", "m/77", "m/78", "m/79", + "m/80", "m/81", "m/82", "m/83", "m/84", "m/85", "m/86", "m/87", "m/88", "m/89", + "m/90", "m/91", "m/92", "m/93", "m/94", "m/95", "m/96", "m/97", "m/98", "m/99", + "m/100", "m/101", "m/102", "m/103", "m/104", "m/105", "m/106", "m/107", "m/108", "m/109", + "m/110", "m/111", "m/112", "m/113", "m/114", "m/115", "m/116", "m/117", "m/118", "m/119", + "m/120", "m/121", "m/122", "m/123", "m/124", "m/125", "m/126", "m/127", "m/128", "m/129", + "m/130", "m/131", "m/132", "m/133", "m/134", "m/135", "m/136", "m/137", "m/138", "m/139", + "m/140", "m/141", "m/142", "m/143", "m/144", "m/145", "m/146", "m/147", "m/148", "m/149", + "m/150", "m/151", "m/152", "m/153", "m/154", "m/155", "m/156", "m/157", "m/158", "m/159", + "m/160", "m/161", "m/162", "m/163", "m/164", "m/165", "m/166", "m/167", "m/168", "m/169", + "m/170", "m/171", "m/172", "m/173", "m/174", "m/175", "m/176", "m/177", "m/178", "m/179", + "m/180", "m/181", "m/182", "m/183", "m/184", "m/185", "m/186", "m/187", "m/188", "m/189", + "m/190", "m/191", "m/192", "m/193", "m/194", "m/195", "m/196", "m/197", "m/198", "m/199", + "m/200", "m/201", "m/202", "m/203", "m/204", "m/205", "m/206", "m/207", "m/208", "m/209", + "m/210", "m/211", "m/212", "m/213", "m/214", "m/215", "m/216", "m/217", "m/218", "m/219", + "m/220", "m/221", "m/222", "m/223", "m/224", "m/225", "m/226", "m/227", "m/228", "m/229", + "m/230", "m/231", "m/232", "m/233", "m/234", "m/235", "m/236", "m/237", "m/238", "m/239", + "m/240", "m/241", "m/242", "m/243", "m/244", "m/245", "m/246", "m/247", "m/248", "m/249", + "m/250", "m/251", "m/252", "m/253", "m/254" + ], + "expected": "ff0100000000010000000101000000020100000003010000000401000000050100000006010000000701000000080100000009010000000a010000000b010000000c010000000d010000000e010000000f0100000010010000001101000000120100000013010000001401000000150100000016010000001701000000180100000019010000001a010000001b010000001c010000001d010000001e010000001f0100000020010000002101000000220100000023010000002401000000250100000026010000002701000000280100000029010000002a010000002b010000002c010000002d010000002e010000002f0100000030010000003101000000320100000033010000003401000000350100000036010000003701000000380100000039010000003a010000003b010000003c010000003d010000003e010000003f0100000040010000004101000000420100000043010000004401000000450100000046010000004701000000480100000049010000004a010000004b010000004c010000004d010000004e010000004f0100000050010000005101000000520100000053010000005401000000550100000056010000005701000000580100000059010000005a010000005b010000005c010000005d010000005e010000005f0100000060010000006101000000620100000063010000006401000000650100000066010000006701000000680100000069010000006a010000006b010000006c010000006d010000006e010000006f0100000070010000007101000000720100000073010000007401000000750100000076010000007701000000780100000079010000007a010000007b010000007c010000007d010000007e010000007f0100000080010000008101000000820100000083010000008401000000850100000086010000008701000000880100000089010000008a010000008b010000008c010000008d010000008e010000008f0100000090010000009101000000920100000093010000009401000000950100000096010000009701000000980100000099010000009a010000009b010000009c010000009d010000009e010000009f01000000a001000000a101000000a201000000a301000000a401000000a501000000a601000000a701000000a801000000a901000000aa01000000ab01000000ac01000000ad01000000ae01000000af01000000b001000000b101000000b201000000b301000000b401000000b501000000b601000000b701000000b801000000b901000000ba01000000bb01000000bc01000000bd01000000be01000000bf01000000c001000000c101000000c201000000c301000000c401000000c501000000c601000000c701000000c801000000c901000000ca01000000cb01000000cc01000000cd01000000ce01000000cf01000000d001000000d101000000d201000000d301000000d401000000d501000000d601000000d701000000d801000000d901000000da01000000db01000000dc01000000dd01000000de01000000df01000000e001000000e101000000e201000000e301000000e401000000e501000000e601000000e701000000e801000000e901000000ea01000000eb01000000ec01000000ed01000000ee01000000ef01000000f001000000f101000000f201000000f301000000f401000000f501000000f601000000f701000000f801000000f901000000fa01000000fb01000000fc01000000fd01000000fe" + } +] diff --git a/src/test/data/bip_encrypted_backup_encrypted_backup.json b/src/test/data/bip_encrypted_backup_encrypted_backup.json new file mode 100644 index 000000000000..327913b2ccee --- /dev/null +++ b/src/test/data/bip_encrypted_backup_encrypted_backup.json @@ -0,0 +1,67 @@ +[ + { + "description": "Single key, no derivation paths, BIP380 content", + "version": 1, + "encryption": 1, + "content": "01017c", + "keys": [ + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443" + ], + "derivation_paths": [], + "plaintext": "00", + "nonce": "a1b2c3d4e5f607080910a1b2", + "expected": "424950585858010001ff34b3411f78127b71ca2e3cc60d0fd71350ee557c37d71f4d81fb913461ae0001a1b2c3d4e5f607080910a1b2151d8f44dba6f420976b9343f792b4bd58c06289d234", + "trailing": "deadbeef00ff", + "expected_base64": "QklQWFhYAQAB/zSzQR94Entxyi48xg0P1xNQ7lV8N9cfTYH7kTRhrgABobLD1OX2BwgJEKGyFR2PRNum9CCXa5ND95K0vVjAYonSNA==" + }, + { + "description": "Two keys, 1 derivation paths, BIP380 content", + "version": 1, + "encryption": 1, + "content": "01017c", + "keys": [ + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443", + "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07" + ], + "derivation_paths": [ + "m/48'/1'/0'/2'" + ], + "plaintext": "wsh(or_d(pk([9d69155f/48'/1'/0'/2']tpubDDxT9mkZzWwkKwpGT5fY6iiM9muYTPkTx6Eig8dpHR7TChuGGCWYAHVmpW1ciido5RiFWwjzYsF1GZHkEHg2nrYp3zNtx3QQRkznyLhQ77x/<0;1>/*),and_v(v:pkh([9d69155f/48'/1'/0'/2']tpubDDxT9mkZzWwkKwpGT5fY6iiM9muYTPkTx6Eig8dpHR7TChuGGCWYAHVmpW1ciido5RiFWwjzYsF1GZHkEHg2nrYp3zNtx3QQRkznyLhQ77x/<2;3>/*),older(52596))))#gx5f42wh", + "nonce": "0102030405060708090a0b0c", + "expected": "42495058585801010480000030800000018000000080000002024900d4ef9021cb059b8fb35c6de9b6db91949a328527ede0645be237899100bd5e3eb8a36f7bf32e02810c14666476f2b28a15cd499c30f8f98e926639a0765c010102030405060708090a0b0cfd63012f51db36ae620d6522a86e4ce7d9daff2f50826aae70c1d3707d18b8075543da1848ad904b11be465e768d8b1ea74a1b21f21f882262bd0d5f7165991720c1836f1bce2dec7ba3813fc1c0bc6404a0fd6228e239f8bddd398c32f8274f9de0f0b5662854ce900d7d5b14a16605eb2a49d031b98513b73777685693b45b17e08a60e095b66403efcc7036cd82a8d675362eab43bcdecb158e8b0dcca476173345d189c2277dc25b9851b2be92c7ef8b69a565af1ccf9726e322db2b8d5266a5df4296527c716b8ba004fb1408cbd7cc7a18575286e6f03e1793b25eea11223fd6cc7a497d8328997b1eb770fcc8125e60511eefb8232b780d80f1d71e9e937627dfb62cd6c5807b35e7d7bb9aaf18d5a46c6ea271f2be26bd1cc35bb2b70cc1930ad5f472b1bf0d7b3bed3dfe358a69beabdafd6316968c530237f21e1c89662ada34d666735f791db5eb68ee29d2d06f42421ec311d6284f5be9850d63e0cfd6cfe207", + "expected_base64": "QklQWFhYAQEEgAAAMIAAAAGAAAAAgAAAAgJJANTvkCHLBZuPs1xt6bbbkZSaMoUn7eBkW+I3iZEAvV4+uKNve/MuAoEMFGZkdvKyihXNSZww+PmOkmY5oHZcAQECAwQFBgcICQoLDP1jAS9R2zauYg1lIqhuTOfZ2v8vUIJqrnDB03B9GLgHVUPaGEitkEsRvkZedo2LHqdKGyHyH4giYr0NX3FlmRcgwYNvG84t7HujgT/BwLxkBKD9YijiOfi93TmMMvgnT53g8LVmKFTOkA19WxShZgXrKknQMbmFE7c3d2hWk7RbF+CKYOCVtmQD78xwNs2CqNZ1Ni6rQ7zeyxWOiw3MpHYXM0XRicInfcJbmFGyvpLH74tppWWvHM+XJuMi2yuNUmal30KWUnxxa4ugBPsUCMvXzHoYV1KG5vA+F5OyXuoRIj/WzHpJfYMomXset3D8yBJeYFEe77gjK3gNgPHXHp6TdifftizWxYB7NefXu5qvGNWkbG6icfK+Jr0cw1uytwzBkwrV9HKxvw17O+09/jWKab6r2v1jFpaMUwI38h4ciWYq2jTWZnNfeR2162juKdLQb0JCHsMR1ihPW+mFDWPgz9bP4gc=" + }, + { + "description": "Three keys, multiple derivation paths, BIP329 content", + "version": 1, + "encryption": 1, + "content": "010149", + "keys": [ + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443", + "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07", + "03c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5" + ], + "derivation_paths": [ + "m/84'/0'/0'", + "m/0/1'/2/3'" + ], + "plaintext": "{\"type\":\"tx\",\"ref\":\"f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd\",\"label\":\"Transaction\",\"origin\":\"wpkh([d34db33f/84'/0'/0'])\"}\n{\"type\":\"addr\",\"ref\":\"bc1q34aq5drpuwy3wgl9lhup9892qp6svr8ldzyy7c\",\"label\":\"Address\"}\n{\"type\":\"pubkey\",\"ref\":\"0283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f448\",\"label\":\"Public Key\"}\n{\"type\":\"input\",\"ref\":\"f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:0\",\"label\":\"Input\"}\n{\"type\":\"output\",\"ref\":\"f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:1\",\"label\":\"Output\",\"spendable\":false}\n{\"type\":\"xpub\",\"ref\":\"xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8\",\"label\":\"Extended Public Key\"}\n{\"type\":\"tx\",\"ref\":\"f546156d9044844e02b181026a1a407abfca62e7ea1159f87bbeaa77b4286c74\",\"label\":\"Account #1 Transaction\",\"origin\":\"wpkh([d34db33f/84'/0'/1'])\"}", + "nonce": "deadbeefcafebabe12345678", + "expected": "4249505858580102040000000080000001000000028000000303800000548000000080000000032424c7f03a4b1ec573f64738c2a61ac0a9480750f6a641ff8dd1e85acf5b8008331aabbcc51126eeeaf8f870c92bdae98a5688af3a1d9ce71004980b7f6af6e96e5f3aab8b6dfe2f8c09da023a29f797d8333736fb7b7c64958d0ff4109ba93a01deadbeefcafebabe12345678fd9c03f6ebb8e2e9c02c5194e453edd274ec677e0dea5f18cda3e00f7cc4e8c8d4821bda377728eb2f6d2f69eef72070a2a7bc01cc720bb989346102076d475cab2802f1e3766526d2c0bfd257a8e424045cd91356e8789458d06aa055fe2ed0c42fb338b43ae394ae3f9807e1840171965708c89e3b42e68dc4bf84c51bcc8738475e8325e07398753327c1afa6a96032cf73b9387c0f4cb6825adf383c8135b63394b1372fb2752c5297a595099d91c59f25ad6e0d136013ce64d67a53fc88861bf1f558fc2c775644fba1bba9efd23f562f6edb9a2cb476c40cc2ae3f006d3f839a9607271b6eed6f58efcf435eb0cf79c12b5f3c4160f8c3de8e9e311c7698090be2c8e2a3ef702daf88612179e21ee4ac401cab342f7a1d1c141eed8f1a7c60d6dd34324ed6bd07e03ae596d7c04350698ce4592660b841aadf5c2a372b0fc57539094bc0af80febc92aa10578c0b35efd164f4c94217d2e0de72461bdea40d881858eb4b16f1c361fa98cfe0fcbc83787c492238ea745a84265e907c8a07d98852fef62a2a360b75c8b700b24d503a0e54260a1a94e0a980d69aa76e34ba8c304f85e0e7f4cfa3cf3c0c4ac8ddad1548bf20dabd4b316ed53903701677e78d3cfd46980acfe482110be8be64a27ce1dd4d7502338d087e9b86b7ca6144fc81a2a7b806a4e397dfb8d8ad9ea54130d9b46d2cd9002e372094399078e0bce1af9f2dfb5a69a16ec88e53ec9c6f34d784596afcece4d8abd33e937d9ea4ddf170088270cc4f59f68b978368833dc7713b0351da5f690991c841f17c42e7b4d89c35a821e110c4b2a9a1f0cfebd14cfb39d938569614ee62bb488049c6b7ed636dd90cfb00170dd80f4a6e6c9a45a3bed0fa1340ecddb538bb888fdaaa1680d711d6f94297a9f7ed3401cecb25b6779b4ba5415a343a95597cb85b074d8e19def182d8581fb7b4bc716ba887af1bd51a10c699f6ddfdb5439c7eac02d9220a0417489a79bbc6da4d10325317a6630da9303c433f261e0d36f977cea8113c7e4581e5d27f6607be0f9f7058fd6730d64377b7d1e70f4858974896e3ae9fbde9fb6eb66be4d0c36544cf8cfb80166875f1672f5aa4991951248414a54457e3f3bea0a2953d27de6d0a299cc06471d9f331ace87937b96547e7bcfa7ae972fd9e08cfa69fae42fe786f1cb1d5ee0bc3bbd9277f38b290eb2033f39dc65bfc963c60d3f01d493ab7546cd72504303f68bd5e376d2b6a2dc59d4c3cfbef490d1cdcb73065f756620528bb0bd92301a26f53f0c1ae61962416c746d1b3b38fd202", + "expected_base64": "QklQWFhYAQIEAAAAAIAAAAEAAAACgAAAAwOAAABUgAAAAIAAAAADJCTH8DpLHsVz9kc4wqYawKlIB1D2pkH/jdHoWs9bgAgzGqu8xREm7ur4+HDJK9rpilaIrzodnOcQBJgLf2r26W5fOquLbf4vjAnaAjop95fYMzc2+3t8ZJWND/QQm6k6Ad6tvu/K/rq+EjRWeP2cA/bruOLpwCxRlORT7dJ07Gd+DepfGM2j4A98xOjI1IIb2jd3KOsvbS9p7vcgcKKnvAHMcgu5iTRhAgdtR1yrKALx43ZlJtLAv9JXqOQkBFzZE1boeJRY0GqgVf4u0MQvszi0OuOUrj+YB+GEAXGWVwjInjtC5o3Ev4TFG8yHOEdegyXgc5h1MyfBr6apYDLPc7k4fA9MtoJa3zg8gTW2M5SxNy+ydSxSl6WVCZ2RxZ8lrW4NE2ATzmTWelP8iIYb8fVY/Cx3VkT7obup79I/Vi9u25ostHbEDMKuPwBtP4OalgcnG27tb1jvz0NesM95wStfPEFg+MPejp4xHHaYCQviyOKj73Atr4hhIXniHuSsQByrNC96HRwUHu2PGnxg1t00Mk7WvQfgOuWW18BDUGmM5FkmYLhBqt9cKjcrD8V1OQlLwK+A/rySqhBXjAs179Fk9MlCF9Lg3nJGG96kDYgYWOtLFvHDYfqYz+D8vIN4fEkiOOp0WoQmXpB8igfZiFL+9ioqNgt1yLcAsk1QOg5UJgoalOCpgNaap240uowwT4Xg5/TPo888DErI3a0VSL8g2r1LMW7VOQNwFnfnjTz9RpgKz+SCEQvovmSifOHdTXUCM40IfpuGt8phRPyBoqe4BqTjl9+42K2epUEw2bRtLNkALjcglDmQeOC84a+fLftaaaFuyI5T7JxvNNeEWWr87OTYq9M+k32epN3xcAiCcMxPWfaLl4Nogz3HcTsDUdpfaQmRyEHxfELntNicNagh4RDEsqmh8M/r0Uz7Odk4VpYU7mK7SIBJxrftY23ZDPsAFw3YD0pubJpFo77Q+hNA7N21OLuIj9qqFoDXEdb5Qpep9+00Ac7LJbZ3m0ulQVo0OpVZfLhbB02OGd7xgthYH7e0vHFrqIevG9UaEMaZ9t39tUOcfqwC2SIKBBdImnm7xtpNEDJTF6ZjDakwPEM/Jh4NNvl3zqgRPH5FgeXSf2YHvg+fcFj9ZzDWQ3e30ecPSFiXSJbjrp+96ftutmvk0MNlRM+M+4AWaHXxZy9apJkZUSSEFKVEV+PzvqCilT0n3m0KKZzAZHHZ8zGs6Hk3uWVH57z6euly/Z4Iz6afrkL+eG8csdXuC8O72Sd/OLKQ6yAz853GW/yWPGDT8B1JOrdUbNclBDA/aL1eN20rai3FnUw8++9JDRzctzBl91ZiBSi7C9kjAaJvU/DBrmGWJBbHRtGzs4/SAg==" + }, + { + "description": "Single key, proprietary content (3 bytes)", + "version": 1, + "encryption": 1, + "content": "0204deadbeef", + "keys": [ + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443" + ], + "derivation_paths": [], + "plaintext": "706c61696e74657874", + "nonce": "000102030405060708090a0b", + "expected": "424950585858010001ff34b3411f78127b71ca2e3cc60d0fd71350ee557c37d71f4d81fb913461ae0001000102030405060708090a0b2803da142accb6215cecfe50629224496c4d35cfc7ee64e906e77cc3398689748c325907c7d5dafef3", + "expected_base64": "QklQWFhYAQAB/zSzQR94Entxyi48xg0P1xNQ7lV8N9cfTYH7kTRhrgABAAECAwQFBgcICQoLKAPaFCrMtiFc7P5QYpIkSWxNNc/H7mTpBud8wzmGiXSMMlkHx9Xa/vM=" + } +] \ No newline at end of file diff --git a/src/test/data/bip_encrypted_backup_encryption_secret.json b/src/test/data/bip_encrypted_backup_encryption_secret.json new file mode 100644 index 000000000000..a04b37af9355 --- /dev/null +++ b/src/test/data/bip_encrypted_backup_encryption_secret.json @@ -0,0 +1,89 @@ +[ + { + "description": "Single public key", + "keys": [ + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443" + ], + "decryption_secret": "a37acb446622cf11ffe44e1f17892d7b330b721b992513f680a52b128fb181b1", + "individual_secrets": [ + "ff34b3411f78127b71ca2e3cc60d0fd71350ee557c37d71f4d81fb913461ae00" + ] + }, + { + "description": "Two public keys", + "keys": [ + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443", + "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07" + ], + "decryption_secret": "154eaceae97b166f15a1d37fbc6d9477b1cf067c60352909a97f32b432412f0c", + "individual_secrets": [ + "5e3eb8a36f7bf32e02810c14666476f2b28a15cd499c30f8f98e926639a0765c", + "4900d4ef9021cb059b8fb35c6de9b6db91949a328527ede0645be237899100bd" + ] + }, + { + "description": "Three public keys", + "keys": [ + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443", + "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07", + "03c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5" + ], + "decryption_secret": "6f54d3b9bc4bfb8464d6985318aff845aa0d14e1df0f580edd204888c4bad958", + "individual_secrets": [ + "2424c7f03a4b1ec573f64738c2a61ac0a9480750f6a641ff8dd1e85acf5b8008", + "6e5f3aab8b6dfe2f8c09da023a29f797d8333736fb7b7c64958d0ff4109ba93a", + "331aabbcc51126eeeaf8f870c92bdae98a5688af3a1d9ce71004980b7f6af6e9" + ] + }, + { + "description": "Three public keys bis (different sorting)", + "keys": [ + "03c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5", + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443", + "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07" + ], + "decryption_secret": "6f54d3b9bc4bfb8464d6985318aff845aa0d14e1df0f580edd204888c4bad958", + "individual_secrets": [ + "2424c7f03a4b1ec573f64738c2a61ac0a9480750f6a641ff8dd1e85acf5b8008", + "6e5f3aab8b6dfe2f8c09da023a29f797d8333736fb7b7c64958d0ff4109ba93a", + "331aabbcc51126eeeaf8f870c92bdae98a5688af3a1d9ce71004980b7f6af6e9" + ] + }, + { + "description": "Three public keys ter (different sorting)", + "keys": [ + "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07", + "03c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5", + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443" + ], + "decryption_secret": "6f54d3b9bc4bfb8464d6985318aff845aa0d14e1df0f580edd204888c4bad958", + "individual_secrets": [ + "2424c7f03a4b1ec573f64738c2a61ac0a9480750f6a641ff8dd1e85acf5b8008", + "6e5f3aab8b6dfe2f8c09da023a29f797d8333736fb7b7c64958d0ff4109ba93a", + "331aabbcc51126eeeaf8f870c92bdae98a5688af3a1d9ce71004980b7f6af6e9" + ] + }, + { + "description": "Keys processed in sorted order", + "keys": [ + "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07", + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443" + ], + "decryption_secret": "154eaceae97b166f15a1d37fbc6d9477b1cf067c60352909a97f32b432412f0c", + "individual_secrets": [ + "5e3eb8a36f7bf32e02810c14666476f2b28a15cd499c30f8f98e926639a0765c", + "4900d4ef9021cb059b8fb35c6de9b6db91949a328527ede0645be237899100bd" + ] + }, + { + "description": "Duplicate keys should be handled", + "keys": [ + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443", + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443" + ], + "decryption_secret": "a37acb446622cf11ffe44e1f17892d7b330b721b992513f680a52b128fb181b1", + "individual_secrets": [ + "ff34b3411f78127b71ca2e3cc60d0fd71350ee557c37d71f4d81fb913461ae00" + ] + } +] \ No newline at end of file diff --git a/src/test/data/bip_encrypted_backup_individual_secrets.json b/src/test/data/bip_encrypted_backup_individual_secrets.json new file mode 100644 index 000000000000..8e4f1a4812a8 --- /dev/null +++ b/src/test/data/bip_encrypted_backup_individual_secrets.json @@ -0,0 +1,554 @@ +[ + { + "description": "Single secret", + "secrets": [ + "0000000000000000000000000000000000000000000000000000000000000000" + ], + "expected": "010000000000000000000000000000000000000000000000000000000000000000" + }, + { + "description": "Two different secrets", + "secrets": [ + "0000000000000000000000000000000000000000000000000000000000000000", + "0101010101010101010101010101010101010101010101010101010101010101" + ], + "expected": "0200000000000000000000000000000000000000000000000000000000000000000101010101010101010101010101010101010101010101010101010101010101" + }, + { + "description": "Three secrets with different patterns", + "secrets": [ + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0000000000000000000000000000000000000000000000000000000000000000", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ], + "expected": "030000000000000000000000000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + { + "description": "Empty secrets should fail", + "secrets": [], + "expected": null + }, + { + "description": "256 secrets should fail (exceeds u8::MAX)", + "secrets": [ + "0000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000001", + "0000000000000000000000000000000000000000000000000000000000000002", + "0000000000000000000000000000000000000000000000000000000000000003", + "0000000000000000000000000000000000000000000000000000000000000004", + "0000000000000000000000000000000000000000000000000000000000000005", + "0000000000000000000000000000000000000000000000000000000000000006", + "0000000000000000000000000000000000000000000000000000000000000007", + "0000000000000000000000000000000000000000000000000000000000000008", + "0000000000000000000000000000000000000000000000000000000000000009", + "000000000000000000000000000000000000000000000000000000000000000a", + "000000000000000000000000000000000000000000000000000000000000000b", + "000000000000000000000000000000000000000000000000000000000000000c", + "000000000000000000000000000000000000000000000000000000000000000d", + "000000000000000000000000000000000000000000000000000000000000000e", + "000000000000000000000000000000000000000000000000000000000000000f", + "0000000000000000000000000000000000000000000000000000000000000010", + "0000000000000000000000000000000000000000000000000000000000000011", + "0000000000000000000000000000000000000000000000000000000000000012", + "0000000000000000000000000000000000000000000000000000000000000013", + "0000000000000000000000000000000000000000000000000000000000000014", + "0000000000000000000000000000000000000000000000000000000000000015", + "0000000000000000000000000000000000000000000000000000000000000016", + "0000000000000000000000000000000000000000000000000000000000000017", + "0000000000000000000000000000000000000000000000000000000000000018", + "0000000000000000000000000000000000000000000000000000000000000019", + "000000000000000000000000000000000000000000000000000000000000001a", + "000000000000000000000000000000000000000000000000000000000000001b", + "000000000000000000000000000000000000000000000000000000000000001c", + "000000000000000000000000000000000000000000000000000000000000001d", + "000000000000000000000000000000000000000000000000000000000000001e", + "000000000000000000000000000000000000000000000000000000000000001f", + "0000000000000000000000000000000000000000000000000000000000000020", + "0000000000000000000000000000000000000000000000000000000000000021", + "0000000000000000000000000000000000000000000000000000000000000022", + "0000000000000000000000000000000000000000000000000000000000000023", + "0000000000000000000000000000000000000000000000000000000000000024", + "0000000000000000000000000000000000000000000000000000000000000025", + "0000000000000000000000000000000000000000000000000000000000000026", + "0000000000000000000000000000000000000000000000000000000000000027", + "0000000000000000000000000000000000000000000000000000000000000028", + "0000000000000000000000000000000000000000000000000000000000000029", + "000000000000000000000000000000000000000000000000000000000000002a", + "000000000000000000000000000000000000000000000000000000000000002b", + "000000000000000000000000000000000000000000000000000000000000002c", + "000000000000000000000000000000000000000000000000000000000000002d", + "000000000000000000000000000000000000000000000000000000000000002e", + "000000000000000000000000000000000000000000000000000000000000002f", + "0000000000000000000000000000000000000000000000000000000000000030", + "0000000000000000000000000000000000000000000000000000000000000031", + "0000000000000000000000000000000000000000000000000000000000000032", + "0000000000000000000000000000000000000000000000000000000000000033", + "0000000000000000000000000000000000000000000000000000000000000034", + "0000000000000000000000000000000000000000000000000000000000000035", + "0000000000000000000000000000000000000000000000000000000000000036", + "0000000000000000000000000000000000000000000000000000000000000037", + "0000000000000000000000000000000000000000000000000000000000000038", + "0000000000000000000000000000000000000000000000000000000000000039", + "000000000000000000000000000000000000000000000000000000000000003a", + "000000000000000000000000000000000000000000000000000000000000003b", + "000000000000000000000000000000000000000000000000000000000000003c", + "000000000000000000000000000000000000000000000000000000000000003d", + "000000000000000000000000000000000000000000000000000000000000003e", + "000000000000000000000000000000000000000000000000000000000000003f", + "0000000000000000000000000000000000000000000000000000000000000040", + "0000000000000000000000000000000000000000000000000000000000000041", + "0000000000000000000000000000000000000000000000000000000000000042", + "0000000000000000000000000000000000000000000000000000000000000043", + "0000000000000000000000000000000000000000000000000000000000000044", + "0000000000000000000000000000000000000000000000000000000000000045", + "0000000000000000000000000000000000000000000000000000000000000046", + "0000000000000000000000000000000000000000000000000000000000000047", + "0000000000000000000000000000000000000000000000000000000000000048", + "0000000000000000000000000000000000000000000000000000000000000049", + "000000000000000000000000000000000000000000000000000000000000004a", + "000000000000000000000000000000000000000000000000000000000000004b", + "000000000000000000000000000000000000000000000000000000000000004c", + "000000000000000000000000000000000000000000000000000000000000004d", + "000000000000000000000000000000000000000000000000000000000000004e", + "000000000000000000000000000000000000000000000000000000000000004f", + "0000000000000000000000000000000000000000000000000000000000000050", + "0000000000000000000000000000000000000000000000000000000000000051", + "0000000000000000000000000000000000000000000000000000000000000052", + "0000000000000000000000000000000000000000000000000000000000000053", + "0000000000000000000000000000000000000000000000000000000000000054", + "0000000000000000000000000000000000000000000000000000000000000055", + "0000000000000000000000000000000000000000000000000000000000000056", + "0000000000000000000000000000000000000000000000000000000000000057", + "0000000000000000000000000000000000000000000000000000000000000058", + "0000000000000000000000000000000000000000000000000000000000000059", + "000000000000000000000000000000000000000000000000000000000000005a", + "000000000000000000000000000000000000000000000000000000000000005b", + "000000000000000000000000000000000000000000000000000000000000005c", + "000000000000000000000000000000000000000000000000000000000000005d", + "000000000000000000000000000000000000000000000000000000000000005e", + "000000000000000000000000000000000000000000000000000000000000005f", + "0000000000000000000000000000000000000000000000000000000000000060", + "0000000000000000000000000000000000000000000000000000000000000061", + "0000000000000000000000000000000000000000000000000000000000000062", + "0000000000000000000000000000000000000000000000000000000000000063", + "0000000000000000000000000000000000000000000000000000000000000064", + "0000000000000000000000000000000000000000000000000000000000000065", + "0000000000000000000000000000000000000000000000000000000000000066", + "0000000000000000000000000000000000000000000000000000000000000067", + "0000000000000000000000000000000000000000000000000000000000000068", + "0000000000000000000000000000000000000000000000000000000000000069", + "000000000000000000000000000000000000000000000000000000000000006a", + "000000000000000000000000000000000000000000000000000000000000006b", + "000000000000000000000000000000000000000000000000000000000000006c", + "000000000000000000000000000000000000000000000000000000000000006d", + "000000000000000000000000000000000000000000000000000000000000006e", + "000000000000000000000000000000000000000000000000000000000000006f", + "0000000000000000000000000000000000000000000000000000000000000070", + "0000000000000000000000000000000000000000000000000000000000000071", + "0000000000000000000000000000000000000000000000000000000000000072", + "0000000000000000000000000000000000000000000000000000000000000073", + "0000000000000000000000000000000000000000000000000000000000000074", + "0000000000000000000000000000000000000000000000000000000000000075", + "0000000000000000000000000000000000000000000000000000000000000076", + "0000000000000000000000000000000000000000000000000000000000000077", + "0000000000000000000000000000000000000000000000000000000000000078", + "0000000000000000000000000000000000000000000000000000000000000079", + "000000000000000000000000000000000000000000000000000000000000007a", + "000000000000000000000000000000000000000000000000000000000000007b", + "000000000000000000000000000000000000000000000000000000000000007c", + "000000000000000000000000000000000000000000000000000000000000007d", + "000000000000000000000000000000000000000000000000000000000000007e", + "000000000000000000000000000000000000000000000000000000000000007f", + "0000000000000000000000000000000000000000000000000000000000000080", + "0000000000000000000000000000000000000000000000000000000000000081", + "0000000000000000000000000000000000000000000000000000000000000082", + "0000000000000000000000000000000000000000000000000000000000000083", + "0000000000000000000000000000000000000000000000000000000000000084", + "0000000000000000000000000000000000000000000000000000000000000085", + "0000000000000000000000000000000000000000000000000000000000000086", + "0000000000000000000000000000000000000000000000000000000000000087", + "0000000000000000000000000000000000000000000000000000000000000088", + "0000000000000000000000000000000000000000000000000000000000000089", + "000000000000000000000000000000000000000000000000000000000000008a", + "000000000000000000000000000000000000000000000000000000000000008b", + "000000000000000000000000000000000000000000000000000000000000008c", + "000000000000000000000000000000000000000000000000000000000000008d", + "000000000000000000000000000000000000000000000000000000000000008e", + "000000000000000000000000000000000000000000000000000000000000008f", + "0000000000000000000000000000000000000000000000000000000000000090", + "0000000000000000000000000000000000000000000000000000000000000091", + "0000000000000000000000000000000000000000000000000000000000000092", + "0000000000000000000000000000000000000000000000000000000000000093", + "0000000000000000000000000000000000000000000000000000000000000094", + "0000000000000000000000000000000000000000000000000000000000000095", + "0000000000000000000000000000000000000000000000000000000000000096", + "0000000000000000000000000000000000000000000000000000000000000097", + "0000000000000000000000000000000000000000000000000000000000000098", + "0000000000000000000000000000000000000000000000000000000000000099", + "000000000000000000000000000000000000000000000000000000000000009a", + "000000000000000000000000000000000000000000000000000000000000009b", + "000000000000000000000000000000000000000000000000000000000000009c", + "000000000000000000000000000000000000000000000000000000000000009d", + "000000000000000000000000000000000000000000000000000000000000009e", + "000000000000000000000000000000000000000000000000000000000000009f", + "00000000000000000000000000000000000000000000000000000000000000a0", + "00000000000000000000000000000000000000000000000000000000000000a1", + "00000000000000000000000000000000000000000000000000000000000000a2", + "00000000000000000000000000000000000000000000000000000000000000a3", + "00000000000000000000000000000000000000000000000000000000000000a4", + "00000000000000000000000000000000000000000000000000000000000000a5", + "00000000000000000000000000000000000000000000000000000000000000a6", + "00000000000000000000000000000000000000000000000000000000000000a7", + "00000000000000000000000000000000000000000000000000000000000000a8", + "00000000000000000000000000000000000000000000000000000000000000a9", + "00000000000000000000000000000000000000000000000000000000000000aa", + "00000000000000000000000000000000000000000000000000000000000000ab", + "00000000000000000000000000000000000000000000000000000000000000ac", + "00000000000000000000000000000000000000000000000000000000000000ad", + "00000000000000000000000000000000000000000000000000000000000000ae", + "00000000000000000000000000000000000000000000000000000000000000af", + "00000000000000000000000000000000000000000000000000000000000000b0", + "00000000000000000000000000000000000000000000000000000000000000b1", + "00000000000000000000000000000000000000000000000000000000000000b2", + "00000000000000000000000000000000000000000000000000000000000000b3", + "00000000000000000000000000000000000000000000000000000000000000b4", + "00000000000000000000000000000000000000000000000000000000000000b5", + "00000000000000000000000000000000000000000000000000000000000000b6", + "00000000000000000000000000000000000000000000000000000000000000b7", + "00000000000000000000000000000000000000000000000000000000000000b8", + "00000000000000000000000000000000000000000000000000000000000000b9", + "00000000000000000000000000000000000000000000000000000000000000ba", + "00000000000000000000000000000000000000000000000000000000000000bb", + "00000000000000000000000000000000000000000000000000000000000000bc", + "00000000000000000000000000000000000000000000000000000000000000bd", + "00000000000000000000000000000000000000000000000000000000000000be", + "00000000000000000000000000000000000000000000000000000000000000bf", + "00000000000000000000000000000000000000000000000000000000000000c0", + "00000000000000000000000000000000000000000000000000000000000000c1", + "00000000000000000000000000000000000000000000000000000000000000c2", + "00000000000000000000000000000000000000000000000000000000000000c3", + "00000000000000000000000000000000000000000000000000000000000000c4", + "00000000000000000000000000000000000000000000000000000000000000c5", + "00000000000000000000000000000000000000000000000000000000000000c6", + "00000000000000000000000000000000000000000000000000000000000000c7", + "00000000000000000000000000000000000000000000000000000000000000c8", + "00000000000000000000000000000000000000000000000000000000000000c9", + "00000000000000000000000000000000000000000000000000000000000000ca", + "00000000000000000000000000000000000000000000000000000000000000cb", + "00000000000000000000000000000000000000000000000000000000000000cc", + "00000000000000000000000000000000000000000000000000000000000000cd", + "00000000000000000000000000000000000000000000000000000000000000ce", + "00000000000000000000000000000000000000000000000000000000000000cf", + "00000000000000000000000000000000000000000000000000000000000000d0", + "00000000000000000000000000000000000000000000000000000000000000d1", + "00000000000000000000000000000000000000000000000000000000000000d2", + "00000000000000000000000000000000000000000000000000000000000000d3", + "00000000000000000000000000000000000000000000000000000000000000d4", + "00000000000000000000000000000000000000000000000000000000000000d5", + "00000000000000000000000000000000000000000000000000000000000000d6", + "00000000000000000000000000000000000000000000000000000000000000d7", + "00000000000000000000000000000000000000000000000000000000000000d8", + "00000000000000000000000000000000000000000000000000000000000000d9", + "00000000000000000000000000000000000000000000000000000000000000da", + "00000000000000000000000000000000000000000000000000000000000000db", + "00000000000000000000000000000000000000000000000000000000000000dc", + "00000000000000000000000000000000000000000000000000000000000000dd", + "00000000000000000000000000000000000000000000000000000000000000de", + "00000000000000000000000000000000000000000000000000000000000000df", + "00000000000000000000000000000000000000000000000000000000000000e0", + "00000000000000000000000000000000000000000000000000000000000000e1", + "00000000000000000000000000000000000000000000000000000000000000e2", + "00000000000000000000000000000000000000000000000000000000000000e3", + "00000000000000000000000000000000000000000000000000000000000000e4", + "00000000000000000000000000000000000000000000000000000000000000e5", + "00000000000000000000000000000000000000000000000000000000000000e6", + "00000000000000000000000000000000000000000000000000000000000000e7", + "00000000000000000000000000000000000000000000000000000000000000e8", + "00000000000000000000000000000000000000000000000000000000000000e9", + "00000000000000000000000000000000000000000000000000000000000000ea", + "00000000000000000000000000000000000000000000000000000000000000eb", + "00000000000000000000000000000000000000000000000000000000000000ec", + "00000000000000000000000000000000000000000000000000000000000000ed", + "00000000000000000000000000000000000000000000000000000000000000ee", + "00000000000000000000000000000000000000000000000000000000000000ef", + "00000000000000000000000000000000000000000000000000000000000000f0", + "00000000000000000000000000000000000000000000000000000000000000f1", + "00000000000000000000000000000000000000000000000000000000000000f2", + "00000000000000000000000000000000000000000000000000000000000000f3", + "00000000000000000000000000000000000000000000000000000000000000f4", + "00000000000000000000000000000000000000000000000000000000000000f5", + "00000000000000000000000000000000000000000000000000000000000000f6", + "00000000000000000000000000000000000000000000000000000000000000f7", + "00000000000000000000000000000000000000000000000000000000000000f8", + "00000000000000000000000000000000000000000000000000000000000000f9", + "00000000000000000000000000000000000000000000000000000000000000fa", + "00000000000000000000000000000000000000000000000000000000000000fb", + "00000000000000000000000000000000000000000000000000000000000000fc", + "00000000000000000000000000000000000000000000000000000000000000fd", + "00000000000000000000000000000000000000000000000000000000000000fe", + "00000000000000000000000000000000000000000000000000000000000000ff" + ], + "expected": null + }, + { + "description": "256 secrets should pass)", + "secrets": [ + "0000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000001", + "0000000000000000000000000000000000000000000000000000000000000002", + "0000000000000000000000000000000000000000000000000000000000000003", + "0000000000000000000000000000000000000000000000000000000000000004", + "0000000000000000000000000000000000000000000000000000000000000005", + "0000000000000000000000000000000000000000000000000000000000000006", + "0000000000000000000000000000000000000000000000000000000000000007", + "0000000000000000000000000000000000000000000000000000000000000008", + "0000000000000000000000000000000000000000000000000000000000000009", + "000000000000000000000000000000000000000000000000000000000000000a", + "000000000000000000000000000000000000000000000000000000000000000b", + "000000000000000000000000000000000000000000000000000000000000000c", + "000000000000000000000000000000000000000000000000000000000000000d", + "000000000000000000000000000000000000000000000000000000000000000e", + "000000000000000000000000000000000000000000000000000000000000000f", + "0000000000000000000000000000000000000000000000000000000000000010", + "0000000000000000000000000000000000000000000000000000000000000011", + "0000000000000000000000000000000000000000000000000000000000000012", + "0000000000000000000000000000000000000000000000000000000000000013", + "0000000000000000000000000000000000000000000000000000000000000014", + "0000000000000000000000000000000000000000000000000000000000000015", + "0000000000000000000000000000000000000000000000000000000000000016", + "0000000000000000000000000000000000000000000000000000000000000017", + "0000000000000000000000000000000000000000000000000000000000000018", + "0000000000000000000000000000000000000000000000000000000000000019", + "000000000000000000000000000000000000000000000000000000000000001a", + "000000000000000000000000000000000000000000000000000000000000001b", + "000000000000000000000000000000000000000000000000000000000000001c", + "000000000000000000000000000000000000000000000000000000000000001d", + "000000000000000000000000000000000000000000000000000000000000001e", + "000000000000000000000000000000000000000000000000000000000000001f", + "0000000000000000000000000000000000000000000000000000000000000020", + "0000000000000000000000000000000000000000000000000000000000000021", + "0000000000000000000000000000000000000000000000000000000000000022", + "0000000000000000000000000000000000000000000000000000000000000023", + "0000000000000000000000000000000000000000000000000000000000000024", + "0000000000000000000000000000000000000000000000000000000000000025", + "0000000000000000000000000000000000000000000000000000000000000026", + "0000000000000000000000000000000000000000000000000000000000000027", + "0000000000000000000000000000000000000000000000000000000000000028", + "0000000000000000000000000000000000000000000000000000000000000029", + "000000000000000000000000000000000000000000000000000000000000002a", + "000000000000000000000000000000000000000000000000000000000000002b", + "000000000000000000000000000000000000000000000000000000000000002c", + "000000000000000000000000000000000000000000000000000000000000002d", + "000000000000000000000000000000000000000000000000000000000000002e", + "000000000000000000000000000000000000000000000000000000000000002f", + "0000000000000000000000000000000000000000000000000000000000000030", + "0000000000000000000000000000000000000000000000000000000000000031", + "0000000000000000000000000000000000000000000000000000000000000032", + "0000000000000000000000000000000000000000000000000000000000000033", + "0000000000000000000000000000000000000000000000000000000000000034", + "0000000000000000000000000000000000000000000000000000000000000035", + "0000000000000000000000000000000000000000000000000000000000000036", + "0000000000000000000000000000000000000000000000000000000000000037", + "0000000000000000000000000000000000000000000000000000000000000038", + "0000000000000000000000000000000000000000000000000000000000000039", + "000000000000000000000000000000000000000000000000000000000000003a", + "000000000000000000000000000000000000000000000000000000000000003b", + "000000000000000000000000000000000000000000000000000000000000003c", + "000000000000000000000000000000000000000000000000000000000000003d", + "000000000000000000000000000000000000000000000000000000000000003e", + "000000000000000000000000000000000000000000000000000000000000003f", + "0000000000000000000000000000000000000000000000000000000000000040", + "0000000000000000000000000000000000000000000000000000000000000041", + "0000000000000000000000000000000000000000000000000000000000000042", + "0000000000000000000000000000000000000000000000000000000000000043", + "0000000000000000000000000000000000000000000000000000000000000044", + "0000000000000000000000000000000000000000000000000000000000000045", + "0000000000000000000000000000000000000000000000000000000000000046", + "0000000000000000000000000000000000000000000000000000000000000047", + "0000000000000000000000000000000000000000000000000000000000000048", + "0000000000000000000000000000000000000000000000000000000000000049", + "000000000000000000000000000000000000000000000000000000000000004a", + "000000000000000000000000000000000000000000000000000000000000004b", + "000000000000000000000000000000000000000000000000000000000000004c", + "000000000000000000000000000000000000000000000000000000000000004d", + "000000000000000000000000000000000000000000000000000000000000004e", + "000000000000000000000000000000000000000000000000000000000000004f", + "0000000000000000000000000000000000000000000000000000000000000050", + "0000000000000000000000000000000000000000000000000000000000000051", + "0000000000000000000000000000000000000000000000000000000000000052", + "0000000000000000000000000000000000000000000000000000000000000053", + "0000000000000000000000000000000000000000000000000000000000000054", + "0000000000000000000000000000000000000000000000000000000000000055", + "0000000000000000000000000000000000000000000000000000000000000056", + "0000000000000000000000000000000000000000000000000000000000000057", + "0000000000000000000000000000000000000000000000000000000000000058", + "0000000000000000000000000000000000000000000000000000000000000059", + "000000000000000000000000000000000000000000000000000000000000005a", + "000000000000000000000000000000000000000000000000000000000000005b", + "000000000000000000000000000000000000000000000000000000000000005c", + "000000000000000000000000000000000000000000000000000000000000005d", + "000000000000000000000000000000000000000000000000000000000000005e", + "000000000000000000000000000000000000000000000000000000000000005f", + "0000000000000000000000000000000000000000000000000000000000000060", + "0000000000000000000000000000000000000000000000000000000000000061", + "0000000000000000000000000000000000000000000000000000000000000062", + "0000000000000000000000000000000000000000000000000000000000000063", + "0000000000000000000000000000000000000000000000000000000000000064", + "0000000000000000000000000000000000000000000000000000000000000065", + "0000000000000000000000000000000000000000000000000000000000000066", + "0000000000000000000000000000000000000000000000000000000000000067", + "0000000000000000000000000000000000000000000000000000000000000068", + "0000000000000000000000000000000000000000000000000000000000000069", + "000000000000000000000000000000000000000000000000000000000000006a", + "000000000000000000000000000000000000000000000000000000000000006b", + "000000000000000000000000000000000000000000000000000000000000006c", + "000000000000000000000000000000000000000000000000000000000000006d", + "000000000000000000000000000000000000000000000000000000000000006e", + "000000000000000000000000000000000000000000000000000000000000006f", + "0000000000000000000000000000000000000000000000000000000000000070", + "0000000000000000000000000000000000000000000000000000000000000071", + "0000000000000000000000000000000000000000000000000000000000000072", + "0000000000000000000000000000000000000000000000000000000000000073", + "0000000000000000000000000000000000000000000000000000000000000074", + "0000000000000000000000000000000000000000000000000000000000000075", + "0000000000000000000000000000000000000000000000000000000000000076", + "0000000000000000000000000000000000000000000000000000000000000077", + "0000000000000000000000000000000000000000000000000000000000000078", + "0000000000000000000000000000000000000000000000000000000000000079", + "000000000000000000000000000000000000000000000000000000000000007a", + "000000000000000000000000000000000000000000000000000000000000007b", + "000000000000000000000000000000000000000000000000000000000000007c", + "000000000000000000000000000000000000000000000000000000000000007d", + "000000000000000000000000000000000000000000000000000000000000007e", + "000000000000000000000000000000000000000000000000000000000000007f", + "0000000000000000000000000000000000000000000000000000000000000080", + "0000000000000000000000000000000000000000000000000000000000000081", + "0000000000000000000000000000000000000000000000000000000000000082", + "0000000000000000000000000000000000000000000000000000000000000083", + "0000000000000000000000000000000000000000000000000000000000000084", + "0000000000000000000000000000000000000000000000000000000000000085", + "0000000000000000000000000000000000000000000000000000000000000086", + "0000000000000000000000000000000000000000000000000000000000000087", + "0000000000000000000000000000000000000000000000000000000000000088", + "0000000000000000000000000000000000000000000000000000000000000089", + "000000000000000000000000000000000000000000000000000000000000008a", + "000000000000000000000000000000000000000000000000000000000000008b", + "000000000000000000000000000000000000000000000000000000000000008c", + "000000000000000000000000000000000000000000000000000000000000008d", + "000000000000000000000000000000000000000000000000000000000000008e", + "000000000000000000000000000000000000000000000000000000000000008f", + "0000000000000000000000000000000000000000000000000000000000000090", + "0000000000000000000000000000000000000000000000000000000000000091", + "0000000000000000000000000000000000000000000000000000000000000092", + "0000000000000000000000000000000000000000000000000000000000000093", + "0000000000000000000000000000000000000000000000000000000000000094", + "0000000000000000000000000000000000000000000000000000000000000095", + "0000000000000000000000000000000000000000000000000000000000000096", + "0000000000000000000000000000000000000000000000000000000000000097", + "0000000000000000000000000000000000000000000000000000000000000098", + "0000000000000000000000000000000000000000000000000000000000000099", + "000000000000000000000000000000000000000000000000000000000000009a", + "000000000000000000000000000000000000000000000000000000000000009b", + "000000000000000000000000000000000000000000000000000000000000009c", + "000000000000000000000000000000000000000000000000000000000000009d", + "000000000000000000000000000000000000000000000000000000000000009e", + "000000000000000000000000000000000000000000000000000000000000009f", + "00000000000000000000000000000000000000000000000000000000000000a0", + "00000000000000000000000000000000000000000000000000000000000000a1", + "00000000000000000000000000000000000000000000000000000000000000a2", + "00000000000000000000000000000000000000000000000000000000000000a3", + "00000000000000000000000000000000000000000000000000000000000000a4", + "00000000000000000000000000000000000000000000000000000000000000a5", + "00000000000000000000000000000000000000000000000000000000000000a6", + "00000000000000000000000000000000000000000000000000000000000000a7", + "00000000000000000000000000000000000000000000000000000000000000a8", + "00000000000000000000000000000000000000000000000000000000000000a9", + "00000000000000000000000000000000000000000000000000000000000000aa", + "00000000000000000000000000000000000000000000000000000000000000ab", + "00000000000000000000000000000000000000000000000000000000000000ac", + "00000000000000000000000000000000000000000000000000000000000000ad", + "00000000000000000000000000000000000000000000000000000000000000ae", + "00000000000000000000000000000000000000000000000000000000000000af", + "00000000000000000000000000000000000000000000000000000000000000b0", + "00000000000000000000000000000000000000000000000000000000000000b1", + "00000000000000000000000000000000000000000000000000000000000000b2", + "00000000000000000000000000000000000000000000000000000000000000b3", + "00000000000000000000000000000000000000000000000000000000000000b4", + "00000000000000000000000000000000000000000000000000000000000000b5", + "00000000000000000000000000000000000000000000000000000000000000b6", + "00000000000000000000000000000000000000000000000000000000000000b7", + "00000000000000000000000000000000000000000000000000000000000000b8", + "00000000000000000000000000000000000000000000000000000000000000b9", + "00000000000000000000000000000000000000000000000000000000000000ba", + "00000000000000000000000000000000000000000000000000000000000000bb", + "00000000000000000000000000000000000000000000000000000000000000bc", + "00000000000000000000000000000000000000000000000000000000000000bd", + "00000000000000000000000000000000000000000000000000000000000000be", + "00000000000000000000000000000000000000000000000000000000000000bf", + "00000000000000000000000000000000000000000000000000000000000000c0", + "00000000000000000000000000000000000000000000000000000000000000c1", + "00000000000000000000000000000000000000000000000000000000000000c2", + "00000000000000000000000000000000000000000000000000000000000000c3", + "00000000000000000000000000000000000000000000000000000000000000c4", + "00000000000000000000000000000000000000000000000000000000000000c5", + "00000000000000000000000000000000000000000000000000000000000000c6", + "00000000000000000000000000000000000000000000000000000000000000c7", + "00000000000000000000000000000000000000000000000000000000000000c8", + "00000000000000000000000000000000000000000000000000000000000000c9", + "00000000000000000000000000000000000000000000000000000000000000ca", + "00000000000000000000000000000000000000000000000000000000000000cb", + "00000000000000000000000000000000000000000000000000000000000000cc", + "00000000000000000000000000000000000000000000000000000000000000cd", + "00000000000000000000000000000000000000000000000000000000000000ce", + "00000000000000000000000000000000000000000000000000000000000000cf", + "00000000000000000000000000000000000000000000000000000000000000d0", + "00000000000000000000000000000000000000000000000000000000000000d1", + "00000000000000000000000000000000000000000000000000000000000000d2", + "00000000000000000000000000000000000000000000000000000000000000d3", + "00000000000000000000000000000000000000000000000000000000000000d4", + "00000000000000000000000000000000000000000000000000000000000000d5", + "00000000000000000000000000000000000000000000000000000000000000d6", + "00000000000000000000000000000000000000000000000000000000000000d7", + "00000000000000000000000000000000000000000000000000000000000000d8", + "00000000000000000000000000000000000000000000000000000000000000d9", + "00000000000000000000000000000000000000000000000000000000000000da", + "00000000000000000000000000000000000000000000000000000000000000db", + "00000000000000000000000000000000000000000000000000000000000000dc", + "00000000000000000000000000000000000000000000000000000000000000dd", + "00000000000000000000000000000000000000000000000000000000000000de", + "00000000000000000000000000000000000000000000000000000000000000df", + "00000000000000000000000000000000000000000000000000000000000000e0", + "00000000000000000000000000000000000000000000000000000000000000e1", + "00000000000000000000000000000000000000000000000000000000000000e2", + "00000000000000000000000000000000000000000000000000000000000000e3", + "00000000000000000000000000000000000000000000000000000000000000e4", + "00000000000000000000000000000000000000000000000000000000000000e5", + "00000000000000000000000000000000000000000000000000000000000000e6", + "00000000000000000000000000000000000000000000000000000000000000e7", + "00000000000000000000000000000000000000000000000000000000000000e8", + "00000000000000000000000000000000000000000000000000000000000000e9", + "00000000000000000000000000000000000000000000000000000000000000ea", + "00000000000000000000000000000000000000000000000000000000000000eb", + "00000000000000000000000000000000000000000000000000000000000000ec", + "00000000000000000000000000000000000000000000000000000000000000ed", + "00000000000000000000000000000000000000000000000000000000000000ee", + "00000000000000000000000000000000000000000000000000000000000000ef", + "00000000000000000000000000000000000000000000000000000000000000f0", + "00000000000000000000000000000000000000000000000000000000000000f1", + "00000000000000000000000000000000000000000000000000000000000000f2", + "00000000000000000000000000000000000000000000000000000000000000f3", + "00000000000000000000000000000000000000000000000000000000000000f4", + "00000000000000000000000000000000000000000000000000000000000000f5", + "00000000000000000000000000000000000000000000000000000000000000f6", + "00000000000000000000000000000000000000000000000000000000000000f7", + "00000000000000000000000000000000000000000000000000000000000000f8", + "00000000000000000000000000000000000000000000000000000000000000f9", + "00000000000000000000000000000000000000000000000000000000000000fa", + "00000000000000000000000000000000000000000000000000000000000000fb", + "00000000000000000000000000000000000000000000000000000000000000fc", + "00000000000000000000000000000000000000000000000000000000000000fd", + "00000000000000000000000000000000000000000000000000000000000000fe" + ], + "expected": "ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000023000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000250000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000003f0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000004700000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000004a000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000520000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000056000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000059000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000005f0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000066000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000680000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000006b000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000000000000000000000000000000000000720000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000780000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000007a000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008100000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000083000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000850000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000008700000000000000000000000000000000000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000000000000000000000000000000000000000008b000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000000000000000000000000000000000000000008e000000000000000000000000000000000000000000000000000000000000008f0000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000920000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000950000000000000000000000000000000000000000000000000000000000000096000000000000000000000000000000000000000000000000000000000000009700000000000000000000000000000000000000000000000000000000000000980000000000000000000000000000000000000000000000000000000000000099000000000000000000000000000000000000000000000000000000000000009a000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000009d000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a100000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000a300000000000000000000000000000000000000000000000000000000000000a400000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000a600000000000000000000000000000000000000000000000000000000000000a700000000000000000000000000000000000000000000000000000000000000a800000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000aa00000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000ad00000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000b100000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000b500000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000b700000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000b900000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000bf00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000c500000000000000000000000000000000000000000000000000000000000000c600000000000000000000000000000000000000000000000000000000000000c700000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000cb00000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000cd00000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000cf00000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000d100000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000d300000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000d500000000000000000000000000000000000000000000000000000000000000d600000000000000000000000000000000000000000000000000000000000000d700000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000da00000000000000000000000000000000000000000000000000000000000000db00000000000000000000000000000000000000000000000000000000000000dc00000000000000000000000000000000000000000000000000000000000000dd00000000000000000000000000000000000000000000000000000000000000de00000000000000000000000000000000000000000000000000000000000000df00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000000e200000000000000000000000000000000000000000000000000000000000000e300000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000e500000000000000000000000000000000000000000000000000000000000000e600000000000000000000000000000000000000000000000000000000000000e700000000000000000000000000000000000000000000000000000000000000e800000000000000000000000000000000000000000000000000000000000000e900000000000000000000000000000000000000000000000000000000000000ea00000000000000000000000000000000000000000000000000000000000000eb00000000000000000000000000000000000000000000000000000000000000ec00000000000000000000000000000000000000000000000000000000000000ed00000000000000000000000000000000000000000000000000000000000000ee00000000000000000000000000000000000000000000000000000000000000ef00000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000f200000000000000000000000000000000000000000000000000000000000000f300000000000000000000000000000000000000000000000000000000000000f400000000000000000000000000000000000000000000000000000000000000f500000000000000000000000000000000000000000000000000000000000000f600000000000000000000000000000000000000000000000000000000000000f700000000000000000000000000000000000000000000000000000000000000f800000000000000000000000000000000000000000000000000000000000000f900000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000fb00000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000fd00000000000000000000000000000000000000000000000000000000000000fe" + } +] diff --git a/src/test/data/bip_encrypted_backup_keys_types.json b/src/test/data/bip_encrypted_backup_keys_types.json new file mode 100644 index 000000000000..ce91762d9865 --- /dev/null +++ b/src/test/data/bip_encrypted_backup_keys_types.json @@ -0,0 +1,27 @@ +[ + { + "description": "Xpub with origin and multipath", + "key": "[58b7f8dc/48'/1'/0'/2']tpubDEPBvXvhta3pjVaKokqC3eeMQnszj9ehFaA2zD5nSdkaccwGAizu8jVB2NeSpvmP2P52MBoZvNCixqXRJnTyXx51FQzARR63tjxQSyP3Btw/<0;1>/*", + "expected": "ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708" + }, + { + "description": "Xpub with origin and w/o multipath", + "key": "[d4ab66f1/48'/1'/1'/2']tpubDFTxBKyUCgkwp5enwZh3t2FJ5AMJqmCWoh1NRT13qNYQb1iKTUrAG6u5gpsDYhG8cZGXouYWuQtzcuSVjPStTc4dwU6JqPMFtgaLGvSQXhi", + "expected": "8e886919a6b72579a28bd292505d2afd41c1b5012414c5e24d7b59f4abdfc0ce" + }, + { + "description": "Compressed public key", + "key": "02ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708", + "expected": "ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708" + }, + { + "description": "X only public key", + "key": "ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708", + "expected": "ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708" + }, + { + "description": "Uncompressed public key", + "key": "04ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b517089e956909c4c07e8529f45f3ff8904d28df5a181619e21bdf748a896322530039", + "expected": "ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708" + } +] \ No newline at end of file diff --git a/src/util/bip32.cpp b/src/util/bip32.cpp index 2488eacf5156..a27ddc288fec 100644 --- a/src/util/bip32.cpp +++ b/src/util/bip32.cpp @@ -11,6 +11,34 @@ #include #include #include +#include + +std::optional ParseKeyPathElement(std::span elem, bool& is_hardened, std::string& error) +{ + is_hardened = false; + const std::string_view raw{elem.begin(), elem.end()}; + if (elem.empty()) { + error = strprintf("Key path value '%s' is not a valid uint32", raw); + return std::nullopt; + } + + const char last = elem.back(); + if (last == '\'' || last == 'h') { + elem = elem.first(elem.size() - 1); + is_hardened = true; + } + + const auto number{ToIntegral(std::string_view{elem.begin(), elem.end()})}; + if (!number) { + error = strprintf("Key path value '%s' is not a valid uint32", raw); + return std::nullopt; + } + if (*number >= BIP32_HARDENED) { + error = strprintf("Key path value %u is out of range", *number); + return std::nullopt; + } + return *number; +} bool ParseHDKeypath(const std::string& keypath_str, std::vector& keypath) { @@ -25,26 +53,11 @@ bool ParseHDKeypath(const std::string& keypath_str, std::vector& keypa } return false; } - // Finds whether it is hardened - uint32_t path = 0; - size_t pos = item.find('\''); - if (pos != std::string::npos) { - // The hardened tick can only be in the last index of the string - if (pos != item.size() - 1) { - return false; - } - path |= 0x80000000; - item = item.substr(0, item.size() - 1); // Drop the last character which is the hardened tick - } - - // Ensure this is only numbers - const auto number{ToIntegral(item)}; - if (!number) { - return false; - } - path |= *number; - - keypath.push_back(path); + bool hardened = false; + std::string error; + const auto index{ParseKeyPathElement(std::span{item.data(), item.size()}, hardened, error)}; + if (!index.has_value()) return false; + keypath.push_back(*index | (hardened ? BIP32_HARDENED : BIP32_UNHARDENED)); first = false; } return true; diff --git a/src/util/bip32.h b/src/util/bip32.h index af48147aa808..9ecc5c052bee 100644 --- a/src/util/bip32.h +++ b/src/util/bip32.h @@ -6,9 +6,21 @@ #define BITCOIN_UTIL_BIP32_H #include +#include +#include #include #include +/** BIP32 unhardened child index (no high bit set) */ +static constexpr uint32_t BIP32_UNHARDENED = 0x0; +/** BIP32 hardened derivation flag (2^31) */ +static constexpr uint32_t BIP32_HARDENED = 0x80000000; + +/** Parse a single key path element like "0", "0'", or "0h". + * Returns the child index and sets is_hardened, or nullopt on failure + * (in which case `error` is populated with a human-readable message). */ +std::optional ParseKeyPathElement(std::span elem, bool& is_hardened, std::string& error); + /** Parse an HD keypaths like "m/7/0'/2000". */ [[nodiscard]] bool ParseHDKeypath(const std::string& keypath_str, std::vector& keypath); diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index 36fd3ef95aec..9b0ed984ece4 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -10,6 +10,7 @@ add_library(bitcoin_wallet STATIC EXCLUDE_FROM_ALL crypter.cpp db.cpp dump.cpp + encryptedbackup.cpp external_signer_scriptpubkeyman.cpp feebumper.cpp fees.cpp diff --git a/src/wallet/encryptedbackup.cpp b/src/wallet/encryptedbackup.cpp new file mode 100644 index 000000000000..dfb14644fd4c --- /dev/null +++ b/src/wallet/encryptedbackup.cpp @@ -0,0 +1,701 @@ +// Copyright (c) 2025-present The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include + +#include +#include +#include +#include +#include