<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 <voisine@gmail.com>
           James MacWhyte <macwhyte@gmail.com>
  Status:  Draft
  Type:    Informational
  Created: 2015-11-20
</pre>

==Abstract==

This BIP is an extension to BIP 70 that provides two enhancements to the existing Payment Protocol.

# It allows the requestor of a Payment Request to voluntarily sign the original request and provide a certificate to allow the payee to know who they are transacting with. 

# It encrypts the Payment Request that is returned, before handing it off to the SSL/TLS layer to prevent man in the middle viewing of the Payment Request details.

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 motivation for defining this extension to the BIP70 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. This also allows for automated creation of off blockchain transaction logs that are human readable, containing who you transacted with, in addition to the information that it contains today.

The motivation for this extension to BIP70 is twofold:

# Ensure that the payment details can only be seen by the participants in the transaction, and not any third party.  By encrypting at the application layer we protect the payment request from being intercepted by a man in the middle, and allow mobile and desktop wallets to use a server to act as a “store and forward server” or “meet point” for serving Payment Requests without having to worry the server operator can spy on their transactions.

# Allow a sender of funds the option of sharing their identity with the receiver.  This information could then be used to:

* Make bitcoin logs more human readable 
* Give the user the ability to decide who to release payment details to 
* Allow an entity such as a political campaign to ensure donors match regulatory and legal requirements 
* Allow for an open standards based way to meet regulatory requirements

In short we wanted to make bitcoin more human, while at the same time improving transaction privacy.

==Definitions==
{| class="wikitable"
| Sender    || Entity wishing to transfer value that they control
|-
| Receiver  || Entity receiving a value transfer
|}

==Acronyms==
{| class="wikitable"
! Acronym !! Expanded !! Description
|-
| IR || InvoiceRequest || A request to create and return an encrypted PaymentRequest
|-
| RPR || ReturnPaymentRequest  || A message returned based on a submitted InvoiceRequest containing an encrypted PaymentRequest
|}

==New Messages==

===InvoiceRequest===
The InvoiceRequest message allows a Sender to send information to the Receiver such that they can create and return a ReturnPaymentRequest.

<pre>
message InvoiceRequest {
        required bytes  sender_public_key = 1;              // Sender's EC Public Key
        required uint64 nonce = 2;                          // Microseconds since epoch
        optional uint64 amount = 3 [default = 0];           // amount is integer-number-of-satoshis
        optional string pki_type = 4 [default = "none"];    // none / x509+sha256
        optional bytes  pki_data = 5;                       // Depends on pki_type
        optional string notification_url = 6;               // URL to notify on ReturnPaymentRequest ready
        optional bytes  signature = 7;                      // PKI-dependent signature
}
</pre>

{| class="wikitable"
! Field Name !! Description
|-
| sender_public_key     || Sender's EC Public Key
|-
| nonce                 || Microseconds since epoch
|-
| amount                || amount is integer-number-of-satoshis (default: 0)
|-
| pki_type              || none / x509+sha256 (default: "none")
|-
| pki_data              || Depends on pki_type
|-
| notification_url      || Secure (usually HTTPS) location where a ReturnPaymentRequest (see below) may be sent when ready
|-
| signature             || PKI-dependent signature
|}

===ReturnPaymentRequest===

The ReturnPaymentRequest message is an encapsulating message that allows the transmission of an encrypted, serialized PaymentRequest.

<pre>
message ReturnPaymentRequest {
        required bytes encrypted_payment_request = 1;      // Encrypted, Serialized PaymentRequest
        required bytes receiver_public_key = 2;            // Receiver's EC Public Key
        required bytes payment_request_hash = 3;           // SHA256 of Serialized PaymentRequest
}
</pre>
{| class="wikitable"
! Field Name</b> !! Description
|-
| encrypted_payment_request || AES-256-CBC Encrypted Serialized PaymentRequest
|-
| receiver_public_key       || Receiver's EC Public Key
|-
| payment_request_hash      || SHA256 Hash of Non-Encrypted, Serialized PaymentRequest
|}

==InvoiceRequest / ReturnPaymentRequest Process==

===Overview===

# Sender creates InvoiceRequest
# Sender transmits InvoiceRequest to Receiver
# Receiver validates InvoiceRequest
# Receiver creates PaymentRequest
# Receiver encrypts the PaymentRequest
# Receiver creates ReturnPaymentRequest (containing an encrypted PaymentRequest)
# Receiver transmits ReturnPaymentRequest to Sender
# Sender validates ReturnPaymentRequest
# Sender decrypts and validates encrypted PaymentRequest

This overview flow is illustrated below:

<img src=bip-ir/overview_flow.png></img>

===Message Interaction Details===

====InvoiceRequest====
Sender must transmit InvoiceRequest to Receiver (or Receiver's agent) via TLS-protected HTTP. Sender transmitting InvoiceRequest 
messages must set appropriate Content-Type headers as specified here:
<pre>Content-Type: application/bitcoin-invoicerequest</pre>

====ReturnPaymentRequest====
Receiver must transmit ReturnPaymentRequest to Sender (or Sender's agent) via TLS-protected HTTP. Receiver transmitting
ReturnPaymentRequest messages must set appropritate Content-Type headers as specified here:
<pre>Content-Type: application/bitcoin-returnpaymentrequest</pre>

====Message or Communication Errors====
An invalid or unparsable message or communications error must be communicated to the party that initiated the communication. This
should be done through standard HTTP Status Code messaging ([https://tools.ietf.org/html/rfc7231 RFC 7231 Section 6]).

===InvoiceRequest Message Creation===
* Create an InvoiceRequest message
* sender_public_key MUST be set to the public key of an EC keypair
* nonce MUST be set to the current epoch time in microseconds
* Amount is optional
* Set notification_url to URL that the Receiver will submit completed ReturnPaymentRequest to
* 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 [https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki#Certificates Certificates]) section)
** Sign InvoiceRequest with signature = "" using the X509 Certificate's private key
** Set signature value to the computed signature

===InvoiceRequest Validation===
* Validate sender_public_key is a valid EC public key
* The nonce must not be repeated. The service receiving the InvoiceRequest may use whatever method to make sure that the nonce is never repeated. 
* 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

===ReturnPaymentRequest Message Creation and PaymentRequest Encryption===
* Encrypt the serialized PaymentRequest using AES-256-CBC setup as described in <b>ECDH Point Generation and AES-256 (CBC Mode) Setup (see below)</b>
* 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 payment_request_hash to generated SHA256 hash of the serialized PaymentRequest (without encryption)

===ReturnPaymentRequest Validation and Decryption===
* Decrypt the serialized PaymentRequest using AES-256-CBC setup as described in <b>ECDH Point Generation and AES-256 (CBC Mode) Setup (see below)</b>
* Validate payment_request_hash matches SHA256 of the decrypted, serialized PaymentRequest
* Deserialize the serialized PaymentRequest

===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 the given InvoiceRequest's nonce field 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)

==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]
