def from_dict(cls, ledger: 'baseledger.BaseLedger', wallet: 'basewallet.Wallet', d: dict): seed = d.get('seed', '') private_key_string = d.get('private_key', '') private_key = None public_key = None encrypted = d.get('encrypted', False) if not encrypted: if seed: private_key = cls.get_private_key_from_seed(ledger, seed, '') public_key = private_key.public_key elif private_key: private_key = from_extended_key_string(ledger, private_key_string) public_key = private_key.public_key if public_key is None: public_key = from_extended_key_string(ledger, d['public_key']) name = d.get('name') if not name: name = 'Account #{}'.format(public_key.address) return cls(ledger=ledger, wallet=wallet, name=name, seed=seed, private_key_string=private_key_string, encrypted=encrypted, private_key=private_key, public_key=public_key, address_generator=d.get('address_generator', {}))
def decrypt(self, password: str) -> None: assert self.encrypted, "Key is not encrypted." self.seed = aes_decrypt(password, self.seed) self.private_key = from_extended_key_string( self.ledger, aes_decrypt(password, self.private_key_string)) self.password = password self.encrypted = False
def keys_from_dict(cls, ledger: 'baseledger.BaseLedger', d: dict) \ -> Tuple[str, Optional[PrivateKey], PubKey]: seed = d.get('seed', '') private_key_string = d.get('private_key', '') private_key = None public_key = None encrypted = d.get('encrypted', False) if not encrypted: if seed: private_key = cls.get_private_key_from_seed(ledger, seed, '') public_key = private_key.public_key elif private_key_string: private_key = from_extended_key_string(ledger, private_key_string) public_key = private_key.public_key if public_key is None: public_key = from_extended_key_string(ledger, d['public_key']) return seed, private_key, public_key
def _decrypt_private_key_string(self, password: str) -> Optional[PrivateKey]: if not self.private_key_string: return None private_key_string, self.init_vectors['private_key'] = aes_decrypt( password, self.private_key_string) if not private_key_string: return None return from_extended_key_string(self.ledger, private_key_string)
async def test_from_extended_keys(self): ledger = ledger_class({ 'db': ledger_class.database_class(':memory:'), 'headers': ledger_class.headers_class(':memory:'), }) self.assertIsInstance( from_extended_key_string( ledger, 'xprv9s21ZrQH143K2dyhK7SevfRG72bYDRNv25yKPWWm6dqApNxm1Zb1m5gGcBWYfbsPjTr2v5joit8Af2Zp5P' '6yz3jMbycrLrRMpeAJxR8qDg8', ), PrivateKey) self.assertIsInstance( from_extended_key_string( ledger, 'xpub661MyMwAqRbcF84AR8yfHoMzf4S2ct6mPJtvBtvNeyN9hBHuZ6uGJszkTSn5fQUCdz3XU17eBzFeAUwV6f' 'iW44g14WF52fYC5J483wqQ5ZP', ), PubKey)
def decrypt(self, password: str) -> None: assert self.encrypted, "Key is not encrypted." try: seed, seed_iv = aes_decrypt(password, self.seed) pk_string, pk_iv = aes_decrypt(password, self.private_key_string) except ValueError: # failed to remove padding, password is wrong return try: Mnemonic().mnemonic_decode(seed) except IndexError: # failed to decode the seed, this either means it decrypted and is invalid # or that we hit an edge case where an incorrect password gave valid padding return try: private_key = from_extended_key_string(self.ledger, pk_string) except (TypeError, ValueError): return self.seed = seed self.seed_encryption_init_vector = seed_iv self.private_key = private_key self.private_key_encryption_init_vector = pk_iv self.password = password self.encrypted = False