Dealing with OP_IF and OP_NOTIF malleability
7 messages, 6 to 10 Nov 2015. Started by Johnson Lau.
Johnson Lau (2), Tier Nolan (2), Oleg Andreev OOO (2), Nick ODell
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
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:
Quoted text (59 lines)
> 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
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:
Quoted text (60 lines)
> 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 >
Quoted text (3 lines)
> 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".
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:
Quoted text (14 lines)
> > > 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". > > >
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 寫到:
Quoted text (35 lines)
> 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
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.
Quoted text (29 lines)
> 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