Discussion:
[bitcoin-dev] Dealing with OP_IF and OP_NOTIF malleability
jl2012 via bitcoin-dev
2015-11-06 08:13:10 UTC
Permalink
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 <***@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
Tier Nolan via bitcoin-dev
2015-11-06 09:27:24 UTC
Permalink
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 <
I have a new BIP draft for fixing OP_IF and OP_NOTIF malleability. Please
https://github.com/jl2012/bips/blob/master/opifmalleability.mediawiki
BIP: x
Title: Dealing with OP_IF and OP_NOTIF malleability
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
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Tier Nolan via bitcoin-dev
2015-11-06 09:37:58 UTC
Permalink
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.
Post by Tier Nolan via 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".
jl2012 via bitcoin-dev
2015-11-06 10:16:46 UTC
Permalink
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
Post by Tier Nolan via bitcoin-dev
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.
Post by Tier Nolan via 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.
Post by Tier Nolan via bitcoin-dev
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
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Oleg Andreev via bitcoin-dev
2015-11-10 10:52:46 UTC
Permalink
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.
Post by Tier Nolan via bitcoin-dev
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.
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
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Nick ODell via bitcoin-dev
2015-11-06 09:22:27 UTC
Permalink
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
I have a new BIP draft for fixing OP_IF and OP_NOTIF malleability. Please
https://github.com/jl2012/bips/blob/master/opifmalleability.mediawiki
BIP: x
Title: Dealing with OP_IF and OP_NOTIF malleability
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
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Loading...