def test_create_bip39_with_me(setup_wallets, pwd, me, valid): def dummyDisplayWords(a, b): pass def getMnemonic(): return ("legal winner thank year wave sausage worth useful legal winner thank yellow", me) def getPassword(): return pwd def getWalletFileName(): return "bip39-test-wallet-name-from-callback.json" def promptMnemonicExtension(): return me if os.path.exists(os.path.join("wallets", getWalletFileName())): os.remove(os.path.join("wallets", getWalletFileName())) success = wallet_generate_recover_bip39("generate", "wallets", "wallet.json", callbacks=(dummyDisplayWords, getMnemonic, getPassword, getWalletFileName, promptMnemonicExtension)) if not valid: #wgrb39 returns false for failed wallet creation case assert not success return assert success #open the wallet file, and decrypt the encrypted mnemonic extension and check #it's the one we intended. with open(os.path.join("wallets", getWalletFileName()), 'r') as f: walletdata = json.load(f) password_key = bitcoin.bin_dbl_sha256(getPassword()) cleartext = decryptData(password_key, walletdata['encrypted_mnemonic_extension'].decode('hex')) assert len(cleartext) >= 79 #throws if not len == 3 padding, me2, checksum = cleartext.split('\xff') strippedme = me.strip() assert strippedme == me2 assert checksum == bitcoin.dbl_sha256(strippedme)[:8] #also test recovery from this combination of mnemonic + extension if os.path.exists(os.path.join("wallets", getWalletFileName())): os.remove(os.path.join("wallets", getWalletFileName())) success = wallet_generate_recover_bip39("recover", "wallets", "wallet.json", callbacks=(dummyDisplayWords, getMnemonic, getPassword, getWalletFileName, None)) assert success with open(os.path.join("wallets", getWalletFileName()), 'r') as f: walletdata = json.load(f) password_key = bitcoin.bin_dbl_sha256(getPassword()) cleartext = decryptData(password_key, walletdata['encrypted_entropy'].decode('hex')).encode('hex') assert cleartext == "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
def decrypt_entropy_extension(enc_data, key): data = decryptData(key, unhexlify(enc_data)) if data[-9] != b'\xff': raise ConvertException("Wrong password.") chunks = data.split(b'\xff') if len(chunks) < 3 or data[-8:] != double_sha256(chunks[1])[:8]: raise ConvertException("Wrong password.") return chunks[1]
def decrypt_wallet_data(data, password): key = double_sha256(password.encode('utf-8')) enc_entropy = data.get('encrypted_seed') or data.get('encrypted_entropy') enc_entropy_ext = data.get('encrypted_mnemonic_extension') enc_imported = data.get('imported_keys') entropy = decryptData(key, unhexlify(enc_entropy)) data['entropy'] = entropy if enc_entropy_ext: data['entropy_ext'] = decrypt_entropy_extension(enc_entropy_ext, key) if enc_imported: imported_keys = defaultdict(list) for e in enc_imported: md = int(e['mixdepth']) imported_enc_key = unhexlify(e['encrypted_privkey']) imported_key = decryptData(key, imported_enc_key) imported_keys[md].append(imported_key) data['imported'] = imported_keys