From: Pieter Wuille <pieter.wuille@gmail.com>
To: Kalle Rosenbaum <kalle@rosenbaum.se>
Cc: Bitcoin Dev <bitcoin-development@lists.sourceforge.net>
Subject: Re: [Bitcoin-development] BIP for Proof of Payment
Date: Sat, 6 Jun 2015 16:47:05 +0200 [thread overview]
Message-ID: <CAPg+sBjtovFpLoibpVGLsNJXexBcoiYzjrvctraXntCUZBJsGg@mail.gmail.com> (raw)
In-Reply-To: <CAPswA9w5Sgg6AV=9Pqx5sqbkdrwv9LmwoxmMu7xZsQSNXtmZnQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 11680 bytes --]
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.
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.
On Sat, Jun 6, 2015 at 4:35 PM, Kalle Rosenbaum <kalle@rosenbaum.se> 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 <kalle@rosenbaum.se>
> 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
> |-
> | <version> || 2 || Version, little endian, currently 0x01 0x00
> |-
> | <txid> || 32 || The transaction to prove
> |-
> | <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
> Bitcoin-development@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/bitcoin-development
>
>
[-- Attachment #2: Type: text/html, Size: 13089 bytes --]
next prev parent reply other threads:[~2015-06-06 14:47 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-06 14:35 [Bitcoin-development] BIP for Proof of Payment Kalle Rosenbaum
2015-06-06 14:47 ` Pieter Wuille [this message]
2015-06-06 15:05 ` Kalle Rosenbaum
2015-06-06 15:13 ` Pieter Wuille
2015-06-06 16:20 ` Kalle Rosenbaum
2015-06-06 16:10 ` Tom Harding
2015-06-06 17:00 ` Kalle Rosenbaum
2015-06-06 21:25 ` Kalle Rosenbaum
2015-06-06 22:01 ` Luke Dashjr
2015-06-15 9:21 ` Kalle Rosenbaum
[not found] ` <CAPg+sBiWykR6RaHhbyYQbL=A5t1TmHgEmS_sC7jj9d3SUTMO9g@mail.gmail.com>
[not found] ` <CAPswA9zycU0pwZKaHU9J3Tvg=ovLJ8TZ9OH6ebTPONaRaiOE8g@mail.gmail.com>
2015-06-15 10:00 ` Pieter Wuille
2015-06-15 11:59 ` Kalle Rosenbaum
2015-06-16 14:31 ` Pieter Wuille
2015-06-16 19:22 ` Kalle Rosenbaum
2015-06-16 19:25 ` Pieter Wuille
[not found] ` <CAPswA9yFUAqFyNBFBnnwpT=B9RcdNssdjz-_KWbX5GuLM5Uyxw@mail.gmail.com>
2015-06-16 19:48 ` Pieter Wuille
2015-06-17 9:51 ` Kalle Rosenbaum
2015-06-21 14:39 ` Kalle Rosenbaum
[not found] ` <CAPswA9w8QaWV72UuGnitWWeDTr5MPKvzwrD5udmq_FQke-NGAQ@mail.gmail.com>
2015-07-24 6:55 ` [bitcoin-dev] " Kalle Rosenbaum
2015-07-27 8:14 ` Sriram Karra
[not found] ` <CABm2gDrickFojwmUi7GqAhSW5K0yTa_59VjKrY+wAXEq1MYUoA@mail.gmail.com>
2015-07-26 21:13 ` Kalle Rosenbaum
2015-07-27 9:08 ` Jorge Timón
2015-07-27 11:21 ` Kalle Rosenbaum
2015-06-16 5:26 ` Tom Harding
2015-06-16 12:12 ` Kalle Rosenbaum
2015-06-16 12:31 ` Kalle Rosenbaum
2015-06-16 14:05 ` Tom Harding
2015-06-16 16:22 ` Kalle Rosenbaum
2015-06-06 15:18 ` Luke Dashjr
2015-06-06 15:23 ` Pieter Wuille
2015-06-06 15:32 ` Peter Todd
2015-06-06 16:35 ` Kalle Rosenbaum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAPg+sBjtovFpLoibpVGLsNJXexBcoiYzjrvctraXntCUZBJsGg@mail.gmail.com \
--to=pieter.wuille@gmail.com \
--cc=bitcoin-development@lists.sourceforge.net \
--cc=kalle@rosenbaum.se \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox