def test_from_seed_and_path(self): for test in TEST_VECT_BIP32: # Create from seed bip32_ctx = Bip32.FromSeedAndPath(binascii.unhexlify(test["seed"]), "m") # Test master key self.assertEqual(test["master"]["ex_pub"] , bip32_ctx.PublicKey().ToExtended()) self.assertEqual(test["master"]["ex_priv"], bip32_ctx.PrivateKey().ToExtended()) # Test derivation paths for chain in test["der_paths"]: # Try to build from path and test again bip32_from_path = Bip32.FromSeedAndPath(binascii.unhexlify(test["seed"]), chain["path"]) # Test keys self.assertEqual(chain["ex_pub"] , bip32_from_path.PublicKey().ToExtended()) self.assertEqual(chain["ex_priv"], bip32_from_path.PrivateKey().ToExtended())
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 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)
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_mnemonic(words: List[str], init_path=VET_EXTERNAL_PATH): ''' Construct an HD Node from a set of words. The init_path is m/44'/818'/0'/0 by default on VeChain. Note ---- The words will generate a seed, which will be further developed into a "m" secret key and "chain code". Parameters ---------- words : List[str] Mnemonic words, usually 12 words. init_path : str, optional The initial derivation path, by default VET_EXTERNAL_PATH Returns ------- HDNode A new HDNode. ''' seed = derive_seed(words) # 64 bytes bip32_ctx = Bip32.FromSeedAndPath(seed, init_path) return HDNode(bip32_ctx)
def from_seed(seed: bytes, init_path=VET_EXTERNAL_PATH): ''' Construct an HD Node from a seed (64 bytes). The init_path is m/44'/818'/0'/0 for starting. or you can simply put in 44'/818'/0'/0 Note ---- The seed will be further developed into a "m" secret key and "chain code". Parameters ---------- seed : bytes Seed itself. init_path : str, optional The derive path, by default VET_EXTERNAL_PATH Returns ------- HDNode A new HDNode. ''' bip32_ctx = Bip32.FromSeedAndPath(seed, init_path) return HDNode(bip32_ctx)
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 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 get_addresses_from(mnemonic): seed_bytes = Bip39SeedGenerator(mnemonic).Generate() addresses = [] # TODO: manually derive last index from one parent to save some time, allow other derive paths for i in range(0, options.indices - 1): bip32_ctx = Bip32.FromSeedAndPath(seed_bytes, f"m/0'/2'/{i}") key = Key(bip32_ctx.PrivateKey().Raw().ToHex()) addresses.append(key.address) return addresses
def test_invalid_paths(self): seed = binascii.unhexlify(b"000102030405060708090a0b0c0d0e0f") for test in TEST_VECT_PATH_INVALID: self.assertEqual([], Bip32PathParser.Parse(test["path"], test["skip_master"])) # Try to derive an invalid path bip32 = Bip32.FromSeed(seed) self.assertRaises(Bip32PathError, bip32.DerivePath, test["path"]) # Try to construct from an invalid path (Bip32.FromSeedAndPath does not skip master) if not test["skip_master"]: self.assertRaises(Bip32PathError, Bip32.FromSeedAndPath, b"", test["path"])
def get_account_from_words(words: str, index: int = 0, hd_path: str = ETHEREUM_PATH) -> Account: """ :param words: Mnemonic words generated using Bip39 :param index: Index of account :param hd_path: Bip44 Path. By default Ethereum is used :return: List of ethereum public addresses """ seed = Bip39SeedGenerator(words).Generate() bip32_ctx = Bip32.FromSeedAndPath(seed, hd_path) return Account.from_key( bip32_ctx.ChildKey(index).PrivateKey().Raw().ToBytes())
def test_from_seed_with_derive_path(self): for test in TEST_VECT_BIP32: # Create from seed bip32_ctx = Bip32.FromSeed(binascii.unhexlify(test["seed"])) # Test master key self.assertEqual(test["master"]["ex_pub"] , bip32_ctx.PublicKey().ToExtended()) self.assertEqual(test["master"]["ex_priv"], bip32_ctx.PrivateKey().ToExtended()) # Test derivation paths for chain in test["der_paths"]: # Update context bip32_from_path = bip32_ctx.DerivePath(chain["path"][2:]) # Test keys self.assertEqual(chain["ex_pub"] , bip32_from_path.PublicKey().ToExtended()) self.assertEqual(chain["ex_priv"], bip32_from_path.PrivateKey().ToExtended())
def get_address_from_words(words: str, index: int = 0, hd_path: str = ETHEREUM_PATH) -> str: """ :param words: Mnemonic words generated using Bip39 :param index: Index of account :param hd_path: Bip44 Path. By default Ethereum is used :return: List of ethereum public addresses """ seed = Bip39SeedGenerator(words).Generate() bip32_ctx = Bip32.FromSeedAndPath(seed, hd_path) pub_key = bip32_ctx.ChildKey(index).m_ver_key.pubkey return checksum_encode( sha3( encode_int32(pub_key.point.x()) + encode_int32(pub_key.point.y()))[12:])
def generate_bitcoin_wallet(query_params={}): if blockchain_validator.generate_litecoin_wallet(query_params): if query_params != {}: mnemonic = query_params['mnemonic'] else: mnemonic = wallet.generate_mnemonic(strength=256) if Bip39MnemonicValidator(mnemonic).Validate(): seed_bytes = Bip39SeedGenerator(mnemonic).Generate() bip32_ctx = Bip32.FromSeedAndPath(seed_bytes, "m/44'/0'/0'/0") return { "xpriv": bip32_ctx.PrivateKey().ToExtended(), "xpub": bip32_ctx.PublicKey().ToExtended(), "mnemonic": mnemonic } else: return 'Mnemonic is not valid!'
def test_from_seed_with_child_key(self): for test in TEST_BIP32_MAIN: # Create from seed bip32_ctx = Bip32.FromSeed(binascii.unhexlify(test["seed"])) # Test master key self.assertEqual(test["master"]["ex_pub"], bip32_ctx.PublicKey().ToExtended()) self.assertEqual(test["master"]["ex_priv"], bip32_ctx.PrivateKey().ToExtended()) # Test derivation paths for chain in test["der_paths"]: # Update context bip32_ctx = bip32_ctx.ChildKey(chain["index"]) # Test keys self.assertEqual(chain["ex_pub"], bip32_ctx.PublicKey().ToExtended()) self.assertEqual(chain["ex_priv"], bip32_ctx.PrivateKey().ToExtended())
def mnemonic_to_private_key(mnemonic, network, pass_phrase=''): """Convert mnemonic (phrase) to a private key :param mnemonic: A phrase :type mnemonic: str :param network: testnet or mainnet :type mnemonic: str :param pass_phrase: A password :type pass_phrase: str :returns: private key """ seed = mnemonic_to_seed(mnemonic, pass_phrase) bip32_ctx = Bip32.FromSeed(seed) HD_PATH = get_derive_path( ).testnet if network == "testnet" else get_derive_path().mainnet hd_path = HD_PATH[2:] bip32_ctx = bip32_ctx.DerivePath(hd_path) priv_key = bip32_ctx.PrivateKey().Raw().ToHex() return priv_key
def derive_private_key(words: List[str], index: int = 0) -> bytes: ''' Get a private key from the mnemonic wallet, default to the 0 index of the deviration. (first key) Parameters ---------- words : List[str] A list of english words. index : int, optional The private key index, first private key., by default 0 Returns ------- bytes [description] ''' seed = derive_seed(words) bip32_ctx = Bip32.FromSeedAndPath(seed, _get_vet_key_path(index)) return bip32_ctx.PrivateKey().Raw().ToBytes()
def generate_uuid(mnemonic, passphrase=""): # At this point the Cobo Vault hardware is directly using the (secret) # BIP39 mnemonic, converting it to a BIP39 seed value. If one is using a # Shamir (SLIP39) mnemonic a different path is taken to generate these # seed bytes. seed_bytes = Bip39SeedGenerator(mnemonic).Generate(passphrase) # From this point onwards the code is identical whether a BIP39 or SLIP39 # mnemonic. The following extracts the BIP32 Root Key. This is still secret # data that we don't want leaking from the Cobo Vault hardware. bip32_root = Bip32.FromSeed(seed_bytes) # Given the BIP32 root key, derive a BIP32 extended (public/private) keypair, # using Cobo's BIP32 derivation path. Note that this path is only used for # generating the 'UUID' used by the Cobo Vault (and app). For coin-specific # (e.g. Bitcoin etc.) keys the Cobo Vault hardware and App use more typical # hardened paths that are commonly used - E.g. m/49'/0'/0' for bitcoin, # m/44'/60'/0' for Ethereum, etc. Still secret data here! cobo_extend_key = ( bip32_root.ChildKey(Bip32Utils.HardenIndex(44)) .ChildKey(Bip32Utils.HardenIndex(1131373167)) .ChildKey(Bip32Utils.HardenIndex(0)) ) # Up until this point the Cobo Vault hardware has been dealing with secret # information that should never be leaked outside the device, as doing so # would allow stealing of one's keys and thus cryptocurrency. The next step # discards the private key information and extracts the public key only. The # public key can be used to find all transactions associated with a wallet, but # it *cannot* be used to spend (or steal) cryptocurrency. public_key = cobo_extend_key.PublicKey().RawCompressed().ToHex() # After discarding the private (secret) key, compress the public key and remove # a couple bytes to produce the 'uuid'. uuid = public_key[2:] return uuid
def key_from_seed(seed): """Return master private key from this seed""" bip32_ctx = Bip32.FromSeed(seed) return bip32_ctx
from bip_utils import Bip32, Bip39SeedGenerator from binascii import hexlify if len(sys.argv) < 2 or sys.argv[1] == "": print("No mnemonic given") exit(1) mnemonic = sys.argv[1] words = mnemonic.split(" ") print("BIP39 mnemonic starts with: {} {} ...".format(words[0], words[1])) seed_bytes = Bip39SeedGenerator(mnemonic).Generate() print("BIP39 seed: {}".format(hexlify(seed_bytes).decode("utf-8"))) bip32 = Bip32.FromSeed(seed_bytes) print("BIP32 root key: {}".format(bip32.PrivateKey().ToExtended())) derivation_path = "m/44'/60'/0'/0" extended = Bip32.FromSeedAndPath(seed_bytes, derivation_path) print("BIP32 extended public key: {}".format( extended.PublicKey().ToExtended())) print("BIP32 extended private key: {}".format( extended.PrivateKey().ToExtended())) derived_0_path = f"{derivation_path}/0" derived_0_address = extended.DerivePath("0") print("Derived {} public key: {}".format( derived_0_path, derived_0_address.EcdsaPublicKey().RawCompressed().ToHex()))
from avaxpython import Config from avaxpython.utils.formatting.encoding import Encoding from bip_utils import Bip32 import ref import json sample_wallet = next(generator.generate(1, Config.KEY_SIZE)) word_length = len(sample_wallet.split(" ")) if len(sys.argv) != word_length+1: print("Invalid phrase length provided. Got {} expected {}.".format(len(sys.argv)-1, word_length)) exit(1) seed = Mnemonic("english").to_seed(" ".join(sys.argv[1:]), passphrase="") masterHdKey = Bip32.FromSeed(seed) accountHdKey = Bip32.FromSeedAndPath(seed, WalletConfig.AVA_ACCOUNT_PATH) # the first private key generated by an HD wallet seeded from this mnemonic phrase firstHDKey = BIP32.derive_master_key(accountHdKey, '0/0') masterKey = masterHdKey.PrivateKey().Raw().ToBytes() accountKey = accountHdKey.PrivateKey().Raw().ToBytes() firstKey = firstHDKey.PrivateKey().Raw().ToBytes() enc = Encoding() pkey_prefix = "PrivateKey-{}" masterKeyEncoded = pkey_prefix.format(enc.Encode(masterKey)) accountKeyEncoded = pkey_prefix.format(enc.Encode(accountKey)) firstKeyEncoded = pkey_prefix.format(enc.Encode(firstKey))