def generate(cls, path=DEFAULT_DERIVATION_PATH) -> (str, "PrivateKey"): """ Generate new private key with random mnemonic phrase :param path: the HD path that follows the BIP32 standard :return: A tuple of mnemonic phrase and PrivateKey instance """ while True: phrase = Mnemonic(language="english").generate(strength=256) try: return (phrase, cls.from_mnemonic(phrase)) except BIP32DerivationError: pass
def test_sorted_unique(self): # Check for duplicated words in wordlist print("------------------------------------") print("Test of sorted and unique wordlists:") languages = Mnemonic.list_languages() for lang in languages: mnemo = Mnemonic(lang) unique = list(set(mnemo.wordlist)) unique.sort() print("Language '{}'".format(lang)) self.assertListEqual(unique, mnemo.wordlist)
def test_expand_word(self): m = Mnemonic("english") self.assertEqual("", m.expand_word("")) self.assertEqual(" ", m.expand_word(" ")) self.assertEqual("access", m.expand_word("access")) # word in list self.assertEqual( "access", m.expand_word("acce") ) # unique prefix expanded to word in list self.assertEqual("acb", m.expand_word("acb")) # not found at all self.assertEqual("acc", m.expand_word("acc")) # multi-prefix match self.assertEqual("act", m.expand_word("act")) # exact three letter match self.assertEqual( "action", m.expand_word("acti") ) # unique prefix expanded to word in list
def new_device_mnemonic(device_type): err = None strength = 128 mnemonic = generate_mnemonic(strength=strength) existing_device = None if request.method == "POST": if len(request.form["mnemonic"].split(" ")) not in [ 12, 15, 18, 21, 24 ]: err = "Invalid mnemonic entered: Must contain either: 12, 15, 18, 21, or 24 words." mnemo = Mnemonic("english") if not mnemo.check(request.form["mnemonic"]): err = "Invalid mnemonic entered." range_start = int(request.form["range_start"]) range_end = int(request.form["range_end"]) if range_start > range_end: err = "Invalid address range selected." mnemonic = request.form["mnemonic"] passphrase = request.form["passphrase"] file_password = request.form["file_password"] existing_device = request.form.get("existing_device", None) if existing_device: existing_device = app.specter.device_manager.get_by_alias( existing_device) if not err: return render_template( "device/new_device/new_device_keys.jinja", device_class=get_device_class(device_type), mnemonic=mnemonic, passphrase=passphrase, file_password=file_password, range_start=range_start, range_end=range_end, existing_device=existing_device, error=err, specter=app.specter, rand=rand, ) return render_template( "device/new_device/new_device_mnemonic.jinja", device_type=device_type, strength=strength, mnemonic=mnemonic, existing_device=existing_device, error=err, specter=app.specter, rand=rand, )
def test_reset_device(self): # No PIN, no passphrase external_entropy = 'zlutoucky kun upel divoke ody' * 2 strength = 128 ret = self.client.call_raw(proto.ResetDevice(display_random=False, strength=strength, passphrase_protection=False, pin_protection=False, language='english', label='test')) # Provide entropy self.assertIsInstance(ret, proto.EntropyRequest) internal_entropy = self.client.debug.read_reset_entropy() resp = self.client.call_raw(proto.EntropyAck(entropy=external_entropy)) # Generate mnemonic locally entropy = generate_entropy(strength, internal_entropy, external_entropy) expected_mnemonic = Mnemonic('english').to_mnemonic(entropy) mnemonic = [] while isinstance(resp, proto.ButtonRequest): mnemonic.append(self.client.debug.read_reset_word()) self.client.debug.press_yes() resp = self.client.call_raw(proto.ButtonAck()) mnemonic = ' '.join(mnemonic) # Compare that device generated proper mnemonic for given entropies self.assertEqual(mnemonic, expected_mnemonic) self.assertIsInstance(resp, proto.Success) # Compare that second pass printed out the same mnemonic once again self.assertEqual(mnemonic, expected_mnemonic) # Check if device is properly initialized resp = self.client.call_raw(proto.Initialize()) self.assertFalse(resp.pin_protection) self.assertFalse(resp.passphrase_protection) # Do passphrase-protected action, PassphraseRequest should NOT be raised resp = self.client.call_raw(proto.Ping(passphrase_protection=True)) self.assertIsInstance(resp, proto.Success) # Do PIN-protected action, PinRequest should NOT be raised resp = self.client.call_raw(proto.Ping(pin_protection=True)) self.assertIsInstance(resp, proto.Success)
def __init__(self): conf = read_config_file("ew.conf") if conf['entropy']: entropy = binascii.unhexlify(conf['entropy']) else: mnemo = Mnemonic('english') entropy = mnemo.to_entropy(conf['passphrase']) print("entropy=" + entropy.hex()) master = BIP32Node.from_master_secret(entropy, 'BTC') print("master address=" + master.address()) # /m/4544288'/0'/0'/0/0 alias alias = master.subkey(i=EW_DERIVATION, is_hardened=True).subkey(i=0, is_hardened=True).subkey(i=0, is_hardened=True).subkey(i=0, is_hardened=False).subkey(i=0, is_hardened=False) self.address = alias.address() print("alias address=" + self.address) self.key = CBitcoinSecret(alias.wif())
def create_peer(self, network): wallet = HDWallet(gap_limit=2) wallet._manually_initialize() manager = super().create_peer(network, wallet=wallet) manager.reactor = self.clock manager.test_mode = False manager.avg_time_between_blocks = 64 # Don't use it anywhere else. It is unsafe to generate mnemonic words like this. # It should be used only for testing purposes. m = Mnemonic('english') words = m.to_mnemonic(bytes(random.randint(0, 255) for _ in range(32))) wallet.unlock(words=words, tx_storage=manager.tx_storage) return manager
def wallet_data_to_seed(self, data): if data is None: return None self.mnemonic_extension = None if isinstance(data, tuple): entropy, self.mnemonic_extension = data else: entropy = data if get_network() == "testnet": if entropy.startswith("FAKESEED"): return entropy[8:] self.entropy = entropy.decode('hex') m = Mnemonic("english") return m.to_seed(m.to_mnemonic(self.entropy), '' if not self.mnemonic_extension else self.mnemonic_extension).encode('hex')
def page5_import_account_is_complete(self): words = self.edit_seed.toPlainText() if not words: self.edit_seed.setStyleSheet('background-color: white;') return False validator = Mnemonic('english') if validator.check(words): self.edit_seed.setStyleSheet('background-color: #c4df9b;') self._mnemonic = words return True else: self.edit_seed.setStyleSheet('background-color: #fff79a;') return False
def generate_keys(mn): m = Mnemonic(language='english') seed = m.to_seed(mn, "") mk = bip32_master_key(seed) bitcoin_priv = bip32_ckd(bip32_ckd(bip32_ckd(mk, 44 + 2**31), 2**31), 2**31) ethereum_priv = bip32_ckd(bip32_ckd(bip32_ckd(mk, 44 + 2**31), 60 + 2**31), 2**31) print("Bitcoin PrivKey : {}".format(bitcoin_priv)) print("Ethereum PrivKey : {}".format(ethereum_priv)) # os.environ['CASHIER_PUB_BTC'] = bip32_privtopub( bitcoin_priv) # os.environ['CASHIER_PUB_ETH'] = bip32_privtopub( ethereum_priv) return (bitcoin_priv, ethereum_priv)
def __init__( self, mnemonic: str, account: int = 0, index: int = 0, coin_type: int = LUNA_COIN_TYPE, ): self.mnemonic = mnemonic seed = Mnemonic("english").to_seed(self.mnemonic) root = derive_root(seed) child = derive_child(root, account, index, coin_type) self.account = account self.index = index self._private_key = child.PrivateKey() self._public_key = child.PublicKey()
def test_expand_word(self): m = Mnemonic('english') self.assertEqual('', m.expand_word('')) self.assertEqual(' ', m.expand_word(' ')) self.assertEqual('access', m.expand_word('access')) # word in list self.assertEqual( 'access', m.expand_word('acce')) # unique prefix expanded to word in list self.assertEqual('acb', m.expand_word('acb')) # not found at all self.assertEqual('acc', m.expand_word('acc')) # multi-prefix match self.assertEqual('act', m.expand_word('act')) # exact three letter match self.assertEqual( 'action', m.expand_word('acti')) # unique prefix expanded to word in list
def recovery_device(hw_device_id: str, word_count: int, passphrase_enabled: bool, pin_enabled: bool, hw_label: str) \ -> Tuple[str, bool]: """ :param hw_device_id: :param passphrase_enbled: :param pin_enbled: :param hw_label: :return: Tuple [0]: Device id. If a device is wiped before initializing with mnemonics, a new device id is generated. It's returned to the caller. [1]: True, if the user cancelled the operation. In this case we deliberately don't raise the 'cancelled' exception, because in the case of changing of the device id (when wiping) we want to pass the new device id back to the caller. """ mnem = Mnemonic('english') def ask_for_word(type): nonlocal mnem msg = "Enter one word of mnemonic: " word = ask_for_word_callback(msg, mnem.wordlist) if not word: raise exceptions.Cancelled return word client = None try: client = connect_trezor(hw_device_id) if client: if client.features.initialized: device.wipe(client) hw_device_id = client.features.device_id device.recover(client, word_count, passphrase_enabled, pin_enabled, hw_label, language='english', input_callback=ask_for_word) return hw_device_id, False else: raise Exception('Couldn\'t connect to Trezor device.') except exceptions.Cancelled: return hw_device_id, True except CancelException: return hw_device_id, True # cancelled by user finally: if client: client.close()
def validate(words: List[str]) -> bool: ''' Check if the words form a valid BIP39 mnemonic words. Parameters ---------- words : List[str] A list of english words. Returns ------- bool True/False ''' sentence = ' '.join(words) return Mnemonic('english').check(sentence)
def validate_mnemonic(mnemonic, language='english'): m = Mnemonic(language) mnemonic = m.normalize_string(mnemonic).split(' ') if len(mnemonic) not in [12, 15, 18, 21, 24]: raise ValueError( 'Number of words must be one of the following: [12, 15, 18, 21, 24], but it is not (%d).' % len(mnemonic)) idx = map(lambda x: bin(m.wordlist.index(x))[2:].zfill(11), mnemonic) b = ''.join(idx) l = len(b) d = b[:l // 33 * 32] h = b[-l // 33:] nd = binascii.unhexlify(hex(int(d, 2))[2:].rstrip('L').zfill(l // 33 * 8)) nh = bin(int(hashlib.sha256(nd).hexdigest(), 16))[2:].zfill(256)[:l // 33] if h != nh: raise ValueError('Failed checksum.')
def create_wallet(testnet=False): path = "m/44'/1'/0'/0/0" if testnet else "m/44'/0'/0'/0/0" mnemo = Mnemonic("english") words = mnemo.generate() seed = mnemo.to_seed(words, passphrase="") bip32 = BIP32.from_seed(seed) privkey = bip32.get_privkey_from_path(path) pubkey = base64.b64encode(bip32.get_pubkey_from_path(path)).decode('utf-8') definition = ['sig', {"pubkey": pubkey}] print(f"privkey: {privkey}") print(f"pubkey: {pubkey}") print(f"address: {get_chash_160(definition)}")
def master_key_from_entropy(passphrase='', strength=128): """Generates a master key from system entropy. strength is the amount of entropy desired, which should be a multiple of 32 between 128 and 256. passphrase is an optional passphrase for the generated mnemonic string. """ if strength % 32 != 0: raise ValueError("strength must be a multiple of 32") if strength < 128 or strength > 256: raise ValueError("strength should be >= 128 and <= 256") entropy = urandom(strength // 8) m = Mnemonic(language='english') n = m.to_mnemonic(entropy) return HDPrivateKey.master_key_from_seed( Mnemonic.to_seed(n, passphrase)), n
def create_wallet(mnemonic, index): w3 = Web3(HTTPProvider("https://kovan.infura.io")) master_key = BIP32Node.from_master_secret( Mnemonic("english").to_seed(mnemonic)) purpose_subtree = master_key.subkey(i=44, is_hardened=True) coin_type_subtree = purpose_subtree.subkey(i=60, is_hardened=True) account_subtree = coin_type_subtree.subkey(i=0, is_hardened=True) change_subtree = account_subtree.subkey(i=0) account = change_subtree.subkey(i=index) private_key = account.secret_exponent().to_bytes(32, 'big') public_key = ecdsa.SigningKey.from_string( string=private_key, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256).get_verifying_key() address = w3.toChecksumAddress("0x" + w3.sha3( hexstr=public_key.to_string().hex())[12:].hex()) return {"address": address, "private_key": private_key.hex()}
def __init__(self, w3, mnemonic, index): self.w3 = w3 master_key = BIP32Node.from_master_secret(Mnemonic("english").to_seed(mnemonic)) purpose_subtree = master_key.subkey(i=44, is_hardened=True) coin_type_subtree = purpose_subtree.subkey(i=60, is_hardened=True) account_subtree = coin_type_subtree.subkey(i=0, is_hardened=True) change_subtree = account_subtree.subkey(i=0) account = change_subtree.subkey(i=index) self.private_key = account.secret_exponent().to_bytes(32, 'big') public_key = ecdsa.SigningKey.from_string(string=self.private_key, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256).get_verifying_key() self.address = self.w3.toChecksumAddress( "0x" + self.w3.sha3(hexstr=public_key.to_string().hex())[12:].hex())
def __init__(self, app): self.app = app # Configure web3 if config.ETHEREUM_JSON_RPC_ENDPOINT.startswith("ws:"): provider = WebsocketProvider(config.ETHEREUM_JSON_RPC_ENDPOINT) else: provider = HTTPProvider(config.ETHEREUM_JSON_RPC_ENDPOINT) self.w3 = Web3(provider) self.w3.eth.enable_unaudited_features( ) # Pending security audit, but required for offline signing of txns # Setup agent contract with open( Path(__file__).absolute().parent.joinpath( "resources", "Agent.json")) as f: abi = json.load(f)["abi"] self.agent = self.w3.eth.contract(address=self.to_checksum_address( config.AGENT_CONTRACT_ADDRESS), abi=abi) if config.PRIVATE_KEY and config.PRIVATE_KEY != "": if config.PRIVATE_KEY.startswith("0x"): self.private_key = bytes( bytearray.fromhex(config.PRIVATE_KEY[2:])) else: self.private_key = bytes(bytearray.fromhex(config.PRIVATE_KEY)) else: # Derive key master_key = bip32utils.BIP32Key.fromEntropy( Mnemonic("english").to_seed(config.HDWALLET_MNEMONIC)) purpose_subtree = master_key.ChildKey(44 + bip32utils.BIP32_HARDEN) coin_type_subtree = purpose_subtree.ChildKey( 60 + bip32utils.BIP32_HARDEN) account_subtree = coin_type_subtree.ChildKey( bip32utils.BIP32_HARDEN) change_subtree = account_subtree.ChildKey(0) account = change_subtree.ChildKey(config.HDWALLET_INDEX) self.private_key = account.PrivateKey() public_key = ecdsa.SigningKey.from_string( string=self.private_key, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256).get_verifying_key() self.address = self.to_checksum_address("0x" + self.w3.sha3( hexstr=public_key.to_string().hex())[12:].hex())
def __init__(self, parent, hw_devices: HWDevices): QWidget.__init__(self, parent=parent) QDetectThemeChange.__init__(self) Ui_WdgRecoverHw.__init__(self) ActionPageBase.__init__(self, parent, parent.app_config, hw_devices, 'Recover from backup seed') self.cur_hw_device: Optional[ HWDevice] = self.hw_devices.get_selected_device() self.current_step: Step = Step.STEP_NONE self.hw_conn_change_allowed = True self.scenario: Scenario = Scenario.NONE self.entropy: Optional[bytearray] = None self.word_count: int = 24 self.mnemonic = Mnemonic('english') self.words_wdg = SeedWordsWdg(self) self.setupUi(self)
def gen_lisk_addr(): mnemo = Mnemonic('english') words = mnemo.generate() hash_object = hashlib.sha256(words) ed25519_pk, ed25519_sk = c.crypto_sign_seed_keypair(hash_object.digest()) #print hexlify(ed25519_sk) pk_sha256_dig=hashlib.sha256(ed25519_pk).hexdigest() n_letter=2 pk_sha256_dig_array = [pk_sha256_dig[i:i+n_letter] for i in range(0, len(pk_sha256_dig), n_letter)] #split into 2 letters array temp=[] for x in range(0, 8): temp.append(pk_sha256_dig_array[7-x]) addr_num="".join(temp) lisk_addr = str(int(addr_num, 16))+"L" return lisk_addr, words
def verify_koinify_words(words): """ This function checks to make sure there are multiple words and that the first word is in the english wordlist. Both of these errors would crash the Mnemonic library, so they should be checked before using it. The Mnemonic library checks for other errors. """ if ' ' in words: wordchecker = Mnemonic('english') firstword = words.split(' ')[0] if firstword in wordchecker.wordlist: check = wordchecker.check(words) return check else: return False else: return False
def validate_mnemonic(mnemonic: str, language: str = DEFAULT_LANGUAGE) -> None: m = Mnemonic(language) mnemonic_words = m.normalize_string(mnemonic).split(' ') if len(mnemonic_words) not in VALID_MNEMONIC_LENGTHS: raise ValueError( 'Number of words must be one of the following: {VALID_MNEMONIC_LENGTHS}, ' 'but it is not (%d).' % len(mnemonic_words)) idx = map(lambda x: bin(m.wordlist.index(x))[2:].zfill(11), mnemonic_words) b = ''.join(idx) l = len(b) d = b[:l // 33 * 32] h = b[-l // 33:] nd = binascii.unhexlify(hex(int(d, 2))[2:].rstrip('L').zfill(l // 33 * 8)) nh = bin(int(hashlib.sha256(nd).hexdigest(), 16))[2:].zfill(256)[:l // 33] if h != nh: raise ValueError('Mnemonic checksum verification failed')
def mk_wallet(filename): mnemo = Mnemonic("english") # code = "all all all all all all all all all all all all" code = mnemo.generate() seed = mnemo.to_seed(code) root = btc.keys.bip32_seed(seed) xpub = root.hwif(as_private=False) xprv = root.hwif(as_private=True) legacy_key = root.subkey_for_path('44H/0H/0H/0/0') legacy_address = legacy_key.address() legacy_wif = legacy_key.wif() p2s_key = root.subkey_for_path('49H/0H/0H/0/0') p2s_hash = p2s_key.hash160(is_compressed=True) p2s_script = btc.contract.for_p2pkh_wit(p2s_hash) p2s_address = btc.address.for_p2s(p2s_script) p2s_wif = p2s_key.wif() segwit_key = root.subkey_for_path('84H/0H/0H/0/0') segwit_hash = segwit_key.hash160(is_compressed=True) segwit_address = btc.address.for_p2pkh_wit(segwit_hash) segwit_wif = segwit_key.wif() print("bip39 mnemonic seed:", code) print("bip39 master seed:", hexlify(seed).decode()) print("root xpub:", xpub) print("root xprv:", xprv) print("m/44'/0'/0'/0/0 legacy pub/priv:", legacy_address, legacy_wif) print("m/49'/0'/0'/0/0 p2sh-wit pub/priv:", p2s_address, p2s_wif) print("m/84'/0'/0'/0/0 segwit pub/priv:", segwit_address, segwit_wif) html = bitaddress() html = render_qr(code, 'seed.png', html) html = render_qr(legacy_address, 'pub.png', html) html = render_qr(legacy_wif, 'priv.png', html) html = thunk_lbl(" ".join(code.split()[0:6]), '__BIP39_SEED_1OF2__', html) html = thunk_lbl(" ".join(code.split()[6:12]), '__BIP39_SEED_2OF2__', html) html = thunk_lbl(legacy_address, '__BTC__ADDRESS__', html) html = thunk_lbl(legacy_wif, '__BTC__WIF__', html) write_pdf(html, filename)
def create_vectors(): m = Mnemonic('english') vectors = [] i = 0 for twelve in TWELVE_WORDS: for passphrase in PASS_PHRASES: entropy = hexlify(m.to_entropy(twelve)).decode() seed = hexlify(m.to_seed(twelve, passphrase)).decode() vectors.append({ "index": i, "twelvewords": twelve, "passphrase": passphrase, "seed": seed, "entropy": entropy }) i += 1 with open("seeds1.json", 'w') as f: json.dump(vectors, f)
def from_mnemonic(cls, words: str, path="m/44'/494'/0'/0/0") -> PrivateKey: """ Create a PrivateKey instance from a given mnemonic phrase and a HD derivation path. If path is not given, default to Band's HD prefix 494 and all other indexes being zeroes. :param words: the mnemonic phrase for recover private key :param path: the HD path that follows the BIP32 standard :return: Initialized PrivateKey object """ seed = Mnemonic("english").to_seed(words) self = cls(_error_do_not_use_init_directly=True) self.signing_key = SigningKey.from_string( BIP32.from_seed(seed).get_privkey_from_path(path), curve=SECP256k1, hashfunc=hashlib.sha256, ) return self
def generate(): mnemo = Mnemonic("english") seedwords = mnemo.generate(strength=256) print("seedwords='" + seedwords + "'") # add a 6x4 formatted version to the output wordlist = list(seedwords.split(" ")) seed_words_6x4 = "" for i in range(0, len(wordlist)): if i % 6 == 0 and i != 0: seed_words_6x4 = seed_words_6x4 + "\n" single_word = str(i + 1) + ":" + wordlist[i] while len(single_word) < 12: single_word = single_word + " " seed_words_6x4 = seed_words_6x4 + single_word print("seedwords6x4='" + seed_words_6x4 + "'")
class Mnemonic: mnemo = Mnemonic("english") def gen_words(self): words = self.mnemo.generate(strength=128) return words def gen_seed(self, words, passphrase=""): seed = self.mnemo.to_seed(words, passphrase="") return seed def make_Skey(self, seed): secexp = randrange_from_seed__trytryagain(seed, NIST384p.order) return SigningKey.from_secret_exponent(secexp, curve=NIST384p) def make_Vkey(self, Skey): return Skey.verifying_key
def generate_mnemonic(self): if self._mnemonic is None: while True: m = Mnemonic('english').generate(256) try: main_address_from_mnemonic(m) break except AssertionError: log.warning('mnemonic failed privtopub - try another') continue self._mnemonic = m self.label_new_seed_info.setText( 'This is your mnemonic. Please make sure to create a safe backup of this phrase before you proceed!' ) self.label_new_seed_info.setStyleSheet('color: red;') self.edit_new_seed.setPlainText(self._mnemonic) self.button_generate_mnemonic.hide() self.page6_create_account.completeChanged.emit()