Ty Everett ([email protected])
We devise a method for applications to request the encryption and decryption of data. Specifically, we define a mechanism for data encryption within the BRC-42 key derivation system, utilizing the BRC-43 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 BRC-42 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 parties1. 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 applications2. 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 BRC-42 key derivation. The BRC-2 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 BRC-43: users with clients, protocols and applications. We stipulate the use of BRC-43 invoice numbers in the context of BRC-42 key derivation, and we build on top of the permissions architecture defined by BRC-43.
When an application sends a message to a client requesting that data be encrypted, the message comprises:
- The BRC-43 security level, protocol ID, key ID and counterparty to facilitate BRC-42 key derivation and permissioning
- The data to encrypt
We stipulate the following process for encryption:
- The message sender begins by computing the BRC-43 invoice number based on the security level, protocol ID, and key ID
- The message sender uses BRC-42 key derivation with the computed invoice number to derive a child public key for the recipient
- The message sender uses BRC-42 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 BRC-1 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 begins by computing the BRC-43 invoice number based on the security level, protocol ID, and key ID
- The recipient uses BRC-42 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
- 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
We build upon the abstract messaging layer first described in BRC-1. Specifically, we define five new BRC-1 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 BRC-43 application to the client. It contains a header with the following information:
Field | Description |
---|---|
protocolID |
The BRC-43 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. |
keyID |
The BRC-43 key ID |
counterparty |
The BRC-43 counterparty, or self |
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:
Field | Description |
---|---|
protocolID |
The BRC-43 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. |
keyID |
The BRC-43 key ID |
counterparty |
The BRC-43 counterparty, or self |
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:
Field | Description |
---|---|
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:
{
"status": "error",
"code": "ERR_PERMISSION_DENIED",
"description": "You have denied permission for encrypting this data."
}
For compatibility with this encryption scheme, we stipulate the following:
A user who has the following identity private key...
6a2991c9de20e38b31d7ea147bf55f5039e4bbc073160f5e0d541d1f17e321b8
...which implies the followign identity public key for that user...
025ad43a22ac38d0bc1f8bacaabb323b5d634703b7a774c4268f6a09e4ddf79097
...should be able to use security level 2
, the BRC2 Test
protocolID with keyID 42
and the following counterparty...
0294c479f762f6baa97fbcd4393564c1d7bd8336ebd15928135bbcf575cd1a71a1
...to decrypt the message with the following ciphertext (with prepended initialization vector)...
[252, 203, 216, 184, 29, 161, 223, 212, 16, 193, 94, 99, 31, 140, 99, 43, 61, 236, 184, 67, 54, 105, 199, 47, 11, 19, 184, 127, 2, 165, 125, 9, 188, 195, 196, 39, 120, 130, 213, 95, 186, 89, 64, 28, 1, 80, 20, 213, 159, 133, 98, 253, 128, 105, 113, 247, 197, 152, 236, 64, 166, 207, 113, 134, 65, 38, 58, 24, 127, 145, 140, 206, 47, 70, 146, 84, 186, 72, 95, 35, 154, 112, 178, 55, 72, 124]
... and receive the following plaintext:
BRC-2 Encryption Compliance Validated!
...and to validate the message with the following HMAC...
[81, 240, 18, 153, 163, 45, 174, 85, 9, 246, 142, 125, 209, 133, 82, 76, 254, 103, 46, 182, 86, 59, 219, 61, 126, 30, 176, 232, 233, 100, 234, 14]
... the message whose HMAC is above as being:
BRC-2 HMAC Compliance Validated!
- This encryption capability is incorporated into the Babbage SDK