Discussion:
BIP sighash_noinput
Add Reply
Christian Decker via bitcoin-dev
2018-04-30 16:29:53 UTC
Reply
Permalink
Raw Message
Hi all,

I'd like to pick up the discussion from a few months ago, and propose a new
sighash flag, `SIGHASH_NOINPUT`, that removes the commitment to the previous
output. This was previously mentioned on the list by Joseph Poon [1], but was
never formally proposed, so I wrote a proposal [2].

We have long known that `SIGHASH_NOINPUT` would be a great fit for Lightning.
They enable simple watch-towers, i.e., outsource the need to watch the
blockchain for channel closures, and react appropriately if our counterparty
misbehaves. In addition to this we just released the eltoo [3,4] paper which
describes a simplified update mechanism that can be used in Lightning, and other
off-chain contracts, with any number of participants.

By not committing to the previous output being spent by the transaction, we can
rebind an input to point to any outpoint with a matching output script and
value. The binding therefore is no longer explicit through a reference, but
through script compatibility, and the transaction ID reference in the input is a
hint to validators. The sighash flag is meant to enable some off-chain use-cases
and should not be used unless the tradeoffs are well-known. In particular we
suggest using contract specific key-pairs, in order to avoid having any unwanted
rebinding opportunities.

The proposal is very minimalistic, and simple. However, there are a few things
where we'd like to hear the input of the wider community with regards to the
implementation details though. We had some discussions internally on whether to
use a separate opcode or a sighash flag, some feeling that the sighash flag
could lead to some confusion with existing wallets, but given that we have
`SIGHASH_NONE`, and that existing wallets will not sign things with unknown
flags, we decided to go the sighash way. Another thing is that we still commit
to the amount of the outpoint being spent. The rationale behind this is that,
while rebinding to outpoints with the same value maintains the value
relationship between input and output, we will probably not want to bind to
something with a different value and suddenly pay a gigantic fee.

The deployment part of the proposal is left vague on purpose in order not to
collide with any other proposals. It should be possible to introduce it by
bumping the segwit script version and adding the new behavior.

I hope the proposal is well received, and I'm looking forward to discussing
variants and tradeoffs here. I think the applications we proposed so far are
quite interesting, and I'm sure there are many more we can enable with this
change.

Cheers,
Christian

[1] https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-February/012460.html
[2] https://github.com/cdecker/bips/blob/noinput/bip-xyz.mediawiki
[3] https://blockstream.com/2018/04/30/eltoo-next-lightning.html
[4] https://blockstream.com/eltoo.pdf
Dario Sneidermanis via bitcoin-dev
2018-04-30 18:25:42 UTC
Reply
Permalink
Raw Message
Something like this might also be useful for several use cases related to
RBF. For example:

Alice sends Bob an RBF-activated transaction T1 with the intention of
bumping its fee if necessary. Bob wants to send these funds to Carol, but
cannot wait until T1 confirms, so he crafts a transaction T2 that spends T1
using SIGHASH_NOINPUT, and pays Carol. Carol can now make sure she receives
the money even if Alice fee-bumps T1, as long as the outputs of the
replaced transactions are compatible.

Extra care should be taken to avoid rebinding, maybe by including an extra
input in T2 that doesn't use SIGHASH_NOINPUT.

On Mon, Apr 30, 2018 at 1:29 PM, Christian Decker via bitcoin-dev <
Post by Christian Decker via bitcoin-dev
Hi all,
I'd like to pick up the discussion from a few months ago, and propose a new
sighash flag, `SIGHASH_NOINPUT`, that removes the commitment to the previous
output. This was previously mentioned on the list by Joseph Poon [1], but was
never formally proposed, so I wrote a proposal [2].
We have long known that `SIGHASH_NOINPUT` would be a great fit for Lightning.
They enable simple watch-towers, i.e., outsource the need to watch the
blockchain for channel closures, and react appropriately if our counterparty
misbehaves. In addition to this we just released the eltoo [3,4] paper which
describes a simplified update mechanism that can be used in Lightning, and other
off-chain contracts, with any number of participants.
By not committing to the previous output being spent by the transaction, we can
rebind an input to point to any outpoint with a matching output script and
value. The binding therefore is no longer explicit through a reference, but
through script compatibility, and the transaction ID reference in the input is a
hint to validators. The sighash flag is meant to enable some off-chain use-cases
and should not be used unless the tradeoffs are well-known. In particular we
suggest using contract specific key-pairs, in order to avoid having any unwanted
rebinding opportunities.
The proposal is very minimalistic, and simple. However, there are a few things
where we'd like to hear the input of the wider community with regards to the
implementation details though. We had some discussions internally on whether to
use a separate opcode or a sighash flag, some feeling that the sighash flag
could lead to some confusion with existing wallets, but given that we have
`SIGHASH_NONE`, and that existing wallets will not sign things with unknown
flags, we decided to go the sighash way. Another thing is that we still commit
to the amount of the outpoint being spent. The rationale behind this is that,
while rebinding to outpoints with the same value maintains the value
relationship between input and output, we will probably not want to bind to
something with a different value and suddenly pay a gigantic fee.
The deployment part of the proposal is left vague on purpose in order not to
collide with any other proposals. It should be possible to introduce it by
bumping the segwit script version and adding the new behavior.
I hope the proposal is well received, and I'm looking forward to discussing
variants and tradeoffs here. I think the applications we proposed so far are
quite interesting, and I'm sure there are many more we can enable with this
change.
Cheers,
Christian
[1] https://lists.linuxfoundation.org/pipermail/bitcoin-dev/
2016-February/012460.html
[2] https://github.com/cdecker/bips/blob/noinput/bip-xyz.mediawiki
[3] https://blockstream.com/2018/04/30/eltoo-next-lightning.html
[4] https://blockstream.com/eltoo.pdf
_______________________________________________
bitcoin-dev mailing list
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Russell O'Connor via bitcoin-dev
2018-05-01 16:58:37 UTC
Reply
Permalink
Raw Message
At the risk of bikeshedding, shouldn't NOINPUT also zero out the
hashSequence so that its behaviour is consistent with ANYONECANPAY?

On Mon, Apr 30, 2018 at 12:29 PM, Christian Decker via bitcoin-dev <
Post by Christian Decker via bitcoin-dev
Hi all,
I'd like to pick up the discussion from a few months ago, and propose a new
sighash flag, `SIGHASH_NOINPUT`, that removes the commitment to the previous
output. This was previously mentioned on the list by Joseph Poon [1], but was
never formally proposed, so I wrote a proposal [2].
We have long known that `SIGHASH_NOINPUT` would be a great fit for Lightning.
They enable simple watch-towers, i.e., outsource the need to watch the
blockchain for channel closures, and react appropriately if our counterparty
misbehaves. In addition to this we just released the eltoo [3,4] paper which
describes a simplified update mechanism that can be used in Lightning, and other
off-chain contracts, with any number of participants.
By not committing to the previous output being spent by the transaction, we can
rebind an input to point to any outpoint with a matching output script and
value. The binding therefore is no longer explicit through a reference, but
through script compatibility, and the transaction ID reference in the input is a
hint to validators. The sighash flag is meant to enable some off-chain use-cases
and should not be used unless the tradeoffs are well-known. In particular we
suggest using contract specific key-pairs, in order to avoid having any unwanted
rebinding opportunities.
The proposal is very minimalistic, and simple. However, there are a few things
where we'd like to hear the input of the wider community with regards to the
implementation details though. We had some discussions internally on whether to
use a separate opcode or a sighash flag, some feeling that the sighash flag
could lead to some confusion with existing wallets, but given that we have
`SIGHASH_NONE`, and that existing wallets will not sign things with unknown
flags, we decided to go the sighash way. Another thing is that we still commit
to the amount of the outpoint being spent. The rationale behind this is that,
while rebinding to outpoints with the same value maintains the value
relationship between input and output, we will probably not want to bind to
something with a different value and suddenly pay a gigantic fee.
The deployment part of the proposal is left vague on purpose in order not to
collide with any other proposals. It should be possible to introduce it by
bumping the segwit script version and adding the new behavior.
I hope the proposal is well received, and I'm looking forward to discussing
variants and tradeoffs here. I think the applications we proposed so far are
quite interesting, and I'm sure there are many more we can enable with this
change.
Cheers,
Christian
[1] https://lists.linuxfoundation.org/pipermail/bitcoin-dev/
2016-February/012460.html
[2] https://github.com/cdecker/bips/blob/noinput/bip-xyz.mediawiki
[3] https://blockstream.com/2018/04/30/eltoo-next-lightning.html
[4] https://blockstream.com/eltoo.pdf
_______________________________________________
bitcoin-dev mailing list
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Christian Decker via bitcoin-dev
2018-05-01 17:32:32 UTC
Reply
Permalink
Raw Message
Post by Russell O'Connor via bitcoin-dev
At the risk of bikeshedding, shouldn't NOINPUT also zero out the
hashSequence so that its behaviour is consistent with ANYONECANPAY?
Good catch, must've missed that somehow. I'll amend the BIP accordingly.
Christian Decker via bitcoin-dev
2018-05-04 11:09:09 UTC
Reply
Permalink
Raw Message
It seems to me, that `SIGHASH_NOINPUT` may help make some protocol
integrate better with existing wallets.
Depends on which end of a transaction the existing wallet is: existing
wallets will refuse to sign a transaction with an unknown sighash flag,
but if the wallet is creating the output that'll later be spent using a
`SIGHASH_NOINPUT` transaction it won't (and shouldn't) care.
I remember vaguely that `SIGHASH_NOINPUT` was also mentioned before in
LN discussions, when the issue of transaction malleation was
considered (before SegWit, being totally uncontroversial, was
massively adopted). The sketch below, I believe, is somewhat
consistent with how it could have been used in funding a channel.
I consider `SIGHASH_NOINPUT` to be a poor-man's malleability fix, since
it comes with some baggage. Without trying to undermine my own proposal,
but address reuse in combination with binding through script, can lead
to very unexpected results. You need to be very careful about where you
allow rebinding, hence the warnings in the proposal.
Consider a CoinSwap protocol. Each side writes a transaction that
pays out to an ordinary 2-of-2 multisig address. But before each side
writes and signs that transaction, it first demands a timelocked
backout transaction to let them recover their own funds in case it
falls through (more generally, every offchain protocol has a similar
setup stage where some way to back out is signed before all parties
enter into the contract).
...
With `SIGHASH_NOINPUT`, we can indeed implement such a walletless
CoinSwap (or other protocol) software. We only need to provide the
public keys that will be used in the initial 2-of-2, and the other
side can create a signature with `SIGHASH_NOINPUT` flag.
I was wondering whether we could actually skip one communication round
w.r.t. the previously described CoinSwap protocol, but it turns out we
need to at least exchange public keys before actually moving any
funds. Would have been nice to do spontaneous CoinSwaps.
The setup of the CoinSwap then goes this way. The swapping nodes
exchange public keys (two for each side in this case), they agree on
who gets to move first in the swap and who generates the preimage, and
then they agree on what the backout transactions look like (in
particular, they agree on the address the backout transactions spend)
and create signatures, with `SIGHASH_NOINPUT`. In particular, the
signatures do not commit to the txid of the transaction that they
authorize spending. The CoinSwap sofwares then turn around to their
users and say "okay, send to this address", the users initiate the
swap using their normal wallet software, the CoinSwap software
monitors only the address it asked the user to use, then when it
appears onchain (the CoinSwap software does not even need to track the
mempool) it continues with the HTLC offers and preimage exchanges
until the protocol completes.
1. A user buys Bitcoin from an exchange. The exchange operates a
wallet which they credit when the user buys Bitcoin.
2. The user starts a CoinSwap, giving the destination address from
their cold-storage wallet.
3. The CoinSwap tells the user an address to send to. The user
withdraws money from the exchange using that address as destination (1
transaction)
4. The user waits for the CoinSwap to finish, which causes the funds
to appear in their cold-storage wallet (1 transaction).
1. A user buys Bitcoin from an exchange.
2. The user withdraws the funds from the exchange to a CoinSwap
implementation wallet (1 transaction).
3. The user performs a CoinSwap which goes back to the CoinSwap
implementation wallet (2 transactions).
4. The user sends from the CoinSwap wallet to their cold storage (1
transaction). (granted, the CoinSwap implementation could offer a
feature that immediately transfers the swapped funds to some other
wallet, but we still cannot get around the transfer from the exchange
to the CoinSwap wallet)
A drawback of course, is that `SIGHASH_NOINPUT` is an unusual flag to
use; it immediately paints the user as using some special protocol.
So much for `SIGHASH_NOINPUT` CoinSwap.
By providing a new use-case you are contributing to the obfuscation of
this technique. The more normal the use of `SIGHASH_NOINPUT` becomes the
less an observer can learn from it being used. In combination with MAST,
Taproot or Graftroot we can further hide the details of the executed
protocol :-)

Loading...