Subject: Re: [Bitcoin-development] BIP for Proof of Payment

From: Kalle Rosenbaum <[email-masked]>
Date: Sat, 6 Jun 2015 17:05:36 +0200

> What do you gain by making PoPs actually valid transactions? You could for
> example change the signature hashing algorithm (prepend a constant string,
> or add a second hashing step) for signing, rendering the signatures in a PoP
> unusable for actual transaction, while still committing to the same actual
> transaction. That would also remove the need for the OP_RETURN to catch
> fees.

The idea is to simplify implementation. Existing software can be used
as is to sign and validate PoPs. But I do agree that it would be a
cleaner specification if we would make the PoP invalid as a
transaction. I'm open to changes here. I do like the idea to prepend a
constant string. But that would require changes in transaction signing
and validation code, wouldn't it?

>
> Also, I would call it "proof of transaction intent", as it's a commitment to
> a transaction and proof of its validity, but not a proof that an actual
> transaction took place, nor a means to prevent it from being double spent.
>

Naming is hard. I think a simpler name that explains what its main
purpose is (prove that you paid for something) is better than a name
that exactly tries to explain what it is. "Proof of transaction
intent" does not help me understand what this is about. But I would
like to see more name suggestions. The name does not prevent people
from using it for other purposes, ie internet over telephone network.

Thank you
/Kalle

>
>
> On Sat, Jun 6, 2015 at 4:35 PM, Kalle Rosenbaum <[email-masked]> wrote:
>>
>> Hi
>>
>> Following earlier posts on Proof of Payment I'm now proposing the
>> following BIP (To read it formatted instead, go to
>> https://github.com/kallerosenbaum/poppoc/wiki/Proof-of-Payment-BIP).
>>
>> Regards,
>> Kalle Rosenbaum
>>
>> <pre>
>>   BIP: <BIP number>
>>   Title: Proof of Payment
>>   Author: Kalle Rosenbaum <[email-masked]>
>>   Status: Draft
>>   Type: Standards Track
>>   Created: <date created on, in ISO 8601 (yyyy-mm-dd) format>
>> </pre>
>>
>> == Abstract ==
>>
>> This BIP describes how a wallet can prove to a server that it has the
>> ability to sign a certain transaction.
>>
>> == Motivation ==
>>
>> There are several scenarios in which it would be useful to prove that you
>> have paid for something. For example:
>>
>> * A pre-paid hotel room where your PoP functions as a key to the door.
>> * An online video rental service where you pay for a video and watch it on
>> any device.
>> * An ad-sign where you pay in advance for e.g. 2 weeks exclusivity. During
>> this period you can upload new content to the sign whenever you like using
>> PoP.
>> * Log in to a pay site using a PoP.
>> * A parking lot you pay for monthly and the car authenticates itself using
>> PoP.
>> * A lottery where all participants pay to the same address, and the winner
>> is selected among the transactions to that address. You exchange the prize
>> for a PoP for the winning transaction.
>>
>> With Proof of Payment, these use cases can be achieved without any
>> personal information (user name, password, e-mail address, etc) being
>> involved.
>>
>> == Rationale ==
>>
>> Desirable properties:
>>
>> # A PoP should be generated on demand.
>> # It should only be usable once to avoid issues due to theft.
>> # It should be able to create a PoP for any payment, regardless of script
>> type (P2SH, P2PKH, etc.).
>> # It should prove that you have enough credentials to unlock all the
>> inputs of the proven transaction.
>> # It should be easy to implement by wallets and servers to ease adoption.
>>
>> Current methods of proving a payment:
>>
>> * In BIP0070, the PaymentRequest together with the transactions fulfilling
>> the request makes some sort of proof. However, it does not meet 1, 2 or 4
>> and it obviously only meets 3 if the payment is made through BIP0070. Also,
>> there's no standard way to request/provide the proof. If standardized it
>> would probably meet 5.
>> * Signing messages, chosen by the server, with the private keys used to
>> sign the transaction. This could meet 1 and 2 but probably not 3. This is
>> not standardized either. 4 Could be met if designed so.
>>
>> If the script type is P2SH, any satisfying script should do, just like for
>> a payment. For M-of-N multisig scripts, that would mean that any set of M
>> keys should be sufficient, not neccesarily the same set of M keys that
>> signed the transaction. This is important because strictly demanding the
>> same set of M keys would undermine the purpose of a multisig address.
>>
>> == Specification ==
>>
>> === Data structure ===
>>
>> A proof of payment for a transaction T, here called PoP(T), is used to
>> prove that one has ownership of the credentials needed to unlock all the
>> inputs of T. It has the exact same structure as a bitcoin transaction with
>> the same inputs and outputs as T and in the same order as in T. There is
>> also one OP_RETURN output inserted at index 0, here called the pop output.
>> This output must have the following format:
>>
>>  OP_RETURN <version> <txid> <nonce>
>>
>> {|
>> ! Field        !! Size [B] !! Description
>> |-
>> | &lt;version> || 2        || Version, little endian, currently 0x01 0x00
>> |-
>> | &lt;txid>    || 32       || The transaction to prove
>> |-
>> | &lt;nonce>   || 6        || Random data
>> |}
>>
>> The value of the pop output is set to the same value as the transaction
>> fee of T. Also, if the outputs of T contains an OP_RETURN output, that
>> output must not be included in the PoP because there can only be one
>> OP_RETURN output in a transaction. The value of that OP_RETURN output is
>> instead added to the value of the pop output.
>>
>> An illustration of the PoP data structure and its original payment is
>> shown below.
>>
>> <pre>
>>   T
>>  +----------------------------------------------+
>>  |inputs       | outputs                        |
>>  |       Value | Value   Script                 |
>>  +----------------------------------------------+
>>  |input0 1     |     0   pay to A               |
>>  |input1 3     |     2   OP_RETURN <some data>  |
>>  |input2 4     |     1   pay to B               |
>>  |             |     4   pay to C               |
>>  +----------------------------------------------+
>>
>>   PoP(T)
>>  +----------------------------------------------------------+
>>  |inputs       | outputs                                    |
>>  |       Value | Value   Script                             |
>>  +----------------------------------------------------------+
>>  |input0 1     |     3   OP_RETURN <version> <txid> <nonce> |
>>  |input1 3     |     0   pay to A                           |
>>  |input2 4     |     1   pay to B                           |
>>  |             |     4   pay to C                           |
>>  +----------------------------------------------------------+
>> </pre>
>>
>> The PoP is signed using the same signing process that is used for bitcoin
>> transactions.
>>
>> The purpose of the nonce is to make it harder to use a stolen PoP; Once
>> the PoP has reached the server, that PoP is useless since the server will
>> generate a new nonce for every PoP request.
>>
>> Since a PoP is indistinguishable from a bitcoin transaction, there is a
>> risk that it, accidently or maliciously, enters the bitcoin p2p network. If
>> T is still unconfirmed, or if a reorg takes place, chances are that PoP(T)
>> ends up in a block, invalidating T. Therefore it is important that the
>> outputs of the PoP are the same as in T. The zero transaction fee in PoP(T)
>> is to minimize the incentives for miners to select PoP(T) for inclusion.
>>
>> === Process ===
>>
>> # A proof of payment request is sent from the server to the wallet. The
>> PoP request contains:
>> ## a random nonce
>> ## a destination where to send the PoP, for example a https URL
>> ## data hinting the wallet which transaction to create a proof for. For
>> example:
>> ##* txid, if known by the server
>> ##* PaymentRequest.PaymentDetails.merchant_data (in case of a BIP0070
>> payment)
>> ##* amount, label, message or other information from a BIP0021 URL
>> # The wallet identifies a transaction T, if possible. Otherwise it asks
>> the user to select among the ones that match the hints in 1.iii.
>> # The wallet creates an unsigned PoP (UPoP) for T, and asks the user to
>> sign it.
>> # The user confirms
>> # The UPoP(T) is signed by the wallet, creating PoP(T).
>> # The PoP is sent to the destination in 1.ii.
>> # The server receiving the PoP validates it and responds with “valid” or
>> “invalid”.
>> # The wallet displays the response in some way to the user.
>>
>> '''Remarks:'''
>>
>> * The method of transferring the PoP request at step 1 is not specified
>> here. Instead that is specified in separate specifications. See [btcpop
>> scheme BIP](btcpop scheme BIP).
>> * The nonce must be randomly generated by the server for every new PoP
>> request.
>>
>> === Validating a PoP ===
>>
>> The server needs to validate the PoP and reply with "valid" or "invalid".
>> That process is outlined below. If any step fails, the validation is aborted
>> and "invalid" is returned:
>>
>> # Check the format of the PoP. It must pass normal transaction checks,
>> except that the inputs may already be spent.
>> # Check the PoP output at index 0. It must conform to the OP_RETURN output
>> format outlined above.
>> # Check that the rest of the outputs exactly corresponds to the outputs of
>> T and that they appear in the same order as in T. An exception to this is
>> that any OP_RETURN outputs of T must not be included in the PoP. All output
>> value from the OP_RETURN must instead be included in the PoP output.
>> # Check that the nonce is the same as the one you requested.
>> # Check that the inputs of the PoP are exactly the same as in transaction
>> T, and in the same order.
>> # Check the scripts of all the inputs, as would be done on a normal
>> transaction.
>> # Check that the txid in the PoP output is the transaction you actually
>> want proof for. If you don’t know exactly what transaction you want proof
>> for, check that the transaction actually pays for the product/service you
>> deliver.
>> # Return "valid".
>>
>> == Security considerations ==
>>
>> * Someone can intercept the PoP-request and change the PoP destination so
>> that the user sends the PoP to the bad actor.
>> * Someone can intercept the PoP-request and change for example the txid to
>> trick the user to sign a PoP for another transaction than the intended. This
>> can of course be avoided if the user is actually looking at the UPoP before
>> signing it. The bad actor could also set hints for a transaction, existing
>> or not, that the user didn’t make, resulting in a broken service.
>> * Someone can steal a PoP and try to use the service hoping to get a
>> matching nonce. Probability per try: 1/(2^48). The server should have a
>> mechanism for detecting a brute force attack of this kind, or at least slow
>> down the process by delaying the PoP request by some 100 ms or so.
>> * Even if a wallet has no funds it might still be valuable as a generator
>> for PoPs. This makes it important to keep the security of the wallet after
>> it has been emptied.
>> * Transaction malleability may cause the server to have another
>> transaction id than the wallet for the payment. In that case the wallet will
>> not be able to prove the transaction for the server. Wallets should not rely
>> on the transaction id of the outgoing transaction. Instead it should listen
>> for the transaction on the network and put that in its list of transactions.
>>
>> The first two issues are the same attack vector as for traditional, ie
>> BIP0021, bitcoin payments. They could be mitigated by using secure
>> connections.
>>
>> == Reference implementation ==
>>
>> [https://github.com/kallerosenbaum/poppoc poppoc on GitHub]
>>
>> [https://github.com/kallerosenbaum/wallet Mycelium fork on GitHub]
>>
>> == References ==
>>
>> [https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki BIP0021]:
>> URI Scheme
>>
>> [https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki BIP0070]:
>> Payment Protocol
>>
>> [[btcpop scheme BIP]]
>>
>>
>>
>> ------------------------------------------------------------------------------
>>
>> _______________________________________________
>> Bitcoin-development mailing list
>> [email-masked]
>> https://lists.sourceforge.net/lists/listinfo/bitcoin-development
>>
>