def main(): # generate 16 bytes of entropy and # convert to a mnemonic phrase (12 words) entropy = bytes([urandom.getrandbits(8) for i in range(16)]) mnemonic = bip39.mnemonic_from_bytes(entropy) # or just define hardcoded: mnemonic = "alien visual jealous source coral memory embark certain radar capable clip edit" print(mnemonic) # convert to seed, empty password seed = bip39.mnemonic_to_seed(mnemonic) # convert to the root key # you can define the version - x/y/zprv for desired network root = bip32.HDKey.from_seed(seed, version=NETWORKS["test"]["xprv"]) print(root.to_base58()) print("\nBIP-44 - legacy") # derive account according to bip44 bip44_xprv = root.derive("m/44h/1h/0h") print(bip44_xprv.to_base58()) # corresponding master public key: bip44_xpub = bip44_xprv.to_public() print(bip44_xpub.to_base58()) # first 5 receiving addresses for i in range(5): # .key member is a public key for HD public keys # and a private key for HD private keys pub = bip44_xpub.derive("m/0/%d" % i).key sc = script.p2pkh(pub) print(sc.address(NETWORKS["test"])) print("\nBIP-84 - native segwit") # derive account according to bip84 bip84_xprv = root.derive("m/84h/1h/0h") # you can also change version of the key to get zpub (vpub on testnet) bip84_xprv.version = NETWORKS["test"]["zprv"] print(bip84_xprv.to_base58()) # corresponding master public key: bip84_xpub = bip84_xprv.to_public() print(bip84_xpub.to_base58()) # first 5 receiving addresses for i in range(5): pub = bip84_xpub.derive("m/0/%d" % i).key sc = script.p2wpkh(pub) print(sc.address(NETWORKS["test"])) print("\nBIP-49 - nested segwit") # derive account according to bip49 bip49_xprv = root.derive("m/49h/1h/0h") # you can also change version of the key to get ypub (upub on testnet) bip49_xprv.version = NETWORKS["test"]["yprv"] print(bip49_xprv.to_base58()) # corresponding master public key: bip49_xpub = bip49_xprv.to_public() print(bip49_xpub.to_base58()) # first 5 receiving addresses for i in range(5): pub = bip49_xpub.derive("m/0/%d" % i).key # use p2sh(p2wpkh(pubkey)) to get nested segwit scriptpubkey sc = script.p2sh(script.p2wpkh(pub)) print(sc.address(NETWORKS["test"]))
def generate_new_wallet(self) -> str: # Get entropy from hardware rng and environmental entropy rng_entropy = os.urandom(64) adc = pyb.ADC("A0") env_entropy = bytes(adc.read() % 256 for i in range(2048)) entropy = hashlib.sha256(rng_entropy + env_entropy).digest()[:16] recovery_phrase = mnemonic_from_bytes(entropy) return recovery_phrase.split(" ")
async def _get_mnemonic(self): await self.check_card(check_pin=True) if not self._is_key_saved: raise KeyStoreError("Key is not saved") self.show_loader("Loading secret to the card...") data = self.applet.get_secret() d, _ = self.parse_data(data) entropy = d["entropy"] return bip39.mnemonic_from_bytes(entropy)
async def load_mnemonic(self): await self.check_card(check_pin=True) if not self._is_key_saved: raise KeyStoreError("Key is not saved") data = self.applet.get_secret() entropy = self.parse_data(data)["entropy"] mnemonic = bip39.mnemonic_from_bytes(entropy) self.set_mnemonic(mnemonic, "") return True
def test_bip39(self): for [seed, exp_mnemonic, hex_seed, xprv] in VECTORS: act_mnemonic = mnemonic_from_bytes(unhexlify(seed)) act_xkey = HDKey.from_seed( mnemonic_to_seed(act_mnemonic, password="******")) self.assertEqual(act_mnemonic, exp_mnemonic) self.assertTrue(mnemonic_is_valid(act_mnemonic)) self.assertEqual( hexlify(mnemonic_to_bytes(act_mnemonic)).decode(), seed) self.assertEqual(act_xkey.to_base58(), xprv)
def init_keys(password): mnemonic = bip39.mnemonic_from_bytes(entropy) seed = bip39.mnemonic_to_seed(mnemonic, password) keystore.load_seed(seed) # choose testnet by default select_network("test") gc.collect() show_main() if usb_host.callback is None: usb_host.callback = host_callback
async def show_card_info(self): note = "Card fingerprint: %s" % self.hexid version = "%s v%s" % (self.applet.NAME, self.applet.version) platform = self.applet.platform data = self.applet.get_secret() key_saved = len(data) > 0 encrypted = True decryptable = True same_mnemonic = False if key_saved: try: d, encrypted = self.parse_data(data) if "entropy" in d: self._is_key_saved = True same_mnemonic = (self.mnemonic == bip39.mnemonic_from_bytes( d["entropy"])) except KeyStoreError as e: decryptable = False # yes = lv.SYMBOL.OK+" Yes" # no = lv.SYMBOL.CLOSE+" No" yes = "Yes" no = "No" props = [ "\n#7f8fa4 PLATFORM #", "Implementation: %s" % platform, "Version: %s" % version, "\n#7f8fa4 KEY INFO: #", "Key saved: " + (yes if key_saved else no), ] if key_saved: if decryptable: props.append("Same as current key: " + (yes if same_mnemonic else no)) props.append("Encrypted: " + (yes if encrypted else no)) if encrypted: props.append("Decryptable: " + (yes if decryptable else no)) scr = Alert("Smartcard info", "\n\n".join(props), note=note) scr.message.set_recolor(True) await self.show(scr)
def gen_mnemonic(num_words: int) -> str: """Generates a mnemonic with num_words""" if num_words < 12 or num_words > 24 or num_words % 3 != 0: raise RuntimeError("Invalid word count") return bip39.mnemonic_from_bytes(rng.get_random_bytes(num_words * 4 // 3))
def test_fix_checksum(self): invalid_mnemonic = ("ghost " * 12).strip() self.assertRaises(ValueError, mnemonic_to_bytes, invalid_mnemonic) entropy = mnemonic_to_bytes(invalid_mnemonic, ignore_checksum=True) valid_mnemonic = mnemonic_from_bytes(entropy) self.assertEqual(valid_mnemonic, "ghost " * 11 + "gentle")
def test_invalid_seed(self): seed = "0000000000000000000000000000000042" self.assertRaises(ValueError, lambda x: mnemonic_from_bytes(unhexlify(x)), seed)
adc_entropy = bytes([adc.read() % 256 for i in range(200)]) entropy = hashlib.sha256(trng_entropy + adc_entropy).digest()[:16] print("Final entropy:", hexlify(entropy).decode()) with open(ENTROPY_FILE, "wb") as f: f.write(entropy) print("Entropy saved") #################################### # # # key generation - part 2 # # # #################################### ################# BIP-39 ##################### phrase = bip39.mnemonic_from_bytes(entropy) print("Your recovery phrase:\n%s\n" % phrase) # uncomment this line to make invalid mnemonic: # phrase += " satoshi" # you can check if recovery phrase is valid or not: if not bip39.mnemonic_is_valid(phrase): raise ValueError("Meh... Typo in the recovery?") # convert mnemonic and password to bip-32 seed seed = bip39.mnemonic_to_seed(phrase, password="******") print("Seed:", hexlify(seed).decode()) ################# BIP-32 #####################
def fix_mnemonic(phrase): entropy = bip39.mnemonic_to_bytes(phrase, ignore_checksum=True) return bip39.mnemonic_from_bytes(entropy)
def fix_mnemonic(phrase): """Fixes checksum of invalid mnemonic""" entropy = bip39.mnemonic_to_bytes(phrase, ignore_checksum=True) return bip39.mnemonic_from_bytes(entropy)
def get_new_mnemonic(words=12): entropy_len = words*4//3 global entropy entropy = get_random_bytes(entropy_len) return bip39.mnemonic_from_bytes(entropy)
def show_mnemonic(): # print(bip39.mnemonic_from_bytes(entropy)) popups.show_mnemonic(bip39.mnemonic_from_bytes(entropy))