As part of Celo’s identity protocol, a public encryption key is stored along with a user’s address in the
Attestations contract. Both the address key pair and the encryption key pair are derived from the backup phrase. When sending a transaction the encryption key of the recipient is retrieved when getting his or her address. The comment is then encrypted using a 128 bit hybrid encryption scheme (ECDH on secp256k1 with AES-128-CTR). This system ensures that comments can only be read by the sending and receiving parties and that messages will be recovered when restoring a wallet from its backup phrase.
A 128 bit randomly generated session key, sk, is generated and used to symmetrically encrypt the comment. sk is asymmetrically encrypted to the sender and to the recipient.
Encrypted = ECIES(sk, to=pubSelf) | ECIES(sk, to=pubOther) | AES(ke=sk, km=sk, comment)
Takes encryption key, ke, and MAC key, km, and the data to encrypt, plaintext
Cipher: AES-128-CTR using a randomly generated iv
Authenticate iv | ciphertext using HMAC with SHA-256 and km
Return iv | ciphertext | mac
Takes data to encrypt, plaintext, and the public key of the recipient, pubKeyTo
Generate an ephemeral keypair, ephemPubKey and ephemPrivKey
Derive 32 bytes of key material, k, from ECDH between ephemPrivKey and pubKeyTousing ConcatKDF (specified as NIST 800-56C Rev 1 One Step KDF) with SHA-256 for H(x)
The encryption key, ke, is the first 128 bits of k
The MAC key, km, is SHA-256 of the second 128 bits of k
Encrypt the plaintext symmetrically with AES-128-CTR using ke, km, and a random iv
Return ephemPubKey | AES-128-CTR-HMAC(ke, km, plaintext) where the public key needs to be uncompressed (current limitation with decrypt).