import binascii from mock import patch import time from unittest import TestCase from ecdsa import SECP256k1 from ecdsa.ellipticcurve import INFINITY from multimerchant.network import BitcoinMainNet from multimerchant.network import BitcoinTestNet from multimerchant.network import DogecoinMainNet from multimerchant.network import LitecoinMainNet from multimerchant.wallet import Wallet from multimerchant.wallet.bip32 import InfinityPointException from multimerchant.wallet.bip32 import InsufficientKeyDataError from multimerchant.wallet.bip32 import InvalidPathError from multimerchant.wallet.bip32 import InvalidPrivateKeyError from multimerchant.wallet.bip32 import InvalidPublicKeyError from multimerchant.wallet.bip32 import KeyMismatchError from multimerchant.wallet.keys import IncompatibleNetworkException from multimerchant.wallet.utils import ensure_bytes from multimerchant.wallet.utils import long_to_hex class TestWallet(TestCase): @classmethod def setUpClass(cls): cls.expected_key = ensure_bytes( "0488ade4" # BitcoinMainNet version "00" # depth "00000000" # parent fingerprint "00000000" # child_number # chain_code "873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508" "00" # key identifier # private exponent "e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35") cls.master_key = Wallet.deserialize(cls.expected_key) def test_serialize_master_key(self): self.assertEqual(self.expected_key, self.master_key.serialize()) def test_from_master_secret(self): secret = binascii.unhexlify(b'000102030405060708090a0b0c0d0e0f') self.assertEqual(Wallet.from_master_secret(secret), self.master_key) def test_from_master_secret_slow(self): """Verified against bip32.org""" password = "correct horse battery staple" w = Wallet.from_master_secret_slow(password) self.assertEqual( w.serialize_b58(private=True), "xprv9s21ZrQH143K3JDqHk5kEb6o2w8pEwm3cmt8qaSw9coaHCYJFtaybzUob6d4" "WyJDf8uspZkBAt7DcEVhvCDRBHZEavVJg51HZEGdVH2uXLK") self.assertEqual(w.depth, 0) self.assertEqual(w.parent_fingerprint, b"0x00000000") self.assertEqual(w.child_number, 0) self.assertEqual( w.chain_code, (b'7c73c15c623128246dcf37d439be2a9d' b'da5fb33b2aec18e66a806d10a236b5c9')) self.assertEqual( w.export_to_wif(), 'KxTFZmNVYgAupo2w8QUNpfDjSEMhGN7RaQ6rhNRvsSHBggASpEr1') child = w.get_child(0, is_prime=False) self.assertEqual( child.serialize_b58(private=True), "xprv9vExvbix4MQgazj3vovZ4UEwmLSEQrktY8yZAVhFAB7W7xzqS9RXH8ZaNEdw" "KoQzbPixY3YSVjK58S3K5h4ktjVEpHrfjUarsiUfKDe6A4i") self.assertEqual( child.export_to_wif(), 'L3LA3KxJELbwCyVjFaSrvvUsnfKcZ9TPmGXbq4s6zmK5kaBVja29') self.assertEqual( child.serialize_b58(private=False), "xpub69EKL7FqtixyoUoX2qTZRcBgKNGipKUjuMu9xt6riWeUzmKyygjmpvt4DXaL" "U2vyoVqYtpqyuDYDHsxbzzReQmou1PtwVthP3SJkjcHEEg4") self.assertEqual( child.get_public_key_hex(), (b"03b18ba94530690859a3f6ebb2b866d1" b"51f8499b3164d027ba5b464e4ed71329aa")) self.assertEqual( child.to_address(), "1MfJvR28iULUb8AwtY7hp7xpc1A8Wg1ojX") def test_invalid_network_prefix(self): key = self.expected_key key = (long_to_hex(BitcoinTestNet.EXT_SECRET_KEY, 8) + self.expected_key[8:]) self.assertRaises(IncompatibleNetworkException, Wallet.deserialize, key, BitcoinMainNet) self.assertTrue(Wallet.deserialize(key, BitcoinTestNet)) def test_public_export(self): """Export a node as public.""" child = self.master_key.get_child(0, as_private=False) self.assertEqual(child.private_key, None) key = child.serialize(private=False) self.assertTrue( long_to_hex(BitcoinMainNet.EXT_PUBLIC_KEY, 8) in key) self.assertEqual(Wallet.deserialize(key), child) def test_public_export_mismatch(self): """Can't export a public node as private.""" child = self.master_key.get_child(0, as_private=False) self.assertEqual(child.private_key, None) self.assertRaises(ValueError, child.serialize) def test_random_wallet(self): w = Wallet.new_random_wallet() self.assertTrue(Wallet.deserialize(w.serialize()), w) self.assertEqual(w.depth, 0) self.assertEqual(w.parent_fingerprint, b'0x' + long_to_hex(0, 8)) self.assertEqual(w.child_number, 0) w2 = Wallet.new_random_wallet() self.assertNotEqual(w.get_private_key_hex(), w2.get_private_key_hex()) def test_random_wallet_with_entropy(self): """Ensure that the user_entropy value actually adds entropy.""" test_time = time.time() with patch('multimerchant.wallet.bip32.urandom', return_value=b'0'*64): with patch('multimerchant.wallet.bip32.time') as mock_time: mock_time.time.return_value = test_time self.assertEqual( Wallet.new_random_wallet('entropy'), Wallet.new_random_wallet('entropy')) self.assertNotEqual( Wallet.new_random_wallet('entropy'), Wallet.new_random_wallet('foo')) def test_insuffient_key_data(self): self.assertRaises(InsufficientKeyDataError, Wallet, chain_code=self.master_key.chain_code, private_exponent=None, private_key=None, public_pair=None, public_key=None) def test_private_exponent(self): """Ensure we can create a wallet with just a private exponent.""" Wallet(chain_code='0' * 64, private_exponent=(self.master_key.private_key._private_key .privkey.secret_multiplier)) def test_private_key(self): """Ensure a private key is sufficient to create a wallet.""" Wallet(chain_code='0' * 64, private_key=self.master_key.private_key) def test_private_key_type(self): """Must be a multimerchant private key""" self.assertRaises( InvalidPrivateKeyError, Wallet, chain_code='0' * 64, private_key=self.master_key.private_key._private_key) def test_public_pair(self): Wallet(chain_code=b'0' * 64, public_pair=self.master_key.public_key.to_public_pair()) def test_public_key(self): Wallet(chain_code=b'0' * 64, public_key=self.master_key.public_key) def test_public_key_type(self): self.assertRaises( InvalidPublicKeyError, Wallet, chain_code=b'0' * 64, public_key=self.master_key.public_key._verifying_key) def test_mismatch_public_private(self): w = Wallet.new_random_wallet() self.assertRaises( KeyMismatchError, Wallet, chain_code=b'0' * 64, private_key=self.master_key.private_key, public_key=w.public_key) class TestInvalidChildren(TestCase): def test_key_too_large(self): w = Wallet.new_random_wallet() order = binascii.unhexlify(long_to_hex(SECP256k1.order, 64)) return_value = order + order with patch('hmac.HMAC.digest', return_value=return_value): self.assertRaises( InvalidPrivateKeyError, w.get_child, 1) def test_infinity_point(self): w = Wallet.new_random_wallet() with patch('multimerchant.wallet.keys.PublicKey.to_point', return_value=INFINITY): self.assertRaises( InfinityPointException, w.get_child, 1) class TestNewAddressForUser(TestCase): def setUp(self): self.w = Wallet.new_random_wallet() def test_invalid_user_id(self): self.assertRaises( ValueError, self.w.create_new_address_for_user, -10) self.assertRaises( ValueError, self.w.create_new_address_for_user, 0x80000000 + 1) def test_new_address(self): child = self.w.create_new_address_for_user(10) self.assertEqual( self.w.get_child(10, as_private=False), child) class TestCrackPrivateKey(TestCase): def setUp(self): self.w = Wallet.new_random_wallet() self.pub_derived_private_child = self.w.get_child(100) self.wpub = self.w.public_copy() self.assertTrue(self.wpub.private_key is None) def test_already_have_private(self): self.assertRaises(AssertionError, self.w.crack_private_key, self.pub_derived_private_child) def test_invalid_fingerprint(self): child = self.pub_derived_private_child.get_child(10) self.assertRaises(ValueError, self.wpub.crack_private_key, child) def test_invalid_prime(self): child = self.w.get_child(-100) self.assertRaises(ValueError, self.wpub.crack_private_key, child) def test_crack_child(self): cracked = self.wpub.crack_private_key(self.pub_derived_private_child) self.assertEqual(cracked, self.w) self.assertEqual(cracked.get_child(100), self.pub_derived_private_child) self.assertEqual(cracked.get_child(-100), self.w.get_child(-100)) class TestSubkeyPath(TestCase): """Tests for get_child_for_path not covered by TestVectors.""" @classmethod def setUpClass(cls): """ This particular key was found by accident to cause the public deserialized wallet to have a bad public key point! There was a bug that did not properly handle restoring a key from a compressed point that had an odd beta parameter. (see PublicKey.from_hex_key) """ cls.wallet = Wallet.deserialize( u'xprv9s21ZrQH143K319oTMcEt2n2g51StkEnXq23t52ajHM4zFX7cyPqaHShDod' 'cHAqorNQuDW82jUhXJLomy5A8kM36y8HntnosgCvc1szPJ6x') def assert_public(self, node): self.assertEqual(node.private_key, None) def test_strip_private_key(self): self.assert_public(self.wallet.public_copy()) self.assertNotEqual(self.wallet.private_key, None) def test_export_as_public(self): self.assert_public(self.wallet.get_child(0, as_private=False)) def test_path_as_public(self): self.assert_public(self.wallet.get_child_for_path("M/0")) self.assert_public(self.wallet.get_child_for_path("M/0.pub")) self.assert_public(self.wallet.get_child_for_path("m/0.pub")) self.assert_public(self.wallet.get_child_for_path("M")) self.assert_public(self.wallet.get_child_for_path("m.pub")) def test_public_final_with_prime(self): self.assert_public(self.wallet.get_child_for_path("M/0/1'/2/3'.pub")) def test_public_child_restore(self): pub_child = self.wallet.get_child_for_path("M/0") self.assert_public(pub_child) loaded = Wallet.deserialize(pub_child.serialize(False)) self.assertEqual(pub_child, loaded) n1 = pub_child.get_child_for_path("m/1") n2 = loaded.get_child_for_path("m/1") self.assertEqual(n1, n2) def test_invalid_path(self): self.assertRaises( ValueError, self.wallet.get_child_for_path, None) self.assertRaises( InvalidPathError, self.wallet.get_child_for_path, "") self.assertRaises( InvalidPathError, self.wallet.get_child_for_path, "m/foo") self.assertRaises( InvalidPathError, self.wallet.get_child_for_path, "M/1234/4567m") def test_child_too_small(self): self.assertRaises( ValueError, self.wallet.get_child, -(0x80000000 + 1)) def test_child_too_big(self): self.assertRaises( ValueError, self.wallet.get_child, 0xFFFFFFFF + 1) def test_path_bigger_than_boundary(self): child_number = 0x80000000 self.assertRaises( ValueError, self.wallet.get_child_for_path, "m/%s" % child_number) self.assertRaises( ValueError, self.wallet.get_child_for_path, "m/%s" % (child_number + 1)) self.assertNotEqual( self.wallet.get_child_for_path("m/%s'" % (child_number - 1)), self.wallet.get_child_for_path("m/%s" % (child_number - 1))) def test_child_bigger_than_boundary(self): child_number = 0x80000000 self.assertRaises( ValueError, self.wallet.get_child, -1, is_prime=True) self.assertRaises( ValueError, self.wallet.get_child, -1, is_prime=False) self.assertRaises( ValueError, self.wallet.get_child, child_number, is_prime=True) self.assertRaises( ValueError, self.wallet.get_child, child_number, is_prime=False) class TestSerialize(TestCase): network = BitcoinMainNet @classmethod def setUpClass(cls): cls.wallet = Wallet.new_random_wallet(network=cls.network) def test_serialize_private(self): prv = self.wallet.serialize(private=True) w = Wallet.deserialize(prv, network=self.network) self.assertTrue(w.private_key) self.assertEqual(w, self.wallet) prv = self.wallet.serialize_b58(private=True) w = Wallet.deserialize(prv, network=self.network) self.assertTrue(w.private_key) self.assertEqual(w, self.wallet) def test_serialize_public(self): pub = self.wallet.serialize(private=False) w = Wallet.deserialize(pub, network=self.network) self.assertFalse(w.private_key) pub = self.wallet.serialize_b58(private=False) w = Wallet.deserialize(pub, network=self.network) self.assertFalse(w.private_key) def test_deserialize_byte_array(self): key = binascii.unhexlify(self.wallet.serialize()) w = Wallet.deserialize(key, network=self.network) self.assertEqual(w, self.wallet) class TestSerializeDogecoin(TestSerialize): network = DogecoinMainNet class TestSerializeLitecoin(TestSerialize): network = LitecoinMainNet class _TestWalletVectors(TestCase): def _test_vector(self, key, id_hex, fingerprint, address, secret_key_hex, secret_key_wif, pubkey_hex, chaincode_hex, pubkey_serialized_hex, private_serialized_hex, pubkey_base58, private_base58, include_private=True ): self.assertEqual(key.identifier, ensure_bytes(id_hex)) self.assertEqual(key.fingerprint, ensure_bytes(fingerprint)) self.assertEqual(key.to_address(), address) self.assertEqual(key.get_public_key_hex(), ensure_bytes(pubkey_hex)) self.assertEqual(key.chain_code, ensure_bytes(chaincode_hex)) self.assertEqual(key.serialize(private=False), ensure_bytes(pubkey_serialized_hex)) self.assertEqual(key.serialize_b58(private=False), pubkey_base58) if include_private: self.assertEqual(key.get_private_key_hex(), ensure_bytes(secret_key_hex)) self.assertEqual(key.export_to_wif(), secret_key_wif) self.assertEqual(key.serialize(), ensure_bytes(private_serialized_hex)) self.assertEqual(key.serialize_b58(), private_base58) def _test_deserialize(self, child, *vector): self._test_vector( Wallet.deserialize(child.serialize(private=True)), *vector) self._test_vector( Wallet.deserialize(child.serialize(private=False)), *vector, include_private=False) class TestWalletVectors1(_TestWalletVectors): @classmethod def setUpClass(cls): cls.master_key = Wallet.from_master_secret( binascii.unhexlify('000102030405060708090a0b0c0d0e0f')) def test_m(self): """[Chain m]""" vector = [ '3442193e1bb70916e914552172cd4e2dbc9df811', '0x3442193e', '15mKKb2eos1hWa6tisdPwwDC1a5J1y9nma', 'e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35', 'L52XzL2cMkHxqxBXRyEpnPQZGUs3uKiL3R11XbAdHigRzDozKZeW', '0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2', # nopep8 '873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508', '0488b21e000000000000000000873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d5080339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2', # nopep8 '0488ade4000000000000000000873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d50800e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35', # nopep8 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8', # nopep8 'xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi', # nopep8 ] self._test_vector(self.master_key, *vector) self._test_vector(self.master_key.get_child_for_path("m"), *vector) self._test_deserialize(self.master_key, *vector) def test_m_0p(self): vector = [ '5c1bd648ed23aa5fd50ba52b2457c11e9e80a6a7', '0x5c1bd648', '19Q2WoS5hSS6T8GjhK8KZLMgmWaq4neXrh', 'edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea', 'L5BmPijJjrKbiUfG4zbiFKNqkvuJ8usooJmzuD7Z8dkRoTThYnAT', '035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56', # nopep8 '47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141', '0488b21e013442193e8000000047fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56', # nopep8 '0488ade4013442193e8000000047fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae623614100edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea', # nopep8 'xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw', # nopep8 'xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7', # nopep8 ] child = self.master_key.get_child(0, is_prime=True) self._test_vector(child, *vector) self._test_vector(self.master_key.get_child_for_path("m/0'"), *vector) self._test_vector(self.master_key.get_child_for_path("m/0p"), *vector) self._test_deserialize(child, *vector) def test_m_0p_1(self): vector = [ 'bef5a2f9a56a94aab12459f72ad9cf8cf19c7bbe', '0xbef5a2f9', '1JQheacLPdM5ySCkrZkV66G2ApAXe1mqLj', '3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368', 'KyFAjQ5rgrKvhXvNMtFB5PCSKUYD1yyPEe3xr3T34TZSUHycXtMM', '03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c', # nopep8 '2a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19', '0488b21e025c1bd648000000012a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c1903501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c', # nopep8 '0488ade4025c1bd648000000012a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19003c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368', # nopep8 'xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ', # nopep8 'xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs', # nopep8 ] m0 = self.master_key.get_child(0, is_prime=True) child = m0.get_child(1, is_prime=False) self._test_vector(child, *vector) self._test_vector( self.master_key.get_child_for_path("m/0'/1"), *vector) self._test_vector( self.master_key.get_child_for_path("m/0p/1"), *vector) self._test_deserialize(child, *vector) def test_m_0p_1_2p(self): vector = [ 'ee7ab90cde56a8c0e2bb086ac49748b8db9dce72', '0xee7ab90c', '1NjxqbA9aZWnh17q1UW3rB4EPu79wDXj7x', 'cbce0d719ecf7431d88e6a89fa1483e02e35092af60c042b1df2ff59fa424dca', 'L43t3od1Gh7Lj55Bzjj1xDAgJDcL7YFo2nEcNaMGiyRZS1CidBVU', '0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2', # nopep8 '04466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f', '0488b21e03bef5a2f98000000204466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2', # nopep8 '0488ade403bef5a2f98000000204466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f00cbce0d719ecf7431d88e6a89fa1483e02e35092af60c042b1df2ff59fa424dca', # nopep8 'xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5', # nopep8 'xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM', # nopep8 ] child = self.master_key.get_child(0, True).get_child(1).get_child(-2) self._test_vector(child, *vector) self._test_vector( self.master_key.get_child_for_path("m/0'/1/2'"), *vector) self._test_vector( self.master_key.get_child_for_path("m/0p/1/2p"), *vector) self._test_deserialize(child, *vector) def test_m_0p_1_2p_2(self): vector = [ 'd880d7d893848509a62d8fb74e32148dac68412f', '0xd880d7d8', '1LjmJcdPnDHhNTUgrWyhLGnRDKxQjoxAgt', '0f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4', 'KwjQsVuMjbCP2Zmr3VaFaStav7NvevwjvvkqrWd5Qmh1XVnCteBR', '02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29', # nopep8 'cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd', '0488b21e04ee7ab90c00000002cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29', # nopep8 '0488ade404ee7ab90c00000002cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd000f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4', # nopep8 'xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV', # nopep8 'xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334', # nopep8 ] node = self.master_key.get_child(0, True).get_child(1).get_child(-2) child = node.get_child(2) self._test_vector(child, *vector) self._test_vector( self.master_key.get_child_for_path("m/0'/1/2'/2"), *vector) self._test_vector( self.master_key.get_child_for_path("m/0p/1/2p/2"), *vector) self._test_deserialize(child, *vector) def test_m_0p_1_2p_2_1000000000(self): vector = [ 'd69aa102255fed74378278c7812701ea641fdf32', '0xd69aa102', '1LZiqrop2HGR4qrH1ULZPyBpU6AUP49Uam', '471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8', 'Kybw8izYevo5xMh1TK7aUr7jHFCxXS1zv8p3oqFz3o2zFbhRXHYs', '022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011', # nopep8 'c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e', '0488b21e05d880d7d83b9aca00c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011', # nopep8 '0488ade405d880d7d83b9aca00c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e00471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8', # nopep8 'xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy', # nopep8 'xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76', # nopep8 ] child = (self.master_key.get_child(0, True) .get_child(1).get_child(-2).get_child(2) .get_child(1000000000)) self._test_vector(child, *vector) self._test_vector( self.master_key.get_child_for_path("m/0'/1/2'/2/1000000000"), *vector) self._test_vector( self.master_key.get_child_for_path("m/0p/1/2p/2/1000000000"), *vector) self._test_deserialize(child, *vector) class TestWalletVectors2(_TestWalletVectors): @classmethod def setUpClass(cls): cls.master_key = Wallet.from_master_secret(binascii.unhexlify( 'fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a2' '9f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542' )) def test_m(self): vector = [ 'bd16bee53961a47d6ad888e29545434a89bdfe95', '0xbd16bee5', '1JEoxevbLLG8cVqeoGKQiAwoWbNYSUyYjg', '4b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e', 'KyjXhyHF9wTphBkfpxjL8hkDXDUSbE3tKANT94kXSyh6vn6nKaoy', '03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7', # nopep8 '60499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689', '0488b21e00000000000000000060499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd968903cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7', # nopep8 '0488ade400000000000000000060499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689004b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e', # nopep8 'xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB', # nopep8 'xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U', # nopep8 ] self._test_vector(self.master_key, *vector) self._test_deserialize(self.master_key, *vector) def test_m_0(self): vector = [ '5a61ff8eb7aaca3010db97ebda76121610b78096', '0x5a61ff8e', '19EuDJdgfRkwCmRzbzVBHZWQG9QNWhftbZ', 'abe74a98f6c7eabee0428f53798f0ab8aa1bd37873999041703c742f15ac7e1e', 'L2ysLrR6KMSAtx7uPqmYpoTeiRzydXBattRXjXz5GDFPrdfPzKbj', '02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea', # nopep8 'f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c', '0488b21e01bd16bee500000000f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea', # nopep8 '0488ade401bd16bee500000000f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c00abe74a98f6c7eabee0428f53798f0ab8aa1bd37873999041703c742f15ac7e1e', # nopep8 'xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH', # nopep8 'xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt', # nopep8 ] child = self.master_key.get_child(0) self._test_vector(child, *vector) self._test_deserialize(child, *vector) def test_m_0_2147483647p(self): vector = [ 'd8ab493736da02f11ed682f88339e720fb0379d1', '0xd8ab4937', '1Lke9bXGhn5VPrBuXgN12uGUphrttUErmk', '877c779ad9687164e9c2f4f0f4ff0340814392330693ce95a58fe18fd52e6e93', 'L1m5VpbXmMp57P3knskwhoMTLdhAAaXiHvnGLMribbfwzVRpz2Sr', '03c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b', # nopep8 'be17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d9', '0488b21e025a61ff8effffffffbe17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d903c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b', # nopep8 '0488ade4025a61ff8effffffffbe17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d900877c779ad9687164e9c2f4f0f4ff0340814392330693ce95a58fe18fd52e6e93', # nopep8 'xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a', # nopep8 'xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9', # nopep8 ] child = self.master_key.get_child(0).get_child(2147483647, True) self._test_vector(child, *vector) self._test_vector(self.master_key.get_child(0) .get_child(-2147483647), *vector) self._test_deserialize(child, *vector) def test_m_0_2147483647p_1(self): vector = [ '78412e3a2296a40de124307b6485bd19833e2e34', '0x78412e3a', '1BxrAr2pHpeBheusmd6fHDP2tSLAUa3qsW', '704addf544a06e5ee4bea37098463c23613da32020d604506da8c0518e1da4b7', 'KzyzXnznxSv249b4KuNkBwowaN3akiNeEHy5FWoPCJpStZbEKXN2', '03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9', # nopep8 'f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb', '0488b21e03d8ab493700000001f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9', # nopep8 '0488ade403d8ab493700000001f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb00704addf544a06e5ee4bea37098463c23613da32020d604506da8c0518e1da4b7', # nopep8 'xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon', # nopep8 'xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef', # nopep8 ] child = (self.master_key.get_child(0) .get_child(2147483647, True) .get_child(1)) self._test_vector(child, *vector) self._test_deserialize(child, *vector) def test_m_0_2147483647p_1_2147483646p(self): vector = [ '31a507b815593dfc51ffc7245ae7e5aee304246e', '0x31a507b8', '15XVotxCAV7sRx1PSCkQNsGw3W9jT9A94R', 'f1c7c871a54a804afe328b4c83a1c33b8e5ff48f5087273f04efa83b247d6a2d', 'L5KhaMvPYRW1ZoFmRjUtxxPypQ94m6BcDrPhqArhggdaTbbAFJEF', '02d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0', # nopep8 '637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e29', '0488b21e0478412e3afffffffe637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e2902d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0', # nopep8 '0488ade40478412e3afffffffe637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e2900f1c7c871a54a804afe328b4c83a1c33b8e5ff48f5087273f04efa83b247d6a2d', # nopep8 'xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL', # nopep8 'xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc', # nopep8 ] child = (self.master_key.get_child(0) .get_child(2147483647, True) .get_child(1) .get_child(2147483646, True)) self._test_vector(child, *vector) self._test_deserialize(child, *vector) def test_m_0_2147483647p_1_2147483646p_2(self): vector = [ '26132fdbe7bf89cbc64cf8dafa3f9f88b8666220', '0x26132fdb', '14UKfRV9ZPUp6ZC9PLhqbRtxdihW9em3xt', 'bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23', 'L3WAYNAZPxx1fr7KCz7GN9nD5qMBnNiqEJNJMU1z9MMaannAt4aK', '024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c', # nopep8 '9452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271', '0488b21e0531a507b8000000029452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c', # nopep8 '0488ade40531a507b8000000029452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed27100bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23', # nopep8 'xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt', # nopep8 'xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j', # nopep8 ] child = (self.master_key.get_child(0) .get_child(2147483647, True) .get_child(1) .get_child(2147483646, True) .get_child(2)) self._test_vector(child, *vector) self._test_vector(self.master_key.get_child(0) .get_child(-2147483647) .get_child(1) .get_child(-2147483646) .get_child(2), *vector) self._test_deserialize(child, *vector) class _TestWalletVectorsBip32org(TestCase): """Test vectors generated with bip32.org""" def _test(self, key, private_key_b58, private_key_wif, pubkey_b58, pubkey_hex, address, include_private=True): if include_private: self.assertEqual(key.serialize_b58(), private_key_b58) self.assertEqual(key.export_to_wif(), private_key_wif) self.assertEqual(key.serialize_b58(private=False), pubkey_b58) self.assertEqual(key.get_public_key_hex(), ensure_bytes(pubkey_hex)) self.assertEqual(key.to_address(), address) def _test_deserialize(self, child, *vector): self._test( Wallet.deserialize( child.serialize(private=True), network=self.network), *vector) self._test( Wallet.deserialize( child.serialize(private=False), network=self.network), *vector, include_private=False) class _TestWalletVectorsDogecoin(_TestWalletVectorsBip32org): network = DogecoinMainNet """ This is a reduced test because Dogecoin doesn't have official vectors. I generated these test values using http://bip32.org """ @classmethod def setUpClass(cls): cls.master_key = Wallet.deserialize( 'dgpv51eADS3spNJh8qd8KgFeT3V2QZBDSkYUqbaKDwZpDN4jd3uLcR7i6CruVDsb' 'acyx3NL2puToxM9MQYhZSsD8tBkXeQkm5btsKxpZawwPQND', cls.network ) class TestWalletVectorsDogecoin1(_TestWalletVectorsDogecoin): def test_m_0p(self): vector = [ 'dgpv54rTeYviMxmUs9cNrWWrvqJZ5C6bfH7yV66f1k9p6EBtFPSiGe8X3zP9e3YyarxzcYHWgbuuc3PcNFynEYyDFNS7yNWbisqdU9nYy2bZGPD', # nopep8 'QTndqZdNU46ndUrbHzMC3rqSP5PWdE3vfEeRrUDZxEHXveLwbpta', 'dgub8ojUzErbv7RpA1GXtk8q3gr9XkUEVQ9gmgssArYntMEtoSZQgQgHhHnoDJ8Wp4swrdBSmQs7WZWp5q96TjgW8k1HpqyyfpqEvq4MD6cNMgn', # nopep8 '037379173b8d4a681c2dfe1d4ea4c0961f3087f7e52380e0d20d617ba175ba18ce', # nopep8 'DCJCTZdCiddc47n23zoaJ1cWCXpkYLfyYJ' ] key = self.master_key.get_child(0, True) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0p_1(self): vector = [ 'dgpv55yu5Hmd9XBBe1UNqhzUuy77eWQyBiyBGHxKrUoZGFGe3foc9AuJxVQ5e8K6C3LogwyGkEmJVwZ9kWCdg8vd61WRXpcJ6fqosi7Q69teU9r', # nopep8 'QUf7sx5yK5Jw6a9rHuMsRwYv3WrdzfMfwX7mwb6MG6CZ4T1TYcBW', 'dgub8prvQyhWhfqWvs8XswcT2pei74nc1qztYtjY1bCY4NKebivJYwT5bnojDMRLqR7pnWY46yChRSoeYYCLxGrQiWWbhvBWi6WSR6kQaabSGdN', # nopep8 '02cbcaa03b355646ac834df6bd24744f1fbe801a9168744604171b6e228f44d4b4', # nopep8 'DF1kyuBcTfUwx5rvEXWLBwjUDJZVXqyNkD' ] key = (self.master_key.get_child(0, True) .get_child(1)) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0p_1_2p(self): vector = [ 'dgpv585jjaM2m4VAQHfu9TQ9iGEiyeRbJbiwF3mqxoC7ER8FDc5rCtmVckFRQXH5XpwBiLduR5PjB85s2n1DBLqYAXkhuXC6AMmfw1mF9MkkiqJ', # nopep8 'QWuyvRUVSzGsPcV6r7wZD51GK8tHJ5CSHpccAdr5ojFaLSQmHXqu', 'dgub8rxm5GGvKD9Vh9L4Bh27q7nKSCoE8ikeXeZ47ub62YBFmfCYcfKGG3f4yijWNXbZDuss3HKmJAZsjkFcC63SiPUYHxLXLnXaGg2Etq6UdSD', # nopep8 '0235881bfba654b68153c3e781588d2c161defeb273ff6bd333b1075f0102c8cd7', # nopep8 'D6VUtfV7L874S9c5Vcxmek3aRV3hDS6eqR' ] key = (self.master_key.get_child(0, True) .get_child(1) .get_child(2, True)) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0p_1_2p_2(self): vector = [ 'dgpv59H2Cgx4gUkZwbZH44mDznT18YtBstwstes8dR5H3fVLzXzo91dwGDFRhTHY637rus3akpLUe1EQ54rsBqxGj5ZJRrxxZc7GSw2bBX9FJWi', # nopep8 'QQMEq6rxPz7ZToTtfkGbshrNzn13kXLUUG6733rrqArzpaWCnYv5', 'dgub8tA3YNsxEdQuETDS6JPC7dzbb7Fpi1ybBFeLnXUFqnYMYb7VYnBhuWf5GgFYWN8B4vSqfSfpEgdR97QSBgMAyp3w2JHyzPCxP41nRXAMdno', # nopep8 '0238859645107ce894071e0ba4243b512d4d0fcd9fc49c0d1f1fe98ab86afe2179', # nopep8 'D5zp6rHbVHWepGxonaSG1CKAmSY7fgRZdW' ] key = (self.master_key.get_child(0, True) .get_child(1) .get_child(2, True) .get_child(2)) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0p_1_2p_2_1000000000(self): vector = [ 'dgpv5B7qzmM1EoGC3RtP2wNxfAxTZsZ8ULrAeTNgTxABfSsdUSGkwpskeHaixWSW4urESb5ATNA49QhJK39RR8wzbXJrkLbBvMiv2MzTCTB3wJR', # nopep8 'QW8D8EFkCa5JqLg4zeDwBj7iuk3jyGgEyFmwV6kUSQQhjwZk3nBv', 'dgub8uzsLTGtnwvXLHYY5Azvn2W42RvmJTssw49td4ZATZve2VPTMbRXHazNXiqqASTcaTsxoPRhsZAeiY3XA9gaJH6dJkZNUw3LwRvbVAYtuEL', # nopep8 '029aa4dc7df5d6b55058ab29b7e4020dbb7253aec3ecfa31fcd3170d2b26ec61b1', # nopep8 'DTRNwCes9k4xqLb9iD9kpSUpLpfsnQk2uw' ] key = (self.master_key.get_child(0, True) .get_child(1) .get_child(2, True) .get_child(2) .get_child(1000000000)) self._test(key, *vector) self._test_deserialize(key, *vector) class TestWalletVectorsDogecoin2(_TestWalletVectorsDogecoin): def test_m(self): vector = [ 'dgpv51eADS3spNJh8qd8KgFeT3V2QZBDSkYUqbaKDwZpDN4jd3uLcR7i6CruVDsbacyx3NL2puToxM9MQYhZSsD8tBkXeQkm5btsKxpZawwPQND', # nopep8 'QPNHZTWZzk2tdNknJqkP5SS4jwqjHwsDA4i4oPcsQ1abCck5dZzx', 'dgub8kXBZ7ymNWy2RhHHMuscZu2cs7YrGsaC8CMXP3xo1V7kB7232BfUjWGZ4VS8wHCPDNWmJdCZjo81gbpm1Co2pLyNSjpqDJYmMTGKeyAGuo9', # nopep8 '0371070e700787e78e1810b2843c0723fcf25643f9de9bb90fca95ca2941dd485c', # nopep8 'DMeAv9o4rFgDTFDhSYupoRHEwNmE98FDDi' ] self._test(self.master_key, *vector) self._test_deserialize(self.master_key, *vector) self._test_deserialize(self.master_key, *vector) def test_m_0(self): vector = [ 'dgpv54rTeYva2JEWgt3hvAU6ukxYEgeKwe9Nh5CNhYkdvRDL2SrhuWHurhsER1cbNuHrtUcRVrSgJ3so8PX7V2Bn6KLhYzq9GZickzbrsavazMV', # nopep8 'QSk4UkgRmxH6XDBofiUZad7grkSKj4NQsxyKWniaoun4Az3fmmdE', 'dgub8ojUzErTaStqyjhrxQ652cW8hF1xmmB5yfyarf9ciYGLaVyQKGqgW1GszEmFjCQkXWGV9SkCpjUfNpc4mQW1EcoBBsQoe4RV61QJC4G9X3d', # nopep8 '029820c6a6046cebadb9a40c717326b004257f4cc111010b571daacfe58b542565', # nopep8 'D6DLgbqjac4JqFQj7TkU2q5uqVAKFvAUHz' ] key = self.master_key.get_child(0) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0_2147483647p(self): vector = [ 'dgpv55VT18PENZdLnv1jMvtZXELhZCfzsFmFG9Qoe5ktw4oLSirqapnwx3x9nHL6jCZSRkYMKwcziQAZmKgBGbttC6kFbwoTfGWtNWnF5hFQwsk', # nopep8 'QVvKXa4BZKMok5WLJVPY9mF6YkhWaS5BJeM8pMfGBufKUKyjiwoL', 'dgub8pNULpK7viHg5mftQAWXe5tJ1m3dhNnxYkC1oC9sjBrLzmyXzbLibMMoMYSUC34ETAQM3BVUHbdgvuFFvCGLTLifbqLeiR67x2rfcndnNC8', # nopep8 '03f91b9fe3110c8cbe885666e9a86237114faf54d6e124a20320a10b7847ad8e7c', # nopep8 'DFLc2YseDUQkS9gChgzjuFA7MNUo2Kz2ch' ] key = self.master_key.get_child(0).get_child(2147483647, True) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0_2147483647p_1(self): vector = [ 'dgpv587FrzGt8WwxqYnVBDDrEmfR5TVjBaH6p2js6YQ6S7arktrwK9Pt4AqzcLMuUnbrCJyUnomeYHHfxp9qDrtJLUJPaEyjg263PfzYgCwXnjH', # nopep8 'QQrZo8xssr5ryo8PBUsu2ukzbGEYu8khaZnTYYDDA8p8xwqe8Ub4', 'dgub8rzHCgCmgfcJ8QSeDSqpMdD1Y1sN1hJp6dX5Feo5EEdsJwydiuwehUFeBcBPyyTMTCToL5E3DsWtMpDLD7ZxwXDHA5Ty7kxnLgK4SxsMmbg', # nopep8 '03bf5c6222396af17f76f577d5b4f1ab291ef051ae538eab1db8586f5de6112aa7', # nopep8 'DRwmLE3MgfPigYkeZ8nJArb37eCrrubVqM' ] key = (self.master_key.get_child(0). get_child(2147483647, True). get_child(1)) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0_2147483647p_1_2147483646p(self): vector = [ 'dgpv5AqzQ1J7t4unSJCG7GhNnvSEnicPLNVdjB1xXseffVjc7HnkCBAJ7vDvZdqYUX3xnhhPDXqTKdwLGkuiLqMjvFoPcSbATYxEgCMYsqexwQB', # nopep8 'QP3TK4n8NaHY35rkzSYFCPX2zMXxjshjVUXcqpStspQ6HE1qsbXX', 'dgub8uj1jhE1SDa7j9rR9WKLumyqFGz2AVXM1moAgz3eTcncfLuSbwi4mDda8uKTuyiw7K66K2CwXY7KPMCGk7rQD7V6CtZ2yr4EVoBPMTqt4Bd', # nopep8 '035cd9e4427e59a367b04ca0b34be7a78968d713004bcf1917fcc11c94c04e4477', # nopep8 'DK6Rf67LRccSVPA8ew1jtDsMV2W6deokqg' ] key = (self.master_key.get_child(0) .get_child(2147483647, True) .get_child(1) .get_child(2147483646, True)) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0_2147483647p_1_2147483646p_2(self): vector = [ 'dgpv5CB6BEhuLSCN16LBqxDgpLZMtAmu88f6c376sK4FVds1PYgSyAy8dB4oMXwxmDiuodEVKEMoWzaDci3fmpi2yE9eE2jQjHcvQ2ojqQLLcrH', # nopep8 'QWLvYMin1VjHqQuS33nq23CMmACUxBxAfYLmZXYaaGuJHjp5T5Lx', 'dgub8w47WvdntarhHwzLtBqewC6xLj9XxFgotdtK2RTEHkv1wbo9NwWuGUUSvnSy57u82XKNZkxzfv6iNTcakj8VLzhtnhCpKLrdW4spZB7eosx', # nopep8 '03b5770cca42dd6159a22113a4f1970794d5db993a46a45bcd1c4ee6399003d394', # nopep8 'DNoz4kLEcUENEjUceiugpw6hGPgmFJoc7C' ] key = (self.master_key.get_child(0) .get_child(2147483647, True) .get_child(1) .get_child(2147483646, True) .get_child(2)) self._test(key, *vector) self._test_deserialize(key, *vector) class _TestWalletVectorsLitecoin(_TestWalletVectorsBip32org): network = LitecoinMainNet """ This is a reduced test because Litecoin doesn't have official vectors. I generated these test values using http://bip32.org """ @classmethod def setUpClass(cls): cls.master_key = Wallet.deserialize( 'Ltpv71G8qDifUiNetGsQje8NP1KYECbgKwSP2kugo4qN9GPfJ1KB8XMXxqBTYsA5' 'PgwQaFV9u5PhKxosbjcnKKCPpPvaYVSUz24KMctXYig39Te', cls.network ) class TestWalletVectorsLitecoin1(_TestWalletVectorsLitecoin): def test_m_0p(self): vector = [ 'Ltpv74V6By3UsgGzZw27UtyGEkYeGUUyP8DeDLwnVNwrkaUHxnai5mJbmAG6JHaKSnZhZMxXyhQXU4NTqqygJxKiNt1MdKgr7jEuDZ4uagqrKDa', # nopep8 'TAqpVhaoeiN17bd7keFxKc4nAhAXFaEVuXQcyRQvBh51LxPLkAAX', 'Ltub2VfRnkU27poxBoiwjWTeKLNri3BATNnJHs3pAMi9gmFtZ9mnQgM2mmNMYdmG16ksFsF3NURRQBirSkAnNTr4gm7Mq85EBCUNCopnJieQvAr', # nopep8 '027bd1f86dcd5bab63040f8f334e56d206959031df9291e4721e018e7206dcf8a2', # nopep8 'Lf9q6hjcHBcyqLbFvUAeW8XrAVtmjksK2x' ] key = self.master_key.get_child(0, True) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0p_1(self): vector = [ 'Ltpv76dbn3DT9k1QZk4jobJ9U4i32rWgwg361gCWCBw6YpEmWd6njuHBnqD9GsP96ZuvPzohf53SwM2WCpd9tRAyxKZ98PHehciT676FoTUJFjG', # nopep8 'T3mHwrvvGQAQYgw6NkEAbvnEW7DuVhHAoHxbrvdrRnCH9ugE3d5W', 'Ltub2XowNpdzPtYNBcma4CnXYeYFURCt1vbk6CJXsAhPV12N6zHs4pKcoSKQXHHb7cTDY9gUxQ95EBYxTTYE2cqjZmvw64uvXAqgx5f5i8DTtnd', # nopep8 '0391f78495549245157979b19b8c6ddad42f4092602819d85278ad22db87cb6730', # nopep8 'LPJZvWyD3i6JSMnwJtcLEMX7kYbPLbTqzE' ] key = (self.master_key.get_child(0, True) .get_child(1)) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0p_1_2p(self): vector = [ 'Ltpv77EctZnoc1SgaSffnPGVABbenBaeYBsiiNquoszDNKphMw3i4AHfJ2NaKRgKV5mUjw9qez5qRF1HTZxXegUE3W1ebdbWVETdKDMxa587Gnk', # nopep8 'T9VTp2qTW18DYLN6Rc6a2XP2cWy2mfLqNAQZDLJm27TdsZUG9jL7', 'Ltub2YQxVMDLr9yeCKNW2zksEmRsDkGqcSSNntwwUrkWJWcHxJEnP5L6JdUqZpdzFr7ijwz4xH3fL9E9jn5246F2nNHhPsSpWrk8Bu5zYDb5LTY', # nopep8 '03c0767a6c05d488b79465e973604eeeb008bfc8646877afb6237e483937beb788', # nopep8 'LdkUqtqarziHXTnC6borMadsfQesVzEJXx' ] key = (self.master_key.get_child(0, True) .get_child(1) .get_child(2, True)) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0p_1_2p_2(self): vector = [ 'Ltpv7AHK5coBDoEZFnWC7WtcSJq58fWbJuM2FrmWVitWz9HoeQijqcW48v1N3aYHp8hkgYKHbzvqydDdPu6Lv6MykvxWhCfifdP5yAJQzHqWKeg', # nopep8 'T9tMP13KhuheJkJGFXaAM2REkFCDfHh5ebF1EHYDShTFG6t775gp', 'Ltub2bTegQDiTwmWsfD2N8NzWtfHaECnP9ugLNsYAheovL5QEmupAXYV9X7dHvJmMptrs9dHRkfPxY7iTYz5Mp8nAPkR26GzqCMVkiV7bVPCn9b', # nopep8 '0227bbb5af873704535c17e7cf3cbd087760d0f4027ec5a44aa35afaba6e7d0266', # nopep8 'LgML9sstrXSnbxEv5UT9VYgp2dE7Je64FH' ] key = (self.master_key.get_child(0, True) .get_child(1) .get_child(2, True) .get_child(2)) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0p_1_2p_2_1000000000(self): vector = [ 'Ltpv7CNcMprvXc2ZzLAXxhuYeKL5N62NnpDsHNnS3gxFr7eJndZL3vKrXrvyMR2miDk7LSrRKQ7gSKWQwhCMLxuazuRFuCCZNbM5NXUBTrwAJwb', # nopep8 'TAefeF5TJVCTFRozizQtVJ9ku6gs1EdBKko3yea23o6w3ESVhQZY', 'Ltub2dYwxcHTmkZXcCsNDKPviuAHoeiZs4nXMttTifiYnJRuNzkQNqNHYU3EbkUg3oz1WvkLs9vnNNGPa5vgHbeBjWZZ7YQbERi8E9GnAzXnVHw', # nopep8 '02145bf57dcfe571710c61143adb44e80dd2ca44910b89406862962545fa567c96', # nopep8 'LQWUfR2ybmJGyLSps2fVSTCa9zmr9p9RQi' ] key = (self.master_key.get_child(0, True) .get_child(1) .get_child(2, True) .get_child(2) .get_child(1000000000)) self._test(key, *vector) self._test_deserialize(key, *vector) class TestWalletVectorsLitecoin2(_TestWalletVectorsLitecoin): def test_m(self): vector = [ 'Ltpv71G8qDifUiNetGsQje8NP1KYECbgKwSP2kugo4qN9GPfJ1KB8XMXxqBTYsA5PgwQaFV9u5PhKxosbjcnKKCPpPvaYVSUz24KMctXYig39Te', # nopep8 'T4HX1Wffx49Wbdfog3RF31m7P611LT8KPc17ZB4USQTMCZhazwNn', 'Ltub2SSUS19CirucW9aEzFckTb9kfmHsQC137H1iU3bf5TBFtNWFTSPxySHioHCHEtCb3NPSZn1FJM6joFKevvxx6vV4ggaQcKiYzaNucXpRyY8', # nopep8 '03b3204919fa92d16d869fc39f3510e0bc7b2ce53c1bf6124448f2cbbbaf29db38', # nopep8 'Lbs921f129AWWyb5kfdtSefUgreidPwqAP' ] self._test(self.master_key, *vector) self._test_deserialize(self.master_key, *vector) self._test_deserialize(self.master_key, *vector) def test_m_0(self): vector = [ 'Ltpv74V6By3LY1k2RyNdNhyBCtTgxbu6VrSDx8177z5g9phb8mmiJnC5dyGEL1AxCX4BWWJEcZBxep1j7wAPUp3jXqramror3Rdtg76ZNfwqeMr', # nopep8 'T9ARV5FUdiaXyp8boDPj9H2FjWxvdEUHaURrgsVeZjVFGTesNfku', 'Ltub2VfRnkTsnAGz3r5TdKTZHUHuQAbHa6zt2e78nxqy61VBj8xndhEWeaNVaQ6N8SLEPiF8UxEXkFBbPyKiutX6FhbKJXnQAaTRXw56e8zm2qs', # nopep8 '03b18ba94530690859a3f6ebb2b866d151f8499b3164d027ba5b464e4ed71329aa', # nopep8 'LftGBdKxo8aXqvs74g71692apDXQaPz17Z' ] key = self.master_key.get_child(0) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0_2147483647p(self): vector = [ 'Ltpv76h2CpMgsQfUbzphcJBPEBDEeP8U9WizJtRsxwTzq8LeSE6eVhZ5nzvPPxK8HifWH3GCpys6qWnzpBeFVVBaKQRki3tEN82PJUi3SdBQZcr', # nopep8 'T3kqK41soU9GEWrDYERqqHo8kcQvVhu9J8tmk8RRqshTi5FWUtBw', 'Ltub2XsMobnE7ZCSDsXXrufmJm3T5wpfDmHePQXudvEHmK8F2bHipcbWoc2eeNsqqjXRCgLQgkV1jS83mAZBtHqyaqPu1hkyUU1bhoQ9Pd2Fry2', # nopep8 '03e89f5654eb8489c71bb68f9df7d28c6f48a0f46c6fc2bef5ae11bb5536cebbb7', # nopep8 'LbMKq3XN8iUCJnCfxM8SgC6YGjoMazcrz3' ] key = self.master_key.get_child(0).get_child(2147483647, True) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0_2147483647p_1(self): vector = [ 'Ltpv78CxVKndj3P8PDBogzwnrxY7Pxtzn8vgExPZFVHeM42MGGNQ9wUJ2isvXPDHLGehGi8DdeFgNPQTGRMEKH72242jutfwB7PFbeKMhSA3pqk', # nopep8 'T3MWHKyN3BVcQ67wLR5H7rsJx3bhmbichmz3p38FeCrTjXE9Xbup', 'Ltub2ZPJ67DAyBv615tdwcSAwYNKqXbBrPVLKUVavU3wHEowrdZUUrWj3KzBmoW21GQSDZBNjMs2SZ2bdBREZLH3HcHT7W2DT6DZiNsNtsEZfqF', # nopep8 '03b855e07eb1837015cbd465b921fb476f99b38cf575f61ec7f594f839f42b5057', # nopep8 'Lbqhtn3eQTiyYKWvktnxGsgSa3bEa4kNrH' ] key = (self.master_key.get_child(0). get_child(2147483647, True). get_child(1)) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0_2147483647p_1_2147483646p(self): vector = [ 'Ltpv7A8P4c3YUGWoxQAsSeGJfm45zJW5fRcVqcvo9a1RifrR2z2EokC4JUnfb23mZDG1a5obbdA3KyfriaxfxdeiCCszjUwy4Tnx4NyZJhg2TXZ', # nopep8 'T3JRr9ymVwWqVhsed96q3hcmKVgmqw2SKGQWepCkCTEmS8bDGRiL', 'Ltub2bJifPU5iR3maGshhFkgkLtJRsCGjgB9v92ppYmiere1dMDK8fEVK5tvqR9xBf37tXswdRY7T92jbT9L1borcpBXMhYe2cxiKB3HTCtKJf4', # nopep8 '031b189497b7661fb452af508ee3e014aaac34b366fc4ea178573bf9263a824bc6', # nopep8 'LPeSxqQM6qyFVAutnGwRDZbABLSMK7gtDD' ] key = (self.master_key.get_child(0) .get_child(2147483647, True) .get_child(1) .get_child(2147483646, True)) self._test(key, *vector) self._test_deserialize(key, *vector) def test_m_0_2147483647p_1_2147483646p_2(self): vector = [ 'Ltpv7B2Va6jguSVYkxsVaYVykvfVURqLTNQVn2pYs6MHFzVtFHPUAgCqbCMChCFPmvjDKfFJZQBmyztATaZTeLpaSvpP6zcaY5DJD5Qcr66MjTW', # nopep8 'T6u7ZdbVd4B8KWuiTdirhwJ5NNrHG73WWVatXtktmGayPERcFMMa', 'Ltub2cCqAtAE9b2WNqaKq9zMqWVhuzXXXcy9rYvaY57aCBHUqeaYVbFGboTTwbhrJc6SezAA3mrUEKi3qey31HZHDnFfcwXYtkD3dbswWCRyKQu', # nopep8 '03b47c7d3f7eb51023206f636276fe6c3a0c51752360b12ec556b86849ca47b3fe', # nopep8 'Ld5QMVg5tych8UKBBs1Q2LxbbVFASfv3tf' ] key = (self.master_key.get_child(0) .get_child(2147483647, True) .get_child(1) .get_child(2147483646, True) .get_child(2)) self._test(key, *vector) self._test_deserialize(key, *vector)