예제 #1
0
 def test_base58decode(self):
     self.assertEqual([base58decode('5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ'),
                       base58decode('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss'),
                       base58decode('5KfazyjBBtR2YeHjNqX5D6MXvqTUd2iZmWusrdDSUqoykTyWQZB')],
                      ['800c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d507a5b8d',
                       '80e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8555c5bbb26',
                       '80f3a375e00cc5147f30bee97bb5d54b31a12eee148a1ac31ac9edc4ecd13bc1f80cc8148e'])
예제 #2
0
    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)
예제 #3
0
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
예제 #4
0
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)