From 8bf7d90d204db64f3af4a28abacb55b961d02c2c Mon Sep 17 00:00:00 2001 From: Matt David Date: Tue, 29 Mar 2016 15:49:49 -0700 Subject: - Update HTTPS to be TLS-protected HTTP - Add Updated Messages section to describe the status_code and status_message - Separated Message and Communication Errors into Payment Protocol Errors and Communication Errors - Add first draft Payment Protocol error codes - Update InvoiceRequest Message Creation description amount example to return Payment Protocol error in the case of an issue with the amount. --- bip-0070/extensions.mediawiki | 4 ++- bip-0075.mediawiki | 60 ++++++++++++++++++++++++++++++++++++++----- bip-0075/paymentrequest.proto | 18 ++++++++----- 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/bip-0070/extensions.mediawiki b/bip-0070/extensions.mediawiki index b572b1d..947622d 100644 --- a/bip-0070/extensions.mediawiki +++ b/bip-0070/extensions.mediawiki @@ -5,5 +5,7 @@ Add your extension below using tags starting at 1000 and submit a pull-req. {| | Field Number || Extension Name || Field Name || Description |- -| 1000 || [[https://example.com|(unassigned)]] || (unassigned) || (unassigned) +| 1000 || [[https://github.com/bitcoin/bips/bip-0075.mediawiki|(BIP75)]] || status_code || Status Code for Payment Protocol error communication +|- +| 1001 || [[https://github.com/bitcoin/bips/bip-0075.mediawiki|(BIP75)]] || status_message || Human-readable message for Payment Protocol error communication |} \ No newline at end of file diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index 753c6e5..6bac44a 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -101,7 +101,7 @@ message InvoiceRequest { |- | memo || Human-readable description of invoice request for the receiver |- -| notification_url || Secure (usually HTTPS) location where an [[#EncryptedPaymentRequest|EncryptedPaymentRequest]] (see below) SHOULD be sent when ready +| notification_url || Secure (usually TLS-protected HTTP) location where an [[#EncryptedPaymentRequest|EncryptedPaymentRequest]] (see below) SHOULD be sent when ready |- | signature || PKI-dependent signature |} @@ -242,6 +242,19 @@ message EncryptedPaymentACK { | identifier || Use the identifier specified with the EncryptedPayment, if any. |} +==Updated Messages== +The BIP70 PaymentRequest, Payment and PaymentACK messages have been updated by this BIP to contain Payment Protocol error communication. The following two extension fields have been added to each of the aforementioned messages: + +
+{
+...
+    optional uint32 status_code = 1000;     // Payment Protocol status code
+    optional string status_message = 1001;  // Human-readable status message
+}
+
+ +status_code and/or status_message MUST be set to communicate a Payment Protocol error to the message receiver. The message consumer MUST handle status_code and status_message if either field is present. + ==InvoiceRequest / PaymentRequest Process== The process overview for using InvoiceRequests and receiving encrypted PaymentRequests is defined below in two sections. Optionally, the Sender MAY choose to encrypt the InvoiceRequest message and therefore MUST follow the '''Encrypted InvoiceRequest Overview''' process below. @@ -282,8 +295,8 @@ The process overview for using InvoiceRequests and receiving encrypted PaymentRe ==Message Interaction Details== -===New Message Content Types=== -Messages MUST be transmitted via TLS-protected HTTP using the appropriate Content-Type header as defined per message type here: +===New Message HTTP Content Types=== +When communicated via HTTP, these messages MUST be transmitted via TLS-protected HTTP using the appropriate Content-Type header as defined per message type here: {| class="wikitable" ! Message Type !! Content Type |- @@ -298,8 +311,43 @@ Messages MUST be transmitted via TLS-protected HTTP using the appropriate Conten | EncryptedPaymentACK || application/bitcoin-encrypted-paymentack |} -===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]). If the provided hash of each message does not match the contents of the message once decrypted, a general error should be returned to prevent oracle attacks. +===Payment Protocol Errors=== + +Payment Protocol errors MUST be communicated to the party that initiated the communication via the status_code and status_message extension fields present in the PaymentRequest, Payment and PaymentACK messages. For example, if the provided hash of each message does not match the contents of the message once decrypted, a general error MUST be returned to prevent oracle attacks. + +====Payment Protocol Status Codes==== +{| class="wikitable" +! Status Code !! Description +|- +| 1 || General / Unknown Error +|- +| 2 || Authentication Failed +|- +| 3 || Encrypted Message Required +|- +| 100 || Amount Too High +|- +| 101 || Amount Too Low +|- +| 102 || Amount Invalid +|- +| 103 || Payment Does Not Meet PaymentRequest Requirements +|- +| 200 || Certificate Required +|- +| 201 || Certificate Expired +|- +| 202 || Certificate Invalid for Transaction +|- +| 203 || Certificate Revoked +|- +| 204 || Certificate Not Well Rooted +|- +|} + +===Communication Errors=== + +Communications errors MUST be communicated to the party that initiated the communication via the communication layer's existing error messaging faciltiies. In the case of TLS-protected HTTP, this SHOULD be done through standard HTTP Status Code messaging ([https://tools.ietf.org/html/rfc7231 RFC 7231 Section 6]). ==Process Step Details== @@ -311,7 +359,7 @@ Where used, '''nonce''' MUST be set to a non-repeating number AND MUST be chosen * Create an InvoiceRequest message * sender_public_key MUST be set to the public key of an EC keypair * 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. +* 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 return a PaymentRequest with the status_code and status_message fields set appropriately. * 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 * If NOT including certificate, set pki_type to "none" diff --git a/bip-0075/paymentrequest.proto b/bip-0075/paymentrequest.proto index 1c9cc8e..912fcd3 100644 --- a/bip-0075/paymentrequest.proto +++ b/bip-0075/paymentrequest.proto @@ -33,19 +33,25 @@ message PaymentRequest { optional bytes pki_data = 3; // depends on pki_type required bytes serialized_payment_details = 4; // PaymentDetails optional bytes signature = 5; // pki-dependent signature + optional uint32 status_code = 1000; // Payment Protocol status code + optional string status_message = 1001; // Human-readable Payment Protocol status message } message X509Certificates { repeated bytes certificate = 1; // DER-encoded X.509 certificate chain } message Payment { - optional bytes merchant_data = 1; // From PaymentDetails.merchant_data - repeated bytes transactions = 2; // Signed transactions that satisfy PaymentDetails.outputs - repeated Output refund_to = 3; // Where to send refunds, if a refund is necessary - optional string memo = 4; // Human-readable message for the merchant + optional bytes merchant_data = 1; // From PaymentDetails.merchant_data + repeated bytes transactions = 2; // Signed transactions that satisfy PaymentDetails.outputs + repeated Output refund_to = 3; // Where to send refunds, if a refund is necessary + optional string memo = 4; // Human-readable message for the merchant + optional uint32 status_code = 1000; // Payment Protocol status code + optional string status_message = 1001; // Human-readable Payment Protocol status message } message PaymentACK { - required Payment payment = 1; // Payment message that triggered this ACK - optional string memo = 2; // Human-readable message for customer + required Payment payment = 1; // Payment message that triggered this ACK + optional string memo = 2; // Human-readable message for customer + optional uint32 status_code = 1000; // Payment Protocol status code + optional string status_message = 1001; // Human-readable Payment Protocol status message } // BIP-IR Extensions -- cgit v1.2.3 From 8bb63058fd80b6b89b2e09de402ad5ba635e9eeb Mon Sep 17 00:00:00 2001 From: Matt David Date: Tue, 26 Apr 2016 15:23:12 -0700 Subject: - Reset bip-0070/extensions.mediawiki to the original BIP70 contents - Remove status_code and status_message from individual Payment Protocol messages - Remove EncryptedInvoiceRequest, EncryptedPaymentRequest, EncryptedPayment and EncryptedPaymentACK messages from protobuf definition file - Add ProtocolMessageType enum and ProtocolMessageType and EncryptedProtocolMesssage messages to bip-0075/paymentrequest.proto definition file - Update BIP75 text to remove old individual message encryption paths and include new encapsulating messages for self-contained PaymentProtocol communication (including errors) over various transport layers - Add initial list of status codes - Update BIP75 to use AES-256-GCM and remove message hash as GCM mode provides authenticated encryption - Update ECDH calculation to use SHA256 hash of ECDH's X point instead of the raw X point itself --- bip-0070/extensions.mediawiki | 4 +- bip-0075.mediawiki | 345 +++++++++++++----------------------------- bip-0075/paymentrequest.proto | 70 +++------ 3 files changed, 128 insertions(+), 291 deletions(-) diff --git a/bip-0070/extensions.mediawiki b/bip-0070/extensions.mediawiki index 947622d..b572b1d 100644 --- a/bip-0070/extensions.mediawiki +++ b/bip-0070/extensions.mediawiki @@ -5,7 +5,5 @@ Add your extension below using tags starting at 1000 and submit a pull-req. {| | Field Number || Extension Name || Field Name || Description |- -| 1000 || [[https://github.com/bitcoin/bips/bip-0075.mediawiki|(BIP75)]] || status_code || Status Code for Payment Protocol error communication -|- -| 1001 || [[https://github.com/bitcoin/bips/bip-0075.mediawiki|(BIP75)]] || status_message || Human-readable message for Payment Protocol error communication +| 1000 || [[https://example.com|(unassigned)]] || (unassigned) || (unassigned) |} \ No newline at end of file diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index 6bac44a..3b0ba1f 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -14,9 +14,9 @@ This BIP is an extension to BIP 70 that provides two enhancements to the existing Payment Protocol. -# It allows the requester (Sender) of a Payment Request to voluntarily sign the original request and provide a certificate to allow the payee to know the identity of who they are transacting with. +# It allows the requester (Sender) of a PaymentRequest to voluntarily sign the original request and provide a certificate to allow the payee to know the identity of 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. +# It encrypts the PaymentRequest 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. @@ -69,12 +69,12 @@ A Bitcoin wallet developer would like to use a public Store & Forward service fo With this BIP, returned payment information is encrypted with an ECDH-computed shared key before sending to a Store & Forward service. In this case, a successful attack against a Store & Forward service would not be able to read or modify wallet address or payment information, only delete encrypted messages. ==New Messages== -Updated [/bip-0075/paymentrequest.proto paymentrequest.proto] contains the existing PaymentRequest Protocol Buffer messages as well asthe messages newly defined in this BIP. +Updated [/bip-0075/paymentrequest.proto paymentrequest.proto] contains the existing PaymentRequest Protocol Buffer messages as well as the messages newly defined in this BIP. Note: Public keys from both parties must be known to each other in order to facilitate encrypted communication. Although including both public keys in every message may get redundant, it provides the most flexibility as each message is completely self-contained. ===InvoiceRequest=== -The InvoiceRequest message allows a Sender to send information to the Receiver such that they can create and return a PaymentRequest. +The InvoiceRequest message allows a Sender to send information to the Receiver such that the Receiver can create and return a PaymentRequest.
 message InvoiceRequest {
@@ -106,190 +106,97 @@ message InvoiceRequest {
 | signature             || PKI-dependent signature
 |}
 
-
-===EncryptedInvoiceRequest===
-The EncryptedInvoiceRequest message allows a Sender to send an encrypted InvoiceRequest to the Receiver such that the details of the InvoiceRequest are kept secret.
+===ProtocolMessageType Enum===
+The ProtocolMessageType enum is defined in an extensible way to allow for new message type additions to the Payment Protocol. This enum is used in the newly defined ProtocolMessage and EncryptedProtocolMessage messages to define the serialized message type.
 
-message EncryptedInvoiceRequest {
-    required bytes  encrypted_invoice_request = 1;
-    required bytes  invoice_request_hash = 2;
-    required bytes  sender_public_key = 3;
-    required bytes  receiver_public_key = 4;
-    required uint64 nonce = 5;
-    optional bytes  signature = 6;
-    optional bytes  identifier = 7;
-    
+enum ProtocolMessageType {
+    INVOICE_REQUEST = 0;
+    PAYMENT_REQUEST = 1;
+    PAYMENT = 2;
+    PAYMENT_ACK =  3;
 }
 
-{| class="wikitable" -! Field Name !! Description -|- -| encrypted_invoice_request || AES-256-CBC encrypted, serialized InvoiceRequest -|- -| invoice_request_hash || SHA256 Hash of non-encrypted, serialized InvoiceRequest. MUST be used for verification to prevent oracle attacks. -|- -| sender_public_key || Sender's EC public key -|- -| receiver_public_key || Receiver'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. REQUIRED if server requires authentication. -|- -| identifier || A unique key to identify this entire exchange on the server. invoice_request_hash SHOULD be used by default. -|} - -===EncryptedPaymentRequest=== - -The EncryptedPaymentRequest message is an encapsulating message that allows the transmission of an encrypted, serialized PaymentRequest. - +===ProtocolMessage=== +The ProtocolMessage message is an encapsulating wrapper for any Payment Protocol message. It allows two-way, non-encrypted communication of Payment Protocol messages. The message also includes a status code and a status message that is used for error communication so the protocol does not rely on transport-layer error handling.
-message EncryptedPaymentRequest {
-        required bytes  encrypted_payment_request = 1;
-        required bytes  payment_request_hash = 2;
-        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 = 8;
+message ProtocolMessage {
+    required ProtocolMessageType message_type = 1;
+    required bytes serialized_message = 2;
+    optional uint64 status_code = 3;
+    optional string status_message = 4;
+    optional bytes identifier = 5;
 }
 
-{| class="wikitable" -! Field Name !! Description -|- -| encrypted_payment_request || AES-256-CBC encrypted, serialized BIP70 PaymentRequest -|- -| 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 -|- -| sender_public_key || Sender's EC public key -|- -| 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. REQUIRED if server requires authentication. -|- -| 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=== - -The EncryptedPayment message allows a BIP70 Payment message to be transmitted through a third party without revealing the details of the transaction. This message allows Store & Forward servers or other third parties to match and authenticate PaymentRequest and Payment messages without revealing the details of the transaction, thereby protecting privacy. - -
-message EncryptedPayment {
-        required bytes  encrypted_payment = 1;
-        required bytes  payment_hash = 2;
-        required bytes  sender_public_key = 3;
-        required bytes  receiver_public_key = 4;
-        required uint64 nonce = 5;
-        optional bytes  signature = 6;
-        optional bytes  identifier = 7;
-}
-
{| class="wikitable" ! Field Name !! Description |- -| encrypted_payment || AES-256-CBC encrypted, serialized BIP70 Payment message -|- -| payment_hash || SHA256 Hash of original non-encrypted, serialized Payment message. MUST be used for verification to prevent oracle attacks. +|message_type || Message Type of serialized_message (using enum ProtocolMessageType) |- -| sender_public_key || Sender's EC public key +|serialized_message || Serialized Payment Protocol Message |- -| receiver_public_key || Receiver's EC public key +|status_code || Payment Protocol Status Code |- -| nonce || The nonce in use for the CBC encryption +|status_message || Human-readable Payment Protocol status message |- -| signature || A signature of this message using Sender's EC key, serialized with a value of "" for signature. REQUIRED if server requires authentication. -|- -| identifier || Use the identifier specified with the EncryptedPaymentRequest, if any. +|identifier || Unique key to identify this entire exchange on the server. SHA256 of initial serialized InvoiceRequest SHOULD be used by default |} -===EncryptedPaymentACK=== - -An encrypted version of the BIP70 PaymentAck. - +===EncryptedProtocolMessage=== +The EncryptedProtocolMessage message is an encapsualting wrapper for any Payment Protocol message. It allows two-way, authenticated and encrypted communication of Payment Protocol messages in order to keep their contents secret. The message also includes a status code and status message that is used for error communication so the protocol does not rely on transport-layer error handling.
-message EncryptedPaymentACK {
-        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;
+message EncryptedProtocolMessage {
+    required ProtocolMessageType message_type = 1;
+    required bytes encrypted_message = 2;
+    required bytes receiver_public_key = 3;
+    required bytes sender_public_key = 4;
+    required uint64 nonce = 5;
+    optional bytes signature = 6;
+    optional bytes identifier = 7;
+    optional uint64 status_code = 8;
+    optional string status_message = 9;
 }
 
{| class="wikitable" -! Field Name !! Description +! Field Name !! Description +| message_type || Message Type of Decrypted encrypted_message |- -| encrypted_payment_ack || AES-256-CBC encrypted, serialized BIP70 PaymentACK message +| encrypted_message || AES-256-GCM Encrypted (as defined in BIP75) Payment Protocol Message |- -| 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 DER-encoded EC Public Key |- -| receiver_public_key || Receiver's EC public key +| sender_public_key || Sender's DER-encoded EC Public Key |- -| sender_public_key || Sender's EC public key +| nonce || Microseconds since epoch |- -| nonce || The nonce in use for the CBC encryption +| signature || DER-encoded Signature over the full EncryptedProtocolMessage with EC Key Belonging to Sender / Receiver, respectively |- -| signature || A signature of this message using Receiver's EC key, serialized with a value of "" for signature. REQUIRED if server requires authentication. +| identifier || Unique key to identify this entire exchange on the server. SHA256 of initial serialized InvoiceRequest SHOULD be used by default |- -| identifier || Use the identifier specified with the EncryptedPayment, if any. +| status_code || Payment Protocol Status Code +|- +| status_message || Human-readable Payment Protocol status message |} -==Updated Messages== -The BIP70 PaymentRequest, Payment and PaymentACK messages have been updated by this BIP to contain Payment Protocol error communication. The following two extension fields have been added to each of the aforementioned messages: +==Payment Protocol Process with InvoiceRequests== +The full process overview for using InvoiceRequests in the Payment Protocol is defined below. All Payment Protocol messages are to be encapsulated in either a ProtocolMessage or EncryptedProcotolMessage. Once the process begins using EncryptedProtocolMessage messages, all subsequent communications MUST use EncryptedProtocolMessages. All Payment Protocol messages SHOULD be communicated using EncryptedProtocolMessage encapsulating messages with the exception that an InvoiceRequest MAY be communicated using the ProtocolMessage if the receiver's public key is unknown. -
-{
-...
-    optional uint32 status_code = 1000;     // Payment Protocol status code
-    optional string status_message = 1001;  // Human-readable status message
-}
-
+See [[Sending_Encrypted_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Sending Encrypted Payment Protocol Messages using EncryptedProtocolMessages]] and [[Validating_and_Decrypting_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Validating and Decrypting Payment Protocol Messages using EncryptedProtocolMessages]] for the process of communicating using encrypted Payment Protocol messages. -status_code and/or status_message MUST be set to communicate a Payment Protocol error to the message receiver. The message consumer MUST handle status_code and status_message if either field is present. +TODO: See about adding some info about using ProtocolMessages -==InvoiceRequest / PaymentRequest Process== -The process overview for using InvoiceRequests and receiving encrypted PaymentRequests is defined below in two sections. Optionally, the Sender MAY choose to encrypt the InvoiceRequest message and therefore MUST follow the '''Encrypted InvoiceRequest Overview''' process below. - -===Non-Encrypted InvoiceRequest Overview=== # Sender creates InvoiceRequest -# Sender transmits InvoiceRequest to Receiver -# Receiver validates InvoiceRequest +# Sender encapsulates InvoiceRequest in (Encrypted)ProtocolMessage +# Sender sends (Encrypted)ProtocolMessage to Receiver +# Receiver retrieves InvoiceRequest from (Encrypted)ProtocolMessage # Receiver creates PaymentRequest -# Receiver encrypts the PaymentRequest -# Receiver creates EncryptedPaymentRequest (containing an encrypted PaymentRequest) -# Receiver transmits EncryptedPaymentRequest to Sender -# Sender validates EncryptedPaymentRequest -# Sender decrypts and validates encrypted PaymentRequest -# The PaymentRequest is processed according to BIP70, including optional Payment and PaymentACK messages - +# Receiver encapsulates PaymentRequest in EncryptedProtocolMessage +# Receiver transmits EncryptedProtocolMessage to Sender +# Sender validates PaymentRequest +# The PaymentRequest is processed according to BIP70, including optional Payment and PaymentACK messages encapsulated in EncryptedProtocolMessage messages. -Flow diagram of Non-Encrypted InvoiceRequest - -===Encrypted InvoiceRequest Overview=== -# Sender retrieves Receiver InvoiceRequest Public Key -# Sender creates InvoiceRequest -# Sender encrypts the InvoiceRequest -# Sender creates EncryptedInvoiceRequest (containing an encrypted InvoiceRequest) -# Sender transmits EncryptedInvoiceRequest to Receiver -# Receiver decrypts and validates EncryptedInvoiceRequest -# Receiver validates InvoiceRequest -# Receiver creates PaymentRequest -# Receiver encrypts the PaymentRequest -# Receiver creates EncryptedPaymentRequest (containing an encrypted PaymentRequest) -# Receiver transmits EncryptedPaymentRequest to Sender -# Sender validates EncryptedPaymentRequest -# Sender decrypts and validates encrypted PaymentRequest -# The PaymentRequest is processed according to BIP70, including optional EncryptedPayment and EncryptedPaymentACK messages - -'''NOTE:''' See section [[#Initial_Public_Key_Retrieval_for_InvoiceRequest_Encryption|Initial Public Key Retrieval for InvoiceRequest Encryption]] below for possible options to retrieve Receiver InvoiceRequest public keys. +'''NOTE:''' See section [[#Initial_Public_Key_Retrieval_for_InvoiceRequest_Encryption|Initial Public Key Retrieval for InvoiceRequest Encryption]] below for possible options to retrieve Receiver's public key. Flow diagram of Encrypted InvoiceRequest @@ -300,48 +207,44 @@ When communicated via HTTP, these messages MUST be transmitted via TLS-protected {| class="wikitable" ! Message Type !! Content Type |- -| InvoiceRequest || application/bitcoin-invoicerequest -|- -| EncryptedInvoiceRequest || application/bitcoin-encrypted-invoicerequest -|- -| EncryptedPaymentRequest || application/bitcoin-encrypted-paymentrequest +| ProtocolMessage || application/bitcoin-paymentprotocol-message |- -| EncryptedPayment || application/bitcoin-encrypted-payment -|- -| EncryptedPaymentACK || application/bitcoin-encrypted-paymentack +| EncryptedProtocolMessage || application/bitcoin-encrypted-paymentprotocol-message |} -===Payment Protocol Errors=== +===Payment Protocol Status Communication=== -Payment Protocol errors MUST be communicated to the party that initiated the communication via the status_code and status_message extension fields present in the PaymentRequest, Payment and PaymentACK messages. For example, if the provided hash of each message does not match the contents of the message once decrypted, a general error MUST be returned to prevent oracle attacks. +In the case of an error that causes the Payment Protocol process to be stopped or retried for a transaction, a ProtocolMessage or EncryptedProtocolMessage MUST be sent by the party generating the error. The content of the message must contain the same serialized_message or encrypted_message and identifier (if used) and MUST have the status_code set appropriately. The status_message value SHOULD be set with a human readable explanation of the status code. For example, if in an EncryptedProtocolMessage, the provided hash of the serialized message does not match the contents of the message once decrypted, a general error (100) MUST be returned to prevent oracle attacks. ====Payment Protocol Status Codes==== {| class="wikitable" ! Status Code !! Description +|- +| 1 || OK |- -| 1 || General / Unknown Error +| 100 || General / Unknown Error |- -| 2 || Authentication Failed +| 102 || Authentication Failed |- -| 3 || Encrypted Message Required +| 102 || Encrypted Message Required |- -| 100 || Amount Too High +| 200 || Amount Too High |- -| 101 || Amount Too Low +| 201 || Amount Too Low |- -| 102 || Amount Invalid +| 202 || Amount Invalid |- -| 103 || Payment Does Not Meet PaymentRequest Requirements +| 203 || Payment Does Not Meet PaymentRequest Requirements |- -| 200 || Certificate Required +| 300 || Certificate Required |- -| 201 || Certificate Expired +| 301 || Certificate Expired |- -| 202 || Certificate Invalid for Transaction +| 302 || Certificate Invalid for Transaction |- -| 203 || Certificate Revoked +| 303 || Certificate Revoked |- -| 204 || Certificate Not Well Rooted +| 304 || Certificate Not Well Rooted |- |} @@ -349,7 +252,8 @@ Payment Protocol errors MUST be communicated to the party that initiated the com Communications errors MUST be communicated to the party that initiated the communication via the communication layer's existing error messaging faciltiies. In the case of TLS-protected HTTP, this SHOULD be done through standard HTTP Status Code messaging ([https://tools.ietf.org/html/rfc7231 RFC 7231 Section 6]). -==Process Step Details== +==New Process Details== +This BIP extends the Payment Protocol as defined in BIP70. For the following we assume the Sender already knows the Receiver's public key, and the exchange is being facilitated by a Store & Forward server which requires valid signatures for authentication. @@ -358,7 +262,6 @@ Where used, '''nonce''' MUST be set to a non-repeating number AND MUST be chosen ===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 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 return a PaymentRequest with the status_code and status_message fields set appropriately. * 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 @@ -369,97 +272,57 @@ Where used, '''nonce''' MUST be set to a non-repeating number AND MUST be chosen ** Sign InvoiceRequest with signature = "" using the X509 Certificate's private key ** Set signature value to the computed signature -===EncryptedInvoiceRequest Message Creation=== -* Create an EncryptedInvoiceRequest -* Retrieve endpoint public key to use in '''ECDH Point Generation''' as specified in [[#Initial_Public_Key_Retrieval_for_InvoiceRequest_Encryption|Initial Public Key Retrieval for InvoiceRequest Encryption]] (see below) -* 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 -* 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 [[#ECDH_Point_Generation_and_AES256_CBC_Mode_Setup|ECDH Point Generation and AES-256 (CBC Mode) Setup]] (see below) -* 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=== -* 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 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 -===EncryptedPaymentRequest Message Creation and PaymentRequest Encryption=== -* Encrypt the serialized PaymentRequest using AES-256-CBC setup as described in [[#ECDH_Point_Generation_and_AES256_CBC_Mode_Setup|ECDH Point Generation and AES-256 (CBC Mode) Setup]] (see below) -* 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) +===Sending Encrypted Payment Protocol Messages using EncryptedProtocolMessages=== +* Encrypt the serialized Payment Protocol message using AES-256-CBC setup as described in [[#ECDH_Point_Generation_and_AES256_GCM_Mode_Setup|ECDH Point Generation and AES-256 (GCM Mode) Setup]] (see below) +* Create EncryptedProtocolMessage message +* Set encrypted_message to be the encrypted value of the Payment Protocol message * 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 +* requires_payment_message MAY be set to true if the PaymentRequest requires a Payment message '''TODO: How are we doing this now?''' +* Set identifier to the identifier value received in the originating InvoiceRequest's ProtocolMessage or EncryptedProtocolMessage wrapper message * Set signature to "" -* Sign the serialized EncryptedPayment message with the Receiver's EC public key +* Sign the serialized EncryptedProtocolMessage message with the communicating party'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 [[#ECDH_Point_Generation_and_AES256_CBC_Mode_Setup|ECDH Point Generation and AES-256 (CBC Mode) Setup]] (see below) -* Validate payment_request_hash matches SHA256 of the decrypted, serialized PaymentRequest -* Deserialize the serialized PaymentRequest +'''SIGNATURE NOTE:''' EncryptedProtocolMessage messages are signed with the public keys of the party transmitting the message. This allows a Store & Forward server or other transmission system to prevent spam or other abuses. For those who are privacy conscious and don't want the server to track the interactions between two public keys, the Sender can generate a new public key for each interaction to keep their identity anonymous. + +===Validating and Decrypting Payment Protocol Messages using EncryptedProtocolMessages=== +* The nonce MUST not be repeated. The service receiving the InvoiceRequest MAY use whatever method to make sure that the nonce is never repeated. +* Decrypt the serialized Payment Protocol message using AES-256-GCM setup as described in [[#ECDH_Point_Generation_and_AES256_GCM_Mode_Setup|ECDH Point Generation and AES-256 (GCM Mode) Setup]] (see below) +* Deserialize the serialized Payment Protocol message -===ECDH Point Generation and AES-256 (CBC Mode) Setup=== +===ECDH Point Generation and AES-256 (GCM Mode) Setup=== +'''NOTE''': AES-256-GCM is used because it provides authenticated encryption facilities, thus negating the need for a separate message hash for authentication. * 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 '''SHA256(secret point's X value)''' for Entropy ** Use the given message's nonce field for Nonce -* Initialize AES-256 in CBC Mode +* Initialize AES-256 in GCM Mode ** Use HMAC_DRBG.GENERATE(32) as the Encryption Key (256 bits) ** Use HMAC_DRBG.GENERATE(16) as the Initialization Vector (IV) (128 bits) ===Initial Public Key Retrieval for InvoiceRequest Encryption=== -Initial public key retrieval for InvoiceRequest encryption can be done in a number of ways including, but not limited to, the following: +Initial public key retrieval for InvoiceRequest encryption in EncryptedProtocolMessage can be done in a number of ways including, but not limited to, the following: * Wallet Name public key asset type resolution - DNSSEC-validated name resolution returns Base64 encoded DER-formatted EC public key via TXT Record [https://www.ietf.org/rfc/rfc5480.txt RFC 5480] * Key Server lookup - Key Server lookup (similar to PGP's pgp.mit.edu) based on key server identifier (i.e., e-mail address) returns Base64 encoded DER-formatted EC public key [https://www.ietf.org/rfc/rfc5480.txt RFC 5480] * QR Code - Use of QR-code to encode DER-formatted EC public key [https://www.ietf.org/rfc/rfc5480.txt RFC 5480] - -==EncryptedPayment and EncryptedPaymentACK Details== - -===EncryptedPayment Message Creation=== -* Encrypt the serialized Payment using AES-256-CBC using secret key calculated in the [[#EncryptedPaymentRequest_Message_Creation_and_PaymentRequest_Encryption|EncryptedPaymentRequest Message Creation and PaymentRequest Encryption]] step (see above) -* Create EncryptedPayment message -* Set encrypted_payment to be the encrypted value of the Payment -* 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 - -===EncryptedPaymentACK Message Creation=== -* Encrypt the serialized PaymentACK using AES-256-CBC using secret key calculated in the [[#EncryptedPaymentRequest_Message_Creation_and_PaymentRequest_Encryption|EncryptedPaymentRequest Message Creation and PaymentRequest Encryption]] step (see above) -* 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 - - -'''SIGNATURE NOTE:''' EncryptedPaymentRequest, EncryptedPayment, and EncryptedPaymentACK messages are signed with the public keys of the party transmitting the message. This allows a Store & Forward server or other transmission system to prevent spam or other abuses. For those who are privacy conscious and don't want the server to track the interactions between two public keys, the Sender can generate a new public key for each interaction to keep their identity anonymous. +* Address Service Public Key Exposure ==Payment / PaymentACK Messages with a Store & Forward Server== -When a Store & Forward server is in use during the Payment Protocol exchange, an EncryptedPayment message generated as the result of a EncryptedPaymentRequest with the requires_payment_message flag set to true MUST be accepted by a Store & Forward server. The accepted Payment message is NOT validated as the Store & Forward server does not have access to encrypted data. +When a Store & Forward server is in use during the Payment Protocol exchange, a Payment message generated as the result of a PaymentRequest with the '''requires_payment_message''' (TODO: Should add something more generic to the encapsulating messages?) flag set to true MUST be accepted by a Store & Forward server. The accepted Payment message is NOT validated as the Store & Forward server does not have access to encrypted data. -Store & Forward servers MAY accept and/or overwrite EncryptedPayment messages until an EncryptedPaymentACK message with matching identifier and valid Receiver signature is received, after which the server MAY reject all further EncryptedPayment messages matching that identifier. This feature SHOULD be used for updating Payment metadata or replacing invalid transactions with valid ones. Clients SHOULD keep in mind Receivers can broadcast a transaction without returning an ACK. If a payment message needs to be updated, it SHOULD include at least one input referenced in the original transaction to prevent the Receiver from broadcasting both transactions and getting paid twice. +Store & Forward servers MAY accept and/or overwrite Payment messages until an PaymentACK message with matching identifier and valid Receiver signature is received, after which the server MAY reject all further Payment messages matching that identifier. This feature SHOULD be used for updating Payment metadata or replacing invalid transactions with valid ones. Clients SHOULD keep in mind Receivers can broadcast a transaction without returning an ACK. If a payment message needs to be updated, it SHOULD include at least one input referenced in the original transaction to prevent the Receiver from broadcasting both transactions and getting paid twice. ==Public Key & Signature Encoding== -* Each EC public key (sender_public_key, receiver_public_key) included in any message defined in this BIP MUST be DER [ITU.X690.1994] encoded. -* Each ECC signature included in any message defined in this BIP MUST use the SHA-256 hashing algorithm and MUST be DER [ITU.X690.1994] encoded. +* All EC public keys (sender_public_key, receiver_public_key) included in any message defined in this BIP MUST be DER [ITU.X690.1994] encoded. +* All ECC signatures included in any message defined in this BIP MUST use the SHA-256 hashing algorithm and MUST be DER [ITU.X690.1994] encoded. ==Implementation== A reference implementation for a Store & Forward server supporting this proposal can be found here: @@ -468,7 +331,7 @@ A reference implementation for a Store & Forward server supporting this proposal A reference client implementation can be found in the InvoiceRequest functional testing for Addressimo here: -[https://github.com/netkicorp/addressimo/blob/master/functest/functest_ir.py InvoiceRequest Client Reference Implementation] +[https://github.com/netkicorp/addressimo/blob/master/functest/functest_bip75.py BIP75 Client Reference Implementation] ==BIP70 Extension== The following flowchart is borrowed from BIP70 and expanded upon in order to visually describe how this BIP is an extension to BIP70. diff --git a/bip-0075/paymentrequest.proto b/bip-0075/paymentrequest.proto index 912fcd3..3c1ef40 100644 --- a/bip-0075/paymentrequest.proto +++ b/bip-0075/paymentrequest.proto @@ -23,9 +23,6 @@ message PaymentDetails { optional string memo = 5; // Human-readable description of request for the customer optional string payment_url = 6; // URL to send Payment and get PaymentACK optional bytes merchant_data = 7; // Arbitrary data to include in the Payment message - optional uint64 subtractable_fee = 1000; // How many Satoshis can be subtracted from the requested amount and instead applied towards the fee - optional uint64 fee_per_kb = 1001; // Minimum transaction fee that must be included with the transaction in order for it to be accepted with zero confirmations. - optional bool replace_by_fee = 1002; // Indicates the sender can enable the Replace By Fee flag for this transaction and the receiver will still consider it accepted with zero confirmations. Otherwise, RBF transactions will not be accepted by the receiver until they are confirmed. } message PaymentRequest { optional uint32 payment_details_version = 1 [default = 1]; @@ -33,8 +30,6 @@ message PaymentRequest { optional bytes pki_data = 3; // depends on pki_type required bytes serialized_payment_details = 4; // PaymentDetails optional bytes signature = 5; // pki-dependent signature - optional uint32 status_code = 1000; // Payment Protocol status code - optional string status_message = 1001; // Human-readable Payment Protocol status message } message X509Certificates { repeated bytes certificate = 1; // DER-encoded X.509 certificate chain @@ -44,20 +39,15 @@ message Payment { repeated bytes transactions = 2; // Signed transactions that satisfy PaymentDetails.outputs repeated Output refund_to = 3; // Where to send refunds, if a refund is necessary optional string memo = 4; // Human-readable message for the merchant - optional uint32 status_code = 1000; // Payment Protocol status code - optional string status_message = 1001; // Human-readable Payment Protocol status message } message PaymentACK { required Payment payment = 1; // Payment message that triggered this ACK optional string memo = 2; // Human-readable message for customer - optional uint32 status_code = 1000; // Payment Protocol status code - optional string status_message = 1001; // Human-readable Payment Protocol status message } // BIP-IR Extensions - message InvoiceRequest { - required bytes sender_public_key = 1; // Sender's EC Public Key + required bytes sender_public_key = 1; // Sender's DER-Encoded EC Public Key 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 @@ -66,43 +56,29 @@ 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 - required 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 - optional bytes signature = 7; // Signature of this message using Sender's EC key -} - -message EncryptedPaymentRequest { - 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. +enum ProtocolMessageType { + INVOICE_REQUEST = 0; + PAYMENT_REQUEST = 1; + PAYMENT = 2; + PAYMENT_ACK = 3; } -message EncryptedPayment { - 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 sender_public_key = 3; // Sender's EC Public Key - required bytes receiver_public_key = 4; // Receiver'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 ProtocolMessage { + required ProtocolMessageType message_type = 1; // Message Type of serialized_message + required bytes serialized_message = 2; // Serialized Payment Protocol Message + optional uint64 status_code = 3; // Payment Protocol Status Code + optional string status_message = 4; // Human-readable Payment Protocol status message + optional bytes identifier = 5; // Unique key to identify this entire exchange on the server. SHA256 of initial serialized InvoiceRequest SHOULD be used by default } -message EncryptedPaymentACK { - 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. -} +message EncryptedProtocolMessage { + required ProtocolMessageType message_type = 1; // Message Type of Decrypted encrypted_message + required bytes encrypted_message = 2; // AES-256-GCM Encrypted (as defined in BIP75) Payment Protocol Message + required bytes receiver_public_key = 3; // Receiver's DER-encoded EC Public Key + required bytes sender_public_key = 4; // Sender's DER-encoded EC Public Key + required uint64 nonce = 5; // Microseconds since epoch + optional bytes signature = 6; // Signature over the full EncryptedProtocolMessage with EC Key Belonging to Sender / Receiver, respectively + optional bytes identifier = 7; // Unique key to identify this entire exchange on the server. SHA256 of initial serialized InvoiceRequest SHOULD be used by default + optional uint64 status_code = 8; // Payment Protocol Status Code + optional string status_message = 9; // Human-readable Payment Protocol status message +} \ No newline at end of file -- cgit v1.2.3 From 6c9625e8322359866c2bffc6812da5691e755d3d Mon Sep 17 00:00:00 2001 From: Matt David Date: Tue, 26 Apr 2016 18:12:29 -0700 Subject: - Fix formatting + fix/add links - Update images --- bip-0075.mediawiki | 141 ++++++++++----------- bip-0075/bip70-extension.png | Bin 88989 -> 89308 bytes bip-0075/encrypted-invoice-request-process.png | Bin 164633 -> 168540 bytes .../mobile-sf-encrypted-ir-without-payment.png | Bin 106744 -> 0 bytes bip-0075/mobile-sf-ir-with-payment.png | Bin 113169 -> 103390 bytes bip-0075/mobile-sf-ir-without-payment.png | Bin 92902 -> 88090 bytes 6 files changed, 69 insertions(+), 72 deletions(-) mode change 100644 => 100755 bip-0075/bip70-extension.png delete mode 100755 bip-0075/mobile-sf-encrypted-ir-without-payment.png diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index 3b0ba1f..a439cd6 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -30,9 +30,9 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S ==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 requester 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 defining this extension to the [[bip-0070.mediawiki|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 requester 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 threefold: +The motivation for this extension to [[bip-0070.mediawiki|BIP70]] is threefold: # Ensure that the payment details can only be seen by the participants in the transaction, and not by any third party. @@ -58,7 +58,7 @@ With this BIP, Bitcoin wallets could maintain an "address book" that only needs 2. Individual Permissioned Address Release -A Bitcoin wallet developer would like to allow users to view a potential sending party's identifying information before deciding whether or not to share payment information with them. Currently, BIP70 specifies that the Merchant Server respond to a "pay now" style request with a PaymentRequest, releasing address and X.509 certificate identity information of the potential receiving party. +A Bitcoin wallet developer would like to allow users to view a potential sending party's identifying information before deciding whether or not to share payment information with them. Currently, [[bip-0070.mediawiki|BIP70]] specifies that the Merchant Server respond to a "pay now" style request with a PaymentRequest, releasing address and X.509 certificate identity information of the potential receiving party. With this BIP, Bitcoin wallets could prompt a wallet user to release payment information while displaying identity information about the potential sending party via an included certificate. This gives the receiving party more control over who receives their payment and identity information, and could be helpful for businesses that need to follow KYC policies or wallets that want to focus on privacy. @@ -71,10 +71,10 @@ With this BIP, returned payment information is encrypted with an ECDH-computed s ==New Messages== Updated [/bip-0075/paymentrequest.proto paymentrequest.proto] contains the existing PaymentRequest Protocol Buffer messages as well as the messages newly defined in this BIP. -Note: Public keys from both parties must be known to each other in order to facilitate encrypted communication. Although including both public keys in every message may get redundant, it provides the most flexibility as each message is completely self-contained. +'''NOTE''': Public keys from both parties must be known to each other in order to facilitate encrypted communication. Although including both public keys in every message may get redundant, it provides the most flexibility as each message is completely self-contained. ===InvoiceRequest=== -The InvoiceRequest message allows a Sender to send information to the Receiver such that the Receiver can create and return a PaymentRequest. +The '''InvoiceRequest''' message allows a Sender to send information to the Receiver such that the Receiver can create and return a PaymentRequest.
 message InvoiceRequest {
@@ -107,7 +107,7 @@ message InvoiceRequest {
 |}
 
 ===ProtocolMessageType Enum===
-The ProtocolMessageType enum is defined in an extensible way to allow for new message type additions to the Payment Protocol. This enum is used in the newly defined ProtocolMessage and EncryptedProtocolMessage messages to define the serialized message type.
+This enum is used in the newly defined [[#ProtocolMessage|ProtocolMessage]] and [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages to define the serialized message type. The '''ProtocolMessageType''' enum is defined in an extensible way to allow for new message type additions to the Payment Protocol.
 
 enum ProtocolMessageType {
     INVOICE_REQUEST = 0;
@@ -118,7 +118,7 @@ enum ProtocolMessageType {
 
===ProtocolMessage=== -The ProtocolMessage message is an encapsulating wrapper for any Payment Protocol message. It allows two-way, non-encrypted communication of Payment Protocol messages. The message also includes a status code and a status message that is used for error communication so the protocol does not rely on transport-layer error handling. +The '''ProtocolMessage''' message is an encapsulating wrapper for any Payment Protocol message. It allows two-way, non-encrypted communication of Payment Protocol messages. The message also includes a status code and a status message that is used for error communication such that the protocol does not rely on transport-layer error handling.
 message ProtocolMessage {
     required ProtocolMessageType message_type = 1;
@@ -132,7 +132,7 @@ message ProtocolMessage {
 {| class="wikitable"
 ! Field Name !! Description
 |-
-|message_type               || Message Type of serialized_message (using enum ProtocolMessageType)
+|message_type               || Message Type of serialized_message
 |-
 |serialized_message         || Serialized Payment Protocol Message
 |-
@@ -144,7 +144,7 @@ message ProtocolMessage {
 |}
 
 ===EncryptedProtocolMessage===
-The EncryptedProtocolMessage message is an encapsualting wrapper for any Payment Protocol message. It allows two-way, authenticated and encrypted communication of Payment Protocol messages in order to keep their contents secret. The message also includes a status code and status message that is used for error communication so the protocol does not rely on transport-layer error handling.
+The '''EncryptedProtocolMessage''' message is an encapsualting wrapper for any Payment Protocol message. It allows two-way, authenticated and encrypted communication of Payment Protocol messages in order to keep their contents secret. The message also includes a status code and status message that is used for error communication such that the protocol does not rely on transport-layer error handling.
 
 message EncryptedProtocolMessage {
     required ProtocolMessageType message_type = 1;
@@ -160,6 +160,7 @@ message EncryptedProtocolMessage {
 
{| class="wikitable" ! Field Name !! Description +|- | message_type || Message Type of Decrypted encrypted_message |- | encrypted_message || AES-256-GCM Encrypted (as defined in BIP75) Payment Protocol Message @@ -180,30 +181,28 @@ message EncryptedProtocolMessage { |} ==Payment Protocol Process with InvoiceRequests== -The full process overview for using InvoiceRequests in the Payment Protocol is defined below. All Payment Protocol messages are to be encapsulated in either a ProtocolMessage or EncryptedProcotolMessage. Once the process begins using EncryptedProtocolMessage messages, all subsequent communications MUST use EncryptedProtocolMessages. All Payment Protocol messages SHOULD be communicated using EncryptedProtocolMessage encapsulating messages with the exception that an InvoiceRequest MAY be communicated using the ProtocolMessage if the receiver's public key is unknown. - -See [[Sending_Encrypted_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Sending Encrypted Payment Protocol Messages using EncryptedProtocolMessages]] and [[Validating_and_Decrypting_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Validating and Decrypting Payment Protocol Messages using EncryptedProtocolMessages]] for the process of communicating using encrypted Payment Protocol messages. +The full process overview for using '''InvoiceRequests''' in the Payment Protocol is defined below. All Payment Protocol messages MUST be encapsulated in either a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProcotolMessage|EncryptedProtocolMessage]. Once the process begins using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages, all subsequent communications MUST use [[#EncryptedProtocolMessage|EncryptedProtocolMessages]]. All Payment Protocol messages SHOULD be communicated using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulating messages with the exception that an [[#InvoiceRequest|InvoiceRequest]] MAY be communicated using the [[#ProtocolMessage|ProtocolMessage]] if the receiver's public key is unknown. -TODO: See about adding some info about using ProtocolMessages +The process of communicating using encrypted Payment Protocol messages is enumerated in [[#Sending_Encrypted_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Sending Encrypted Payment Protocol Messages using EncryptedProtocolMessages]] and [[#Validating_and_Decrypting_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Validating and Decrypting Payment Protocol Messages using EncryptedProtocolMessages]]. # Sender creates InvoiceRequest # Sender encapsulates InvoiceRequest in (Encrypted)ProtocolMessage # Sender sends (Encrypted)ProtocolMessage to Receiver -# Receiver retrieves InvoiceRequest from (Encrypted)ProtocolMessage +# Receiver retrieves InvoiceRequest in (Encrypted)ProtocolMessage from Sender # Receiver creates PaymentRequest # Receiver encapsulates PaymentRequest in EncryptedProtocolMessage # Receiver transmits EncryptedProtocolMessage to Sender -# Sender validates PaymentRequest -# The PaymentRequest is processed according to BIP70, including optional Payment and PaymentACK messages encapsulated in EncryptedProtocolMessage messages. +# Sender validates PaymentRequest retrieved from the EncryptedProtocolMessage +# The PaymentRequest is processed according to [[bip-0070.mediawiki|BIP70]], including optional Payment and PaymentACK messages encapsulated in EncryptedProtocolMessage messages. -'''NOTE:''' See section [[#Initial_Public_Key_Retrieval_for_InvoiceRequest_Encryption|Initial Public Key Retrieval for InvoiceRequest Encryption]] below for possible options to retrieve Receiver's public key. +'''NOTE:''' See section [[#Initial_Public_Key_Retrieval_for_InvoiceRequest_Encryption|Initial Public Key Retrieval for InvoiceRequest Encryption]] for possible options to retrieve Receiver's public key. Flow diagram of Encrypted InvoiceRequest ==Message Interaction Details== -===New Message HTTP Content Types=== -When communicated via HTTP, these messages MUST be transmitted via TLS-protected HTTP using the appropriate Content-Type header as defined per message type here: +===HTTP Content Types for New Message Types=== +When communicated via '''HTTP''', the listed messages MUST be transmitted via TLS-protected HTTP using the appropriate Content-Type header as defined here per message: {| class="wikitable" ! Message Type !! Content Type |- @@ -214,7 +213,9 @@ When communicated via HTTP, these messages MUST be transmitted via TLS-protected ===Payment Protocol Status Communication=== -In the case of an error that causes the Payment Protocol process to be stopped or retried for a transaction, a ProtocolMessage or EncryptedProtocolMessage MUST be sent by the party generating the error. The content of the message must contain the same serialized_message or encrypted_message and identifier (if used) and MUST have the status_code set appropriately. The status_message value SHOULD be set with a human readable explanation of the status code. For example, if in an EncryptedProtocolMessage, the provided hash of the serialized message does not match the contents of the message once decrypted, a general error (100) MUST be returned to prevent oracle attacks. +In the case of an error that causes the Payment Protocol process to be stopped or requires that message be retried, a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] MUST be sent by the party generating the error. The content of the message MUST contain the same '''serialized_message''' or '''encrypted_message''' and identifier (if present) and MUST have the status_code set appropriately. + +The status_message value SHOULD be set with a human readable explanation of the status code. For example, if in an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]], the AES-256-GCM decryption fails to authenticate, an Authentication Failed (102) '''status_code''' MUST be returned to prevent oracle attacks. ====Payment Protocol Status Codes==== {| class="wikitable" @@ -248,54 +249,53 @@ In the case of an error that causes the Payment Protocol process to be stopped o |- |} -===Communication Errors=== +===Transport Layer Communication Errors=== Communications errors MUST be communicated to the party that initiated the communication via the communication layer's existing error messaging faciltiies. In the case of TLS-protected HTTP, this SHOULD be done through standard HTTP Status Code messaging ([https://tools.ietf.org/html/rfc7231 RFC 7231 Section 6]). ==New Process Details== -This BIP extends the Payment Protocol as defined in BIP70. +This BIP extends the Payment Protocol as defined in [[bip-0070.mediawiki|BIP70]]. For the following we assume the Sender already knows the Receiver's public key, and the exchange is being facilitated by a Store & Forward server which requires valid signatures for authentication. -Where used, '''nonce''' MUST be set to a non-repeating number AND MUST be chosen by the encryptor. 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. +'''nonce''' MUST be set to a non-repeating number '''and''' MUST be chosen by the encryptor. 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 -* 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 return a PaymentRequest with the status_code and status_message fields set appropriately. -* 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 -* If NOT including certificate, set pki_type to "none" +* Create an [[#InvoiceRequest|InvoiceRequest]] message +* '''sender_public_key''' MUST be set to the public key of an EC keypair +* '''amount''' is optional. If the amount is not specified by the [[#InvoiceRequest|InvoiceRequest]], the Receiver MAY specify the amount in the returned PaymentRequest. If an amount is specified by the [[#InvoiceRequest|InvoiceRequest]] and a PaymentRequest cannot be generated for that amount, the [[#InvoiceRequest|InvoiceRequest]] SHOULD return the same [[#InvoiceRequest|InvoiceRequest]] in a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] with the status_code and status_message fields set appropriately. +* '''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 PaymentRequest (encapsulated in an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] 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 +** 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|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 -* 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 +* 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|InvoiceRequest]] is VALID +* If '''pki_type''' is x509+sha256 and '''signature''' is valid for the serialized [[#InvoiceRequest|InvoiceRequest]] where signature is set to "", [[#InvoiceRequest|InvoiceRequest]] is VALID ===Sending Encrypted Payment Protocol Messages using EncryptedProtocolMessages=== * Encrypt the serialized Payment Protocol message using AES-256-CBC setup as described in [[#ECDH_Point_Generation_and_AES256_GCM_Mode_Setup|ECDH Point Generation and AES-256 (GCM Mode) Setup]] (see below) -* Create EncryptedProtocolMessage message -* Set encrypted_message to be the encrypted value of the Payment Protocol message -* 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 '''TODO: How are we doing this now?''' -* Set identifier to the identifier value received in the originating InvoiceRequest's ProtocolMessage or EncryptedProtocolMessage wrapper message -* Set signature to "" -* Sign the serialized EncryptedProtocolMessage message with the communicating party's EC public key -* Set signature to the result of the signature operation above - -'''SIGNATURE NOTE:''' EncryptedProtocolMessage messages are signed with the public keys of the party transmitting the message. This allows a Store & Forward server or other transmission system to prevent spam or other abuses. For those who are privacy conscious and don't want the server to track the interactions between two public keys, the Sender can generate a new public key for each interaction to keep their identity anonymous. +* Create [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] message +* Set '''encrypted_message''' to be the encrypted value of the Payment Protocol message +* '''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 identifier value received in the originating InvoiceRequest's ProtocolMessage or EncryptedProtocolMessage wrapper message +* Set '''signature''' to "" +* Sign the serialized [#EncryptedProtocolMessage|EncryptedProtocolMessage]] message with the communicating party's EC public key +* Set '''signature''' to the result of the signature operation above + +'''SIGNATURE NOTE:''' [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages are signed with the public keys of the party transmitting the message. This allows a Store & Forward server or other transmission system to prevent spam or other abuses. For those who are privacy conscious and don't want the server to track the interactions between two public keys, the Sender can generate a new public key for each interaction to keep their identity anonymous. ===Validating and Decrypting Payment Protocol Messages using EncryptedProtocolMessages=== -* The nonce MUST not be repeated. The service receiving the InvoiceRequest MAY use whatever method to make sure that the nonce is never repeated. -* Decrypt the serialized Payment Protocol message using AES-256-GCM setup as described in [[#ECDH_Point_Generation_and_AES256_GCM_Mode_Setup|ECDH Point Generation and AES-256 (GCM Mode) Setup]] (see below) +* The '''nonce''' MUST not be repeated. The service receiving the [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] MAY use whatever method to make sure that the nonce is never repeated. +* Decrypt the serialized Payment Protocol message using AES-256-GCM setup as described in [[#ECDH_Point_Generation_and_AES256_GCM_Mode_Setup|ECDH Point Generation and AES-256 (GCM Mode) Setup]] * Deserialize the serialized Payment Protocol message ===ECDH Point Generation and AES-256 (GCM Mode) Setup=== @@ -303,25 +303,27 @@ Where used, '''nonce''' MUST be set to a non-repeating number AND MUST be chosen * 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 '''SHA256(secret point's X value)''' for Entropy -** Use the given message's nonce field for Nonce +** Use the given message's '''nonce''' field for Nonce * Initialize AES-256 in GCM Mode ** Use HMAC_DRBG.GENERATE(32) as the Encryption Key (256 bits) ** Use HMAC_DRBG.GENERATE(16) as the Initialization Vector (IV) (128 bits) ===Initial Public Key Retrieval for InvoiceRequest Encryption=== -Initial public key retrieval for InvoiceRequest encryption in EncryptedProtocolMessage can be done in a number of ways including, but not limited to, the following: -* Wallet Name public key asset type resolution - DNSSEC-validated name resolution returns Base64 encoded DER-formatted EC public key via TXT Record [https://www.ietf.org/rfc/rfc5480.txt RFC 5480] -* Key Server lookup - Key Server lookup (similar to PGP's pgp.mit.edu) based on key server identifier (i.e., e-mail address) returns Base64 encoded DER-formatted EC public key [https://www.ietf.org/rfc/rfc5480.txt RFC 5480] -* QR Code - Use of QR-code to encode DER-formatted EC public key [https://www.ietf.org/rfc/rfc5480.txt RFC 5480] -* Address Service Public Key Exposure +Initial public key retrieval for [[#InvoiceRequest|InvoiceRequest]] encryption via [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulation can be done in a number of ways including, but not limited to, the following: +# Wallet Name public key asset type resolution - DNSSEC-validated name resolution returns Base64 encoded DER-formatted EC public key via TXT Record [https://www.ietf.org/rfc/rfc5480.txt RFC 5480] +# Key Server lookup - Key Server lookup (similar to PGP's pgp.mit.edu) based on key server identifier (i.e., e-mail address) returns Base64 encoded DER-formatted EC public key [https://www.ietf.org/rfc/rfc5480.txt RFC 5480] +# QR Code - Use of QR-code to encode DER-formatted EC public key [https://www.ietf.org/rfc/rfc5480.txt RFC 5480] +# Address Service Public Key Exposure -==Payment / PaymentACK Messages with a Store & Forward Server== -When a Store & Forward server is in use during the Payment Protocol exchange, a Payment message generated as the result of a PaymentRequest with the '''requires_payment_message''' (TODO: Should add something more generic to the encapsulating messages?) flag set to true MUST be accepted by a Store & Forward server. The accepted Payment message is NOT validated as the Store & Forward server does not have access to encrypted data. +==Payment / PaymentACK Messages with a HTTP Store & Forward Server== +A Store & Forward server SHOULD store PaymentRequest messages until either a timeout expires the message or a Payment message for the PaymentRequest message has been received. The timeout SHOULD be greater than 24 hours. + +When a Store & Forward server is used for a Payment Protocol exchange, a Payment message generated as the result of a PaymentRequest MUST be accepted by a Store & Forward server if the associated PaymentRequest message exists on the Store & Forward server, otherwise an HTTP 404 Not Found message should be returned. The accepted Payment message is NOT validated as the Store & Forward server does not have access to encrypted data. Store & Forward servers MAY accept and/or overwrite Payment messages until an PaymentACK message with matching identifier and valid Receiver signature is received, after which the server MAY reject all further Payment messages matching that identifier. This feature SHOULD be used for updating Payment metadata or replacing invalid transactions with valid ones. Clients SHOULD keep in mind Receivers can broadcast a transaction without returning an ACK. If a payment message needs to be updated, it SHOULD include at least one input referenced in the original transaction to prevent the Receiver from broadcasting both transactions and getting paid twice. ==Public Key & Signature Encoding== -* All EC public keys (sender_public_key, receiver_public_key) included in any message defined in this BIP MUST be DER [ITU.X690.1994] encoded. +* All EC public keys ('''sender_public_key''', '''receiver_public_key''') included in any message defined in this BIP MUST be DER [ITU.X690.1994] encoded. * All ECC signatures included in any message defined in this BIP MUST use the SHA-256 hashing algorithm and MUST be DER [ITU.X690.1994] encoded. ==Implementation== @@ -334,26 +336,21 @@ A reference client implementation can be found in the InvoiceRequest functional [https://github.com/netkicorp/addressimo/blob/master/functest/functest_bip75.py BIP75 Client Reference Implementation] ==BIP70 Extension== -The following flowchart is borrowed from BIP70 and expanded upon in order to visually describe how this BIP is an extension to BIP70. +The following flowchart is borrowed from [[bip-0070.mediawiki|BIP70]] and expanded upon in order to visually describe how this BIP is an extension to [[bip-0070.mediawiki|BIP70]]. Flowchart explaining how this BIP extends BIP 70 ==Mobile to Mobile Examples== -===EncryptedPayment Required=== -The following diagram shows a sample flow in which one mobile client is sending value to a second mobile client with the use of an InvoiceRequest, a Store & Forward server, an EncryptedPaymentRequest (with require_payment_message = true), an EncryptedPayment and an EncryptedPaymentACK. In this case, the Receiver submits the transaction to the Bitcoin network. - -EncryptedPayment Required flow diagram - -===EncryptedPayment NOT Required=== -The following diagram shows a sample flow in which one mobile client is sending value to a second mobile client with the use of an InvoiceRequest, a Store & Forward server, and an EncryptedPaymentRequest (with require_payment_message = false). In this case, the Sender submits the transaction to the Bitcoin network. +===Full Payment Protocol=== +The following diagram shows a sample flow in which one mobile client is sending value to a second mobile client with the use of an InvoiceRequest, a Store & Forward server, PaymentRequest, Payment and PaymentACK. In this case, the PaymentRequest, Payment and PaymentACK messages are encrypted using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] '''and''' the Receiver submits the transaction to the Bitcoin network. -EncryptedPayment NOT Required flow diagram +Payment Required flow diagram -===Using EncryptedInvoiceRequest Message=== -The following diagram shows a sample flow in which one mobile client is sending value to a second mobile client with the use of an EncryptedInvoiceRequest, a Store & Forward server, and an EncryptedPaymentRequest (with require_payment_message = false). In this case, the Sender submits the transaction to the Bitcoin network. +===Encrypting Initial InvoiceRequest via EncryptedProtocolMessage=== +The following diagram shows a sample flow in which one mobile client is sending value to a second mobile client using an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] to transmit the InvoiceRequest using encryption, Store & Forward server, and PaymentRequest. In this case, all Payment Protocol messages are encrypting using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] '''and''' the Sender submits the transaction to the Bitcoin network. -EncryptedInvoiceRequest without payment +Encrypted InvoiceRequest without payment ==References== diff --git a/bip-0075/bip70-extension.png b/bip-0075/bip70-extension.png old mode 100644 new mode 100755 index d235992..e02db32 Binary files a/bip-0075/bip70-extension.png and b/bip-0075/bip70-extension.png differ diff --git a/bip-0075/encrypted-invoice-request-process.png b/bip-0075/encrypted-invoice-request-process.png index beb5df1..918cf70 100644 Binary files a/bip-0075/encrypted-invoice-request-process.png and b/bip-0075/encrypted-invoice-request-process.png differ diff --git a/bip-0075/mobile-sf-encrypted-ir-without-payment.png b/bip-0075/mobile-sf-encrypted-ir-without-payment.png deleted file mode 100755 index af66a4d..0000000 Binary files a/bip-0075/mobile-sf-encrypted-ir-without-payment.png and /dev/null differ diff --git a/bip-0075/mobile-sf-ir-with-payment.png b/bip-0075/mobile-sf-ir-with-payment.png index c668eac..729fa79 100755 Binary files a/bip-0075/mobile-sf-ir-with-payment.png and b/bip-0075/mobile-sf-ir-with-payment.png differ diff --git a/bip-0075/mobile-sf-ir-without-payment.png b/bip-0075/mobile-sf-ir-without-payment.png index ab18d0f..19cf842 100755 Binary files a/bip-0075/mobile-sf-ir-without-payment.png and b/bip-0075/mobile-sf-ir-without-payment.png differ -- cgit v1.2.3 From c2a73346a3b2c4da8189cbdd0278069a062e6ee0 Mon Sep 17 00:00:00 2001 From: Matt David Date: Tue, 26 Apr 2016 18:14:14 -0700 Subject: - Fix straggling EncryptedPaymentRequest reference --- bip-0075.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index a439cd6..51bb1ec 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -101,7 +101,7 @@ message InvoiceRequest { |- | memo || Human-readable description of invoice request for the receiver |- -| notification_url || Secure (usually TLS-protected HTTP) location where an [[#EncryptedPaymentRequest|EncryptedPaymentRequest]] (see below) SHOULD be sent when ready +| notification_url || Secure (usually TLS-protected HTTP) location where an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] (see below) SHOULD be sent when ready |- | signature || PKI-dependent signature |} -- cgit v1.2.3 From 32d9f9d266f7bca15ea248b15a75092a46a61902 Mon Sep 17 00:00:00 2001 From: Matt David Date: Tue, 26 Apr 2016 18:51:54 -0700 Subject: Adding linebreaks and fixing some bad links --- bip-0075.mediawiki | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index 51bb1ec..32649c9 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -101,7 +101,7 @@ message InvoiceRequest { |- | memo || Human-readable description of invoice request for the receiver |- -| notification_url || Secure (usually TLS-protected HTTP) location where an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] (see below) SHOULD be sent when ready +| notification_url || Secure (usually TLS-protected HTTP) location where an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] SHOULD be sent when ready |- | signature || PKI-dependent signature |} @@ -181,8 +181,12 @@ message EncryptedProtocolMessage { |} ==Payment Protocol Process with InvoiceRequests== -The full process overview for using '''InvoiceRequests''' in the Payment Protocol is defined below. All Payment Protocol messages MUST be encapsulated in either a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProcotolMessage|EncryptedProtocolMessage]. Once the process begins using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages, all subsequent communications MUST use [[#EncryptedProtocolMessage|EncryptedProtocolMessages]]. All Payment Protocol messages SHOULD be communicated using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulating messages with the exception that an [[#InvoiceRequest|InvoiceRequest]] MAY be communicated using the [[#ProtocolMessage|ProtocolMessage]] if the receiver's public key is unknown. - +The full process overview for using '''InvoiceRequests''' in the Payment Protocol is defined below. +
+All Payment Protocol messages MUST be encapsulated in either a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProcotolMessage|EncryptedProtocolMessage]]. Once the process begins using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages, all subsequent communications MUST use [[#EncryptedProtocolMessage|EncryptedProtocolMessages]]. +
+All Payment Protocol messages SHOULD be communicated using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulating messages with the exception that an [[#InvoiceRequest|InvoiceRequest]] MAY be communicated using the [[#ProtocolMessage|ProtocolMessage]] if the receiver's public key is unknown. +
The process of communicating using encrypted Payment Protocol messages is enumerated in [[#Sending_Encrypted_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Sending Encrypted Payment Protocol Messages using EncryptedProtocolMessages]] and [[#Validating_and_Decrypting_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Validating and Decrypting Payment Protocol Messages using EncryptedProtocolMessages]]. # Sender creates InvoiceRequest @@ -195,7 +199,7 @@ The process of communicating using encrypted Payment Protocol messages is enumer # Sender validates PaymentRequest retrieved from the EncryptedProtocolMessage # The PaymentRequest is processed according to [[bip-0070.mediawiki|BIP70]], including optional Payment and PaymentACK messages encapsulated in EncryptedProtocolMessage messages. -'''NOTE:''' See section [[#Initial_Public_Key_Retrieval_for_InvoiceRequest_Encryption|Initial Public Key Retrieval for InvoiceRequest Encryption]] for possible options to retrieve Receiver's public key. +'''NOTE:''' See [[#Initial_Public_Key_Retrieval_for_InvoiceRequest_Encryption|Initial Public Key Retrieval for InvoiceRequest Encryption]] for possible options to retrieve Receiver's public key. Flow diagram of Encrypted InvoiceRequest @@ -203,6 +207,7 @@ The process of communicating using encrypted Payment Protocol messages is enumer ===HTTP Content Types for New Message Types=== When communicated via '''HTTP''', the listed messages MUST be transmitted via TLS-protected HTTP using the appropriate Content-Type header as defined here per message: +
{| class="wikitable" ! Message Type !! Content Type |- @@ -213,8 +218,8 @@ When communicated via '''HTTP''', the listed messages MUST be transmitted via TL ===Payment Protocol Status Communication=== -In the case of an error that causes the Payment Protocol process to be stopped or requires that message be retried, a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] MUST be sent by the party generating the error. The content of the message MUST contain the same '''serialized_message''' or '''encrypted_message''' and identifier (if present) and MUST have the status_code set appropriately. - +In the case of an error that causes the Payment Protocol process to be stopped or requires that message be retried, a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] MUST be returned by the party generating the error status_code. The content of the message MUST contain the same '''serialized_message''' or '''encrypted_message''' and identifier (if present) and MUST have the status_code set appropriately. +
The status_message value SHOULD be set with a human readable explanation of the status code. For example, if in an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]], the AES-256-GCM decryption fails to authenticate, an Authentication Failed (102) '''status_code''' MUST be returned to prevent oracle attacks. ====Payment Protocol Status Codes==== @@ -253,7 +258,7 @@ The status_message value SHOULD be set with a human readable explanation of the Communications errors MUST be communicated to the party that initiated the communication via the communication layer's existing error messaging faciltiies. In the case of TLS-protected HTTP, this SHOULD be done through standard HTTP Status Code messaging ([https://tools.ietf.org/html/rfc7231 RFC 7231 Section 6]). -==New Process Details== +==Extended Payment Protocol Process Details== This BIP extends the Payment Protocol as defined in [[bip-0070.mediawiki|BIP70]]. For the following we assume the Sender already knows the Receiver's public key, and the exchange is being facilitated by a Store & Forward server which requires valid signatures for authentication. @@ -265,11 +270,11 @@ For the following we assume the Sender already knows the Receiver's public key, * '''sender_public_key''' MUST be set to the public key of an EC keypair * '''amount''' is optional. If the amount is not specified by the [[#InvoiceRequest|InvoiceRequest]], the Receiver MAY specify the amount in the returned PaymentRequest. If an amount is specified by the [[#InvoiceRequest|InvoiceRequest]] and a PaymentRequest cannot be generated for that amount, the [[#InvoiceRequest|InvoiceRequest]] SHOULD return the same [[#InvoiceRequest|InvoiceRequest]] in a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] with the status_code and status_message fields set appropriately. * '''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 PaymentRequest (encapsulated in an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] to +* Set '''notification_url''' to URL that the Receiver will submit completed PaymentRequest (encapsulated in an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]]) 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) +** Set '''pki_data''' as it would be set in BIP-0070 ([https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki#Certificates Certificates]) ** Sign [[#InvoiceRequest|InvoiceRequest]] with signature = "" using the X509 Certificate's private key ** Set '''signature''' value to the computed signature @@ -280,7 +285,7 @@ For the following we assume the Sender already knows the Receiver's public key, * If '''pki_type''' is x509+sha256 and '''signature''' is valid for the serialized [[#InvoiceRequest|InvoiceRequest]] where signature is set to "", [[#InvoiceRequest|InvoiceRequest]] is VALID ===Sending Encrypted Payment Protocol Messages using EncryptedProtocolMessages=== -* Encrypt the serialized Payment Protocol message using AES-256-CBC setup as described in [[#ECDH_Point_Generation_and_AES256_GCM_Mode_Setup|ECDH Point Generation and AES-256 (GCM Mode) Setup]] (see below) +* Encrypt the serialized Payment Protocol message using AES-256-CBC setup as described in [[#ECDH_Point_Generation_and_AES256_GCM_Mode_Setup|ECDH Point Generation and AES-256 (GCM Mode) Setup]] * Create [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] message * Set '''encrypted_message''' to be the encrypted value of the Payment Protocol message * '''sender_public_key''' MUST be set to the public key of the Sender's EC keypair @@ -288,7 +293,7 @@ For the following we assume the Sender already knows the Receiver's public key, * '''nonce''' MUST be set to the nonce used in the AES-256-CBC encryption operation * Set '''identifier''' to the identifier value received in the originating InvoiceRequest's ProtocolMessage or EncryptedProtocolMessage wrapper message * Set '''signature''' to "" -* Sign the serialized [#EncryptedProtocolMessage|EncryptedProtocolMessage]] message with the communicating party's EC public key +* Sign the serialized [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] message with the communicating party's EC public key * Set '''signature''' to the result of the signature operation above '''SIGNATURE NOTE:''' [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages are signed with the public keys of the party transmitting the message. This allows a Store & Forward server or other transmission system to prevent spam or other abuses. For those who are privacy conscious and don't want the server to track the interactions between two public keys, the Sender can generate a new public key for each interaction to keep their identity anonymous. @@ -317,9 +322,9 @@ Initial public key retrieval for [[#InvoiceRequest|InvoiceRequest]] encryption v ==Payment / PaymentACK Messages with a HTTP Store & Forward Server== A Store & Forward server SHOULD store PaymentRequest messages until either a timeout expires the message or a Payment message for the PaymentRequest message has been received. The timeout SHOULD be greater than 24 hours. - +
When a Store & Forward server is used for a Payment Protocol exchange, a Payment message generated as the result of a PaymentRequest MUST be accepted by a Store & Forward server if the associated PaymentRequest message exists on the Store & Forward server, otherwise an HTTP 404 Not Found message should be returned. The accepted Payment message is NOT validated as the Store & Forward server does not have access to encrypted data. - +
Store & Forward servers MAY accept and/or overwrite Payment messages until an PaymentACK message with matching identifier and valid Receiver signature is received, after which the server MAY reject all further Payment messages matching that identifier. This feature SHOULD be used for updating Payment metadata or replacing invalid transactions with valid ones. Clients SHOULD keep in mind Receivers can broadcast a transaction without returning an ACK. If a payment message needs to be updated, it SHOULD include at least one input referenced in the original transaction to prevent the Receiver from broadcasting both transactions and getting paid twice. ==Public Key & Signature Encoding== -- cgit v1.2.3 From b5517bab86c7039e654cc1c1f6584808a3cbba39 Mon Sep 17 00:00:00 2001 From: Matt David Date: Tue, 26 Apr 2016 18:53:05 -0700 Subject: Add more linebreaks --- bip-0075.mediawiki | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index 32649c9..95e620f 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -182,11 +182,11 @@ message EncryptedProtocolMessage { ==Payment Protocol Process with InvoiceRequests== The full process overview for using '''InvoiceRequests''' in the Payment Protocol is defined below. -
+

All Payment Protocol messages MUST be encapsulated in either a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProcotolMessage|EncryptedProtocolMessage]]. Once the process begins using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages, all subsequent communications MUST use [[#EncryptedProtocolMessage|EncryptedProtocolMessages]]. -
+

All Payment Protocol messages SHOULD be communicated using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulating messages with the exception that an [[#InvoiceRequest|InvoiceRequest]] MAY be communicated using the [[#ProtocolMessage|ProtocolMessage]] if the receiver's public key is unknown. -
+

The process of communicating using encrypted Payment Protocol messages is enumerated in [[#Sending_Encrypted_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Sending Encrypted Payment Protocol Messages using EncryptedProtocolMessages]] and [[#Validating_and_Decrypting_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Validating and Decrypting Payment Protocol Messages using EncryptedProtocolMessages]]. # Sender creates InvoiceRequest @@ -219,7 +219,7 @@ When communicated via '''HTTP''', the listed messages MUST be transmitted via TL ===Payment Protocol Status Communication=== In the case of an error that causes the Payment Protocol process to be stopped or requires that message be retried, a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] MUST be returned by the party generating the error status_code. The content of the message MUST contain the same '''serialized_message''' or '''encrypted_message''' and identifier (if present) and MUST have the status_code set appropriately. -
+

The status_message value SHOULD be set with a human readable explanation of the status code. For example, if in an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]], the AES-256-GCM decryption fails to authenticate, an Authentication Failed (102) '''status_code''' MUST be returned to prevent oracle attacks. ====Payment Protocol Status Codes==== @@ -322,9 +322,9 @@ Initial public key retrieval for [[#InvoiceRequest|InvoiceRequest]] encryption v ==Payment / PaymentACK Messages with a HTTP Store & Forward Server== A Store & Forward server SHOULD store PaymentRequest messages until either a timeout expires the message or a Payment message for the PaymentRequest message has been received. The timeout SHOULD be greater than 24 hours. -
+

When a Store & Forward server is used for a Payment Protocol exchange, a Payment message generated as the result of a PaymentRequest MUST be accepted by a Store & Forward server if the associated PaymentRequest message exists on the Store & Forward server, otherwise an HTTP 404 Not Found message should be returned. The accepted Payment message is NOT validated as the Store & Forward server does not have access to encrypted data. -
+

Store & Forward servers MAY accept and/or overwrite Payment messages until an PaymentACK message with matching identifier and valid Receiver signature is received, after which the server MAY reject all further Payment messages matching that identifier. This feature SHOULD be used for updating Payment metadata or replacing invalid transactions with valid ones. Clients SHOULD keep in mind Receivers can broadcast a transaction without returning an ACK. If a payment message needs to be updated, it SHOULD include at least one input referenced in the original transaction to prevent the Receiver from broadcasting both transactions and getting paid twice. ==Public Key & Signature Encoding== -- cgit v1.2.3 From 7d9e11dbcbb9b14fa748848b4c75c69b9299d054 Mon Sep 17 00:00:00 2001 From: Matt David Date: Wed, 27 Apr 2016 09:52:22 -0700 Subject: - Add information about the use of GCM Authentication tag - Add requirement of additional authenticated data in the case that either status_code and/or status_message are in use --- bip-0075.mediawiki | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index 95e620f..ef10c08 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -312,6 +312,13 @@ For the following we assume the Sender already knows the Receiver's public key, * Initialize AES-256 in GCM Mode ** Use HMAC_DRBG.GENERATE(32) as the Encryption Key (256 bits) ** Use HMAC_DRBG.GENERATE(16) as the Initialization Vector (IV) (128 bits) +

+ +====AES-256 GCM Authentication Tag Use==== +The 16 byte authentication tag resulting from the AES-GCM encrypt operation MUST be prefixed to the returned ciphertext. The decrypt operation will use the first 16 bytes of the ciphertext as the GCM authentication tag and the remainder of the ciphertext as the ciphertext in the decrypt operation. + +====AES-256 GCM Additional Authenticated Data==== +When either '''status_code''' OR '''status_message''' are present, the AES-256 GCM authenticated data used in both the encrypt and decrypt operations MUST be: STRING(status_code) || status_message. Otherwise, there is no additional authenticated data. This provides that, while not encrypted, the status_code and status_message are authenticated. ===Initial Public Key Retrieval for InvoiceRequest Encryption=== Initial public key retrieval for [[#InvoiceRequest|InvoiceRequest]] encryption via [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulation can be done in a number of ways including, but not limited to, the following: -- cgit v1.2.3 From 1e6e914ca7ba8946614abff02fcd6d917771af0e Mon Sep 17 00:00:00 2001 From: Matt David Date: Wed, 27 Apr 2016 09:54:06 -0700 Subject: - Fix spacing --- bip-0075.mediawiki | 1 - 1 file changed, 1 deletion(-) diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index ef10c08..9cbc605 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -312,7 +312,6 @@ For the following we assume the Sender already knows the Receiver's public key, * Initialize AES-256 in GCM Mode ** Use HMAC_DRBG.GENERATE(32) as the Encryption Key (256 bits) ** Use HMAC_DRBG.GENERATE(16) as the Initialization Vector (IV) (128 bits) -

====AES-256 GCM Authentication Tag Use==== The 16 byte authentication tag resulting from the AES-GCM encrypt operation MUST be prefixed to the returned ciphertext. The decrypt operation will use the first 16 bytes of the ciphertext as the GCM authentication tag and the remainder of the ciphertext as the ciphertext in the decrypt operation. -- cgit v1.2.3 From dcbbc871dc552f946a1ddf56190f3bf22ed1fcdf Mon Sep 17 00:00:00 2001 From: Matt David Date: Wed, 27 Apr 2016 09:54:43 -0700 Subject: - Fix spacing --- bip-0075.mediawiki | 1 - 1 file changed, 1 deletion(-) diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index 9cbc605..b3e3498 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -200,7 +200,6 @@ The process of communicating using encrypted Payment Protocol messages is enumer # The PaymentRequest is processed according to [[bip-0070.mediawiki|BIP70]], including optional Payment and PaymentACK messages encapsulated in EncryptedProtocolMessage messages. '''NOTE:''' See [[#Initial_Public_Key_Retrieval_for_InvoiceRequest_Encryption|Initial Public Key Retrieval for InvoiceRequest Encryption]] for possible options to retrieve Receiver's public key. - Flow diagram of Encrypted InvoiceRequest ==Message Interaction Details== -- cgit v1.2.3 From 057591da8c25e296e71333b355d12fe6fa6e81d2 Mon Sep 17 00:00:00 2001 From: Matt David Date: Wed, 27 Apr 2016 10:01:03 -0700 Subject: Fix spacing again and pull IV size down to 12 bytes in accord with NIST 800-38D --- bip-0075.mediawiki | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index b3e3498..27dbc44 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -200,6 +200,7 @@ The process of communicating using encrypted Payment Protocol messages is enumer # The PaymentRequest is processed according to [[bip-0070.mediawiki|BIP70]], including optional Payment and PaymentACK messages encapsulated in EncryptedProtocolMessage messages. '''NOTE:''' See [[#Initial_Public_Key_Retrieval_for_InvoiceRequest_Encryption|Initial Public Key Retrieval for InvoiceRequest Encryption]] for possible options to retrieve Receiver's public key. + Flow diagram of Encrypted InvoiceRequest ==Message Interaction Details== @@ -310,11 +311,11 @@ For the following we assume the Sender already knows the Receiver's public key, ** Use the given message's '''nonce''' field for Nonce * Initialize AES-256 in GCM Mode ** Use HMAC_DRBG.GENERATE(32) as the Encryption Key (256 bits) -** Use HMAC_DRBG.GENERATE(16) as the Initialization Vector (IV) (128 bits) +** Use HMAC_DRBG.GENERATE(12) as the Initialization Vector (IV) (96 bits) ====AES-256 GCM Authentication Tag Use==== The 16 byte authentication tag resulting from the AES-GCM encrypt operation MUST be prefixed to the returned ciphertext. The decrypt operation will use the first 16 bytes of the ciphertext as the GCM authentication tag and the remainder of the ciphertext as the ciphertext in the decrypt operation. - + ====AES-256 GCM Additional Authenticated Data==== When either '''status_code''' OR '''status_message''' are present, the AES-256 GCM authenticated data used in both the encrypt and decrypt operations MUST be: STRING(status_code) || status_message. Otherwise, there is no additional authenticated data. This provides that, while not encrypted, the status_code and status_message are authenticated. @@ -367,6 +368,7 @@ The following diagram shows a sample flow in which one mobile client is sending * [[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] +* [http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf NIST Special Publication 800-38D - Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC] * [https://tools.ietf.org/html/rfc6979 RFC6979] * [https://en.bitcoin.it/wiki/Address_reuse Address Reuse] * [http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf FIPS 180-4 (Secure Hash Standard)] -- cgit v1.2.3 From a79432ac99e0ccda46720047166ef2500cabc8a6 Mon Sep 17 00:00:00 2001 From: Matt David Date: Thu, 28 Apr 2016 16:39:16 -0700 Subject: - Spacing - Recommit mistakently deleted encrypted invoicerequest flow diagram --- bip-0075.mediawiki | 2 ++ bip-0075/mobile-sf-encrypted-ir-without-payment.png | Bin 0 -> 99162 bytes 2 files changed, 2 insertions(+) create mode 100755 bip-0075/mobile-sf-encrypted-ir-without-payment.png diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index 27dbc44..b5110e0 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -306,9 +306,11 @@ For the following we assume the Sender already knows the Receiver's public key, ===ECDH Point Generation and AES-256 (GCM Mode) Setup=== '''NOTE''': AES-256-GCM is used because it provides authenticated encryption facilities, thus negating the need for a separate message hash for authentication. * 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 '''SHA256(secret point's X value)''' for Entropy ** Use the given message's '''nonce''' field for Nonce + * Initialize AES-256 in GCM Mode ** Use HMAC_DRBG.GENERATE(32) as the Encryption Key (256 bits) ** Use HMAC_DRBG.GENERATE(12) as the Initialization Vector (IV) (96 bits) diff --git a/bip-0075/mobile-sf-encrypted-ir-without-payment.png b/bip-0075/mobile-sf-encrypted-ir-without-payment.png new file mode 100755 index 0000000..fb0b5d1 Binary files /dev/null and b/bip-0075/mobile-sf-encrypted-ir-without-payment.png differ -- cgit v1.2.3 From f8f05f0ac943ec5fc688914c28b733fc9b31497f Mon Sep 17 00:00:00 2001 From: jmacwhyte Date: Thu, 28 Apr 2016 16:47:37 -0700 Subject: Updated S&F suggestions, some other tweaks and typos. --- bip-0075.mediawiki | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index 27dbc44..7a24a0e 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -187,7 +187,10 @@ All Payment Protocol messages MUST be encapsulated in either a [[#ProtocolMessag

All Payment Protocol messages SHOULD be communicated using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulating messages with the exception that an [[#InvoiceRequest|InvoiceRequest]] MAY be communicated using the [[#ProtocolMessage|ProtocolMessage]] if the receiver's public key is unknown.

-The process of communicating using encrypted Payment Protocol messages is enumerated in [[#Sending_Encrypted_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Sending Encrypted Payment Protocol Messages using EncryptedProtocolMessages]] and [[#Validating_and_Decrypting_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Validating and Decrypting Payment Protocol Messages using EncryptedProtocolMessages]]. + +The process of creating encrypted Payment Protocol messages is enumerated in [[#Sending_Encrypted_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Sending Encrypted Payment Protocol Messages using EncryptedProtocolMessages]], and the process of decrypting encrypted messages can be found under [[#Validating_and_Decrypting_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Validating and Decrypting Payment Protocol Messages using EncryptedProtocolMessages]]. + +A standard exchange from start to finish would look like the following: # Sender creates InvoiceRequest # Sender encapsulates InvoiceRequest in (Encrypted)ProtocolMessage @@ -256,7 +259,7 @@ The status_message value SHOULD be set with a human readable explanation of the ===Transport Layer Communication Errors=== -Communications errors MUST be communicated to the party that initiated the communication via the communication layer's existing error messaging faciltiies. In the case of TLS-protected HTTP, this SHOULD be done through standard HTTP Status Code messaging ([https://tools.ietf.org/html/rfc7231 RFC 7231 Section 6]). +Communication errors MUST be communicated to the party that initiated the communication via the communication layer's existing error messaging faciltiies. In the case of TLS-protected HTTP, this SHOULD be done through standard HTTP Status Code messaging ([https://tools.ietf.org/html/rfc7231 RFC 7231 Section 6]). ==Extended Payment Protocol Process Details== This BIP extends the Payment Protocol as defined in [[bip-0070.mediawiki|BIP70]]. @@ -327,11 +330,14 @@ Initial public key retrieval for [[#InvoiceRequest|InvoiceRequest]] encryption v # Address Service Public Key Exposure ==Payment / PaymentACK Messages with a HTTP Store & Forward Server== -A Store & Forward server SHOULD store PaymentRequest messages until either a timeout expires the message or a Payment message for the PaymentRequest message has been received. The timeout SHOULD be greater than 24 hours. -

-When a Store & Forward server is used for a Payment Protocol exchange, a Payment message generated as the result of a PaymentRequest MUST be accepted by a Store & Forward server if the associated PaymentRequest message exists on the Store & Forward server, otherwise an HTTP 404 Not Found message should be returned. The accepted Payment message is NOT validated as the Store & Forward server does not have access to encrypted data. +If a Store & Forward server wishes to protect themselves from spam or abuse, they MAY enact whatever rules they deem fit, such as the following: + +* Once an InvoiceRequest or PaymentRequest is received, all subsequent messages using the same identifier must use the same Sender and Receiver public keys. +* For each unique identifier, only one message each of type InvoiceRequest, PaymentRequest, and PaymentACK may be submitted. Payment messages may be submitted/overwritten multiple times. All messages submitted after a PaymentACK is received will be rejected. +* Specific messages are only saved until they have been verifiably received by the intended recipient or a certain amount of time has passed, whichever comes first. +

-Store & Forward servers MAY accept and/or overwrite Payment messages until an PaymentACK message with matching identifier and valid Receiver signature is received, after which the server MAY reject all further Payment messages matching that identifier. This feature SHOULD be used for updating Payment metadata or replacing invalid transactions with valid ones. Clients SHOULD keep in mind Receivers can broadcast a transaction without returning an ACK. If a payment message needs to be updated, it SHOULD include at least one input referenced in the original transaction to prevent the Receiver from broadcasting both transactions and getting paid twice. +Clients SHOULD keep in mind Receivers can broadcast a transaction without returning an ACK. If a Payment message needs to be updated, it SHOULD include at least one input referenced in the original transaction to prevent the Receiver from broadcasting both transactions and getting paid twice. ==Public Key & Signature Encoding== * All EC public keys ('''sender_public_key''', '''receiver_public_key''') included in any message defined in this BIP MUST be DER [ITU.X690.1994] encoded. -- cgit v1.2.3 From e1d74be3b664798ce869bf4a9b565f96abd5c1ea Mon Sep 17 00:00:00 2001 From: Matt David Date: Wed, 11 May 2016 11:19:30 -0700 Subject: - Update ECDH output to use SHA512 instead of SHA256 - Specify HMAC_DRBG security strength --- bip-0075.mediawiki | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index b62c753..0552758 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -308,13 +308,14 @@ For the following we assume the Sender already knows the Receiver's public key, ===ECDH Point Generation and AES-256 (GCM Mode) Setup=== '''NOTE''': AES-256-GCM is used because it provides authenticated encryption facilities, thus negating the need for a separate message hash for authentication. -* 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 '''SHA256(secret point's X value)''' for Entropy +* 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 '''SHA512(secret point's X value in Big-Endian bytes)''' for Entropy ** Use the given message's '''nonce''' field for Nonce * Initialize AES-256 in GCM Mode +** Initialize HMAC_DRBG with Security Strength of 256 bits ** Use HMAC_DRBG.GENERATE(32) as the Encryption Key (256 bits) ** Use HMAC_DRBG.GENERATE(12) as the Initialization Vector (IV) (96 bits) @@ -380,3 +381,4 @@ The following diagram shows a sample flow in which one mobile client is sending * [https://tools.ietf.org/html/rfc6979 RFC6979] * [https://en.bitcoin.it/wiki/Address_reuse Address Reuse] * [http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf FIPS 180-4 (Secure Hash Standard)] +* [https://github.com/bitcoin-core/secp256k1/blob/master/src/modules/ecdh/main_impl.h libsecp256k1 ECDH Implementation] -- cgit v1.2.3 From 40d4246d3d83b7f9be213b51bc7ca4ef6e0d3980 Mon Sep 17 00:00:00 2001 From: Matt David Date: Wed, 11 May 2016 12:59:02 -0700 Subject: - Remove libsecp256k1 reference --- bip-0075.mediawiki | 1 - 1 file changed, 1 deletion(-) diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index 0552758..9ce90f6 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -381,4 +381,3 @@ The following diagram shows a sample flow in which one mobile client is sending * [https://tools.ietf.org/html/rfc6979 RFC6979] * [https://en.bitcoin.it/wiki/Address_reuse Address Reuse] * [http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf FIPS 180-4 (Secure Hash Standard)] -* [https://github.com/bitcoin-core/secp256k1/blob/master/src/modules/ecdh/main_impl.h libsecp256k1 ECDH Implementation] -- cgit v1.2.3 From f71727f1c38ab42b7c28b50aa491b3243e04cbfd Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Sat, 14 May 2016 14:21:46 +0200 Subject: BIP0009 code syntax fix --- bip-0009.mediawiki | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index 509a8a9..e9b61ee 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -112,7 +112,7 @@ other one simultaneously transitions to STARTED, which would mean both would dem Note that a block's state never depends on its own nVersion; only on that of its ancestors. - case STARTED: { + case STARTED: if (GetMedianTimePast(block.parent) >= timeout) { return FAILED; } @@ -127,7 +127,6 @@ Note that a block's state never depends on its own nVersion; only on that of its if (count >= threshold) { return LOCKED_IN; } - } After a retarget period of LOCKED_IN, we automatically transition to ACTIVE. -- cgit v1.2.3 From 1a3613622b15cb85c301e3ab29697b8c19804421 Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Sat, 14 May 2016 14:22:56 +0200 Subject: Error in BIP0009 code --- bip-0009.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index e9b61ee..8941247 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -127,6 +127,7 @@ Note that a block's state never depends on its own nVersion; only on that of its if (count >= threshold) { return LOCKED_IN; } + return STARTED; After a retarget period of LOCKED_IN, we automatically transition to ACTIVE. -- cgit v1.2.3 From 580db159079a7a8f0ee3d6646e7e6a668fce00a2 Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Tue, 17 May 2016 02:06:18 +0200 Subject: Less visible error --- bip-0009.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index 8941247..995ae85 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -120,7 +120,7 @@ Note that a block's state never depends on its own nVersion; only on that of its walk = block; for (i = 0; i < 2016; i++) { walk = walk.parent; - if (walk.nVersion & 0xE0000000 == 0x2000000 && (walk.nVersion >> bit) & 1 == 1) { + if (walk.nVersion & 0xE0000000 == 0x20000000 && (walk.nVersion >> bit) & 1 == 1) { count++; } } -- cgit v1.2.3 From 62a82092687d235ba48c9d0a77c9de56657c77a8 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 23 Mar 2016 15:57:00 +0100 Subject: Add BIP151, Peer-to-Peer Communication Encryption --- README.mediawiki | 6 ++ bip-0151.mediawiki | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 bip-0151.mediawiki diff --git a/README.mediawiki b/README.mediawiki index 974870e..5a90ee8 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -505,6 +505,12 @@ Those proposing changes should consider that ultimately consent may rest with th | Luke Dashjr | Standard | Draft +|- +| [[bip-0151.mediawiki|151]] +| Peer-to-Peer Communication Encryption +| Jonas Schnelli +| Standard +| Draft |} diff --git a/bip-0151.mediawiki b/bip-0151.mediawiki new file mode 100644 index 0000000..18d3901 --- /dev/null +++ b/bip-0151.mediawiki @@ -0,0 +1,178 @@ +
+  BIP: 151
+  Title: Peer-to-Peer Communication Encryption
+  Author: Jonas Schnelli 
+  Status: Draft
+  Type: Standards Track
+  Created: 2016-03-23
+
+ +== Abstract == + +This BIP describes an alternative way that a peer can encrypt their communication between a selective subset of remote peers. + +== Motivation == + + +The Bitcoin network does not encrypt communication between peers today. This opens up security issues (eg: traffic manipulation by others) and allows for mass surveillance / analysis of bitcoin users. Mostly this is negligible because of the nature of Bitcoins trust model, however for SPV nodes this can have significant privacy impacts [1] and could reduce the censorship-resistance of a peer. + +Encrypting peer traffic will make analysis and specific user targeting much more difficult than it currently is. Today it's trivial for a network provider or any other men-in-the-middle to identify a Bitcoin user and its controlled addresses/keys (and link with his Google profile, etc.). Just created and broadcasted transactions will reveal the amount and the payee to the network provider. + +This BIP also describes a way that data manipulation (blocking commands by a intercepting TCP/IP node) would be identifiable by the communicating peers. + +Analyzing the type of p2p communication would still be possible because of the characteristics (size, sending-interval, etc.) of the encrypted messages. + +Encrypting traffic between peers is already possible with VPN, tor, stunnel, curveCP or any other encryption mechanism on a deeper OSI level, however, most mechanism are not practical for SPV or other DHCP/NAT environment and will require significant knowhow in how to setup such a secure channel. + +== Specification == + +A peer that supports encryption must accept encryption requests from all peers. + +A independent ECDH negotiation for both communication directions is required and therefore a bidirectional communication will use two symmetric cipher keys (one per direction). + +Both peers must only send encrypted messages after a successful ECDH negotiation in ''both directions''. + +Encryption initialization must happen before sending any other messages to the responding peer (encinit message after a version message must be ignored). + +=== Symmetric Encryption Cipher Keys === + +The symmetric encryption cipher keys will be calculated with ECDH by sharing the pubkeys of a ephemeral key. Once the ECDH secret is calculated on each side, the symmetric encryption cipher keys must be calculated with HMAC_SHA512(key=ecdh_secret|cipher-type,msg="encryption key"). + +K_1 must be the left 32bytes of the HMAC_SHA512 hash. + +K_2 must be the right 32bytes of the HMAC_SHA512 hash. + +It is important to include the cipher-type into the symmetric cipher key to avoid weak-cipher-attacks. + +=== Session ID === + +Both sides must also calculate the 256bit session-id using HMAC_SHA256(key=ecdh_secret,msg="session id"). The session-id can be used for linking the encryption-session to an identity check. + +=== The encinit message type === + +To request encrypted communication, the requesting peer generates an EC ephemeral-session-keypair and sends an encinit message to the responding peer and waits for a encack message. The responding node must do the same encinit/encack interaction for the opposite communication direction. + +{|class="wikitable" +! Field Size !! Description !! Data type !! Comments +|- +| 33bytes || ephemeral-pubkey || comp.-pubkey || The session pubkey from the requesting peer +|- +| 1bytes || symmetric key cipher type || int8 || symmetric key cipher type to use +|} + +Possible symmetric key ciphers types +{|class="wikitable" +! Number !! symmetric key ciphers type +|- +| 0 || chacha20-poly1305@openssh.com +|} + +=== ChaCha20-Poly1305 Cipher Suite === + +ChaCha20 is a stream cipher designed by Daniel Bernstein [2]. It operates by permuting 128 fixed bits, 128 or 256 bits of key, +a 64 bit nonce and a 64 bit counter into 64 bytes of output. This output is used as a keystream, with any unused bytes simply discarded. + +Poly1305, also by Daniel Bernstein [3], is a one-time Carter-Wegman MAC that computes a 128 bit integrity tag given a message and a single-use +256 bit secret key. + +The chacha20-poly1305@openssh.com specified and defined by openssh [4] combines these two primitives into an authenticated encryption mode. The construction used is based on that proposed for TLS by Adam Langley [5], but differs in the layout of data passed to the MAC and in the addition of encyption of the packet lengths. + +K_1 must be used to only encrypt the payload size of the encrypted message to avoid leaking information by revealing the message size. + +K_2 must be used in conjunction with poly1305 to build an AEAD. + +Optimized implementations of ChaCha20-Poly1305 are very fast in general, therefore it is very likely that encrypted messages require less CPU cycles per bytes then the current unencrypted p2p message format. A quick analysis by Pieter Wuille of the current ''standard implementations'' has shown that SHA256 requires more CPU cycles per byte then ChaCha20 & Poly1304 [5]. + +=== The encack message type === + +The responding peer accepts the encryption request by sending a encack message. + +{|class="wikitable" +! Field Size !! Description !! Data type !! Comments +|- +| 33bytes || ephemeral-pubkey || comp.-pubkey || The session pubkey from the responding peer +|} + +At this point, the shared secret key for the symmetric key cipher must be calculated by using ECDH (own privkey x remote pub key). +Private keys will never be transmitted. The shared secret can only be calculated if an attacker knows at least one private key and the remote peer's public key. + +* '''The encinit/encack interaction must be done from both sides.''' +* Each communication direction uses its own secret key for the symmetric cipher. +* The second encinit request (from the responding peer) must use the same symmetric cipher type. +* All unencrypted messages before the second encack response (from the responding peer) must be ignored. +* After a successful encinit/encack interaction, the "encrypted messages structure" must be used. Non-encrypted messages from the requesting peer must lead to a connection termination. + +After a successful encinit/encack interaction from both sides, the messages format must use the "encrypted messages structure". Non-encrypted messages from the requesting peer must lead to a connection termination (can be detected by the 4 byte network magic in the unencrypted message structure). + +=== Encrypted Messages Structure === + +{|class="wikitable" +! Field Size !! Description !! Data type !! Comments +|- +| 4 || length || uint32_t || Length of ciphertext payload in number of bytes +|- +| ? || ciphertext payload || ? || One or many ciphertext command & message data +|- +| 16 || MAC tag || ? || 128bit MAC-tag +|} + +Encrypted messages do not have the 4byte network magic. + +The maximum message length needs to be chosen carefully. The 4 byte length field can lead to a required message buffer of 4 GiB. +Processing the message before the authentication succeeds must not be done. + +The 4byte sha256 checksum is no longer required because the AEAD. + +Both peers need to track the message number (int64) of sent messages to the remote peer for building a symmetric cipher IV. Padding might be required (96bit IVs). + +The encrypted payload will result decrypted in one or many unencrypted messages: + +{|class="wikitable" +! Field Size !! Description !! Data type !! Comments +|- +| ? || command || varlen || ASCII string identifying the packet content, we are using varlen in the encrypted messages. +|- +| 4 || length || uint32_t || Length of plaintext payload +|- +| ? || payload || ? || The actual data +|} +If more data is present, another message must be deserialized. There is no explicit amount-of-messages integer. + + +=== Re-Keying === + +A responding peer can inform the requesting peer over a re-keying with a encack message containing 33byte of zeros to indicate that all encrypted message following after this encack message will be encrypted with ''the next symmetric cipher key''. + +The new symmetric cipher key will be calculated by SHA256(SHA256(old_symetric_cipher_key)). + +Re-Keying interval is a peer policy with a minimum timespan of 10 seconds. + +The Re-Keying must be done after every 1GB of data sent or received (recommended by RFC4253 SSH Transport). + +=== Risks === + +The encryption does not include an identity authentication scheme. This BIP does not cover a proposal to avoid MITM attacks during the encryption initialization. + +Identity authentication will be covered in another BIP and will presume communication encryption after this BIP. + +== Compatibility == + +This proposal is backward compatible. Non-supporting peers will ignore the encinit messages. + +== Reference implementation == + +== References == + +* [1] http://e-collection.library.ethz.ch/eserv/eth:48205/eth-48205-01.pdf +* [2] ChaCha20 http://cr.yp.to/chacha/chacha-20080128.pdf +* [3] Poly1305 http://cr.yp.to/mac/poly1305-20050329.pdf +* [4] https://github.com/openssh/openssh-portable/blob/05855bf2ce7d5cd0a6db18bc0b4214ed5ef7516d/PROTOCOL.chacha20poly1305 +* [5] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03 + +== Acknowledgements == +* Pieter Wuille and Gregory Maxwell for most of the ideas in this BIP. + +== Copyright == +This work is placed in the public domain. + + -- cgit v1.2.3 From b8907db95076abe39596934d4f04a3b8ffce0160 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 30 Mar 2016 21:58:51 +0000 Subject: BIP 9: Clarify nVersion interpretation and bit order --- bip-0009.mediawiki | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index 995ae85..6ea0ddd 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -51,6 +51,8 @@ With each block and soft fork, we associate a deployment state. The possible sta ===Bit flags=== +The nVersion block header field is to be interpreted as a 32-bit little-endian integer (as present), and bits are selected within this integer as values (1 << N) where N is the bit number. + Blocks in the STARTED state get an nVersion whose bit position bit is set to 1. The top 3 bits of such blocks must be 001, so the range of actually possible nVersion values is [0x20000000...0x3FFFFFFF], inclusive. -- cgit v1.2.3 From 4e9591d8c787f0d32b5a79862c8570300dc742d6 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 30 Mar 2016 22:22:09 +0000 Subject: BIP 9: Add softfork deployment "name" --- bip-0009.mediawiki | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index 6ea0ddd..a8604fa 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -24,6 +24,7 @@ In addition, BIP 34 made the integer comparison (nVersion >= 2) a consensus rule Each soft fork deployment is specified by the following per-chain parameters (further elaborated below): +# The '''name''' specifies a very brief description of the soft fork, reasonable for use as an identifier. # The '''bit''' determines which bit in the nVersion field of the block is to be used to signal the soft fork lock-in and activation. It is chosen from the set {0,1,2,...,28}. # The '''starttime''' specifies a minimum median time past of a block at which the bit gains its meaning. # The '''timeout''' specifies a time at which the deployment is considered failed. If the median time past of a block >= timeout and the soft fork has not yet locked in (including this block's bit state), the deployment is considered failed on all descendants of the block. @@ -32,6 +33,7 @@ Each soft fork deployment is specified by the following per-chain parameters (fu The following guidelines are suggested for selecting these parameters for a soft fork: +# '''name''' should be selected such that no two softforks, concurrent or otherwise, ever use the same name. # '''bit''' should be selected such that no two concurrent softforks use the same bit. # '''starttime''' should be set to some date in the future, approximately one month after a software release date including the soft fork. This allows for some release delays, while preventing triggers as a result of parties running pre-release software. # '''timeout''' should be 1 year (31536000 seconds) after starttime. -- cgit v1.2.3 From 4c124a8c5dad794b9c13d27990fa42651f44676f Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 30 Mar 2016 22:38:57 +0000 Subject: BIP 9: GBT specification --- bip-0009.mediawiki | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index a8604fa..98eb190 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -161,6 +161,35 @@ block, indexed by its parent. To support upgrade warnings, an extra "unknown upgrade" is tracked, using the "implicit bit" mask = (block.nVersion & ~expectedVersion) != 0. Mask will be non-zero whenever an unexpected bit is set in nVersion. Whenever LOCKED_IN for the unknown upgrade is detected, the software should warn loudly about the upcoming soft fork. It should warn even more loudly after the next retarget period (when the unknown upgrade is in the ACTIVE state). +===getblocktemplate changes=== + +The template request Object is extended to include a new item: + +{| class="wikitable" +!colspan=4| template request +|- +! Key !! Required !! Type !! Description +|- +| rules || {{No}} || Array of Strings || list of supported softfork deployments, by name +|} + +The template Object is also extended: + +{| class="wikitable" +!colspan=4| template +|- +! Key !! Required !! Type !! Description +|- +| rules || {{Yes}} || Object || set of pending, supported softfork deployments; each uses the softfork name as the key, and the softfork bit as its value +|- +| rulesrequired || {{No}} || Array of Strings || list of softfork deployments the server requires support for +|- +| rulesenforced || {{Yes}} || Array of Strings || list of softfork deployments that are active state +|} + +The "version" key of the template is retained, and used to indicate the server's preference of deployments. +Miners MAY clear or set bits in the block version WITHOUT any special "mutable" key, provided they are listed among the template's "rules" and (when clearing is desired) NOT listed in "rulesrequired". + ==Support for future changes== The mechanism described above is very generic, and variations are possible for future soft forks. Here are some ideas that can be taken into account. -- cgit v1.2.3 From c7a31304e7741aa369864059ea183ae8e3b0aa33 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 23 Apr 2016 20:12:41 +0000 Subject: bip-0009: Recommend name "bipN" --- bip-0009.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index 98eb190..a54da68 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -24,7 +24,7 @@ In addition, BIP 34 made the integer comparison (nVersion >= 2) a consensus rule Each soft fork deployment is specified by the following per-chain parameters (further elaborated below): -# The '''name''' specifies a very brief description of the soft fork, reasonable for use as an identifier. +# The '''name''' specifies a very brief description of the soft fork, reasonable for use as an identifier. For deployments described in a single BIP, it is recommended to use the name "bipN" where N is the appropriate BIP number. # The '''bit''' determines which bit in the nVersion field of the block is to be used to signal the soft fork lock-in and activation. It is chosen from the set {0,1,2,...,28}. # The '''starttime''' specifies a minimum median time past of a block at which the bit gains its meaning. # The '''timeout''' specifies a time at which the deployment is considered failed. If the median time past of a block >= timeout and the soft fork has not yet locked in (including this block's bit state), the deployment is considered failed on all descendants of the block. -- cgit v1.2.3 From adbf64c626ca4e79bd4ff983ec37d9ffd8577148 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 23 Apr 2016 20:20:13 +0000 Subject: BIP 9: Switch to rules/vbavailable/vbrequired GBT interface --- bip-0009.mediawiki | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index a54da68..6334142 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -180,15 +180,15 @@ The template Object is also extended: |- ! Key !! Required !! Type !! Description |- -| rules || {{Yes}} || Object || set of pending, supported softfork deployments; each uses the softfork name as the key, and the softfork bit as its value +| rules || {{Yes}} || Array of Strings || list of softfork deployments, by name, that are active state |- -| rulesrequired || {{No}} || Array of Strings || list of softfork deployments the server requires support for +| vbavailable || {{Yes}} || Object || set of pending, supported softfork deployments; each uses the softfork name as the key, and the softfork bit as its value |- -| rulesenforced || {{Yes}} || Array of Strings || list of softfork deployments that are active state +| vbrequired || {{No}} || Number || bit mask of softfork deployment version bits the server requires enabled in submissions |} The "version" key of the template is retained, and used to indicate the server's preference of deployments. -Miners MAY clear or set bits in the block version WITHOUT any special "mutable" key, provided they are listed among the template's "rules" and (when clearing is desired) NOT listed in "rulesrequired". +Miners MAY clear or set bits in the block version WITHOUT any special "mutable" key, provided they are listed among the template's "vbavailable" and (when clearing is desired) NOT included as a bit in "vbrequired". ==Support for future changes== -- cgit v1.2.3 From baacb0c64572548829db9a0609036b17e5d25a5c Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 23 Apr 2016 20:32:59 +0000 Subject: BIP 9: Use simple Yes/No rather than templates (which don't work on GitHub) --- bip-0009.mediawiki | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index 6334142..fbb0fde 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -170,7 +170,7 @@ The template request Object is extended to include a new item: |- ! Key !! Required !! Type !! Description |- -| rules || {{No}} || Array of Strings || list of supported softfork deployments, by name +| rules || No || Array of Strings || list of supported softfork deployments, by name |} The template Object is also extended: @@ -180,11 +180,11 @@ The template Object is also extended: |- ! Key !! Required !! Type !! Description |- -| rules || {{Yes}} || Array of Strings || list of softfork deployments, by name, that are active state +| rules || Yes || Array of Strings || list of softfork deployments, by name, that are active state |- -| vbavailable || {{Yes}} || Object || set of pending, supported softfork deployments; each uses the softfork name as the key, and the softfork bit as its value +| vbavailable || Yes || Object || set of pending, supported softfork deployments; each uses the softfork name as the key, and the softfork bit as its value |- -| vbrequired || {{No}} || Number || bit mask of softfork deployment version bits the server requires enabled in submissions +| vbrequired || No || Number || bit mask of softfork deployment version bits the server requires enabled in submissions |} The "version" key of the template is retained, and used to indicate the server's preference of deployments. -- cgit v1.2.3 From 074909a173cc5c425f057dba12dad8bf52eb0eab Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 23 Apr 2016 21:13:02 +0000 Subject: BIP 9: Clarify GBT "version" --- bip-0009.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index fbb0fde..38a4396 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -188,6 +188,7 @@ The template Object is also extended: |} The "version" key of the template is retained, and used to indicate the server's preference of deployments. +If versionbits is being used, "version" MUST be within the versionbits range of [0x20000000...0x3FFFFFFF]. Miners MAY clear or set bits in the block version WITHOUT any special "mutable" key, provided they are listed among the template's "vbavailable" and (when clearing is desired) NOT included as a bit in "vbrequired". ==Support for future changes== -- cgit v1.2.3 From d28a720f2aed00c2051b51402d4093062a8c431a Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 25 Apr 2016 00:18:39 +0000 Subject: BIP 9: rules/force mutation --- bip-0009.mediawiki | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index 38a4396..52c2add 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -191,6 +191,19 @@ The "version" key of the template is retained, and used to indicate the server's If versionbits is being used, "version" MUST be within the versionbits range of [0x20000000...0x3FFFFFFF]. Miners MAY clear or set bits in the block version WITHOUT any special "mutable" key, provided they are listed among the template's "vbavailable" and (when clearing is desired) NOT included as a bit in "vbrequired". +The mutable key defined by BIP 23 is expanded to optionally include one new mutation: + +{| class="wikitable" +!colspan=4| mutations +|- +! Value !! Significance +|- +| rules/force || the miner may ignore rules it does not understand, if the template is to be used as-is (not modified by the client) +|} + +Servers should only signal this mutation when they have verified a client behaving this way will not produce invalid blocks. +This includes verifying the client's supported rules (listed in the template request) are not lacking of a rule that would change serialisation. + ==Support for future changes== The mechanism described above is very generic, and variations are possible for future soft forks. Here are some ideas that can be taken into account. -- cgit v1.2.3 From 949bb13c1d1d4f5b1d1166c6ff33c924dae47dc3 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 11 May 2016 17:45:08 +0000 Subject: Replace "rules/force" mutation with a "cannot be ignored" prefix to rule names --- bip-0009.mediawiki | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index 52c2add..45123e0 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -191,15 +191,11 @@ The "version" key of the template is retained, and used to indicate the server's If versionbits is being used, "version" MUST be within the versionbits range of [0x20000000...0x3FFFFFFF]. Miners MAY clear or set bits in the block version WITHOUT any special "mutable" key, provided they are listed among the template's "vbavailable" and (when clearing is desired) NOT included as a bit in "vbrequired". -The mutable key defined by BIP 23 is expanded to optionally include one new mutation: - -{| class="wikitable" -!colspan=4| mutations -|- -! Value !! Significance -|- -| rules/force || the miner may ignore rules it does not understand, if the template is to be used as-is (not modified by the client) -|} +Softfork deployment names listed in "rules" or as keys in "vbavailable" may be prefixed by a '!' character. +Without this prefix, GBT clients may assume the rule will not impact usage of the template as-is; typical examples of this would be when previously valid transactions cease to be valid, such as BIPs 16, 65, 66, 68, 112, and 113. +If a client does not understand a rule without the prefix, it may use it unmodified for mining. +On the other hand, when this prefix is used, it indicates a more subtle change to the block structure or generation transaction; examples of this would be BIP 34 (because it modifies coinbase construction) and 141 (since it modifies the txid hashing and adds a commitment to the generation transaction). +A client that does not understand a rule prefixed by '!' must not attempt to process the template, and must not attempt to use it for mining even unmodified. Servers should only signal this mutation when they have verified a client behaving this way will not produce invalid blocks. This includes verifying the client's supported rules (listed in the template request) are not lacking of a rule that would change serialisation. -- cgit v1.2.3 From a95b8f8796533f52061d62442d8a596ba65902fc Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 11 May 2016 21:54:09 +0000 Subject: bip-0009: Remove n/a paragraph --- bip-0009.mediawiki | 3 --- 1 file changed, 3 deletions(-) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index 45123e0..153f6db 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -197,9 +197,6 @@ If a client does not understand a rule without the prefix, it may use it unmodif On the other hand, when this prefix is used, it indicates a more subtle change to the block structure or generation transaction; examples of this would be BIP 34 (because it modifies coinbase construction) and 141 (since it modifies the txid hashing and adds a commitment to the generation transaction). A client that does not understand a rule prefixed by '!' must not attempt to process the template, and must not attempt to use it for mining even unmodified. -Servers should only signal this mutation when they have verified a client behaving this way will not produce invalid blocks. -This includes verifying the client's supported rules (listed in the template request) are not lacking of a rule that would change serialisation. - ==Support for future changes== The mechanism described above is very generic, and variations are possible for future soft forks. Here are some ideas that can be taken into account. -- cgit v1.2.3 From 20a842244bbdf85c36b16544def261b9da0948da Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 27 Apr 2016 21:19:57 -0700 Subject: Add compact-block bip --- README.mediawiki | 6 ++ bip-0152.mediawiki | 186 +++++++++++++++++++++++++++++++++++++++++++++ bip-0152/protocol-flow.png | Bin 0 -> 32870 bytes 3 files changed, 192 insertions(+) create mode 100644 bip-0152.mediawiki create mode 100644 bip-0152/protocol-flow.png diff --git a/README.mediawiki b/README.mediawiki index 5a90ee8..ee7b0d8 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -511,6 +511,12 @@ Those proposing changes should consider that ultimately consent may rest with th | Jonas Schnelli | Standard | Draft +|- +| [[bip-0152.mediawiki|152]] +| Compact Block Relay +| Matt Corallo +| Standard +| Draft |} diff --git a/bip-0152.mediawiki b/bip-0152.mediawiki new file mode 100644 index 0000000..b9a83f9 --- /dev/null +++ b/bip-0152.mediawiki @@ -0,0 +1,186 @@ +
+  BIP: 152
+  Title: Compact Block Relay
+  Author: Matt Corallo 
+  Status: Draft
+  Type: Standards Track
+  Created: 2016-04-27
+
+ +==Abstract== + +Compact blocks on the wire as a way to save bandwidth for nodes on the P2P network. + +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== + +Historically, the Bitcoin P2P protocol has not been very bandwidth efficient for block relay. Every transaction in a block is included when relayed, even though a large number of the transactions in a given block are already available to nodes before the block is relayed. This causes moderate inbound bandwidth spikes for nodes when receiving blocks, but can cause very significant outbound bandwidth spikes for some nodes which receive a block before their peers. When such spikes occur, buffer bloat can make consumer-grade internet connections temporarily unusable, and can delay the relay of blocks to remote peers who may choose to wait instead of redundantly requesting the same block from other, less congested, peers. + +Thus, decreasing the bandwidth used during block relay is very useful for many individuals running nodes. + +While the goal of this work is explicitly not to reduce block transfer latency, it does, as a side effect reduce block transfer latencies in some rather significant ways. Additionally, this work forms a foundation for future work explicitly targeting low-latency block transfer. + +==Specification== + +===Intended Protocol Flow=== + + +The protocol is intended to be used in two ways, depending on the peers and bandwidth available, as discussed [[#Implementation_Details|later]]. The "high-bandwidth" mode, which nodes may only enable for a few of their peers, is enabled by setting the first boolean to 1 in a sendcmpct message. In this mode, peers send new block announcements with the short transaction IDs already (via a cmpctblock message), possibly even before fully validating the block (as indicated by the grey box in the image above). In some cases no further round-trip is needed, and the receiver can reconstruct the block and process it as usual immediately. When some transactions were not available from local sources (ie mempool), a getblocktxn/blocktxn roundtrip is necessary, bringing the best-case latency to the same 1.5*RTT minimum time that nodes take today, though with significantly less bandwidth usage. + +The "low-bandwidth" mode is enabled by setting the first boolean to 0 in a sendcmpct message. In this mode, peers send new block announcements with the usual inv/headers announcements (as per BIP130, and after fully validating the block). The receiving peer may then request the block using a MSG_CMPCT_BLOCK getdata request, which will receive a response of the header and short transaction IDs. In some cases no further round-trip is needed, and the receiver can reconstruct the block and process it as usual, taking the same 1.5*RTT minimum time that nodes take today, though with significantly less bandwidth usage. When some transactions were not available from local sources (ie mempool), a getblocktxn/blocktxn roundtrip is necessary, bringing the latency to at least 2.5*RTT in this case, again with significantly less bandwidth usage than today. Because TCP often exhibits worse transfer latency for larger data sizes (as a multiple of RTT), total latency is expected to be reduced even when the full 2.5*RTT transfer mechanism is used. + +===New data structures=== +Several new data structures are added to the P2P network to relay compact blocks: PrefilledTransaction, HeaderAndShortIDs, BlockTransactionsRequest, and BlockTransactions. + +For the purposes of this section, CompactSize refers to the variable-length integer encoding used across the existing P2P protocol to encode array lengths, among other things, in 1, 3, 5 or 9 bytes. Only CompactSize encodings which are minimally-encoded (ie the shortest length possible) are used by this spec. Any other CompactSize encodings are left with undefined behavior. + +Several uses of CompactSize below are "differentially encoded". For these, instead of using raw indexes, the number encoded is the difference between the current index and the previous index, minus one. For example, a first index of 0 implies a real index of 0, a second index of 0 thereafter refers to a real index of 1, etc. + +====PrefilledTransaction==== +A PrefilledTransaction structure is used in HeaderAndShortIDs to provide a list of a few transactions explicitly. + +{| +|Field Name||Type||Size||Encoding||Purpose +|- +|index||CompactSize||1, 3 bytes||Compact Size, differentially encoded since the last PrefilledTransaction in a list||The index into the block at which this transaction is +|- +|tx||Transaction||variable||As encoded in "tx" messages||The transaction which is in the block at index index. +|} + +====HeaderAndShortIDs==== +A HeaderAndShortIDs structure is used to relay a block header, the short transactions IDs used for matching already-available transactions, and a select few transactions which we expect a peer may be missing. + +{| +|Field Name||Type||Size||Encoding||Purpose +|- +|header||Block header||80 bytes||First 80 bytes of the block as defined by the encoding used by "block" messages||The header of the block being provided +|- +|nonce||uint64_t||8 bytes||Little Endian||A nonce for use in short transaction ID calculations +|- +|shortids_length||CompactSize||1 or 3 bytes||As used to encode array lengths elsewhere||||The number of short transaction IDs in shortids (ie block tx count - prefilledtxn_length) +|- +|shortids||List of 6-byte integers||6*shortids_length bytes||Little Endian||The short transaction IDs calculated from the transactions which were not provided explicitly in prefilledtxn +|- +|prefilledtxn_length||CompactSize||1 or 3 bytes||As used to encode array lengths elsewhere||||The number of prefilled transactions in prefilledtxn (ie block tx count - shortids_length) +|- +|prefilledtxn||List of PrefilledTransactions||variable size*prefilledtxn_length||As defined by PrefilledTransaction definition, above||Used to provide the coinbase transaction and a select few which we expect a peer may be missing +|} + +====BlockTransactionsRequest==== +A BlockTransactionsRequest structure is used to list transaction indexes in a block being requested. + +{| +|Field Name||Type||Size||Encoding||Purpose +|- +|blockhash||Binary blob||32 bytes||The output from a double-SHA256 of the block header, as used elsewhere||The blockhash of the block which the transactions being requested are in +|- +|indexes_length||CompactSize||1 or 3 bytes||As used to encode array lengths elsewhere||||The number of transactions being requested +|- +|indexes||List of CompactSizes||1 or 3 bytes*indexes_length||Differentially encoded||The indexes of the transactions being requested in the block +|} + +====BlockTransactions==== +A BlockTransactions structure is used to provide some of the transactions in a block, as requested. + +{| +|Field Name||Type||Size||Encoding||Purpose +|- +|blockhash||Binary blob||32 bytes||The output from a double-SHA256 of the block header, as used elsewhere||The blockhash of the block which the transactions being provided are in +|- +|transactions_length||CompactSize||1 or 3 bytes||As used to encode array lengths elsewhere||||The number of transactions provided +|- +|transactions||List of Transactions||variable||As encoded in "tx" messages||The transactions provided +|} + +====Short transaction IDs==== +Short transaction IDs are used to represent a transaction without sending a full 256-bit hash. They are calculated by: +# single-SHA256 hashing the block header with the nonce appended (in little-endian) +# Running SipHash-2-4 with the input being the transaction ID and the keys (k0/k1) set to the first two little-endian 64-bit integers from the above hash, respectively. +# Dropping the 2 most significant bytes from the SipHash output to make it 6 bytes. + +===New messages=== +A new inv type (MSG_CMPCT_BLOCK == 4) and several new protocol messages are added: sendcmpct, cmpctblock, getblocktxn, and blocktxn. + +====sendcmpct==== +# The sendcmpct message is defined as a message containing a 1-byte integer followed by a 8-byte integer where pchCommand == "sendcmpct". +# The first integer SHALL be interpreted as a boolean (and MUST have a value of either 1 or 0) +# The second integer SHALL be interpreted as a little-endian version number. Nodes sending a sendcmpct message MUST currently set this value to 1. +# Upon receipt of a "sendcmpct" message with the first and second integers set to 1, the node SHOULD announce new blocks by sending a cmpctblock message. +# Upon receipt of a "sendcmpct" message with the first integer set to 0, the node SHOULD NOT announce new blocks by sending a cmpctblock message, but SHOULD announce new blocks by sending invs or headers, as defined by BIP130. +# Upon receipt of a "sendcmpct" message with the second integer set to something other than 1, nodes MUST treat the peer as if they had not received the message (as it indicates the peer will provide an unexpected encoding in cmpctblock, and/or other, messages). This allows future versions to send duplicate sendcmpct messages with different versions as a part of a version handshake for future versions. +# Nodes SHOULD check for a protocol version of >= 70014 before sending sendcmpct messages. +# Nodes MUST NOT send a request for a MSG_CMPCT_BLOCK object to a peer before having received a sendcmpct message from that peer. + +====MSG_CMPCT_BLOCK==== +# getdata messages may now contain requests for MSG_CMPCT_BLOCK objects. +# Upon receipt of a getdata containing a request for a MSG_CMPCT_BLOCK object with the hash of a block which was recently announced and after having sent the requesting peer a sendcmpct message, nodes MUST respond with a cmpctblock message containing appropriate data representing the block being requested. +# MSG_CMPCT_BLOCK inv objects MUST NOT appear anywhere except for in getdata messages. + +====cmpctblock==== +# The cmpctblock message is defined as as a message containing a serialized HeaderAndShortIDs message and pchCommand == "cmpctblock". +# Upon receipt of a cmpctblock message after sending a sendcmpct message, nodes SHOULD calculate the short transaction ID for each unconfirmed transaction they have available (ie in their mempool) and compare each to each short transaction ID in the cmpctblock message. +# After finding already-available transactions, nodes which do not have all transactions available to reconstruct the full block SHOULD request the missing transactions using a getblocktxn message. +# A node MUST NOT send a cmpctblock message unless they are able to respond to a getblocktxn message which requests every transaction in the block. +# A node MUST NOT send a cmpctblock message without having validated that the header properly commits to each transaction in the block, and properly builds on top of the existing chain with a valid proof-of-work. A node MAY send a cmpctblock before validating that each transaction in the block validly spends existing UTXO set entries. + +====getblocktxn==== +# The getblocktxn message is defined as as a message containing a serialized BlockTransactionsRequest message and pchCommand == "getblocktxn". +# Upon receipt of a properly-formatted getblocktxnmessage, nodes which recently provided the sender of such a message a cmpctblock for the block hash identified in this message MUST respond with an appropriate blocktxn message. Such a blocktxn message MUST contain exactly and only each transaction which is present in the appropriate block at the index specified in the getblocktxn indexes list, in the order requested. + +====blocktxn==== +# The blocktxn message is defined as as a message containing a serialized BlockTransactions message and pchCommand == "blocktxn". +# Upon receipt of a properly-formatted requested blocktxn message, nodes SHOULD attempt to reconstruct the full block by: +## Taking the prefilledtxn transactions from the original cmpctblock and placing them in the marked positions. +## For each short transaction ID from the original cmpctblock, in order, find the corresponding transaction either from the blocktxn message or from other sources and place it in the first available position in the block. +# Once the block has been reconstructed, it shall be processed as normal, keeping in mind that short transaction IDs are expected to occasionally collide, and that nodes MUST NOT be penalized for such collisions, wherever they appear. + +===Implementation Notes=== +# For nodes which have sufficient inbound bandwidth, sending a sendcmpct message with the first integer set to 1 to up to 3 peers is RECOMMENDED. If possible, it is RECOMMENDED that those peers be selected based on their past performance in providing blocks quickly (eg the three peers which provided the highest number of the recent N blocks the quickest), allowing nodes to receive blocks which come from those peers in only 0.5*RTT. + +# Nodes MUST NOT send such sendcmpct messages to more than three peers, as it encourages wasting outbound bandwidth across the network. + +# All nodes SHOULD send a sendcmpct message to all appropriate peers. This will reduce their outbound bandwidth usage by allowing their peers to request compact blocks instead of full blocks. + +# Nodes with limited inbound bandwidth SHOULD request blocks using MSG_CMPCT_BLOCK/getblocktxn requests, when possible. While this increases worst-case message round-trips, it is expected to reduce overall transfer latency as TCP is more likely to exhibit poor throughput on low-bandwidth nodes. + +# Nodes sending cmpctblock messages SHOULD limit prefilledtxn to 10KB of transactions. When in doubt, nodes SHOULD only include the coinbase transaction in prefilledtxn. + +# Nodes MAY pick one nonce per block they wish to send, and only build a cmpctblock message once for all peers which they wish to send a given block to. Nodes SHOULD NOT use the same nonce across multiple different blocks. + +# Nodes MAY impose additional requirements on when they announce new blocks by sending cmpctblock messages. For example, nodes with limited outbound bandwidth MAY choose to announce new blocks using inv/header messages (as per BIP130) to conserve outbound bandwidth. + +# Note that the MSG_CMPCT_BLOCK section does not require that nodes respond to MSG_CMPCT_BLOCK getdata requests for blocks which they did not recently announce. This allows nodes to calculate cmpctblock messages at announce-time instead of at request-time. Thus, nodes MUST NOT request blocks using MSG_CMPCT_BLOCK getdatas unless it is in response to an inv/headers block announcement (as per BIP130), and MUST NOT request blocks using MSG_CMPCT_BLOCK getdatas in response to headers messages which were, themselves, responses to getheaders requests. + +# While the current version sends transactions with the same encodings as is used in tx messages and elsewhere in the protocol, the version field in sendcmpct is intended to allow this to change in the future. For this reason, it is recommended that the code used to decode PrefilledTransaction and BlockTransactions messages be prepared to take a different transaction encoding, if and when the version field in sendcmpct changes in a future BIP. + +# Any undefined behavior in this spec may cause failure to transfer block to, peer disconnection by, or self-destruction by the receiving node. A node receiving non-minimally-encoded CompactSize encodings should make a best-effort to eat the sender's cat. + +==Justification== + +====Protocol design==== +There have been many proposals to save wire bytes when relaying blocks. Many of them have a two-fold goal of reducing block relay time and thus rely on the use of significant processing power in order to avoid introducing additional worst-case RTTs. Because this work is not focused primarily on reducing block relay time, its design is much simpler (ie does not rely on set reconciliation protocols). Still, in testing at the time of writing, nodes are able to relay blocks without the extra getblocktxn/blocktxn RTT around 90% of the time. With a smart compact-block-announcement policy, it is thus expected that this work might allow blocks to be relayed between nodes in 0.5*RTT instead of 1.5*RTT at least 75% of the time. + +====Short transaction ID calculation==== +The short transaction ID calculation is designed to take absolutely minimal processing time during block compaction to avoid introducing serious DoS vulnerabilities such as those introduced by the bloom-filtering in BIP 37. As such, it is possible for a node to construct one compact-block representation of a block for relay to multiple peers. Additionally, only one cryptographic hash (2 SHA rounds) is used when calculating the short transaction IDs for an entire block. + +SipHash-2-4 is used for calculating short transaction IDs primarily because it is fast and is reasonably able to limit the ability of an attacker who does not know the block hash or nonce to cause collisions in short transaction IDs. If an attacker were able to cause such collisions, filling mempools (and, thus, blocks) with them would cause poor network propagation of new (or non-attacker, in the case of a miner) blocks. As SipHash was designed, in part, to be used as a key selector for hash maps with malicious data, it should work very well for our use. + +The 8-byte nonce in short transaction ID calculation is used to introduce additional entropy on a per-node level. While the use of 8 bytes is sufficient for an attacker to maliciously cause short transaction ID collisions in their own block relay, this would have less of an effect than if such an attacker were relaying headers/invs and not responding to requests for the full block. + +==Backward compatibility== + +Older clients remain fully compatible and interoperable after this change. + +==Implementation== + +https://github.com/TheBlueMatt/bitcoin/tree/udp + +==Acknowledgements== + +Thanks to Gregory Maxwell for the initial suggestion as well as a lot of back-and-forth design and significant testing. +Thanks to Nicolas Dorier for the protocol flow diagram. + +==Copyright== + +This document is placed in the public domain. diff --git a/bip-0152/protocol-flow.png b/bip-0152/protocol-flow.png new file mode 100644 index 0000000..f1d1d17 Binary files /dev/null and b/bip-0152/protocol-flow.png differ -- cgit v1.2.3 From 7ae81736cfb5504cd60d8982be86d0ee1e63a7c7 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 22 May 2016 18:23:15 -0700 Subject: Replace my generic bip@ email with bip-specific emails everywhere --- bip-0037.mediawiki | 2 +- bip-0111.mediawiki | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0037.mediawiki b/bip-0037.mediawiki index f76891e..eba0628 100644 --- a/bip-0037.mediawiki +++ b/bip-0037.mediawiki @@ -2,7 +2,7 @@ BIP: 37 Title: Connection Bloom filtering Author: Mike Hearn - Matt Corallo + Matt Corallo Status: Final Type: Standards Track Created: 2012-10-24 diff --git a/bip-0111.mediawiki b/bip-0111.mediawiki index e0ae9e8..f759f5c 100644 --- a/bip-0111.mediawiki +++ b/bip-0111.mediawiki @@ -1,7 +1,7 @@
   BIP: 111
   Title: NODE_BLOOM service bit
-  Author: Matt Corallo 
+  Author: Matt Corallo 
           Peter Todd 
   Status: Draft
   Type: Standards Track
-- 
cgit v1.2.3


From 9d89d2b77819734dd262603204a16be016746880 Mon Sep 17 00:00:00 2001
From: Matt Corallo 
Date: Mon, 23 May 2016 22:06:06 -0700
Subject: Update to new BIP 152 Protocol Flow

---
 bip-0152/protocol-flow.png | Bin 32870 -> 25231 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/bip-0152/protocol-flow.png b/bip-0152/protocol-flow.png
index f1d1d17..207a78e 100644
Binary files a/bip-0152/protocol-flow.png and b/bip-0152/protocol-flow.png differ
-- 
cgit v1.2.3


From ed0f8da4ad97703f1c57919303da082810885fb7 Mon Sep 17 00:00:00 2001
From: Luke Dashjr 
Date: Sat, 23 Apr 2016 20:32:59 +0000
Subject: BIP 22 & 145: Use simple Yes/No rather than templates (which don't
 work on GitHub)

---
 bip-0022.mediawiki | 28 ++++++++++++++--------------
 bip-0145.mediawiki |  6 +++---
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/bip-0022.mediawiki b/bip-0022.mediawiki
index 35b59be..4b33e59 100644
--- a/bip-0022.mediawiki
+++ b/bip-0022.mediawiki
@@ -26,9 +26,9 @@ Block template creation can be influenced by various parameters:
 |-
 ! Key !! Required !! Type !! Description
 |-
-| capabilities || {{No}} || Array of Strings || SHOULD contain a list of the following, to indicate client-side support: [[#Optional: Long Polling|"longpoll"]], "coinbasetxn", "coinbasevalue", [[bip-0023.mediawiki#Block Proposal|"proposal"]], [[bip-0023.mediawiki#Logical Services|"serverlist"]], "workid", and any of the [[bip-0023.mediawiki#Mutations|mutations]]
+| capabilities || No || Array of Strings || SHOULD contain a list of the following, to indicate client-side support: [[#Optional: Long Polling|"longpoll"]], "coinbasetxn", "coinbasevalue", [[bip-0023.mediawiki#Block Proposal|"proposal"]], [[bip-0023.mediawiki#Logical Services|"serverlist"]], "workid", and any of the [[bip-0023.mediawiki#Mutations|mutations]]
 |-
-| mode || {{No}} || String || MUST be "template" or omitted
+| mode || No || String || MUST be "template" or omitted
 |}
 
 getblocktemplate MUST return a JSON Object containing the following keys:
@@ -37,29 +37,29 @@ getblocktemplate MUST return a JSON Object containing the following keys:
 |-
 ! Key !! Required !! Type !! Description
 |-
-| bits || {{Yes}} || String || the compressed difficulty in hexadecimal
+| bits || Yes || String || the compressed difficulty in hexadecimal
 |-
-| curtime || {{Yes}} || Number || the current time as seen by the server (recommended for block time) - note this is not necessarily the system clock, and must fall within the mintime/maxtime rules
+| curtime || Yes || Number || the current time as seen by the server (recommended for block time) - note this is not necessarily the system clock, and must fall within the mintime/maxtime rules
 |-
-| height || {{Yes}} || Number || the height of the block we are looking for
+| height || Yes || Number || the height of the block we are looking for
 |-
-| previousblockhash || {{Yes}} || String || the hash of the previous block, in big-endian hexadecimal
+| previousblockhash || Yes || String || the hash of the previous block, in big-endian hexadecimal
 |-
-| sigoplimit || {{No}} || Number || number of sigops allowed in blocks
+| sigoplimit || No || Number || number of sigops allowed in blocks
 |-
-| sizelimit || {{No}} || Number || number of bytes allowed in blocks
+| sizelimit || No || Number || number of bytes allowed in blocks
 |-
-| transactions || {{Yes|Should}} || Array of Objects || Objects containing [[#Transactions Object Format|information for Bitcoin transactions]] (excluding coinbase)
+| transactions || Should || Array of Objects || Objects containing [[#Transactions Object Format|information for Bitcoin transactions]] (excluding coinbase)
 |-
-| version || {{Yes}} || Number || always 1 or 2 (at least for bitcoin) - clients MUST understand the implications of the version they use (eg, comply with [[bip-0034.mediawiki|BIP 0034]] for version 2)
+| version || Yes || Number || always 1 or 2 (at least for bitcoin) - clients MUST understand the implications of the version they use (eg, comply with [[bip-0034.mediawiki|BIP 0034]] for version 2)
 |-
-| coinbaseaux || {{No}} || Object || data that SHOULD be included in the coinbase's scriptSig content. Only the values (hexadecimal byte-for-byte) in this Object should be included, not the keys. This does not include the block height, which is required to be included in the scriptSig by [[bip-0034.mediawiki|BIP 0034]]. It is advisable to encode values inside "PUSH" opcodes, so as to not inadvertently expend SIGOPs (which are counted toward limits, despite not being executed).
+| coinbaseaux || No || Object || data that SHOULD be included in the coinbase's scriptSig content. Only the values (hexadecimal byte-for-byte) in this Object should be included, not the keys. This does not include the block height, which is required to be included in the scriptSig by [[bip-0034.mediawiki|BIP 0034]]. It is advisable to encode values inside "PUSH" opcodes, so as to not inadvertently expend SIGOPs (which are counted toward limits, despite not being executed).
 |-
-| coinbasetxn || {{Patch|this or ↓}} || Object || [[#Transactions Object Format|information for coinbase transaction]]
+| coinbasetxn || this or ↓ || Object || [[#Transactions Object Format|information for coinbase transaction]]
 |-
-| coinbasevalue || {{Patch|this or ↑}} || Number || total funds available for the coinbase (in Satoshis)
+| coinbasevalue || this or ↑ || Number || total funds available for the coinbase (in Satoshis)
 |-
-| workid || {{No}} || String || if provided, this value must be returned with results (see [[#Block Submission|Block Submission]])
+| workid || No || String || if provided, this value must be returned with results (see [[#Block Submission|Block Submission]])
 |}
 
 ==== Transactions Object Format ====
diff --git a/bip-0145.mediawiki b/bip-0145.mediawiki
index b90725e..a4528c5 100644
--- a/bip-0145.mediawiki
+++ b/bip-0145.mediawiki
@@ -22,11 +22,11 @@ The template Object is revised to include these keys:
 |-
 ! Key !! Required !! Type !! Description
 |-
-| costlimit || {{No}} || Number || total cost allowed in blocks
+| costlimit || No || Number || total cost allowed in blocks
 |-
-| sigoplimit || {{No}} || Number || total sigop cost allowed in blocks divided by 4
+| sigoplimit || No || Number || total sigop cost allowed in blocks divided by 4
 |-
-| version || {{Yes}} || Number || block version; clients MUST understand the implications of the version they use (eg, comply with [[bip-0141.mediawiki|BIP 141]] for version 5)
+| version || Yes || Number || block version; clients MUST understand the implications of the version they use (eg, comply with [[bip-0141.mediawiki|BIP 141]] for version 5)
 |}
 
 ====Transactions Object Format====
-- 
cgit v1.2.3