SIGHASH_NOINPUT in Segregated Witness

SIGHASH_NOINPUT in Segregated Witness
2016-02-26  1:32 ` Gregory Maxwell
                   ` (3 more replies)
  
From: Joseph Poon @ 2016-02-26  1:07 UTC (permalink / raw)
  To: bitcoin-dev

As Segregated Witness will be merged soon as a solution for transaction
malleability, especially with multi-party adversarial signatures, there
may be an additional use case/functionality which is helpful for
Lightning Network and possibly other Bitcoin use cases. This requires a
new SIGHASH flag inside Segregated Witness which does not sign the input
txid/index.

Segwit is very helpful in resolving malleability in pretty much every
case which matters. It is especially helpful in having solid and safe
defaults for standard Bitcoin payments; it's very difficult to mess up
if you are writing code in conjunction with the Bitcoin RPC API.

However, it is very useful for LN if there is a certain level of
outsourcibility for transactions without this 3rd party taking on
onerous costs. In LN, there is a dispute resolution period established
to prevent the counterparty from attesting an incorrect channel state
(represented by broadcasting a timelocked transaction). In other words,
if someone in a channel broadcasts an incorrect state, the output can be
redeemed by a 3rd party (but this 3rd party is not a custodian, since
the output goes to the other party in the channel).

Ideally, a 3rd-party can be handed a transaction which can encompass all
prior states in a compact way. For currently-designed Segregated Witness
transactions, this requires storing all previous signatures, which can
become very costly if individuals to thousands of channel state updates
per day. This is very possible, as fees are near-zero, the value in
atomizing all payments to many transactions becomes viable (reducing
transaction/information costs). If individuals are doing tens of
thousands of transactions per day, and one presumes something like
70-bytes of data per Commitment state in the channel, it quickly becomes
infeasible to watch on behalf of many channels without material costs.

This is especially necessary because it is highly desirable to make
keeping track of these channels be very cheap, as it allows for more
participants to be watching on one's behalf (reducing the chance of a
3rd party fail to watch). Further, it may reduce the need to notify the
3rd party for every single channel Commitment state, instead only
providing the most recent one should provide sufficient information for
all prior states (since the signature will apply for any type of
transaction), making the only updated information the revocation
secret/preimage. Without this SIGHASH flag, every single state would
need to be contacted and updated with 3rd parties. With this SIGHASH
flag, one could instead delegate outsourcing when one's client goes
offline with a single message several hundred bytes in size,
encompassing all prior states.

Of course, while running a 24/7 full-node is encouraged, I suspect many
people will not want to do so at the current time, and it needs to be
functional for those who elect to be connected intermittently. This
requires outsourcing or watching on one's behalf.

This would be achieved using a SIGHASH flag, termed SIGHASH_NOINPUT. It
does not include as part of the signature, the outpoint being spent
(txid and index), nor the amount. It however, would include the spent
outpoint's script as part of the signature. Note that this is just a
SIGHASH flag, and the outpoints are still being included as part of the
txins (if they are mutated, the new txids can be updated by the wallet
without resigning). This allows for a signature to apply to anything
with that pubkey (therefore pubkeys with this flag should not be
reused). For safety, this only applies in SegWit transactions, as segwit
provides a sufficient malleability solution, there is no incentive to
improperly use this sighash flag as a roundabout way to resolve
malleability.

This helps with 3rd-party outsourcing for watching the blockchain, as
one can provide a signature (and the most recent hash-chain of
revocation preimages), which encompasses penalty transactions for all
prior states. Functionally, this allows for opt-in wildcard inputs, but
wallets which do not require these transactions do not need to be
concerned with this flag; since they will never be signing with this
flag, they do not need to be concerned with address re-use.

I'm interested in input and in the level of receptiveness to this. If
there is interest, I'll write up a draft BIP in the next couple days.

-- 
Joseph Poon


 permalink raw reply	[|nested]
2016-02-26  1:32 ` 
                   ` 
  
From: Joseph Poon @ 2016-02-26  1:07 UTC (permalink / raw)
  To: bitcoin-dev

As Segregated Witness will be merged soon as a solution for transaction
malleability, especially with multi-party adversarial signatures, there
may be an additional use case/functionality which is helpful for
Lightning Network and possibly other Bitcoin use cases. This requires a
new SIGHASH flag inside Segregated Witness which does not sign the input
txid/index.

Segwit is very helpful in resolving malleability in pretty much every
case which matters. It is especially helpful in having solid and safe
defaults for standard Bitcoin payments; it's very difficult to mess up
if you are writing code in conjunction with the Bitcoin RPC API.

However, it is very useful for LN if there is a certain level of
outsourcibility for transactions without this 3rd party taking on
onerous costs. In LN, there is a dispute resolution period established
to prevent the counterparty from attesting an incorrect channel state
(represented by broadcasting a timelocked transaction). In other words,
if someone in a channel broadcasts an incorrect state, the output can be
redeemed by a 3rd party (but this 3rd party is not a custodian, since
the output goes to the other party in the channel).

Ideally, a 3rd-party can be handed a transaction which can encompass all
prior states in a compact way. For currently-designed Segregated Witness
transactions, this requires storing all previous signatures, which can
become very costly if individuals to thousands of channel state updates
per day. This is very possible, as fees are near-zero, the value in
atomizing all payments to many transactions becomes viable (reducing
transaction/information costs). If individuals are doing tens of
thousands of transactions per day, and one presumes something like
70-bytes of data per Commitment state in the channel, it quickly becomes
infeasible to watch on behalf of many channels without material costs.

This is especially necessary because it is highly desirable to make
keeping track of these channels be very cheap, as it allows for more
participants to be watching on one's behalf (reducing the chance of a
3rd party fail to watch). Further, it may reduce the need to notify the
3rd party for every single channel Commitment state, instead only
providing the most recent one should provide sufficient information for
all prior states (since the signature will apply for any type of
transaction), making the only updated information the revocation
secret/preimage. Without this SIGHASH flag, every single state would
need to be contacted and updated with 3rd parties. With this SIGHASH
flag, one could instead delegate outsourcing when one's client goes
offline with a single message several hundred bytes in size,
encompassing all prior states.

Of course, while running a 24/7 full-node is encouraged, I suspect many
people will not want to do so at the current time, and it needs to be
functional for those who elect to be connected intermittently. This
requires outsourcing or watching on one's behalf.

This would be achieved using a SIGHASH flag, termed SIGHASH_NOINPUT. It
does not include as part of the signature, the outpoint being spent
(txid and index), nor the amount. It however, would include the spent
outpoint's script as part of the signature. Note that this is just a
SIGHASH flag, and the outpoints are still being included as part of the
txins (if they are mutated, the new txids can be updated by the wallet
without resigning). This allows for a signature to apply to anything
with that pubkey (therefore pubkeys with this flag should not be
reused). For safety, this only applies in SegWit transactions, as segwit
provides a sufficient malleability solution, there is no incentive to
improperly use this sighash flag as a roundabout way to resolve
malleability.

This helps with 3rd-party outsourcing for watching the blockchain, as
one can provide a signature (and the most recent hash-chain of
revocation preimages), which encompasses penalty transactions for all
prior states. Functionally, this allows for opt-in wildcard inputs, but
wallets which do not require these transactions do not need to be
concerned with this flag; since they will never be signing with this
flag, they do not need to be concerned with address re-use.

I'm interested in input and in the level of receptiveness to this. If
there is interest, I'll write up a draft BIP in the next couple days.

-- 
Joseph Poon


 permalink raw reply	[|nested]
* 
  2016-02-26  1:07 [bitcoin-dev] SIGHASH_NOINPUT in Segregated Witness Joseph Poon

  2016-02-26  1:48   ` Joseph Poon
  2016-02-26  3:20   ` Anthony Towns
  2016-02-26  1:34 ` 
                   ` 
  3 siblings, 2 replies; 8+ messages in thread
From: Gregory Maxwell @ 2016-02-26  1:32 UTC (permalink / raw)
  To: Joseph Poon;  Bitcoin Dev

On Fri, Feb 26, 2016 at 1:07 AM, Joseph Poon via bitcoin-dev
<bitcoin-dev@lists•linuxfoundation.org> wrote:
> I'm interested in input and in the level of receptiveness to this. If
> there is interest, I'll write up a draft BIP in the next couple days.

The design of segwit was carefully constructed to make it maximally
easy and safe to soft-fork in future script enhancements after its
deployment with the specific goal of avoiding indefinite delays in its
deployment from inevitable scope creep from additional things that are
"easy" to deploy as part of segwit.  I think to be successful we must
be absolutely ruthless about changes that go in there beyond the
absolute minimum needed for the safe deployment of segwit... so I
think this should probably be constructed as a new segwit script type,
and not a base feature.

The exact construction you're thinking of there isn't clear to me...
one thing that comes to mind is that I think it is imperative that we
do not deploy a without-inputs SIGHASH flag without also deploying at
least a fee-committing sighash-all. The reason for this is that if
hardware wallets are forced to continue transferring input
transactions to check fees or to use without-inputs, they may choose
the latter and leave the users needlessly exposed to replay attacks.

When you do write a BIP for this its imperative that the vulnerability
to replay is called out in bold blinking flaming text, along with the
necessary description of how to use it safely. The fact that without
input commitments transactions are replayable is highly surprising to
many developers... Personally, I'd even go so far as to name the flag
SIGHASH_REPLAY_VULNERABLE. :)


^ permalink raw reply	[|nested] 8+ messages in thread
2016-02-26  1:32 ` Gregory Maxwell

  2016-02-26  3:20   ` Anthony Towns
  
From: Joseph Poon @ 2016-02-26  1:48 UTC (permalink / raw)
  To: Gregory Maxwell;  Bitcoin Dev

Hi Greg,

On Fri, Feb 26, 2016 at 01:32:34AM +0000, Gregory Maxwell wrote:
> I think to be successful we must be absolutely ruthless about changes
> that go in there beyond the absolute minimum needed for the safe
> deployment of segwit... so I think this should probably be constructed
> as a new segwit script type, and not a base feature.

Absolutely, I'd certainly be interested in this being the first
proof/example for the script upgrade mechanisms if it's not ideal for
this to be implemented as part of Segregated Witness itself.

> The reason for this is that if hardware wallets are forced to continue
> transferring input transactions to check fees or to use
> without-inputs, they may choose the latter and leave the users
> needlessly exposed to replay attacks.

Yes, I think it's necessary to include the fees as part of the
signature, which will also allow for wallets to not require downloading
the input transactions. However, it's necessary to not include the input
amount itself, as they may differ. SegWit itself is very nice in that it
prevents improperly designed wallets and services using the bitcoin RPC
from making mistakes, you can resolve malleability without compromises
-- I also think any proposed SIGHASH should ensure some measure of
safety from design error/shortcuts.

> The fact that without input commitments transactions are replayable is
> highly surprising to many developers... Personally, I'd even go so far
> as to name the flag SIGHASH_REPLAY_VULNERABLE. :)

That's a good point, choosing a scary name is probably very helpful.

Thanks, I'll clarify with a specific BIP soon.

-- 
Joseph Poon


 permalink raw reply	[|nested]
2016-02-26  1:34 ` Bryan Bishop

  
From: Joseph Poon @ 2016-02-26  2:02 UTC (permalink / raw)
  To: Bryan Bishop;  Bitcoin Dev, lightning-dev

Hi Bryan,

On Thu, Feb 25, 2016 at 07:34:24PM -0600, Bryan Bishop wrote:
> Well if you are bothering to draft up a BIP about that SIGHASH flag,
> then perhaps also consider some other SIGHASH flag types as well while
> you are at it?

I'll take a look at those proposals when drafting the BIP. I think for
LN, there is a single clean way to achieve outsourcability, but may be
compatible with other arrangements. I'm somewhat averse to proposing too
much flexibility before there's clear use-cases, though. However, if
others do have uses/examples for other sighash flags, I'd be very
interested while drafting this BIP!

> FWIW there was some concern about replay using SIGHAHS_NOINPUT or something:
> http://gnusha.org/bitcoin-wizards/2015-04-07.log

Yeah, I think the nice thing about SegWit is that you resolve
malleability without worrying about replay attacks in the event of key
reuse. That's why I think it's only safe to do this new sighash type
inside segwit itself -- if you only wanted protection against
malleability you'd use segwit, and not touch this new sighash type
(you'd only use the new sighash flag if you actually need its features).

-- 
Joseph Poon


 permalink raw reply	[|nested]
2016-02-26  1:07 [bitcoin-dev] SIGHASH_NOINPUT in Segregated Witness Joseph Poon
  2016-02-26  1:32 ` Gregory Maxwell
  2016-02-26  1:34 ` Bryan Bishop

  2016-02-29  0:25 ` Rusty Russell
  
From: Luke Dashjr @ 2016-02-26  2:35 UTC (permalink / raw)
  To: bitcoin-dev, Joseph Poon

On Friday, February 26, 2016 1:07:46 AM Joseph Poon via bitcoin-dev wrote:
> This would be achieved using a SIGHASH flag, termed SIGHASH_NOINPUT. It
> does not include as part of the signature, the outpoint being spent
> (txid and index), nor the amount. It however, would include the spent
> outpoint's script as part of the signature. Note that this is just a
> SIGHASH flag, and the outpoints are still being included as part of the
> txins (if they are mutated, the new txids can be updated by the wallet
> without resigning). This allows for a signature to apply to anything
> with that pubkey (therefore pubkeys with this flag should not be
> reused). 

I'd like this regardless of Lightning, as it makes it possible to write fully 
malleability-proof wallet software also.

> For safety, this only applies in SegWit transactions, as segwit
> provides a sufficient malleability solution, there is no incentive to
> improperly use this sighash flag as a roundabout way to resolve
> malleability.

SegWit's malleability solution is not really sufficient in comparison, but I 
don't think there's a need to make this available to pre-SegWit transactions 
anyway (and doing so would probably complicate it).

Luke


 permalink raw reply	[|nested]
2016-02-26  1:32 ` Gregory Maxwell
  2016-02-26  1:48   ` Joseph Poon

  
From: Anthony Towns @ 2016-02-26  3:20 UTC (permalink / raw)
  To: bitcoin-dev, lightning-dev

On Fri, Feb 26, 2016 at 01:32:34AM +0000, Gregory Maxwell via bitcoin-dev wrote:
> On Fri, Feb 26, 2016 at 1:07 AM, Joseph Poon via bitcoin-dev
> <bitcoin-dev@lists•linuxfoundation.org> wrote:
> > I'm interested in input and in the level of receptiveness to this. If
> > there is interest, I'll write up a draft BIP in the next couple days.
> .. I think this should probably be constructed as a new segwit script type,
> and not a base feature.

+1 to both

> The exact construction you're thinking of there isn't clear to me...

I think the idea is that you have three transactions:

 anchor:
   input: whatever
   output:
     - single output, spendable by 2-of-2 multisig
     - [possibly others as well, whatever]

 commitment:
   input: anchor
   outputs:
     1. payment to A
     2. payment to B
     3. HTLC to A on R1, timeout T1
     4. HTLC to A on R2, timeout T2
     5. HTLC to B on R3, timeout T3
     ...

 penalty:
   inputs:
     all the outputs from the commitment tx
   outputs:
     1. 99% as payment to me
     2.  1% as outsourcing fee

As long as the key I use for spending each of commitment transactions
outputs is "single use" -- ie, I don't use it for other channels or
anywhere else on the blockchain, then as long as the signature commits
to the outputs it's safe afaics.

(You still have to send a lot of data to the place you're outsourcing
chain-monitoring to; all the R1,R2,R3 and T1,T2,T3 values are needed in
order to reconstruct the redeem scripts)

> one thing that comes to mind is that I think it is imperative that we
> do not deploy a without-inputs SIGHASH flag without also deploying at
> least a fee-committing sighash-all.

If the fee for commitment transactions changes regularly (eg, a new
commitment transaction is generated every few seconds/minutes, and the fee
is chosen based on whatever estimatefee returns), I think this would cause
problems -- you couldn't use a single signature to cover every revoked
commitment, you'd need one for each different fee level that you'd used
for the lifetime of the channel. Actually, the size of the commitment
transaction will differ anyway depending on how many HTLCs are open,
so even if estimatefee didn't change, the fee would still differ. So I
think commiting to a fee isn't workable for the lightning use case...

> When you do write a BIP for this its imperative that the vulnerability
> to replay is called out in bold blinking flaming text, along with the
> necessary description of how to use it safely. The fact that without
> input commitments transactions are replayable is highly surprising to
> many developers... Personally, I'd even go so far as to name the flag
> SIGHASH_REPLAY_VULNERABLE. :)

+1, though I'm not sure it's so much "vulnerable" to replay as it is
"explicitly designed" to be replayable...

Cheers,
aj



 permalink raw reply	[|nested]
2016-02-26  1:07 [bitcoin-dev] SIGHASH_NOINPUT in Segregated Witness Joseph Poon
                   ` (2 preceding siblings ...)
  2016-02-26  2:35 ` Luke Dashjr

  
From: Rusty Russell @ 2016-02-29  0:25 UTC ( / )
  To: Joseph Poon, bitcoin-dev;  lightning-dev

Joseph Poon via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org> writes:
> Ideally, a 3rd-party can be handed a transaction which can encompass all
> prior states in a compact way. For currently-designed Segregated Witness
> transactions, this requires storing all previous signatures, which can
> become very costly if individuals to thousands of channel state updates
> per day.

AFAICT we need more than this.  Or are you using something other than
the deployable lightning commit tx style?

If each HTLC output is a p2sh[1], you need the timeout and rhash for
each one to build the script to redeem it.  In practice, there's not
much difference between sending a watcher a tx for every commit tx and
sending it information for every new HTLC (roughly a factor of 2).

So we also need to put more in the scriptPubKey for this to work; either
the entire redeemscript, or possibly some kind of multiple-choice P2SH
where any one of the hashes will redeem the payment.

Cheers,
Rusty.
[1] eg. from https://github.com/ElementsProject/lightning/blob/master/doc/deployable-lightning.pdf
        OP_HASH160 OP_DUP # Replace top element with two copies of its hash
        <R-HASH> OP_EQUAL # Test if they supplied the HTLC R value
        OP_SWAP <COMMIT-REVOCATION-HASH> OP_EQUAL OP_ADD
                          # Or the commitment revocation hash
        OP_IF # If any hash matched.
                <KEY-B> # Pay to B.
        OP_ELSE # Must be A, after HTLC has timed out.
                <HTLC-TIMEOUT> OP_CHECKLOCKTIMEVERIFY Ensure (absolute) time has passed.
                <DELAY> OP_CHECKSEQUENCEVERIFY # Delay gives B enough time to use revocation if it has it.
                OP_2DROP # Drop the delay and htlc-timeout from the stack.
                <KEY-A> # Pay to A.
        OP_ENDIF
        OP_CHECKSIG # Verify A or B's signature is correct.

Cheers,
Rusty.