Encryption layout - Storing and recovering encrypted information
This protocol allows each persona of a RIA to use secret-key cryptography to encrypt and decrypt information needing only the the mnemonic phrase.
This protocol is based on uPort DAF Secret Box implementation using Libsodium authenticated encryption.
Please make use of this section for core concept definitions
The protocol for encryption is:
- Private key calculation
- Let the nonce
i
be the nonce index of the persona derivation count (see persona creation protocol) - From the RIA seed derive the same nonce, using BIP-449
change = 1
- for example, RSK would usem/44'/137'/0'/1/i
- Get the private key of the derived account
- Let the nonce
- Data encryption
- Create a random nonce
n
to use for encrypting - Let
cyph
be the Libsodium authenticated encryption of data
- Create a random nonce
- Use
n+cyph
as the cyphertext. It can be used to recover the information using just the mnemonic
The authenticated encryption operation
- Encrypts a message with a key and a nonce to keep it confidential
- Computes an authentication tag. This tag is used to make sure that the message hasn’t been tampered with before decrypting it.
A single key is used both to encrypt/authenticate and verify/decrypt messages.
The nonce doesn’t have to be confidential, but it should never ever be reused with the same key.
uPort implementation
async encrypt(message: string): Promise<string> {
await sodium.ready
const nonce = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES)
const cipherText = sodium.crypto_secretbox_easy(message, nonce, sodium.from_hex(this.secretKey))
return sodium.to_hex(new Uint8Array([...nonce, ...cipherText]))
}
async decrypt(encryptedMessageHex: string): Promise<string> {
await sodium.ready
const cipherTextWithNonce = sodium.from_hex(encryptedMessageHex)
const nonce = cipherTextWithNonce.slice(0, sodium.crypto_secretbox_NONCEBYTES)
const cipherText = cipherTextWithNonce.slice(sodium.crypto_secretbox_NONCEBYTES)
return sodium.to_string(
sodium.crypto_secretbox_open_easy(cipherText, nonce, sodium.from_hex(this.secretKey)),
)
}
Implementations
WIP