Browse Source

- Make message public key sharing mandatory for messages that are encrypted and where both keys are known. For EncryptedInvoiceRequest, only the sender_public_key is required

- Add nonce to EncryptedPaymentRequest, EncryptedPayment and EncryptedPaymentACK
- Update ECDH instruction to allow for the current message instead of an InvoiceRequest to contain the nonce
- Updated paymentrequest.proto with BIP definition changes
20170314-comments
Matt David 9 years ago
parent
commit
10e6f46569
  1. 84
      bip-invoicerequest-extension.mediawiki
  2. 49
      bip-ir/paymentrequest.proto

84
bip-invoicerequest-extension.mediawiki

@ -145,13 +145,15 @@ message EncryptedInvoiceRequest {
|-
| sender_public_key || Sender's EC public key
|-
| receiver_public_key || Receiver's EC public key, can be omitted if this message is sent directly to the recipient, or is sent to a Store & Forward server that already understands who the recipient should be (if specified by URI endpoint, for example)
| receiver_public_key || Receiver's EC public key
|-
| nonce || The nonce in use for the CBC encryption
|-
| identifier || A unique key to identify this entire exchange on the server. By default, invoice_request_hash SHOULD be used.
| identifier || A unique key to identify this entire exchange on the server. invoice_request_hash SHOULD be used by default.
|}
receiver_public_key MAY be omitted if this message is sent directly to the Receiver. receiver_public_key MAY also be omitted if the EncryptedInvoiceRequest is being sent to a Store & Forward server which already understands who the Receiver is. An example of this is a Store & Forward server URL that uniquely identifies the Receiver (and their public key).
===EncryptedPaymentRequest===
The EncryptedPaymentRequest message is an encapsulating message that allows the transmission of an encrypted, serialized PaymentRequest.
@ -160,12 +162,12 @@ The EncryptedPaymentRequest message is an encapsulating message that allows the
message EncryptedPaymentRequest {
required bytes encrypted_payment_request = 1;
required bytes payment_request_hash = 2;
optional bytes receiver_public_key = 3;
optional bytes sender_public_key = 4;
optional uint64 nonce = 5;
required bytes receiver_public_key = 3;
required bytes sender_public_key = 4;
required uint64 nonce = 5;
optional bool requires_payment_message = 6;
optional bytes signature = 7;
optional bytes identifier = 6;
optional bytes identifier = 8;
}
</pre>
{| class="wikitable"
@ -175,17 +177,17 @@ message EncryptedPaymentRequest {
|-
| payment_request_hash || SHA256 Hash of non-encrypted, serialized PaymentRequest. MUST be used for verification to prevent oracle attacks.
|-
| receiver_public_key || Receiver's EC public key, only necessary if not already shared or known (for example, if this message is not in response to an InvoiceRequest)
| receiver_public_key || Receiver's EC public key
|-
| sender_public_key || Sender's EC public key, can be omitted if this message is sent directly to the recipient, or is sent to a Store & Forward server that already understands who the recipient should be (if specified by URI endpoint, for example)
| sender_public_key || Sender's EC public key
|-
| nonce || The nonce in use for the CBC encryption, only necessary if not already shared (for example, if this message is not in response to an InvoiceRequest)
| nonce || The nonce in use for the CBC encryption
|-
| requires_payment_message || Internal PaymentRequest requires follow-up Payment message
|-
| signature || A signature of this message using Receiver's EC key, serialized with a value of "" for signature. Only necessary if required by the server to authenticate a reply to an InvoiceRequest.
| signature || A signature of this message using Receiver's EC key, serialized with a value of "" for signature. REQUIRED if server requires InvoiceRequest reply authentication.
|-
| identifier || If the PaymentRequest is in response to an InvoiceRequest, use the identifier specified with the InvoiceRequest, if any. Otherwise, use payment_request_hash or other unique value.
| identifier || MUST use the identifier specified with the InvoiceRequest if the PaymentRequest is in response to an InvoiceRequest. Otherwise, use payment_request_hash or other unique value.
|}
===EncryptedPayment===
@ -194,10 +196,13 @@ The EncryptedPayment message allows a BIP70 Payment message to be transmitted th
<pre>
message EncryptedPayment {
required bytes encrypted_payment = 1;
required bytes payment_hash = 2;
required bytes signature = 3;
optional bytes identifier = 4;
required bytes encrypted_payment = 1;
required bytes payment_hash = 2;
required bytes receiver_public_key = 3;
required bytes sender_public_key = 4;
required uint64 nonce = 5;
required bytes signature = 6;
optional bytes identifier = 7;
}
</pre>
{| class="wikitable"
@ -207,6 +212,12 @@ message EncryptedPayment {
|-
| payment_hash || SHA256 Hash of original non-encrypted, serialized Payment message. MUST be used for verification to prevent oracle attacks.
|-
| receiver_public_key || Receiver's EC public key
|-
| sender_public_key || Sender's EC public key
|-
| nonce || The nonce in use for the CBC encryption
|-
| signature || A signature of this message using Sender's EC key, serialized with a value of "" for signature.
|-
| identifier || Use the identifier specified with the EncryptedPaymentRequest, if any.
@ -218,10 +229,13 @@ An encrypted version of the BIP70 PaymentAck.
<pre>
message EncryptedPaymentACK {
required bytes encrypted_payment_ack = 1;
required bytes payment_ack_hash = 2;
required bytes signature = 3;
optional bytes identifier = 4;
required bytes encrypted_payment_ack = 1;
required bytes payment_ack_hash = 2;
required bytes receiver_public_key = 3;
required bytes sender_public_key = 4;
required uint64 nonce = 5;
required bytes signature = 6;
optional bytes identifier = 7;
}
</pre>
{| class="wikitable"
@ -231,6 +245,12 @@ message EncryptedPaymentACK {
|-
| payment_ack_hash || SHA256 Hash of original non-encrypted, serialized Payment message. MUST be used for verification to prevent oracle attacks.
|-
| receiver_public_key || Receiver's EC public key
|-
| sender_public_key || Sender's EC public key
|-
| nonce || The nonce in use for the CBC encryption
|-
| signature || A signature of this message using Receiver's EC key, serialized with a value of "" for signature.
|-
| identifier || Use the identifier specified with the EncryptedPayment, if any.
@ -301,10 +321,12 @@ SHOULD be done through standard HTTP Status Code messaging ([https://tools.ietf.
For the following we assume the Sender already knows the Receiver's public key, and the exchange starts with an EncryptedInvoiceRequest.
Where used, **nonce** MUST be set to a non-repeating number. The current epoch time in microseconds SHOULD be used, unless the creating device doesn't have access to a RTC (in the case of a smart card, for example). The service receiving the message containing the **nonce** MAY use whatever method to make sure that the **nonce** is never repeated.
===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 a non-repeating number. The current epoch time in microseconds SHOULD be used, unless the creating device doesn't have access to a RTC (in the case of a smart card, for example)
* nonce MUST be set according to the requirement above.
* Amount is optional. If the amount is not specified by the InvoiceRequest, the Receiver MAY specify the amount in the returned PaymentRequest. If an amount is specified by the InvoiceRequest and a PaymentRequest cannot be generated for that amount, the InvoiceRequest SHOULD be rejected with HTTP status code 406.
* Memo is optional. This MAY be set to a human readable description of the InvoiceRequest
* Set notification_url to URL that the Receiver will submit completed EncryptedPaymentRequest to
@ -318,10 +340,12 @@ For the following we assume the Sender already knows the Receiver's public key,
===EncryptedInvoiceRequest Message Creation===
* Create an EncryptedInvoiceRequest
* Retrieve endpoint public key to use in <b>ECDH Point Generation</b> as specified in <b>Initial Public Key Retrieval for InvoiceRequest Encryption</b> (see below)
* sender_public_key MUST be set to the public key of an EC keypair
* sender_public_key MUST be set to the public key of the Sender's EC keypair
* receiver_public_key MAY be set to the public key of the Receiver's EC keypair
* invoice_request_hash MUST be set to the SHA256 hash of the serialized InvoiceRequest (without encryption)
* Encrypt the serialized InvoiceRequest using AES-256-CBC setup as described in <b>ECDH Point Generation and AES-256 (CBC Mode) Setup (see below)</b>
* encrypted_invoice_Request MUST be set to the encrypted values of the InvoiceRequest
* nonce MUST be set to the nonce used in the AES-256-CBC encryption operation
* Set identifier to invoice_request_hash
===InvoiceRequest Validation===
@ -336,9 +360,14 @@ For the following we assume the Sender already knows the Receiver's public key,
* Create EncryptedPaymentRequest message
* Set encrypted_payment_request to be the encrypted value of the PaymentRequest
* Set payment_request_hash to generated SHA256 hash of the serialized PaymentRequest (without encryption)
* sender_public_key MUST be set to the public key of the Sender's EC keypair
* receiver_public_key MUST be set to the public key of the Receiver's EC keypair
* nonce MUST be set to the nonce used in the AES-256-CBC encryption operation
* requires_payment_message MAY be set to true if the PaymentRequest requires a Payment message
* Set identifier to the value received in EncryptedInvoiceRequest
* Set signature to ""
* Sign the serialized EncryptedPayment message with the Receiver's EC public key
* Set signature to the result of the signature operation above
===EncryptedPaymentRequest 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>
@ -349,7 +378,7 @@ For the following we assume the Sender already knows the Receiver's public key,
* 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
** Use the given message'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)
@ -366,8 +395,11 @@ Initial public key retrieval for InvoiceRequest encryption can be done in a numb
* Encrypt the serialized Payment using AES-256-CBC using secret key calculated in the <b>EncryptedPaymentRequest Message Creation and PaymentRequest Encryption</b> step (see above)
* Create EncryptedPayment message
* Set encrypted_payment to be the encrypted value of the Payment
* Set identifier to the value received in EncryptedPaymentRequest
* Set payment_hash to generated SHA256 hash of the serialized Payment (without encryption)
* sender_public_key MUST be set to the public key of the Sender's EC keypair
* receiver_public_key MUST be set to the public key of the Receiver's EC keypair
* nonce MUST be set to the nonce used in the AES-256-CBC encryption operation
* Set identifier to the value received in EncryptedPaymentRequest
* Set signature to ""
* Sign the serialized EncryptedPayment message with the Sender's EC public key
* Set signature to the result of the signature operation above
@ -377,6 +409,10 @@ Initial public key retrieval for InvoiceRequest encryption can be done in a numb
* Create EncryptedPaymentACK message
* Set encrypted_payment_ack to be the encrypted value of the PaymentACK
* Set payment_ack_hash to generated SHA256 hash of the serialized PaymentACK (without encryption)
* sender_public_key MUST be set to the public key of the Sender's EC keypair
* receiver_public_key MUST be set to the public key of the Receiver's EC keypair
* nonce MUST be set to the nonce used in the AES-256-CBC encryption operation
* Set identifier to the value received in EncryptedPaymentRequest
* Set signature to ""
* Sign the serialized EncryptedPaymentACK message with the Receiver's EC public key
* Set signature to the result of the signature operation above
@ -432,4 +468,4 @@ In this case, the Sender submits the transaction to the bitcoin network.
* [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]
* [https://en.bitcoin.it/wiki/Address_reuse Address Reuse]
* [https://en.bitcoin.it/wiki/Address_reuse Address Reuse]

49
bip-ir/paymentrequest.proto

@ -46,11 +46,6 @@ message PaymentACK {
}
// BIP-IR Extensions
message EncryptedInvoiceRequest {
required bytes encrypted_invoice_request = 1; // AES-256-CBC Encrypted InvoiceRequest as defined in InvoiceRequest Spec
required bytes sender_public_key = 2; // Sender's EC Public Key
required bytes invoice_request_hash = 3; // SHA256 Hash of Non-Encrypted, Serialized InvoiceRequest (used for authentication)
}
message InvoiceRequest {
required bytes sender_public_key = 1; // Sender's EC Public Key
@ -63,22 +58,42 @@ message InvoiceRequest {
optional bytes signature = 8; // PKI-dependent signature
}
message EncryptedInvoiceRequest {
required bytes encrypted_invoice_request = 1; // AES-256-CBC Encrypted InvoiceRequest as defined in InvoiceRequest Spec
required bytes invoice_request_hash = 2; // SHA256 Hash of Non-Encrypted, Serialized InvoiceRequest (used for authentication)
required bytes sender_public_key = 3; // Sender's EC Public Key
optional bytes receiver_public_key = 4; // Receiver's EC Public Key
required uint64 nonce = 5; // Microseconds since epoch
optional bytes identifier = 6; // Unique key to identify this entire exchange on the server. invoice_request_hash SHOULD be used by default
}
message EncryptedPaymentRequest {
required bytes encrypted_payment_request = 1; // AES-256-CBC Encrypted PaymentRequest as defined in InvoiceRequest Spec
required bytes receiver_public_key = 2; // Receiver's EC Public Key
required bytes ephemeral_public_key = 3; // Public Key of ECDH-derived keypair
required bytes payment_request_hash = 4; // SHA256 Hash of Non-Encrypted, Serialized PaymentRequest (used for authentication)
required bool requires_payment_message = 5 [default = false]; // Requires Payment/PaymentACK message exchange
required bytes encrypted_payment_request = 1; // AES-256-CBC Encrypted PaymentRequest as defined in InvoiceRequest Spec
required bytes payment_request_hash = 2; // SHA256 Hash of Non-Encrypted, Serialized PaymentRequest (used for authentication)
required bytes receiver_public_key = 3; // Receiver's EC Public Key
required bytes sender_public_key = 4; // Sender's EC Public Key
required uint64 nonce = 5; // Microseconds since epoch
optional bool requires_payment_message = 6 [default = false]; // Requires Payment/PaymentACK message exchange
optional bytes signature = 7; // Signature of this message using Receiver's EC key
optional bytes identifier = 8; // MUST use the identifier specified with the InvoiceRequest if the PaymentRequest is in response to an InvoiceRequest. Otherwise, use payment_request_hash or other unique value.
}
message EncryptedPayment {
required bytes encrypted_payment = 1; // AES-256-CBC Encrypted Payment as defined in InvoiceRequest Spec
required bytes payment_request_hash = 2; // SHA256 Hash of Non-Encrypted, Serialized PaymentRequest returned in the transaction's EncryptedPaymentRequest message
required bytes signature = 3; // Signature over EncryptedPayment with original Sender's EC Private Key
required bytes encrypted_payment = 1; // AES-256-CBC Encrypted BIP70 Payment as defined in InvoiceRequest Spec
required bytes payment_hash = 2; // SHA256 Hash of Non-Encrypted, Serialized BIP70 Payment
required bytes receiver_public_key = 3; // Receiver's EC Public Key
required bytes sender_public_key = 4; // Sender's EC Public Key
required uint64 nonce = 5; // Microseconds since epoch
required bytes signature = 6; // Signature over EncryptedPayment with Sender's EC Key
optional bytes identifier = 7; // Use the identifier specified with the EncryptedPaymentRequest, if any.
}
message EncryptedPaymentACK {
required bytes encrypted_payment_ack = 1; // AES-256-CBC Encrypted Payment as defined in InvoiceRequest Spec
required bytes payment_request_hash = 2; // SHA256 Hash of Non-Encrypted, Serialized PaymentRequest returned in the transaction's EncryptedPaymentRequest message
required bytes signature = 3; // Signature over EncryptedPaymentACK with the Receiver's EC Private key.
}
required bytes encrypted_payment_ack = 1; // AES-256-CBC Encrypted BIP70 PaymentACK as defined in InvoiceRequest Spec
required bytes payment_ack_hash = 2; // SHA256 Hash of Non-Encrypted, Serialized BIP70 PaymentACK
required bytes receiver_public_key = 3; // Receiver's EC Public Key
required bytes sender_public_key = 4; // Sender's EC Public Key
required uint64 nonce = 5; // Microseconds since epoch
required bytes signature = 6; // Signature over EncryptedPaymentACK with Receiver's EC Key
optional bytes identifier = 7; // Use the identifier specified with the EncryptedPaymentRequest, if any.
}

Loading…
Cancel
Save