def test_base58encode(self): self.assertEqual(['5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ', '5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss', '5KfazyjBBtR2YeHjNqX5D6MXvqTUd2iZmWusrdDSUqoykTyWQZB'], [base58encode('800c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d507a5b8d'), base58encode('80e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8555c5bbb26'), base58encode('80f3a375e00cc5147f30bee97bb5d54b31a12eee148a1ac31ac9edc4ecd13bc1f80cc8148e')])
def encode_memo(priv, pub, nonce, message, **kwargs): """ Encode a message with a shared secret between Alice and Bob :param PrivateKey priv: Private Key (of Alice) :param PublicKey pub: Public Key (of Bob) :param int nonce: Random nonce :param str message: Memo message :return: Encrypted message :rtype: hex """ shared_secret = get_shared_secret(priv, pub) aes, check = init_aes(shared_secret, nonce) " Padding " raw = py23_bytes(message, "utf8") raw = _pad(raw, 16) " Encryption " cipher = hexlify(aes.encrypt(raw)).decode("ascii") prefix = kwargs.pop("prefix", default_prefix) s = { "from": format(priv.pubkey, prefix), "to": format(pub, prefix), "nonce": nonce, "check": check, "encrypted": cipher, "prefix": prefix } tx = Memo(**s) return "#" + base58encode(hexlify(py23_bytes(tx)).decode("ascii"))
def decrypt_binary(self, infile, outfile, buffer_size=2048): """ Decrypt a binary file :param str infile: encrypted binary file :param str outfile: output file name :param int buffer_size: read buffer size :returns: encrypted memo information :rtype: dict """ if not os.path.exists(infile): raise ValueError("%s does not exists!" % infile) if buffer_size % 16 != 0: raise ValueError("buffer_size must be dividable by 16") with open(infile, 'rb') as fin: memo_size = struct.unpack('<Q', fin.read(struct.calcsize('<Q')))[0] memo = fin.read(memo_size) orig_file_size = struct.unpack('<Q', fin.read(struct.calcsize('<Q')))[0] memo = '#' + base58encode(hexlify(memo).decode("ascii")) memo_to = self.to_account memo_from = self.from_account from_key, to_key, nonce, check, cipher = BtsMemo.extract_memo_data(memo) if memo_to is None and memo_from is None: try: memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey( str(to_key) ) pubkey = from_key except MissingKeyError: try: # if that failed, we assume that we have sent the memo memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey( str(from_key) ) pubkey = to_key except MissingKeyError: # if all fails, raise exception raise MissingKeyError( "Non of the required memo keys are installed!" "Need any of {}".format( [str(to_key), str(from_key)])) elif memo_to is not None and memo_from is not None and isinstance(memo_from, PrivateKey): memo_wif = memo_from if isinstance(memo_to, Account): pubkey = memo_to["memo_key"] else: pubkey = memo_to elif memo_to is not None and memo_from is not None and isinstance(memo_to, PrivateKey): memo_wif = memo_to if isinstance(memo_from, Account): pubkey = memo_from["memo_key"] else: pubkey = memo_from else: try: memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey( memo_to["memo_key"] ) pubkey = memo_from["memo_key"] except MissingKeyError: try: # if that failed, we assume that we have sent the memo memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey( memo_from["memo_key"] ) pubkey = memo_to["memo_key"] except MissingKeyError: # if all fails, raise exception raise MissingKeyError( "Non of the required memo keys are installed!" "Need any of {}".format( [memo_to["name"], memo_from["name"]])) if not hasattr(self, 'chain_prefix'): self.chain_prefix = self.blockchain.prefix priv = PrivateKey(memo_wif) pubkey = PublicKey(pubkey, prefix=self.chain_prefix) beem_version = BtsMemo.decode_memo( priv, memo ) shared_secret = BtsMemo.get_shared_secret(priv, pubkey) # Init encryption aes, checksum = BtsMemo.init_aes(shared_secret, nonce) with open(infile, 'rb') as fin: memo_size = struct.unpack('<Q', fin.read(struct.calcsize('<Q')))[0] memo = fin.read(memo_size) file_size = struct.unpack('<Q', fin.read(struct.calcsize('<Q')))[0] with open(outfile, 'wb') as fout: while True: data = fin.read(buffer_size) n = len(data) if n == 0: break decd = aes.decrypt(data) n = len(decd) if file_size > n: fout.write(decd) else: fout.write(decd[:file_size]) # <- remove padding on last block file_size -= n return { "file_size": orig_file_size, "from_key": str(from_key), "to_key": str(to_key), "nonce": nonce, "beem_version": beem_version }