New BIP: Dealing with OP_IF and OP_NOTIF malleability in P2WSH

New BIP: Dealing with OP_IF and OP_NOTIF malleability in P2WSH
2016-08-16 19:37 ` Luke Dashjr
  2016-09-01 11:39 ` Johnson Lau
  
From: Johnson Lau @ 2016-08-16 17:53 UTC (permalink / raw)
  To: bitcoin-dev

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

A new BIP is prepared to deal with OP_IF and OP_NOTIF malleability in P2WSH:
https://github.com/jl2012/bips/blob/minimalif/bip-minimalif.mediawiki
https://github.com/bitcoin/bitcoin/pull/8526

   BIP: x
   Title: Dealing with OP_IF and OP_NOTIF malleability in P2WSH
   Author: Johnson Lau <jl2012@xbt•hk>
   Status: Draft
   Type: Standards Track
   Created: 2016-08-17

Abstract

This document specifies proposed changes to the Bitcoin script validity rules in order to make transaction malleability related to OP_IF and OP_NOTIF impossible in pay-to-witness-script-hash (P2WSH) scripts.

Motivation

OP_IF and OP_NOTIF are flow control codes in the Bitcoin script system. The programme flow is decided by whether the top stake value is True or False. However, this behaviour opens a source of malleability as a third party may replace a True (False) stack item with any other True (False) value without invalidating the transaction.

The proposed rules apply only to pay-to-witness-script-hash (P2WSH) scripts described in BIP141, which has not been activated on the Bitcoin mainnet as of writing. To ensure OP_IF and OP_NOTIF transactions created before the introduction of this BIP will still be accepted by the network, the new rules are not applied to non-segregated witness scripts.

Specification

In P2WSH, the argument for OP_IF and OP_NOTIF MUST be exactly an empty vector or 0x01, or the script evaluation fails immediately.

This is deployed using BIP9 after segregated witness (BIP141) is activated. Details TBD.

Compatibility

This is a softfork on top of BIP141. The rules are enforced as a relay policy by the reference client since the first release of BIP141 (v0.13.1). To avoid risks of fund loss, users MUST NOT create P2WSH scripts that are incompatible with this BIP. An OP_0NOTEQUAL may be used before OP_IF or OP_NOTIF to imitate the original behaviour (which may also re-enable the malleability vector depending on the exact script).

Implementation

https://github.com/bitcoin/bitcoin/pull/8526

Copyright

This work is placed in the public domain.
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - https://gpgtools.org

iQGcBAEBCgAGBQJXs1LgAAoJEO6eVSA0viTSrJQL/A/womJKgi4FuyBTL9oykCss
aBMNN9+SLtmuH7SBgEUGZ8TFxa2st+6RP6Imu+Vvn4O5sXQl3DIXV+X38X93sUYk
wrjdpvdpqFFYJezPDESz6pR/6bZ1ES0aO2QqX578/8sqr8GO6L388s66vJeIGj4n
0LWW8sdEypMuV3HUG/9FFdUNHgiVX1U0sS1rT3P4aN30JYtb7PQpd7r8KTMta7Rt
L1VOZB+W3m2m2YZ9gB7IRmMfzzNm2QXRTPIZXt2x3mYDBuMkp+zEd5+ogA4sBpgP
wp2+l/aos686v0w8QYiNUX2+9Qpe7+238qUpw75d2XJYmLzdotWFvmp4g1hP+awX
HEfwe4BUM+El17LjrHkNeMWNJXMlhTtXb2i0XMj8tU5lZVHep4WpQ+LEahrNlsUl
FdFsi3q8HeWh8JsGaNCL41Bgbg/rKb5hUXyF6hTRHa//E6llOrpXRnsloKgBLv8c
QezgKTAPwwgdjcS6Ek0AqgLp7bCFRijCduYH9i9uaQ==
=lLIZ
-----END PGP SIGNATURE-----


 permalink raw reply	[|nested]
2016-08-16 17:53 [bitcoin-dev] New BIP: Dealing with OP_IF and OP_NOTIF malleability in P2WSH Johnson Lau

  2016-08-16 19:43   ` Peter Todd
  2016-09-01 11:39 ` Johnson Lau
  
From: Luke Dashjr @ 2016-08-16 19:37 UTC (permalink / raw)
  To: bitcoin-dev, Johnson Lau

On Tuesday, August 16, 2016 5:53:08 PM Johnson Lau via bitcoin-dev wrote:
> A new BIP is prepared to deal with OP_IF and OP_NOTIF malleability in
> P2WSH:
> https://github.com/jl2012/bips/blob/minimalif/bip-minimalif.mediawiki
> https://github.com/bitcoin/bitcoin/pull/8526

I am not sure this makes sense. SegWit transactions are already non-malleable 
due to skipping the witness data in calculating the transaction id. What is 
the benefit to this?

Luke


 permalink raw reply	[|nested]
2016-08-16 19:37 ` Luke Dashjr

  2016-08-16 21:58     ` Joseph Poon
  2016-08-16 22:23     ` Russell O'Connor
  
From: Peter Todd @ 2016-08-16 19:43 UTC (permalink / raw)
  To: Luke Dashjr, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 1314 bytes --]

On Tue, Aug 16, 2016 at 07:37:19PM +0000, Luke Dashjr via bitcoin-dev wrote:
> On Tuesday, August 16, 2016 5:53:08 PM Johnson Lau via bitcoin-dev wrote:
> > A new BIP is prepared to deal with OP_IF and OP_NOTIF malleability in
> > P2WSH:
> > https://github.com/jl2012/bips/blob/minimalif/bip-minimalif.mediawiki
> > https://github.com/bitcoin/bitcoin/pull/8526
> 
> I am not sure this makes sense. SegWit transactions are already non-malleable 
> due to skipping the witness data in calculating the transaction id. What is 
> the benefit to this?

SegWit txids aren't malleable, but segwit transactions as a whole still are.
For instance, I could mess with a segwit transaction by replacing part of the
witness that is used as an argument to an OP_IF with a much larger push,
potentially making the transaction larger, thus making it not get mined due to
the higher fee. There are also potential legal issues if someone replaces a
push with data where posession in your jurisdiction is illegal.

Having said that, a better approach may be a separate CHECKBOOLVERIFY opcode
that fails unless the top item on the stack is a minimally encoded true or
false value, to allow script writers to opt into this behavior; it's not always
ideal.

-- 
https://petertodd.org 'peter'[:-1]@petertodd.org

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

 permalink raw reply	[|nested]
2016-08-16 19:43   ` Peter Todd

  2016-08-16 22:23     ` Russell O'Connor
  
From: Joseph Poon @ 2016-08-16 21:58 UTC (permalink / raw)
  To: Peter Todd, Bitcoin Protocol Discussion

I agree this is an interesting area of transaction malleability to still
consider in the future, and minimization of these areas of malleability
with regards to its impact on the p2p network should be easy to resolve
and (hopefully) well-understood by script writers in the future.

On Tue, Aug 16, 2016 at 12:43:32PM -0700, Peter Todd via bitcoin-dev wrote:
> Having said that, a better approach may be a separate CHECKBOOLVERIFY opcode
> that fails unless the top item on the stack is a minimally encoded true or
> false value, to allow script writers to opt into this behavior; it's not always
> ideal.

I think the biggest value of the proposed BIP behavior is that the cost
is lower for "doing it right" to create script enforcement of OP_TRUE or
OP_FALSE. It is already possible to enforce with 2 bytes pushing OP_TRUE
and then OP_EQUAL. Creating an "OP_CHECKBOOLVERIFY" definitely achieves
the same result, but at a 1-byte (insetad of 2-byte) cost to "do it
right", so there is the same incentive to save on the byte and push
potential DoS costs onto the network -- whereas enforcing OP_TRUE byte
in OP_IF would create costs for those who want to evaluate pushdata, so
that has to be explicitly opt-in from an optimization/convenience
standpoint.

-- 
Joseph Poon


 permalink raw reply	[|nested]
2016-08-16 19:43   ` Peter Todd
  2016-08-16 21:58     ` Joseph Poon

  2016-08-16 22:30       ` Pieter Wuille
  
From: Russell O'Connor @ 2016-08-16 22:23 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 1687 bytes --]

On Tue, Aug 16, 2016 at 3:43 PM, Peter Todd via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> On Tue, Aug 16, 2016 at 07:37:19PM +0000, Luke Dashjr via bitcoin-dev
> wrote:
> > On Tuesday, August 16, 2016 5:53:08 PM Johnson Lau via bitcoin-dev wrote:
> > > A new BIP is prepared to deal with OP_IF and OP_NOTIF malleability in
> > > P2WSH:
> > > https://github.com/jl2012/bips/blob/minimalif/bip-minimalif.mediawiki
> > > https://github.com/bitcoin/bitcoin/pull/8526
> >
> > I am not sure this makes sense. SegWit transactions are already
> non-malleable
> > due to skipping the witness data in calculating the transaction id. What
> is
> > the benefit to this?
>
> SegWit txids aren't malleable, but segwit transactions as a whole still
> are.
> For instance, I could mess with a segwit transaction by replacing part of
> the
> witness that is used as an argument to an OP_IF with a much larger push,
> potentially making the transaction larger, thus making it not get mined
> due to
> the higher fee. There are also potential legal issues if someone replaces a
> push with data where posession in your jurisdiction is illegal.
>

If one's goal is to mess with an transaction to prevent it from being
mined, it is more effective to just not relay the transaction rather than
to mess with the witness.  Given two transactions with the same txid and
different witness data, miners and good nodes ought to mine/relay the
version with the lower cost (smaller?) witness data.

Worries about "illegal data" appearing in the blockchain is not an issue
worth writing a soft-fork over.

There may be good reasons for this BIP, but I don't think the reasons give
above are good.

[-- Attachment #2: Type: text/html, Size: 2406 bytes --]

 permalink raw reply	[|nested]
2016-08-16 22:23     ` Russell O'Connor

  2016-08-16 22:36         ` Russell O'Connor
  
From: Pieter Wuille @ 2016-08-16 22:30 UTC (permalink / raw)
  To: Russell O'Connor, Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 1147 bytes --]

On Aug 17, 2016 00:23, "Russell O'Connor via bitcoin-dev" <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> If one's goal is to mess with an transaction to prevent it from being
mined, it is more effective to just not relay the transaction rather than
to mess with the witness.  Given two transactions with the same txid and
different witness data, miners and good nodes ought to mine/relay the
version with the lower cost (smaller?) witness data.

That implies that everyone will see both versions and be able to make that
choice. Unfortunately, those two versions will be definition be in conflict
with each other, and thus only one will end up paying a fee. We're can't
relay two transactions for the price of one, or we'd expose the p2p network
to a very cheap DDoS attack: just send increasingly small versions of the
same transaction.

Segwit's third party mallebility protection makes it not an issue for
dependent contracts if transactions are mauled (=apparently the verb
related to malleability), but there are still good reasons for senders not
to gratuitously make their transactions extensible in size or other
resources.

--
Pieter

[-- Attachment #2: Type: text/html, Size: 1346 bytes --]

 permalink raw reply	[|nested]
2016-08-16 22:30       ` Pieter Wuille

  2016-08-16 22:39           ` Pieter Wuille
  
From: Russell O'Connor @ 2016-08-16 22:36 UTC (permalink / raw)
  To: Pieter Wuille;  Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 1038 bytes --]

On Tue, Aug 16, 2016 at 6:30 PM, Pieter Wuille <pieter.wuille@gmail•com>
wrote:

> On Aug 17, 2016 00:23, "Russell O'Connor via bitcoin-dev" <
> bitcoin-dev@lists•linuxfoundation.org> wrote:
>
> > If one's goal is to mess with an transaction to prevent it from being
> mined, it is more effective to just not relay the transaction rather than
> to mess with the witness.  Given two transactions with the same txid and
> different witness data, miners and good nodes ought to mine/relay the
> version with the lower cost (smaller?) witness data.
>
> That implies that everyone will see both versions and be able to make that
> choice. Unfortunately, those two versions will be definition be in conflict
> with each other, and thus only one will end up paying a fee. We're can't
> relay two transactions for the price of one, or we'd expose the p2p network
> to a very cheap DDoS attack: just send increasingly small versions of the
> same transaction.
>
Can I already do something similar with replace by fee, or are there limits
on that?

[-- Attachment #2: Type: text/html, Size: 1514 bytes --]

 permalink raw reply	[|nested]
2016-08-16 22:36         ` Russell O'Connor

  2016-08-16 22:52             ` Russell O'Connor
  2016-09-05 14:55             ` Russell O'Connor
  
From: Pieter Wuille @ 2016-08-16 22:39 UTC (permalink / raw)
  To: Russell O'Connor;  Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 331 bytes --]

On Aug 17, 2016 00:36, "Russell O'Connor" <roconnor@blockstream•io> wrote:

> Can I already do something similar with replace by fee, or are there
limits on that?

BIP125 and mempool eviction both require the replacing transaction to have
higher fee, to compensate for the cost of relaying the replaced
transaction(s).

-- 
Pieter

[-- Attachment #2: Type: text/html, Size: 469 bytes --]

 permalink raw reply	[|nested]
2016-08-16 22:39           ` Pieter Wuille

  2016-08-17  0:18               ` Gregory Maxwell
  2016-09-05 14:55             ` Russell O'Connor
  
From: Russell O'Connor @ 2016-08-16 22:52 UTC (permalink / raw)
  To: Pieter Wuille;  Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 773 bytes --]

I see.

But is it really necessary to soft fork over this issue?  Why not just make
it a relay rule?  Miners are already incentivized to modify transactions to
drop excess witness data and/or prioritize (versions of) transactions based
on their cost.  If a miner wants to mine a block with excess witness data,
it is mostly their own loss.

On Tue, Aug 16, 2016 at 6:39 PM, Pieter Wuille <pieter.wuille@gmail•com>
wrote:

> On Aug 17, 2016 00:36, "Russell O'Connor" <roconnor@blockstream•io> wrote:
>
> > Can I already do something similar with replace by fee, or are there
> limits on that?
>
> BIP125 and mempool eviction both require the replacing transaction to have
> higher fee, to compensate for the cost of relaying the replaced
> transaction(s).
>
> --
> Pieter
>

[-- Attachment #2: Type: text/html, Size: 1313 bytes --]

 permalink raw reply	[|nested]
2016-08-16 22:52             ` Russell O'Connor

  2016-08-17  0:27                 ` Russell O'Connor
  
From: Gregory Maxwell @ 2016-08-17  0:18 UTC (permalink / raw)
  To: Russell O'Connor, Bitcoin Protocol Discussion

On Tue, Aug 16, 2016 at 10:52 PM, Russell O'Connor via bitcoin-dev
<bitcoin-dev@lists•linuxfoundation.org> wrote:
> I see.
>
> But is it really necessary to soft fork over this issue?  Why not just make
> it a relay rule?  Miners are already incentivized to modify transactions to
> drop excess witness data and/or prioritize (versions of) transactions based
> on their cost.  If a miner wants to mine a block with excess witness data,
> it is mostly their own loss.

Relay rules are quite fragile-- people build programs or protocols not
expecting them to be violated, without proper error handling in those
cases... and then eventually some miner rips them out because they
simply don't care about them: not enforcing them won't make their
blocks invalid.

It's my general view that we should avoid blocking things with relay
rules unless we think that someday they could be made invalid... not
necessarily that they will, but that it's plausible. Then the
elimination at the relay level is just the first exploratory step in
that direction.

One should also consider adversarial behavior by miners.  For example,
I can mine blocks with mutated witnesses with a keyed mac that chooses
the mutation. The key is shared by conspirators or customers, and now
collectively we have a propagation advantage (since we know the
mutated version before it shows up).  Not the _biggest_ concern, since
parties doing this could just create their own new transactions to
selectively propagate; but doing that would require leaving behind fee
paying public transactions, while using malleability wouldn't.


 permalink raw reply	[|nested]
2016-08-17  0:18               ` Gregory Maxwell

  2016-08-17  2:30                   ` Peter Todd
  2016-08-17  3:02                   ` Johnson Lau
  
From: Russell O'Connor @ 2016-08-17  0:27 UTC (permalink / raw)
  To: Gregory Maxwell;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 2014 bytes --]

Okay.

I'm not really opposed to this BIP, but I am worried that fighting script
malleability is a battle that can never be won; even leaving one avenue of
malleability open is probably just as bad as having many avenues of
malleability, so it just doesn't seem worthwhile to me.

On Tue, Aug 16, 2016 at 8:18 PM, Gregory Maxwell <greg@xiph•org> wrote:

> On Tue, Aug 16, 2016 at 10:52 PM, Russell O'Connor via bitcoin-dev
> <bitcoin-dev@lists•linuxfoundation.org> wrote:
> > I see.
> >
> > But is it really necessary to soft fork over this issue?  Why not just
> make
> > it a relay rule?  Miners are already incentivized to modify transactions
> to
> > drop excess witness data and/or prioritize (versions of) transactions
> based
> > on their cost.  If a miner wants to mine a block with excess witness
> data,
> > it is mostly their own loss.
>
> Relay rules are quite fragile-- people build programs or protocols not
> expecting them to be violated, without proper error handling in those
> cases... and then eventually some miner rips them out because they
> simply don't care about them: not enforcing them won't make their
> blocks invalid.
>
> It's my general view that we should avoid blocking things with relay
> rules unless we think that someday they could be made invalid... not
> necessarily that they will, but that it's plausible. Then the
> elimination at the relay level is just the first exploratory step in
> that direction.
>
> One should also consider adversarial behavior by miners.  For example,
> I can mine blocks with mutated witnesses with a keyed mac that chooses
> the mutation. The key is shared by conspirators or customers, and now
> collectively we have a propagation advantage (since we know the
> mutated version before it shows up).  Not the _biggest_ concern, since
> parties doing this could just create their own new transactions to
> selectively propagate; but doing that would require leaving behind fee
> paying public transactions, while using malleability wouldn't.
>

[-- Attachment #2: Type: text/html, Size: 2545 bytes --]

 permalink raw reply	[|nested]
2016-08-17  0:27                 ` Russell O'Connor

  2016-08-17  3:02                   ` Johnson Lau
  
From: Peter Todd @ 2016-08-17  2:30 UTC (permalink / raw)
  To: Russell O'Connor, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 769 bytes --]

On Tue, Aug 16, 2016 at 08:27:54PM -0400, Russell O'Connor via bitcoin-dev wrote:
> Okay.
> 
> I'm not really opposed to this BIP, but I am worried that fighting script
> malleability is a battle that can never be won; even leaving one avenue of
> malleability open is probably just as bad as having many avenues of
> malleability, so it just doesn't seem worthwhile to me.

At least some types of malleability are less harmful than others: changing a
few bits with some weird ECC transformation isn't as likely to cause problems
as being able to append arbitrary data to a transaction's input script. And of
course, we do prevent the latter with the cleanstack rule - consensus enforced
in segwit.

-- 
https://petertodd.org 'peter'[:-1]@petertodd.org

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

 permalink raw reply	[|nested]
2016-08-17  0:27                 ` Russell O'Connor
  2016-08-17  2:30                   ` Peter Todd

  2016-08-17  4:40                     ` Luke Dashjr
  
From: Johnson Lau @ 2016-08-17  3:02 UTC (permalink / raw)
  To: Gregory Maxwell, Russell O'Connor, Bitcoin Protocol Discussion, pete


> On August 16, 2016 at 8:27 PM Russell O'Connor via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org> wrote:
> 
> Okay.
> 
> I'm not really opposed to this BIP, but I am worried that fighting script malleability is a battle that can never be won; even leaving one avenue of malleability open is probably just as bad as having many avenues of malleability, so it just doesn't seem worthwhile to me.

Not really. I think the goal is to protect as many common scripts as possible.

For example:
1) BIP146 (Low S values signatures) will eliminate all malleability for P2WPKH
2) BIP146 + null dummy value for CHECKMULTISIG ("NULLDUMMY") will eliminate all malleability for simple multi-sig in P2WSH. This is particularly interesting since without NULLDUMMY, attackers are able to replace the dummy value with anything.
3) BIP146 + NULLDUMMY + minimal IF argument ("MINIMALIF") will eliminate malleability for any Lightening Network scripts that I'm aware of.

With 3), 99.99% of segwit transactions in foreseeable future should be fully protected.

The plan is to implement MINIMALIF as a relay policy first, and enforce the softfork after further risks assessment. This BIP serves as a warning to users for not using incompatible script.

Peter Todd:
> Having said that, a better approach may be a separate CHECKBOOLVERIFY opcode that fails unless the top item on the stack is a minimally encoded true or false value, to allow script writers to opt into this behavior; it's not always ideal.

I believe all Lightening Network scripts (the only real users of IF/NOTIF in foreseeable future) are already compatible with MINIMALIF. It may not be a good idea for them to spend 1 more byte to get protected.

If people want to have the original OP_IF behaviour, a simple way would be using "0NOTEQUAL IF". However, this works only if the argument is a valid number (also beware of MINIMALDATA rule in BIP62).

To completely replicate the original behaviour, one may use:
"DEPTH TOALTSTACK IFDUP DEPTH FROMALTSTACK NUMNOTEQUAL IF 2DROP {if script} ELSE DROP {else script} ENDIF"

This is because we don't have a simple OP_CASTTOBOOL, and IFDUP is 1 of the 4 codes that perform CastToBool on top stack item (the others are VERIFY, IF, and NOTIF; and VERIFY can't be used here since it terminates the script with a False).


 permalink raw reply	[|nested]
2016-08-17  3:02                   ` Johnson Lau

  2016-08-17 10:15                       ` Johnson Lau
  
From: Luke Dashjr @ 2016-08-17  4:40 UTC (permalink / raw)
  To: bitcoin-dev, Johnson Lau

On Wednesday, August 17, 2016 3:02:53 AM Johnson Lau via bitcoin-dev wrote:
> To completely replicate the original behaviour, one may use:
> "DEPTH TOALTSTACK IFDUP DEPTH FROMALTSTACK NUMNOTEQUAL IF 2DROP {if script}
> ELSE DROP {else script} ENDIF"

This is much uglier than expected. IMO if that's the best workaround for the 
current behaviour, people should just use "OP_1 OP_EQUAL OP_IF" when/if they 
need to avoid malleability issues.

I suspect most cases OP_IF would be used, you really want to accept any non-
zero value. For example, the HTLC script I posted on the list about not long 
ago (OP_IF operates on the result from OP_SIZE). Counter-examples would be BIP 
124, the examples in BIP 65 and BIP 112, but I note all of these could be just 
as easily done without the explicit boolean being fed to the OP_IF (you'd need 
an OP_DUP to keep the value, so it wouldn't reduce the byte-size).

Of course, as long as we're talking about a softfork activating together with 
segwit, and only having effect in segwit scripts... there's no reason we can't 
add whatever opcodes we need so long as it gets done before 0.13.1. I suggest 
OP_CASTTOBOOL and OP_DUPASBOOL would be two good candidates if we make OP_IF 
stricter. There's also the possibility of adding an OP_RETAINIF which behaves 
as the current OP_IF, except not popping the conditional value off the stack. 
But perhaps this is getting too complicated for testing in time for segwit...

Luke


 permalink raw reply	[|nested]
2016-08-17  4:40                     ` Luke Dashjr

  2016-08-18  0:11                         ` Sergio Demian Lerner
  
From: Johnson Lau @ 2016-08-17 10:15 UTC (permalink / raw)
  To: bitcoin-dev, Luke Dashjr

[-- Attachment #1: Type: text/plain, Size: 1140 bytes --]


> On August 17, 2016 at 12:40 AM Luke Dashjr <luke@dashjr•org> wrote:
>
>
> On Wednesday, August 17, 2016 3:02:53 AM Johnson Lau via bitcoin-dev wrote:
> > To completely replicate the original behaviour, one may use:
> > "DEPTH TOALTSTACK IFDUP DEPTH FROMALTSTACK NUMNOTEQUAL IF 2DROP {if script}
> > ELSE DROP {else script} ENDIF"
>
> This is much uglier than expected. IMO if that's the best workaround for the
> current behaviour, people should just use "OP_1 OP_EQUAL OP_IF" when/if they
> need to avoid malleability issues.

It is ugly only if you want to faithfully replicate the behaviour. I'd argue that in no real use case you need to do this. For example, "OP_SIZE OP_IF" could just become "OP_SIZE OP_0NOTEQUAL OP_IF", since OP_SIZE must return a valid MINIMALDATA number.

And your workaround does not fix malleability, since any non-0x01 values are valid FALSE

However, in some case, enforcing MINIMALIF does require 1 more witness byte: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-August/013036.html

I think the best strategy is to make it a relay policy first, and decide whether we want a softfork later.

[-- Attachment #2: Type: text/html, Size: 1504 bytes --]

 permalink raw reply	[|nested]
2016-08-17 10:15                       ` Johnson Lau

       [not found]                           ` <CAAS2fgQ=Z+xmg0DcANV4vhp+XhpL1Vz0HNkJwNGdHTxtK1q1kg@mail.gmail.com>
  
From: Sergio Demian Lerner @ 2016-08-18  0:11 UTC (permalink / raw)
  To: Johnson Lau, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 2456 bytes --]

I think that we're not attacking the real source of the problem: that the
witness data size is not signed. It may be the case that a new source of
malleability is detected in witness programs later, or related to new
opcodes we'll soft-fork in the future.

The problem is real, as some systems (such as hardware wallets or other
low-memory IoT embedded systems) may have hard limits in the size of the
witness program they can accept. So we need a solution for all current and
future segwit extension problems.

We could soft-fork to add an opcode OP_PROGSIZE using segwit script
versioning that pushes in the stack the size of the segwit program being
evaluated, and then the script can take any action it wishes based on that.

Example:
<0x50> OP_PROGSIZE OP_GREATERTHAN OP_VERIFY ..... OP_CHECKSIG

Then an attacker cannot create a clone of the transaction having a witness
ECDSA signature longer than 0x50 bytes. (many details omitted in this
example)



On Wed, Aug 17, 2016 at 7:15 AM, Johnson Lau via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

>
> > On August 17, 2016 at 12:40 AM Luke Dashjr <luke@dashjr•org> wrote:
> >
> >
> > On Wednesday, August 17, 2016 3:02:53 AM Johnson Lau via bitcoin-dev
> wrote:
> > > To completely replicate the original behaviour, one may use:
> > > "DEPTH TOALTSTACK IFDUP DEPTH FROMALTSTACK NUMNOTEQUAL IF 2DROP {if
> script}
> > > ELSE DROP {else script} ENDIF"
> >
> > This is much uglier than expected. IMO if that's the best workaround for
> the
> > current behaviour, people should just use "OP_1 OP_EQUAL OP_IF" when/if
> they
> > need to avoid malleability issues.
>
> It is ugly only if you want to faithfully replicate the behaviour. I'd
> argue that in no real use case you need to do this. For example, "OP_SIZE
> OP_IF" could just become "OP_SIZE OP_0NOTEQUAL OP_IF", since OP_SIZE must
> return a valid MINIMALDATA number.
>
> And your workaround does not fix malleability, since any non-0x01 values
> are valid FALSE
>
> However, in some case, enforcing MINIMALIF does require 1 more witness
> byte: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-August/
> 013036.html
>
> I think the best strategy is to make it a relay policy first, and decide
> whether we want a softfork later.
>
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>
>

[-- Attachment #2: Type: text/html, Size: 3407 bytes --]

 permalink raw reply	[|nested]
[not found]                           ` <CAAS2fgQ=Z+xmg0DcANV4vhp+XhpL1Vz0HNkJwNGdHTxtK1q1kg@mail.gmail.com>

  2016-08-18  3:00                               ` Peter Todd
  
From: Sergio Demian Lerner @ 2016-08-18  0:33 UTC (permalink / raw)
  To: Gregory Maxwell;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 1678 bytes --]

On Wed, Aug 17, 2016 at 9:19 PM, Gregory Maxwell <gmaxwell@gmail•com> wrote:

> On Thu, Aug 18, 2016 at 12:11 AM, Sergio Demian Lerner via bitcoin-dev
> <bitcoin-dev@lists•linuxfoundation.org> wrote:
> > I think that we're not attacking the real source of the problem: that the
> > witness data size is not signed.
>
> It's not possible to do that for the general case, since you may not
> even know the witness size in advance (even for checksig's ECDSA, the
> encoding is variable sized).
>
> That's why scripts can check a maximum witness size, and not necessarily
an exact value.


I think that is overly focusing on "someone might change the feerate",
> yes that is an example of an undesirable witness tampering, but it's
> not the only one.
>
> I don't think fees are the problem. There is another problem. Let me
re-explain.
If I send a transaction to an IoT device (say to an OpenDime or to the old
Firmcoin), and the OpenDime must verify that the transaction has been mined
(SPV verification), then it may expect the witness program to be of certain
maximum size (an implementation-imposed  limit). If a Miner modifies the
witness size and makes it too large, then the device may not be able to
accept the transaction and the bitcoins may be lost. Lost because the
private key is in the device, and because the device cannot accept that
cloned transaction, never ever.

The same is true (although less strict) for side-chains and drive-chains:
they may have certain restrictions on the size of transactions they accept
to lock bitcoins.

That's why I'm proposing that a transaction becomes INVALID if the witness
size is higher than the expected size (by the sender).

[-- Attachment #2: Type: text/html, Size: 2378 bytes --]

 permalink raw reply	[|nested]
2016-08-18  0:33                             ` Sergio Demian Lerner

  
From: Peter Todd @ 2016-08-18  3:00 UTC (permalink / raw)
  To: Sergio Demian Lerner, Bitcoin Protocol Discussion;  Gregory Maxwell

[-- Attachment #1: Type: text/plain, Size: 1499 bytes --]

On Wed, Aug 17, 2016 at 09:33:24PM -0300, Sergio Demian Lerner via bitcoin-dev wrote:
> If I send a transaction to an IoT device (say to an OpenDime or to the old
> Firmcoin), and the OpenDime must verify that the transaction has been mined
> (SPV verification), then it may expect the witness program to be of certain
> maximum size (an implementation-imposed  limit). If a Miner modifies the
> witness size and makes it too large, then the device may not be able to
> accept the transaction and the bitcoins may be lost. Lost because the
> private key is in the device, and because the device cannot accept that
> cloned transaction, never ever.
> 
> The same is true (although less strict) for side-chains and drive-chains:
> they may have certain restrictions on the size of transactions they accept
> to lock bitcoins.
> 
> That's why I'm proposing that a transaction becomes INVALID if the witness
> size is higher than the expected size (by the sender).

An important part of the design of segwit is that resource constained devices
doing lite-client verification don't need to get witness data at all to verify
lite-client merkle-path proofs.

Remember that lite-clients can't verify anything useful in witnesses anyway, so
for them to have witness data is useless (unless they're doing some kind of
embedded consensus protocol with data published in witnesses, but few people
here care about that use-case).

-- 
https://petertodd.org 'peter'[:-1]@petertodd.org

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

 permalink raw reply	[|nested]
2016-08-16 17:53 [bitcoin-dev] New BIP: Dealing with OP_IF and OP_NOTIF malleability in P2WSH Johnson Lau
  2016-08-16 19:37 ` Luke Dashjr

  2016-09-05  1:32   ` Rusty Russell
  
From: Johnson Lau @ 2016-09-01 11:39 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion, lightning-dev

[-- Attachment #1: Type: text/plain, Size: 3991 bytes --]

Restriction for segwit OP_IF argument as a policy has got a few concept ACK. I would like to have more people to ACK or NACK, especially the real users of OP_IF. I think Lightning network would use that at lot.

Pull request: https://github.com/bitcoin/bitcoin/pull/8526

more related discussion could be found at https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-August/013036.html

It does have impact if your script uses the combination of "OP_SIZE OP_IF" or "OP_DEPTH OP_IF". With this policy/softfork, you need to use  "OP_SIZE OP_0NOTEQUAL OP_IF" or "OP_DEPTH OP_0NOTEQUAL OP_IF", or reconstruct your scripts.

> 
>     On August 16, 2016 at 1:53 PM Johnson Lau via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org> wrote:
> 
>     -----BEGIN PGP SIGNED MESSAGE-----
>     Hash: SHA512
> 
>     A new BIP is prepared to deal with OP_IF and OP_NOTIF malleability in P2WSH:
>     https://github.com/jl2012/bips/blob/minimalif/bip-minimalif.mediawiki
>     https://github.com/bitcoin/bitcoin/pull/8526
> 
>     BIP: x
>     Title: Dealing with OP_IF and OP_NOTIF malleability in P2WSH
>     Author: Johnson Lau <jl2012@xbt•hk>
>     Status: Draft
>     Type: Standards Track
>     Created: 2016-08-17
> 
>     Abstract
> 
>     This document specifies proposed changes to the Bitcoin script validity rules in order to make transaction malleability related to OP_IF and OP_NOTIF impossible in pay-to-witness-script-hash (P2WSH) scripts.
> 
>     Motivation
> 
>     OP_IF and OP_NOTIF are flow control codes in the Bitcoin script system. The programme flow is decided by whether the top stake value is True or False. However, this behaviour opens a source of malleability as a third party may replace a True (False) stack item with any other True (False) value without invalidating the transaction.
> 
>     The proposed rules apply only to pay-to-witness-script-hash (P2WSH) scripts described in BIP141, which has not been activated on the Bitcoin mainnet as of writing. To ensure OP_IF and OP_NOTIF transactions created before the introduction of this BIP will still be accepted by the network, the new rules are not applied to non-segregated witness scripts.
> 
>     Specification
> 
>     In P2WSH, the argument for OP_IF and OP_NOTIF MUST be exactly an empty vector or 0x01, or the script evaluation fails immediately.
> 
>     This is deployed using BIP9 after segregated witness (BIP141) is activated. Details TBD.
> 
>     Compatibility
> 
>     This is a softfork on top of BIP141. The rules are enforced as a relay policy by the reference client since the first release of BIP141 (v0.13.1). To avoid risks of fund loss, users MUST NOT create P2WSH scripts that are incompatible with this BIP. An OP_0NOTEQUAL may be used before OP_IF or OP_NOTIF to imitate the original behaviour (which may also re-enable the malleability vector depending on the exact script).
> 
>     Implementation
> 
>     https://github.com/bitcoin/bitcoin/pull/8526
> 
>     Copyright
> 
>     This work is placed in the public domain.
>     -----BEGIN PGP SIGNATURE-----
>     Comment: GPGTools - https://gpgtools.org
> 
>     iQGcBAEBCgAGBQJXs1LgAAoJEO6eVSA0viTSrJQL/A/womJKgi4FuyBTL9oykCss
>     aBMNN9+SLtmuH7SBgEUGZ8TFxa2st+6RP6Imu+Vvn4O5sXQl3DIXV+X38X93sUYk
>     wrjdpvdpqFFYJezPDESz6pR/6bZ1ES0aO2QqX578/8sqr8GO6L388s66vJeIGj4n
>     0LWW8sdEypMuV3HUG/9FFdUNHgiVX1U0sS1rT3P4aN30JYtb7PQpd7r8KTMta7Rt
>     L1VOZB+W3m2m2YZ9gB7IRmMfzzNm2QXRTPIZXt2x3mYDBuMkp+zEd5+ogA4sBpgP
>     wp2+l/aos686v0w8QYiNUX2+9Qpe7+238qUpw75d2XJYmLzdotWFvmp4g1hP+awX
>     HEfwe4BUM+El17LjrHkNeMWNJXMlhTtXb2i0XMj8tU5lZVHep4WpQ+LEahrNlsUl
>     FdFsi3q8HeWh8JsGaNCL41Bgbg/rKb5hUXyF6hTRHa//E6llOrpXRnsloKgBLv8c
>     QezgKTAPwwgdjcS6Ek0AqgLp7bCFRijCduYH9i9uaQ==
>     =lLIZ
>     -----END PGP SIGNATURE-----
> 
>     _______________________________________________
>     bitcoin-dev mailing list
>     bitcoin-dev@lists•linuxfoundation.org
>     https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
> 

[-- Attachment #2: Type: text/html, Size: 4474 bytes --]

 permalink raw reply	[|nested]
2016-09-01 11:39 ` Johnson Lau

  
From: Rusty Russell @ 2016-09-05  1:32 UTC (permalink / raw)
  To: Johnson Lau, Bitcoin Protocol Discussion,
	Bitcoin Protocol Discussion, lightning-dev

Johnson Lau via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org>
writes:
> Restriction for segwit OP_IF argument as a policy has got a few concept ACK. I would like to have more people to ACK or NACK, especially the real users of OP_IF. I think Lightning network would use that at lot.

My current scripts use OP_IF and OP_NOTIF only after OP_EQUAL, except
for one place where they use OP_EQUAL ... OP_EQUAL... OP_ADD OP_IF
(where the two OP_EQUALs are comparing against different hashes, so only
0 or 1 of the two OP_EQUAL can return 1).

So there's no effect either way on the c-lightning implementation, at
least.

Thanks!
Rusty.


 permalink raw reply	[|nested]
2016-08-16 22:39           ` Pieter Wuille
  2016-08-16 22:52             ` Russell O'Connor

  
From: Russell O'Connor @ 2016-09-05 14:55 UTC (permalink / raw)
  To: Pieter Wuille;  Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 988 bytes --]

For sake of example, suppose we have a marginal fee rate of 50 satoshis per
byte.  At that rate reducing the size of the witness data by 1 byte is
approximately equivalent from a miner and relayer's perspective as a
replace by fee that increases the fee by 50 satoshis.  In both cases miners
get an extra potential of 50 satoshis in revenue.

So in this sense replacing witness data with smaller witness data can pay
for its own relay cost as much as RBF can simply by requiring that the
smaller witness be smaller enough to cover the same RBF threshold.

On Tue, Aug 16, 2016 at 6:39 PM, Pieter Wuille <pieter.wuille@gmail•com>
wrote:

> On Aug 17, 2016 00:36, "Russell O'Connor" <roconnor@blockstream•io> wrote:
>
> > Can I already do something similar with replace by fee, or are there
> limits on that?
>
> BIP125 and mempool eviction both require the replacing transaction to have
> higher fee, to compensate for the cost of relaying the replaced
> transaction(s).
>
> --
> Pieter
>

[-- Attachment #2: Type: text/html, Size: 1553 bytes --]

 permalink raw reply	[|nested]