2015-12-04 02:24:29 +01:00
<pre>
BIP: XXX
Title: Out of Band Address Exchange using Encrypted PaymentRequests
Authors: Matt David <matt@netki.com>
Justin Newton <justin@netki.com>
Aaron Voisine <aaron@breadwallet.com>
Status: Draft
Type: Informational
Created: 2015-11-20
</pre>
==Abstract==
This BIP is an extension to BIP70 the extends the payment protocol to prevent PaymentRequet interception / modification
during transmission using ephemeral key encryption, allow permissioned release of PaymentRequests to PaymentRequest requestors
and, allow a requestor to supply a certificate and signature to the PaymentRequest creator.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in RFC 2119.
==Motivation==
The motiviation for defining this extension to the BIP-70 Payment Protocol is to allow 2 parties to exchange payment
information in a permissioned and encrypted way such that wallet address communication can become a more automated process.
Additionally, this extension allows for the requestor of a PaymentRequest to supply a certificate and signature in order
to facilitate identification for address release.
==Definitions==
2015-12-04 02:30:04 +01:00
{| class="wikitable"
2015-12-04 20:10:01 +01:00
| Sender || Entity wishes to transfer value that they control
2015-12-04 02:31:09 +01:00
|-
2015-12-04 20:10:01 +01:00
| Receiver || Entity receiving a value transfer
2015-12-04 02:24:29 +01:00
|}
===Acronyms===
2015-12-04 02:30:04 +01:00
{| class="wikitable"
! Acronym !! Expanded !! Description
2015-12-04 02:31:09 +01:00
|-
2015-12-04 02:24:29 +01:00
| IR || InvoiceRequest || A request to create a PaymentRequest
2015-12-04 02:31:09 +01:00
|-
2015-12-04 02:24:29 +01:00
| RPR || ReturnPaymentRequest || A ReturnPaymentRequest returned based on a submitted InvoiceRequest
|}
===New Messages===
====InvoiceRequest====
The new InvoiceRequest message allows a requestor to send information to the responder such that they can return a ReturnPaymentRequest.
<pre>
message InvoiceRequest {
required bytes sender_public_key = 1; // Sender's EC Public Key
optional uint64 amount = 2 [default = 0]; // amount is integer-number-of-satoshis
optional string pki_type = 3 [default = "none"]; // none / x509+sha256
optional bytes pki_data = 4; // Depends on pki_type
optional string notification_url = 5; // URL to notify on ReturnPaymentRequest ready
optional bytes signature = 6; // PKI-dependent signature
}
</pre>
2015-12-04 02:30:04 +01:00
{| class="wikitable"
! Field Name !! Description
2015-12-04 02:32:01 +01:00
|-
2015-12-04 02:24:29 +01:00
| sender_public_key || Sender's EC Public Key
2015-12-04 02:31:09 +01:00
|-
2015-12-04 02:24:29 +01:00
| amount || amount is integer-number-of-satoshis (default: 0)
2015-12-04 02:31:09 +01:00
|-
2015-12-04 02:24:29 +01:00
| pki_type || none / x509+sha256 (default: "none")
2015-12-04 02:31:09 +01:00
|-
2015-12-04 02:24:29 +01:00
| pki_data || Depends on pki_type
2015-12-04 02:31:09 +01:00
|-
2015-12-04 02:24:29 +01:00
| notification_url || URL to notify on ReturnPaymentRequest ready
2015-12-04 02:31:09 +01:00
|-
2015-12-04 02:24:29 +01:00
| signature || PKI-dependent signature
|}
====ReturnPaymentRequest====
The new ReturnPaymentRequest message is an encapsulating message that allows the transmission of an encrypted, serialized PaymentRequest.
<pre>
message ReturnPaymentRequest {
required bytes encrypted_payment_request = 1;
required bytes receiver_public_key = 2;
required bytes ephemeral_public_key = 3;
required bytes payment_request_hash = 4;
}
</pre>
2015-12-04 02:30:04 +01:00
{| class="wikitable"
! Field Name</b> !! Description
2015-12-04 02:31:09 +01:00
|-
2015-12-04 20:10:01 +01:00
| encrypted_payment_request || AES-256-CBC Encrypted Serialized PaymentRequest
2015-12-04 02:31:09 +01:00
|-
2015-12-04 20:10:01 +01:00
| receiver_public_key || Receiver's EC Public Key
2015-12-04 02:31:09 +01:00
|-
2015-12-04 20:10:01 +01:00
| ephemeral_public_key || Ephemeral EC Public Key
2015-12-04 02:31:09 +01:00
|-
2015-12-04 20:10:01 +01:00
| payment_request_hash || SHA256 Hash of Non-Encrypted, Serialized PaymentRequest
2015-12-04 02:24:29 +01:00
|}
2015-12-04 20:10:01 +01:00
==InvoiceRequest / ReturnPaymentRequest Process==
2015-12-04 02:24:29 +01:00
===Overview===
2015-12-04 20:31:38 +01:00
# Sender [[#invoicerequest-message-creation|creates]] InvoiceRequest
2015-12-04 20:10:01 +01:00
# Sender transmits InvoiceRequest to Receiver
2015-12-04 20:26:32 +01:00
# Receiver [[#ir-validation|validates]] InvoiceRequest
2015-12-04 20:10:01 +01:00
# Receiver creates PaymentRequest
2015-12-04 20:26:32 +01:00
# Receiver [[#rpr-creation-encryption|encrypts]] the PaymentRequest
# Receiver [[#rpr-creation-encryption|creates]] ReturnPaymentRequest (containing an encrypted PaymentRequest)
2015-12-04 20:10:01 +01:00
# Receiver transmits ReturnPaymentRequest to Sender
# Sender validates ReturnPaymentRequest
2015-12-04 20:26:32 +01:00
# Sender [[#rpr-validation-pr-decryption|decrypts and validates]] encrypted PaymentRequest
2015-12-04 20:10:01 +01:00
2015-12-04 20:29:44 +01:00
<span id="ir-creation"></span>
2015-12-04 02:24:29 +01:00
===InvoiceRequest Message Creation===
* Create an InvoiceRequest message
2015-12-04 20:10:01 +01:00
* sender_public_key MUST be set. This is the public key of an EC keypair using secp256k1.
2015-12-04 02:24:29 +01:00
* Set amount if desired
2015-12-04 20:10:01 +01:00
* Set notification_url to URL that Receiver will submit completed ReturnPaymentRequest to
2015-12-04 02:24:29 +01:00
* If NOT including certificate, set pki_type to "none"
* If including certificate:
** Set pki_type to "x509+sha256"
** Set pki_data as it would be set in BIP-0070 (see [Certificates](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki#Certificates) section)
** Sign InvoiceRequest with signature == "" using the X509 Certificate's private key
2015-12-04 20:29:44 +01:00
<span id="ir-validation"></span>
2015-12-04 20:10:01 +01:00
===InvoiceRequest Validation===
2015-12-04 02:24:29 +01:00
2015-12-04 20:10:01 +01:00
* Validate sender_public_key is a valid EC public key
* Validate notification_url if set, contains characters deemed valid for a URL (avoiding XSS related characters, etc).
* If pki_type is None, InvoiceRequest is VALID
* If pki_type is x509+sha256 and signature is valid for the serialized InvoiceRequest where signature is set to "", InvoiceRequest is VALID
2015-12-04 02:24:29 +01:00
2015-12-04 20:29:44 +01:00
<span id="rpr-creation-encryption"></span>
2015-12-04 20:10:01 +01:00
===ReturnPaymentRequest Message Creation and PaymentRequest Encryption===
* Encrypt the serialized PaymentRequest using AES-256-CBC setup as described in [[#ECDH-AES-Setup ECDH Point Generation and AES-256 (CBC Mode) Setup]]
2015-12-04 02:24:29 +01:00
* Create ReturnPaymentRequest message
* Set encrypted_payment_request to be the encrypted value of the PaymentRequest
* Set receiver_public_key to the Receiver's EC public key (of which the private key was previously used in ECDH secret point calculation)
* Set ephemeral_public_key to the public key of an EC keypair created using the secret point's X value.
* Set payment_request_hash to generated SHA256 hash of the serialized PaymentRequest (without encryption)
2015-12-04 20:29:44 +01:00
<span id="rpr-validation-pr-decryption"></span>
2015-12-04 02:24:29 +01:00
===ReturnPaymentRequest Validation and Decryption===
* Validate ephemeral_public_key matches public key of an EC keypair created using the secret point's X value.
2015-12-04 20:10:01 +01:00
* Decrypt the serialized PaymentRequest using AES-256-CBC setup as described in [[#ECDH-AES-Setup ECDH Point Generation and AES-256 (CBC Mode) Setup]]
2015-12-04 02:24:29 +01:00
* Validate payment_request_hash matches SHA256 of the decrypted, serialized PaymentRequest
* Deserialize the serialized PaymentRequest
2015-12-04 20:26:32 +01:00
{{anchor|ECDH-AES-Setup}}
2015-12-04 20:10:01 +01:00
===ECDH Point Generation and AES-256 (CBC Mode) Setup===
* Generate the '''secret point''' using [https://en.wikipedia.org/wiki/Elliptic_curve_Diffie– Hellman ECDH] using the local entity's private key and the remote entity's public key as inputs.
* Initialize [http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf HMAC_DRBG]
** Use '''secret point's''' X value for Entropy
** Use Sender's public key for Nonce
* Initialize AES-256 in CBC Mode
** Use HMAC_DRBG.GENERATE(32) as the Encryption Key (256 bits)
** Use HMAC_DRBG.GENERATE(16) as the Initialization Vector (IV) (128 bits)
2015-12-04 02:24:29 +01:00
==Reference==
* [[bip-0070.mediawiki|BIP70 - Payment Protocol]]
* [https://en.wikipedia.org/wiki/Elliptic_curve_Diffie– Hellman ECDH]
* [http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf HMAC_DRBG]
* [https://tools.ietf.org/html/rfc6979 RFC6979]