Normally steem memos are sent as plain text, this article describes how to format your memos for encryption.
When using the cli wallet, if you include '#' as the first character of your memo will be encrypted.
unlocked >>> transfer from to "1.000 STEEM" "#encrypted memo" false
{
"operations": [[ "transfer",{
"from": "steemit",
"to": "steem",
"amount": "1.000 STEEM",
"memo": "#CqojqJfFwawzgnYSFUWokj...xAfynekJtySMsqK8A9doD4gHA5fDKgQTEfUKZgAm8Dx"
} ] ]
}
When the wallet is unlocked and get_account_history is called, the "memo" field will be replaced with "encrypted memo" without the initial '#'. This means that exchanges that upgrade to the latest CLI wallet can transparently support encrypted memos.
The algorithm for encrypting the memo involves the following steps:
1. Generate a memo_data struct containing:
public_key from
public_key to
uint64_t nonce
uint32_t check
vector<char> encrypted
shared_secret = from_private_key.get_shared_secret( to );
/// concatenate nonce and shared secret (binary)
encryption_key = sha512( nonce + shared_secret )
///< check is first 64 bit of sha256 hash treated as uint64_t truncated to 32 bits.
check = sha256( encryption_key )._hash[0]
/// pack the memo as a length-prefixed string, length is serialized as varint
plain_text = pack( memo_text)
encrypted = aes_encrypt( encryption_key, plain_text )
string result = '#' + to_base58( pack( memodata ) );
The to and from keys should be fetched as the memo_key property on the respective accounts.