def test_crypto(): pts = ((0x50863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352, 0x2cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6), (0xa83b8de893467d3a88d959c0eb4032d9ce3bf80f175d4d9e75892a3ebb8ab7e5, 0x370f723328c24b7a97fe34063ba68f253fb08f8645d7c8b9a4ff98e3c29e7f0d), (0xf680556678e25084a82fa39e1b1dfd0944f7e69fddaa4e03ce934bd6b291dca0, 0x52c10b721d34447e173721fb0151c68de1106badb089fb661523b8302a9097f5), (0x241febb8e23cbd77d664a18f66ad6240aaec6ecdc813b088d5b901b2e285131f, 0x513378d9ff94f8d3d6c420bd13981df8cd50fd0fbd0cb5afabb3e66f2750026d)) for pt in pts: b = bytes([(pt[1] & 0x1) + 0x2]) + pt[0].to_bytes(32, 'big') b_full = bytes([0x04]) + pt[0].to_bytes(32, 'big') + pt[1].to_bytes(32, 'big') pk = PublicKey.from_bytes(b) assert pk.point.y == pt[1] assert b == pk.compressed_bytes assert b_full == bytes(pk) assert bytes(PublicKey.from_hex(pk.to_hex())) == b_full for i in range(10): pk = PrivateKey.from_random() assert PrivateKey.from_hex(pk.to_hex()).key == pk.key hd_priv = HDPrivateKey.master_key_from_entropy()[0] hd_priv2 = HDKey.from_hex(hd_priv.to_hex()) hd_pub = hd_priv.public_key hd_pub2 = HDKey.from_hex(hd_pub.to_hex()) assert isinstance(hd_priv2, HDPrivateKey) assert hd_priv2._key.key == hd_priv._key.key assert hd_priv2.chain_code == hd_priv.chain_code assert isinstance(hd_pub2, HDPublicKey) assert hd_pub2._key.point.x == hd_pub._key.point.x assert hd_pub2._key.point.y == hd_pub._key.point.y assert hd_pub2.chain_code == hd_pub.chain_code
def hd_master_key(self, k): self._hd_master_key = k self._acct_keys = {} keys = HDKey.from_path(self._hd_master_key, self.account_type.account_derivation_prefix) for i in range(self.max_accounts): acct_key = HDPrivateKey.from_parent(keys[-1], 0x80000000 | i) payout_key = HDPrivateKey.from_parent(acct_key, 0) change_key = HDPrivateKey.from_parent(acct_key, 1) payout_addresses = [HDPublicKey.from_parent(payout_key.public_key, i).address() for i in range(self.max_address)] change_addresses = [HDPublicKey.from_parent(change_key.public_key, i).address() for i in range(self.max_address)] self._acct_keys[i] = {'acct_key': acct_key, 'payout_key': payout_key, 'change_key': change_key, 'payout_addresses': payout_addresses, 'change_addresses': change_addresses} self._num_used_addresses[i][0] = 0 self._num_used_addresses[i][1] = 0 self._setup_balances()
def __init__(self, mnemonic, child): master_key = HDPrivateKey.master_key_from_mnemonic(mnemonic) root_keys = HDKey.from_path(master_key,"m/44'/60'/0'") acct_priv_key = root_keys[-1] keys = HDKey.from_path(acct_priv_key,'{change}/{index}'.format(change=0, index=child)) self.address = ethereumAddressFromBytes(bytes(keys[-1].public_key._key)) self.private_key = keys[-1]._key.to_hex()
def __init__(self, hd_key, name, index, data_provider, cache_manager, testnet=False, last_state=None, skip_discovery=False): # Take in either public or private key for this account as we # can derive everything from it. if not isinstance(hd_key, HDKey): raise TypeError("hd_key must be a HDKey object") self.key = hd_key self.name = name self.index = index self.data_provider = data_provider self.testnet = testnet self.last_indices = [-1, -1] self._cache_manager = cache_manager self._last_update = 0 self._last_full_update = 0 if last_state is not None and isinstance(last_state, dict): if "last_payout_index" in last_state: self.last_indices[ self.PAYOUT_CHAIN] = last_state["last_payout_index"] if "last_change_index" in last_state: self.last_indices[ self.CHANGE_CHAIN] = last_state["last_change_index"] # Check to see that the address cache has up to last_indices for change in [self.PAYOUT_CHAIN, self.CHANGE_CHAIN]: k = self._cache_manager.get_chain_indices(self.index, change) for i in range(self.last_indices[change] + 1): if i not in k or k[i] != i: self.last_indices[change] = -1 break self._chain_priv_keys = [None, None] self._chain_pub_keys = [None, None] for change in [0, 1]: if isinstance(self.key, HDPrivateKey): self._chain_priv_keys[change] = HDPrivateKey.from_parent( self.key, change) self._chain_pub_keys[change] = self._chain_priv_keys[ change].public_key else: self._chain_pub_keys[change] = HDPublicKey.from_parent( self.key, change) if not skip_discovery: self._sync_txns(check_all=True) self._update_balance()
def create(cls, mnemonic=None): """ Create Minter wallet @param mnemonic|string: Mnemonic phrase @return: dict """ # Create mnemonic phrase if None if not mnemonic: _mnemonic = Mnemonic(language='english') mnemonic = _mnemonic.generate(cls.BIP44_ENTROPY_BITS) if len(mnemonic.split(' ')) != 12: raise Exception('Mnemonic phrase should have 12 words.') # Mnemonic to seed (bytes) seed = Mnemonic.to_seed(mnemonic, '') # Generate master key from master seed I = hmac.new(cls.MASTER_SEED, seed, hashlib.sha512).hexdigest() IL = I[:64] IR = I[64:] master_key = HDPrivateKey(key=int.from_bytes(binascii.unhexlify(IL), 'big'), chain_code=binascii.unhexlify(IR), index=0, depth=0) # Get child keys from master key by path keys = HDKey.from_path(master_key, cls.BIP44_SEED_ADDRESS_PATH) # Get private key private_key = binascii.hexlify(bytes(keys[-1]._key)) # Get public key public_key = cls.get_public_from_private(private_key) # Get address address = cls.get_address_from_public_key(public_key) return { 'address': address, 'private_key': private_key.decode(), 'mnemonic': mnemonic, 'seed': binascii.hexlify(seed).decode() }
def get_private_key(self, change, n): """ Returns a private key in the chain for use in signing messages or transactions. Args: change (bool): If True, returns an address for change purposes, otherwise returns an address for payment. n (int): index of address in chain. Returns: HDPrivateKey: A private key in this account's chain. """ # We only use public key derivation per BIP44 k = self._chain_priv_keys[change] if k is None: raise ValueError("No private key provided for account.") return HDPrivateKey.from_parent(k, n)
def __init__(self, hd_key, name, index, data_provider, cache_manager, testnet=False, last_state=None, skip_discovery=False): # Take in either public or private key for this account as we # can derive everything from it. if not isinstance(hd_key, HDKey): raise TypeError("hd_key must be a HDKey object") self.key = hd_key self.name = name self.index = index self.data_provider = data_provider self.testnet = testnet self.last_indices = [-1, -1] self._cache_manager = cache_manager self._last_update = 0 self._last_full_update = 0 if last_state is not None and isinstance(last_state, dict): if "last_payout_index" in last_state: self.last_indices[self.PAYOUT_CHAIN] = last_state["last_payout_index"] if "last_change_index" in last_state: self.last_indices[self.CHANGE_CHAIN] = last_state["last_change_index"] # Check to see that the address cache has up to last_indices for change in [self.PAYOUT_CHAIN, self.CHANGE_CHAIN]: k = self._cache_manager.get_chain_indices(self.index, change) for i in range(self.last_indices[change] + 1): if i not in k or k[i] != i: self.last_indices[change] = -1 break self._chain_priv_keys = [None, None] self._chain_pub_keys = [None, None] for change in [0, 1]: if isinstance(self.key, HDPrivateKey): self._chain_priv_keys[change] = HDPrivateKey.from_parent(self.key, change) self._chain_pub_keys[change] = self._chain_priv_keys[change].public_key else: self._chain_pub_keys[change] = HDPublicKey.from_parent(self.key, change) if not skip_discovery: self._sync_txns(check_all=True) self._update_balance()
def test_crypto(): pts = ( (0x50863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352, 0x2cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6), (0xa83b8de893467d3a88d959c0eb4032d9ce3bf80f175d4d9e75892a3ebb8ab7e5, 0x370f723328c24b7a97fe34063ba68f253fb08f8645d7c8b9a4ff98e3c29e7f0d), (0xf680556678e25084a82fa39e1b1dfd0944f7e69fddaa4e03ce934bd6b291dca0, 0x52c10b721d34447e173721fb0151c68de1106badb089fb661523b8302a9097f5), (0x241febb8e23cbd77d664a18f66ad6240aaec6ecdc813b088d5b901b2e285131f, 0x513378d9ff94f8d3d6c420bd13981df8cd50fd0fbd0cb5afabb3e66f2750026d)) for pt in pts: b = bytes([(pt[1] & 0x1) + 0x2]) + pt[0].to_bytes(32, 'big') b_full = bytes([0x04]) + pt[0].to_bytes(32, 'big') + pt[1].to_bytes( 32, 'big') pk = PublicKey.from_bytes(b) assert pk.point.y == pt[1] assert b == pk.compressed_bytes assert b_full == bytes(pk) assert bytes(PublicKey.from_hex(pk.to_hex())) == b_full for i in range(10): pk = PrivateKey.from_random() assert PrivateKey.from_hex(pk.to_hex()).key == pk.key hd_priv = HDPrivateKey.master_key_from_entropy()[0] hd_priv2 = HDKey.from_hex(hd_priv.to_hex()) hd_pub = hd_priv.public_key hd_pub2 = HDKey.from_hex(hd_pub.to_hex()) assert isinstance(hd_priv2, HDPrivateKey) assert hd_priv2._key.key == hd_priv._key.key assert hd_priv2.chain_code == hd_priv.chain_code assert isinstance(hd_pub2, HDPublicKey) assert hd_pub2._key.point.x == hd_pub._key.point.x assert hd_pub2._key.point.y == hd_pub._key.point.y assert hd_pub2.chain_code == hd_pub.chain_code
'key_salt': bytes_to_str(enc_key_salt), 'account_type': "BIP44BitcoinMainnet", 'accounts': [{ 'public_key': "xpub6CNX3TRAXGpoV1a3ai3Hs9R85t63V3k6BGsTaxZZMJJ4DL6kRY8riYA1r6hxyeuxgeb33FfBgrJrV6wxv6VXEVHAfPGJNw8ZzbEJHgsbmpz", # nopep8 'last_payout_index': 2, 'last_change_index': 1 }], 'account_map': { 'default': 0 } } master = HDPrivateKey.master_key_from_mnemonic(master_seed, passphrase) mock_provider = MockProvider("BIP44BitcoinMainnet", master) def test_encrypt_decrypt(): mkey_enc, mseed_enc = Two1Wallet.encrypt(master_key=config['master_key'], master_seed=config['master_seed'], passphrase=passphrase, key_salt=enc_key_salt) mkey, mseed = Two1Wallet.decrypt(master_key_enc=mkey_enc, master_seed_enc=mseed_enc, passphrase=passphrase, key_salt=enc_key_salt) assert mkey == config['master_key']
import pytest from two1.bitcoin.crypto import HDKey, HDPrivateKey from two1.blockchain.mock_provider import MockProvider from two1.wallet.account_types import account_types from two1.wallet.cache_manager import CacheManager from two1.wallet.hd_account import HDAccount master_key_mnemonic = 'cage minimum apology region aspect wrist demise gravity another bulb tail invest' master_key_passphrase = "test" account_type = account_types['BIP44BitcoinMainnet'] master_key = HDPrivateKey.master_key_from_mnemonic(mnemonic=master_key_mnemonic, passphrase=master_key_passphrase) acct0_key = HDKey.from_path(master_key, account_type.account_derivation_prefix + "/0'")[-1] mock_provider = MockProvider(account_type, master_key) def test_init(): with pytest.raises(TypeError): HDAccount(master_key_passphrase, "default", 0, mock_provider, CacheManager()) ''' The MockProvider is designed in a strange way that explains how the parameters are chosen for test_all: the get_transactions side effects are set so that for each DISCOVERY_INCREMENT block of addresses, a single transaction is returned
import pytest from two1.bitcoin.crypto import HDKey, HDPrivateKey from two1.blockchain.mock_provider import MockProvider from two1.wallet.account_types import account_types from two1.wallet.cache_manager import CacheManager from two1.wallet.hd_account import HDAccount master_key_mnemonic = 'cage minimum apology region aspect wrist demise gravity another bulb tail invest' master_key_passphrase = "test" account_type = account_types['BIP44BitcoinMainnet'] master_key = HDPrivateKey.master_key_from_mnemonic( mnemonic=master_key_mnemonic, passphrase=master_key_passphrase) acct0_key = HDKey.from_path(master_key, account_type.account_derivation_prefix + "/0'")[-1] mock_provider = MockProvider(account_type, master_key) def test_init(): with pytest.raises(TypeError): HDAccount(master_key_passphrase, "default", 0, mock_provider, CacheManager()) ''' The MockProvider is designed in a strange way that explains how the parameters are chosen for test_all: the get_transactions side effects are set so that for each DISCOVERY_INCREMENT block of addresses, a single transaction is returned
master_seed=master_seed, passphrase=passphrase, key_salt=enc_key_salt) config = {'master_key': mkey_enc, 'master_seed': mseed_enc, 'locked': True, 'passphrase_hash': passphrase_hash, 'key_salt': bytes_to_str(enc_key_salt), 'account_type': "BIP44BitcoinMainnet", 'accounts': [{'public_key': "xpub6CNX3TRAXGpoV1a3ai3Hs9R85t63V3k6BGsTaxZZMJJ4DL6kRY8riYA1r6hxyeuxgeb33FfBgrJrV6wxv6VXEVHAfPGJNw8ZzbEJHgsbmpz", # nopep8 'last_payout_index': 2, 'last_change_index': 1}], 'account_map': {'default': 0}} master = HDPrivateKey.master_key_from_mnemonic(master_seed, passphrase) mock_provider = MockProvider("BIP44BitcoinMainnet", master) def test_encrypt_decrypt(): mkey_enc, mseed_enc = Two1Wallet.encrypt(master_key=config['master_key'], master_seed=config['master_seed'], passphrase=passphrase, key_salt=enc_key_salt) mkey, mseed = Two1Wallet.decrypt(master_key_enc=mkey_enc, master_seed_enc=mseed_enc, passphrase=passphrase, key_salt=enc_key_salt) assert mkey == config['master_key']