def test_from_ex_key(self): for test in TEST_VECT_BIP32: # Create from private extended key bip32_ctx = Bip32.FromExtendedKey(test["master"]["ex_priv"]) # Test master key self.assertEqual(test["master"]["ex_pub"] , bip32_ctx.PublicKey().ToExtended()) self.assertEqual(test["master"]["ex_priv"], bip32_ctx.PrivateKey().ToExtended()) # Same test for derivation paths for chain in test["der_paths"]: # Create from private extended key bip32_ctx = Bip32.FromExtendedKey(chain["ex_priv"]) # Test keys self.assertEqual(chain["ex_pub"] , bip32_ctx.PublicKey().ToExtended()) self.assertEqual(chain["ex_priv"], bip32_ctx.PrivateKey().ToExtended())
def test_public_derivation(self): # Construct from extended private key bip32_ctx = Bip32.FromExtendedKey(TEST_PUBLIC_DER_MAIN["ex_priv"]) # Shall not be public self.assertFalse(bip32_ctx.IsPublicOnly()) # Convert to public bip32_ctx.ConvertToPublic() # Shall be public and the public key shall be correct self.assertTrue(bip32_ctx.IsPublicOnly()) self.assertEqual(TEST_PUBLIC_DER_MAIN["ex_pub"], bip32_ctx.PublicKey().ToExtended()) # Getting the private key shall raise an exception self.assertRaises(Bip32KeyError, bip32_ctx.PrivateKey) self.assertRaises(Bip32KeyError, bip32_ctx.EcdsaPrivateKey) # Test derivation paths for test in TEST_PUBLIC_DER_MAIN["der_paths"]: # Public derivation does not support hardened indexes if Bip32Utils.IsHardenedIndex(test["index"]): self.assertRaises(Bip32KeyError, bip32_ctx.ChildKey, test["index"]) else: bip32_ctx = bip32_ctx.ChildKey(test["index"]) self.assertEqual(test["ex_pub"], bip32_ctx.PublicKey().ToExtended())
def from_private_key(priv: bytes, chain_code: bytes): ''' Construct an HD Node from a private key. Parameters ---------- priv : bytes The privte key in bytes. chain_code : bytes 32 bytes of random number you choose. Returns ------- HDNode A new HDNode. ''' # print('input priv', len(priv)) # parts net_version = VERSION_MAINNET_PRIVATE depth = DEPTH_MASTER_NODE fprint = FINGER_PRINT_MASTER_KEY index = CHILD_NUMBER_MASTER_KEY chain = chain_code key_bytes = b'\x00' + priv # assemble all_bytes = net_version + depth + fprint + index + chain + key_bytes # double sha-256 checksum xpriv = Base58Encoder.CheckEncode(all_bytes) bip32_ctx = Bip32.FromExtendedKey(xpriv) return HDNode(bip32_ctx)
def new_oas_address( user_id: str, use_ex_priv: Optional[bool] = False) -> Tuple[str, str, str]: hash = hashlib.md5(user_id.encode('utf-8')).digest() #base i.e "m/44'/60'/0'" bip32 = Bip32.FromExtendedKey( oas_config.get("EXTENDED_PUBKEY") if not use_ex_priv else oas_config. get("EXTENDED_PRIVKEY")) d_path = oas_config.get("EXTENDED_PATH") for i in range(2): a = struct.unpack('<L', hash[i * 4:(i + 1) * 4]) idx = a[0] % 1000000 bip32 = bip32.ChildKey(idx) d_path = d_path + "/" + str(idx) #now "m/44'/60'/0'/a1/a2", should be treated as geth like key(i.e. only private key use used, not true HD wallet at this level. a = BipPublicKey( bip32, Bip44Coins.ETHEREUM) if not use_ex_priv else BipPrivateKey( bip32, Bip44Coins.ETHEREUM) b = a.ToExtended() z = py_cryto_hd_wallet_fact.CreateFromExtendedKey("aa", b) z.Generate() c = z.ToDict() return c["addresses"]["address_1"]["address"], d_path, c["addresses"][ "address_1"]["raw_priv"] if use_ex_priv else None
def from_public_key(pub: bytes, chain_code: bytes): ''' Construct an HD Node from an uncompressed public key. (starts with 0x04 as first byte) Parameters ---------- pub : bytes An uncompressed public key in bytes. chain_code : bytes 32 bytes Returns ------- HDNode A new HDNode. ''' # parts net_version = VERSION_MAINNET_PUBLIC depth = DEPTH_MASTER_NODE fprint = FINGER_PRINT_MASTER_KEY index = CHILD_NUMBER_MASTER_KEY chain = chain_code key_bytes = KeyAPI.PublicKey(strip_0x04(pub)).to_compressed_bytes() # assemble all_bytes = net_version + depth + fprint + index + chain + key_bytes # double sha-256 checksum xpub_str = Base58Encoder.CheckEncode(all_bytes) bip32_ctx = Bip32.FromExtendedKey(xpub_str) return HDNode(bip32_ctx)