Data Encryption and Decryption
Last updated
Was this helpful?
Last updated
Was this helpful?
Ty Everett (ty@projectbabbage.com)
We devise a method for applications to request the encryption and decryption of data. Specifically, we define a mechanism for data encryption within the key derivation system, utilizing the protocol and key ID scheme. During encryption, the sender derives their own child private key and the child public key of the recipient using the process, then computes an ECDH shared secret between the child keys which is used in symmetric encryption with AES-256-GCM. The initialization vector, together with the ciphertext, are sent to the recipient. During decryption, the recipient computes their own private key and the public key of the sender, and uses ECDH to compute the same shared secret. The key is then used together with the provided initialization vector to decrypt the ciphertext. When no counterparty exists, we stipulate substitution for the sender's own public key in the child key derivation process.
The Bitcoin ecosystem has demonstrated a clear desire for wallets to support data encryption between parties. This capability facilitates secure exchange of information, improves user privacy, and enables novel applications that require direct and secure communication between users. The unique economic incentives of micropayment-based applications, particularly those facilitated by Bitcoin wallets, make user privacy paramount, and have led to the adoption of end-to-end encryption by many applications. While several encryption systems have been developed and integrated into various platforms, there is currently no standard methodology that supports both single-party and multi-party encryption, protocol-level permissions management, and leverages key derivation. The standard aims to fill this gap and provide a secure and standardized framework for encryption and decryption within the Bitcoin ecosystem.
We start with the same constructs defined in : users with clients, protocols and applications. We stipulate the use of invoice numbers in the context of key derivation, and we build on top of the permissions architecture defined by .
When an application sends a message to a client requesting that data be encrypted, the message comprises:
The security level, protocol ID, key ID and counterparty to facilitate key derivation and permissioning
The data to encrypt
We stipulate the following process for encryption:
The message sender begins by computing the invoice number based on the security level, protocol ID, and key ID
The message sender uses key derivation with the computed invoice number to derive a child public key for the recipient
The message sender uses key derivation with the computed invoice number to derive their own child private key
The message sender computes the ECDH shared secret between the two derived child keys
The resulting elliptic curve point's X and Y values are hashed with SHA256 to create an AES-256-GCM symmetric encryption key
The resulting 256-bit value is used in conjunction with a randomly-generated 256-bit initialization vector to encrypt the message with AES-256-GCM
The initialization vector is prepended to the ciphertext, and the combined value is returned by the client to the application over the abstract communications substrate.
We stipulate the following process for message decryption:
The recipient somehow comes to know the ciphertext (prepended with the initialization vector), the counterparty, the security level, protocol ID, and key ID. The mechanism for conveying this information to the recipient is beyond the scope of this specification.
The recipient uses the same process to compute his own child private key
The recipient computes a shared secret between the two child keys, using the hash of the X and Y values as an AES-256-GCM symmetric key
The recipient then uses the symmetric key to decrypt the ciphertext with the provided initialization vector
protocolID
keyID
counterparty
The message payload comprises the data to encrypt.
The response message comprises a payload containing the encrypted ciphertext, prepended with the 32-byte initialization vector.
The decryption request is a message sent by the application to the client. It contains a header with the following information:
protocolID
keyID
counterparty
The message payload comprises the data to decrypt, prepended with the 32-byte initialization vector.
The response message comprises a payload containing the decrypted plaintext.
If the client is unable to fulfill the encryption or decryption requests for any reason, we specify that it should respond with a JSON-formatted Cryptography Error. The fields for the object are specified as follows:
status
This should always be a string comprising "error"
.
code
A machine-readable error code. Extensions to this standard can define specific error codes and standardize additional fields. Codes are strings, for example "ERR_DECRYPTION_FAILED"
.
description
All errors must have a human-readable description
field that describes the error. This allows the application to represent the error for the user.
One example of a Cryptography Error is given below:
For compatibility with this encryption scheme, we stipulate the following:
A user who has the following identity private key...
...which implies the followign identity public key for that user...
...should be able to use security level 2
, the BRC2 Test
protocolID with keyID 42
and the following counterparty...
...to decrypt the message with the following ciphertext (with prepended initialization vector)...
... and receive the following plaintext:
...and to validate the message with the following HMAC...
... the message whose HMAC is above as being:
The recipient begins by computing the invoice number based on the security level, protocol ID, and key ID
The recipient uses key derivation with the computed invoice number, their own private key and the public key of the sender, to compute the sender's child public key
We build upon the abstract messaging layer first described in . Specifically, we define five new messages to facilitate requests and responses for encryption and decryption, and error handling. For each of the messages, we stipulate that there exists some out-of-band mechanism for the parties to communicate which of the messages are being exchanged, removing the need for a message type field. Finally, specifically for the request messages, we stipulate that the message comprises a header and a payload, with the payload containing the data (ciphertext or plaintext), and the header containing the other information. For the response messages, no message header is defined and the payload simply contains the specified data.
The encryption request is a message sent by the application to the client. It contains a header with the following information:
The security level and protocol ID represented as an array. For example, [0, "hello world"]
represents a level-0 protocol with open permissions, while [2, "document signing"]
represents a level 2 protocol.
The key ID
The counterparty, or self
The security level and protocol ID represented as an array. For example, [0, "hello world"]
represents a level-0 protocol with open permissions, while [2, "document signing"]
represents a level 2 protocol.
The key ID
The counterparty, or self
This encryption capability is incorporated into the
1:
2: