Dealing with OP_IF and OP_NOTIF malleability

Dealing with OP_IF and OP_NOTIF malleability
2015-11-06  9:22 ` Nick ODell
  2015-11-06  9:27 ` Tier Nolan
  
From: jl2012 @ 2015-11-06  8:13 UTC (permalink / raw)
  To: bitcoin-dev

I have a new BIP draft for fixing OP_IF and OP_NOTIF malleability. 
Please comment: 
https://github.com/jl2012/bips/blob/master/opifmalleability.mediawiki

Copied below:

BIP: x
   Title: Dealing with OP_IF and OP_NOTIF malleability
   Author: jl2012 <jl2012@xbt•hk>
   Status: Draft
   Type: Standards Track
   Created: 2015-11-06

Abstract

As an supplement to BIP62, this document specifies proposed changes to 
the Bitcoin transaction validity rules in order to make malleability of 
transactions with OP_IF and OP_NOTIF impossible.

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 0 or 
not. However, this behavior opens a source of malleability as a third 
party may alter a non-zero flow control value to any other non-zero 
value without invalidating the transaction.

As of November 2015, OP_IF and OP_NOTIF are not commonly used in the 
blockchain. However, as more sophisticated functions such as 
OP_CHECKLOCKTIMEVERITY are being introduced, OP_IF and OP_NOTIF will 
become more popular and the related malleability should be fixed. This 
proposal serves as a supplement to BIP62 and should be implemented with 
other malleability fixes together.

Specification

If the transaction version is 3 or above, the flow control value for 
OP_IF and OP_NOTIF must be either 0 or 1, or the transaction fails.

This is to be implemented with BIP62.

Compatibility

This is a softfork. To ensure OP_IF and OP_NOTIF transactions created 
before the introduction of this BIP will still be accpeted by the 
network, the new rules only apply to transactions of version 3 or above.

For people who want to preserve the original behaviour of OP_IF and 
OP_NOTIF, an OP_0NOTEQUAL could be  used before the flow control code to 
transform any non-zero value to 1.

Reference

BIP62: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki



 permalink raw reply	[|nested]
2015-11-06  8:13 [bitcoin-dev] Dealing with OP_IF and OP_NOTIF malleability jl2012

  2015-11-06  9:27 ` Tier Nolan
  
From: Nick ODell @ 2015-11-06  9:22 UTC (permalink / raw)
  To: jl2012, bitcoin-dev

Your suggested modification seems sound.

Though, a script author could do something similar right now by
prefacing his IF with this:

    OP_DUP OP_DUP OP_0 OP_EQUAL OP_SWAP OP_1 OP_EQUAL OP_BOOLOR
OP_NOTIF OP_RETURN OP_ENDIF [actual OP_IF goes here]

That checks whether the input is 0 or 1, and runs OP_RETURN if not.
Your way is cleaner, though.

On Fri, Nov 6, 2015 at 1:13 AM, jl2012 via bitcoin-dev
<bitcoin-dev@lists•linuxfoundation.org> wrote:
> I have a new BIP draft for fixing OP_IF and OP_NOTIF malleability. Please
> comment:
> https://github.com/jl2012/bips/blob/master/opifmalleability.mediawiki
>
> Copied below:
>
> BIP: x
>   Title: Dealing with OP_IF and OP_NOTIF malleability
>   Author: jl2012 <jl2012@xbt•hk>
>   Status: Draft
>   Type: Standards Track
>   Created: 2015-11-06
>
> Abstract
>
> As an supplement to BIP62, this document specifies proposed changes to the
> Bitcoin transaction validity rules in order to make malleability of
> transactions with OP_IF and OP_NOTIF impossible.
>
> 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 0 or not.
> However, this behavior opens a source of malleability as a third party may
> alter a non-zero flow control value to any other non-zero value without
> invalidating the transaction.
>
> As of November 2015, OP_IF and OP_NOTIF are not commonly used in the
> blockchain. However, as more sophisticated functions such as
> OP_CHECKLOCKTIMEVERITY are being introduced, OP_IF and OP_NOTIF will become
> more popular and the related malleability should be fixed. This proposal
> serves as a supplement to BIP62 and should be implemented with other
> malleability fixes together.
>
> Specification
>
> If the transaction version is 3 or above, the flow control value for OP_IF
> and OP_NOTIF must be either 0 or 1, or the transaction fails.
>
> This is to be implemented with BIP62.
>
> Compatibility
>
> This is a softfork. To ensure OP_IF and OP_NOTIF transactions created before
> the introduction of this BIP will still be accpeted by the network, the new
> rules only apply to transactions of version 3 or above.
>
> For people who want to preserve the original behaviour of OP_IF and
> OP_NOTIF, an OP_0NOTEQUAL could be  used before the flow control code to
> transform any non-zero value to 1.
>
> Reference
>
> BIP62: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
>
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


 permalink raw reply	[|nested]
2015-11-06  8:13 [bitcoin-dev] Dealing with OP_IF and OP_NOTIF malleability jl2012
  2015-11-06  9:22 ` Nick ODell

  2015-11-06  9:32   ` Oleg Andreev
  
From: Tier Nolan @ 2015-11-06  9:27 UTC (permalink / raw)
  Cc: Bitcoin Dev

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

One and zero should be defined as arrays of length one.  Otherwise, it is
still possible to mutate the transaction by changing the length of the
array.

They should also be minimally encoded but that is covered by previous rules.

On Fri, Nov 6, 2015 at 8:13 AM, jl2012 via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> I have a new BIP draft for fixing OP_IF and OP_NOTIF malleability. Please
> comment:
> https://github.com/jl2012/bips/blob/master/opifmalleability.mediawiki
>
> Copied below:
>
> BIP: x
>   Title: Dealing with OP_IF and OP_NOTIF malleability
>   Author: jl2012 <jl2012@xbt•hk>
>   Status: Draft
>   Type: Standards Track
>   Created: 2015-11-06
>
> Abstract
>
> As an supplement to BIP62, this document specifies proposed changes to the
> Bitcoin transaction validity rules in order to make malleability of
> transactions with OP_IF and OP_NOTIF impossible.
>
> 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 0 or not.
> However, this behavior opens a source of malleability as a third party may
> alter a non-zero flow control value to any other non-zero value without
> invalidating the transaction.
>
> As of November 2015, OP_IF and OP_NOTIF are not commonly used in the
> blockchain. However, as more sophisticated functions such as
> OP_CHECKLOCKTIMEVERITY are being introduced, OP_IF and OP_NOTIF will become
> more popular and the related malleability should be fixed. This proposal
> serves as a supplement to BIP62 and should be implemented with other
> malleability fixes together.
>
> Specification
>
> If the transaction version is 3 or above, the flow control value for OP_IF
> and OP_NOTIF must be either 0 or 1, or the transaction fails.
>
> This is to be implemented with BIP62.
>
> Compatibility
>
> This is a softfork. To ensure OP_IF and OP_NOTIF transactions created
> before the introduction of this BIP will still be accpeted by the network,
> the new rules only apply to transactions of version 3 or above.
>
> For people who want to preserve the original behaviour of OP_IF and
> OP_NOTIF, an OP_0NOTEQUAL could be  used before the flow control code to
> transform any non-zero value to 1.
>
> Reference
>
> BIP62: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
>
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

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

 permalink raw reply	[|nested]
2015-11-06  9:27 ` Tier Nolan

  2015-11-06  9:37     ` Tier Nolan
  
From: Oleg Andreev @ 2015-11-06  9:32 UTC (permalink / raw)
  To: Tier Nolan;  Bitcoin Dev


> One and zero should be defined as arrays of length one. Otherwise, it is still possible to mutate the transaction by changing the length of the array. 
> 
> They should also be minimally encoded but that is covered by previous rules.

These two lines contradict each other. Minimally-encoded "zero" is an array of length zero, not one. I'd suggest defining this explicitly here as "IF/NOTIF argument must be either zero-length array or a single byte 0x01".




 permalink raw reply	[|nested]
2015-11-06  9:32   ` Oleg Andreev

  2015-11-06 10:16       ` jl2012
  2015-11-10 10:52       ` Oleg Andreev
  
From: Tier Nolan @ 2015-11-06  9:37 UTC (permalink / raw)
  Cc: Bitcoin Dev

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

I meant not to use the OP_PUSH opcodes to do the push.

Does OP_0 give a zero length byte array?

Would this script return true?

OP_0
OP_PUSHDATA1 (length = 1, data = 0)
OP_EQUAL

The easiest definition is that OP_0 and OP_1 must be used to push the data
and not any other push opcodes.


On Fri, Nov 6, 2015 at 9:32 AM, Oleg Andreev <oleganza@gmail•com> wrote:

>
> > One and zero should be defined as arrays of length one. Otherwise, it is
> still possible to mutate the transaction by changing the length of the
> array.
> >
> > They should also be minimally encoded but that is covered by previous
> rules.
>
> These two lines contradict each other. Minimally-encoded "zero" is an
> array of length zero, not one. I'd suggest defining this explicitly here as
> "IF/NOTIF argument must be either zero-length array or a single byte 0x01".
>
>
>

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

 permalink raw reply	[|nested]
2015-11-06  9:37     ` Tier Nolan

  2015-11-10 10:52       ` Oleg Andreev
  
From: jl2012 @ 2015-11-06 10:16 UTC (permalink / raw)
  To: Tier Nolan;  Bitcoin Dev

I assume this proposal is implemented at the same time as BIP62. As long 
as OP_IF/OP_NOTIF interprets the argument as a number, zero-padded 
number and negative zero are already prohibited in BIP62

Tier Nolan via bitcoin-dev 於 2015-11-06 04:37 寫到:
> I meant not to use the OP_PUSH opcodes to do the push.
> 
> Does OP_0 give a zero length byte array?
> 
> Would this script return true?
> 
> OP_0
> 
> OP_PUSHDATA1 (length = 1, data = 0)
> 
> OP_EQUAL
> 
> The easiest definition is that OP_0 and OP_1 must be used to push the
> data and not any other push opcodes.
> 
> On Fri, Nov 6, 2015 at 9:32 AM, Oleg Andreev <oleganza@gmail•com>
> wrote:
> 
>>> One and zero should be defined as arrays of length one.
>> Otherwise, it is still possible to mutate the transaction by
>> changing the length of the array.
>>> 
>>> They should also be minimally encoded but that is covered by
>> previous rules.
>> 
>> These two lines contradict each other. Minimally-encoded "zero" is
>> an array of length zero, not one. I'd suggest defining this
>> explicitly here as "IF/NOTIF argument must be either zero-length
>> array or a single byte 0x01".
> 
> 
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev



 permalink raw reply	[|nested]
2015-11-06  9:37     ` Tier Nolan
  2015-11-06 10:16       ` jl2012

  
From: Oleg Andreev @ 2015-11-10 10:52 UTC ( / )
  To: Tier Nolan;  Bitcoin Dev



OP_0 gives a zero length byte array because OP_0 == 0x00 which is equivalent to pushdata with zero length.

OP_EQUAL compares byte strings as-is. So it will push "false" because empty string is not the same as a single-byte string with 0x00 byte in it. Value "false" in turn is encoded as empty string, just like result of OP_0.

> On 06 Nov 2015, at 10:37, Tier Nolan via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org> wrote:
> 
> I meant not to use the OP_PUSH opcodes to do the push.
> 
> Does OP_0 give a zero length byte array?
> 
> Would this script return true?
> 
> OP_0
> OP_PUSHDATA1 (length = 1, data = 0)
> OP_EQUAL
> 
> The easiest definition is that OP_0 and OP_1 must be used to push the data and not any other push opcodes.
> 
> 
> On Fri, Nov 6, 2015 at 9:32 AM, Oleg Andreev <oleganza@gmail•com <mailto:oleganza@gmail•com>> wrote:
> 
> > One and zero should be defined as arrays of length one. Otherwise, it is still possible to mutate the transaction by changing the length of the array.
> >
> > They should also be minimally encoded but that is covered by previous rules.
> 
> These two lines contradict each other. Minimally-encoded "zero" is an array of length zero, not one. I'd suggest defining this explicitly here as "IF/NOTIF argument must be either zero-length array or a single byte 0x01".
> 
> 
> 
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev