def test_base58decode(self): self.assertEqual([base58decode('5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ'), base58decode('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss'), base58decode('5KfazyjBBtR2YeHjNqX5D6MXvqTUd2iZmWusrdDSUqoykTyWQZB')], ['800c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d507a5b8d', '80e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8555c5bbb26', '80f3a375e00cc5147f30bee97bb5d54b31a12eee148a1ac31ac9edc4ecd13bc1f80cc8148e'])
def encrypt_binary(self, infile, outfile, buffer_size=2048, nonce=None): """ Encrypt a binary file :param str infile: input file name :param str outfile: output file name :param int buffer_size: write buffer size :param str nonce: when not set, a random string is generated and used """ if not os.path.exists(infile): raise ValueError("%s does not exists!" % infile) if nonce is None: nonce = str(random.getrandbits(64)) if isinstance(self.from_account, Account): memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey( self.from_account["memo_key"] ) else: memo_wif = self.from_account if isinstance(self.to_account, Account): pubkey = self.to_account["memo_key"] else: pubkey = self.to_account if not memo_wif: raise MissingKeyError("Memo key for %s missing!" % self.from_account["name"]) if not hasattr(self, 'chain_prefix'): self.chain_prefix = self.blockchain.prefix file_size = os.path.getsize(infile) priv = PrivateKey(memo_wif) pub = PublicKey( pubkey, prefix=self.chain_prefix ) enc = BtsMemo.encode_memo( priv, pub, nonce, "beem/%s" % __version__, prefix=self.chain_prefix ) enc = unhexlify(base58decode(enc[1:])) shared_secret = BtsMemo.get_shared_secret(priv, pub) aes, check = BtsMemo.init_aes(shared_secret, nonce) with open(outfile, 'wb') as fout: fout.write(struct.pack('<Q', len(enc))) fout.write(enc) fout.write(struct.pack('<Q', file_size)) with open(infile, 'rb') as fin: while True: data = fin.read(buffer_size) n = len(data) if n == 0: break elif n % 16 != 0: data += b' ' * (16 - n % 16) # <- padded with spaces encd = aes.encrypt(data) fout.write(encd)
def extract_memo_data(message): """ Returns the stored pubkey keys, nonce, checksum and encrypted message of a memo""" raw = base58decode(message[1:]) from_key = PublicKey(raw[:66]) raw = raw[66:] to_key = PublicKey(raw[:66]) raw = raw[66:] nonce = str(struct.unpack_from("<Q", unhexlify(raw[:16]))[0]) raw = raw[16:] check = struct.unpack_from("<I", unhexlify(raw[:8]))[0] raw = raw[8:] cipher = raw return from_key, to_key, nonce, check, cipher
def decode_memo(priv, message): """ Decode a message with a shared secret between Alice and Bob :param PrivateKey priv: Private Key (of Bob) :param base58encoded message: Encrypted Memo message :return: Decrypted message :rtype: str :raise ValueError: if message cannot be decoded as valid UTF-8 string """ # decode structure raw = base58decode(message[1:]) from_key = PublicKey(raw[:66]) raw = raw[66:] to_key = PublicKey(raw[:66]) raw = raw[66:] nonce = str(struct.unpack_from("<Q", unhexlify(raw[:16]))[0]) raw = raw[16:] check = struct.unpack_from("<I", unhexlify(raw[:8]))[0] raw = raw[8:] cipher = raw if repr(to_key) == repr(priv.pubkey): shared_secret = get_shared_secret(priv, from_key) elif repr(from_key) == repr(priv.pubkey): shared_secret = get_shared_secret(priv, to_key) else: raise ValueError("Incorrect PrivateKey") # Init encryption aes, checksum = init_aes(shared_secret, nonce) # Check if not check == checksum: raise AssertionError("Checksum failure") # Encryption # remove the varint prefix (FIXME, long messages!) message = cipher[2:] message = aes.decrypt(unhexlify(py23_bytes(message, 'ascii'))) try: return _unpad(message.decode('utf8'), 16) except: # noqa FIXME(sneak) raise ValueError(message)