|
|
@ -9,6 +9,7 @@ from electrum.bitcoin import (public_key_to_p2pkh, address_from_private_key, |
|
|
|
is_compressed_privkey, EncodeBase58Check, DecodeBase58Check, |
|
|
|
script_num_to_hex, push_script, add_number_to_script, int_to_hex, |
|
|
|
opcodes, base_encode, base_decode, BitcoinException) |
|
|
|
from electrum import bip32 |
|
|
|
from electrum.bip32 import (BIP32Node, convert_bip32_intpath_to_strpath, |
|
|
|
xpub_from_xprv, xpub_type, is_xprv, is_bip32_derivation, |
|
|
|
is_xpub, convert_bip32_path_to_list_of_uint32, |
|
|
@ -457,6 +458,77 @@ class Test_xprv_xpub(ElectrumTestCase): |
|
|
|
self.assertEqual("m/0/2/1'", normalize_bip32_derivation("m/0/2/-1/")) |
|
|
|
self.assertEqual("m/0/1'/1'/5'", normalize_bip32_derivation("m/0//-1/1'///5h")) |
|
|
|
|
|
|
|
def test_is_xkey_consistent_with_key_origin_info(self): |
|
|
|
### actual data (high depth path) |
|
|
|
self.assertTrue(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"Zpub75NQordWKAkaF7utBw95GEodyxqwFdR3idtTqQtrvWkYFeiuYdg5c3Q9L9bLjPLhEahLCTjmmS2YQcXPwr6twYCEJ55k6uhE5JxRqvUowmd", |
|
|
|
derivation_prefix="m/48'/1'/0'/2'", |
|
|
|
root_fingerprint="b2768d2f")) |
|
|
|
# ok to skip args |
|
|
|
self.assertTrue(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"Zpub75NQordWKAkaF7utBw95GEodyxqwFdR3idtTqQtrvWkYFeiuYdg5c3Q9L9bLjPLhEahLCTjmmS2YQcXPwr6twYCEJ55k6uhE5JxRqvUowmd", |
|
|
|
derivation_prefix="m/48'/1'/0'/2'")) |
|
|
|
self.assertTrue(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"Zpub75NQordWKAkaF7utBw95GEodyxqwFdR3idtTqQtrvWkYFeiuYdg5c3Q9L9bLjPLhEahLCTjmmS2YQcXPwr6twYCEJ55k6uhE5JxRqvUowmd", |
|
|
|
root_fingerprint="b2768d2f")) |
|
|
|
# path changed: wrong depth |
|
|
|
self.assertFalse(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"Zpub75NQordWKAkaF7utBw95GEodyxqwFdR3idtTqQtrvWkYFeiuYdg5c3Q9L9bLjPLhEahLCTjmmS2YQcXPwr6twYCEJ55k6uhE5JxRqvUowmd", |
|
|
|
derivation_prefix="m/48'/0'/2'", |
|
|
|
root_fingerprint="b2768d2f")) |
|
|
|
# path changed: wrong child index |
|
|
|
self.assertFalse(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"Zpub75NQordWKAkaF7utBw95GEodyxqwFdR3idtTqQtrvWkYFeiuYdg5c3Q9L9bLjPLhEahLCTjmmS2YQcXPwr6twYCEJ55k6uhE5JxRqvUowmd", |
|
|
|
derivation_prefix="m/48'/1'/0'/3'", |
|
|
|
root_fingerprint="b2768d2f")) |
|
|
|
# path changed: but cannot tell |
|
|
|
self.assertTrue(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"Zpub75NQordWKAkaF7utBw95GEodyxqwFdR3idtTqQtrvWkYFeiuYdg5c3Q9L9bLjPLhEahLCTjmmS2YQcXPwr6twYCEJ55k6uhE5JxRqvUowmd", |
|
|
|
derivation_prefix="m/48'/1'/1'/2'", |
|
|
|
root_fingerprint="b2768d2f")) |
|
|
|
# fp changed: but cannot tell |
|
|
|
self.assertTrue(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"Zpub75NQordWKAkaF7utBw95GEodyxqwFdR3idtTqQtrvWkYFeiuYdg5c3Q9L9bLjPLhEahLCTjmmS2YQcXPwr6twYCEJ55k6uhE5JxRqvUowmd", |
|
|
|
derivation_prefix="m/48'/1'/0'/2'", |
|
|
|
root_fingerprint="aaaaaaaa")) |
|
|
|
|
|
|
|
### actual data (depth=1 path) |
|
|
|
self.assertTrue(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"zpub6nsHdRuY92FsMKdbn9BfjBCG6X8pyhCibNP6uDvpnw2cyrVhecvHRMa3Ne8kdJZxjxgwnpbHLkcR4bfnhHy6auHPJyDTQ3kianeuVLdkCYQ", |
|
|
|
derivation_prefix="m/0'", |
|
|
|
root_fingerprint="b2e35a7d")) |
|
|
|
# path changed: wrong depth |
|
|
|
self.assertFalse(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"zpub6nsHdRuY92FsMKdbn9BfjBCG6X8pyhCibNP6uDvpnw2cyrVhecvHRMa3Ne8kdJZxjxgwnpbHLkcR4bfnhHy6auHPJyDTQ3kianeuVLdkCYQ", |
|
|
|
derivation_prefix="m/0'/0'", |
|
|
|
root_fingerprint="b2e35a7d")) |
|
|
|
# path changed: wrong child index |
|
|
|
self.assertFalse(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"zpub6nsHdRuY92FsMKdbn9BfjBCG6X8pyhCibNP6uDvpnw2cyrVhecvHRMa3Ne8kdJZxjxgwnpbHLkcR4bfnhHy6auHPJyDTQ3kianeuVLdkCYQ", |
|
|
|
derivation_prefix="m/1'", |
|
|
|
root_fingerprint="b2e35a7d")) |
|
|
|
# fp changed: can tell |
|
|
|
self.assertFalse(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"zpub6nsHdRuY92FsMKdbn9BfjBCG6X8pyhCibNP6uDvpnw2cyrVhecvHRMa3Ne8kdJZxjxgwnpbHLkcR4bfnhHy6auHPJyDTQ3kianeuVLdkCYQ", |
|
|
|
derivation_prefix="m/0'", |
|
|
|
root_fingerprint="aaaaaaaa")) |
|
|
|
|
|
|
|
### actual data (depth=0 path) |
|
|
|
self.assertTrue(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"xpub661MyMwAqRbcFWohJWt7PHsFEJfZAvw9ZxwQoDa4SoMgsDDM1T7WK3u9E4edkC4ugRnZ8E4xDZRpk8Rnts3Nbt97dPwT52CwBdDWroaZf8U", |
|
|
|
derivation_prefix="m", |
|
|
|
root_fingerprint="48adc7a0")) |
|
|
|
# path changed: wrong depth |
|
|
|
self.assertFalse(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"xpub661MyMwAqRbcFWohJWt7PHsFEJfZAvw9ZxwQoDa4SoMgsDDM1T7WK3u9E4edkC4ugRnZ8E4xDZRpk8Rnts3Nbt97dPwT52CwBdDWroaZf8U", |
|
|
|
derivation_prefix="m/0", |
|
|
|
root_fingerprint="48adc7a0")) |
|
|
|
# fp changed: can tell |
|
|
|
self.assertFalse(bip32.is_xkey_consistent_with_key_origin_info( |
|
|
|
"xpub661MyMwAqRbcFWohJWt7PHsFEJfZAvw9ZxwQoDa4SoMgsDDM1T7WK3u9E4edkC4ugRnZ8E4xDZRpk8Rnts3Nbt97dPwT52CwBdDWroaZf8U", |
|
|
|
derivation_prefix="m", |
|
|
|
root_fingerprint="aaaaaaaa")) |
|
|
|
|
|
|
|
def test_is_all_public_derivation(self): |
|
|
|
self.assertFalse(is_all_public_derivation("m/0/1'/1'")) |
|
|
|
self.assertFalse(is_all_public_derivation("m/0/2/1'")) |
|
|
|