Multi-byte opcodes

Multi-byte opcodes
2024-11-18 15:10 ` [bitcoindev] " Garlo Nicon
  2024-11-18 17:15 ` [bitcoindev] " Brandon Black
  
From: Weikeng Chen @ 2024-11-16  0:45 UTC (permalink / raw)
  To: Bitcoin Development Mailing List


[-- Attachment #1.1: Type: text/plain, Size: 2096 bytes --]

I think we need a way to allow more opcodes without taking up the rest of 
the NOPs.

This is related to a point from Murch 
(https://groups.google.com/g/bitcoindev/c/usHmnXDuJQc/m/hhtvAjSdCgAJ) that 
the reasoning of "its' compatible, why not" for adding 
CHECKSIGFROMSTACK(VERIFY/ADD) is not solid because when we add a new 
opcode, we usually have to give up a NOP. We do not have many NOPs left.

We can, however, solve that by allowing multi-byte opcodes.

Say, for example, we can have:
    OP_OP { 0x1521 }
which will set the current opcode to be the one with the assigned number 
0x1521.

Another idea is maybe OP_OP takes a stack element as the opcode.
    { 0x1521 } OP_OP

We can enforce some sort of minimal rule, or not do so, to allow more 
flexible use of existing opcodes.

This, of course, runs at a cost as this opcode needs three bytes in total 
to represent, but since the existing opcodes already take care of most of 
the basic functionalities that we expect users to use very frequently, the 
new opcodes that we want to add are likely those that complete something 
important and are going to be used only a few times in a script.

Similarly, we can require that multi-byte opcodes that have not been 
enabled my result in OP_SUCCESS.

OP_OP is not the best name as it could be confusing. OP_SETOP, OP_NEXT, etc 
could be taken into consideration.

The result of this is that we can worry less about whether it is worthy of 
a NOP to do an opcode, but focus on if the opcode has enough use cases to 
support it.

I feel that someone must have brought this up before (but it is a little 
bit hard to find the history in this mailing list at this moment).

What do people think?

Thanks,
Weikeng

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups•com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/4235f7d2-8e09-428a-813d-9034cb21f48an%40googlegroups.com.

[-- Attachment #1.2: Type: text/html, Size: 2699 bytes --]

 permalink raw reply	[|nested]
2024-11-16  0:45 [bitcoindev] Multi-byte opcodes Weikeng Chen

  2024-11-18 17:15 ` [bitcoindev] " Brandon Black
  
From: Garlo Nicon @ 2024-11-18 15:10 UTC (permalink / raw)
  To: Bitcoin Development Mailing List


[-- Attachment #1.1: Type: text/plain, Size: 2872 bytes --]

> I think we need a way to allow more opcodes without taking up the rest of 
the NOPs.

It is already possible since Taproot. For example: OP_CHECKSIGADD was 
added, without replacing any OP_NOP.

> I feel that someone must have brought this up before (but it is a little 
bit hard to find the history in this mailing list at this moment).

Satoshi added OP_SINGLEBYTE_END, set to 0xf0, and OP_DOUBLEBYTE_BEGIN, set 
to 0xf000. It was removed later, but it can be reintroduced in a similar 
way, if needed. See source code for version 0.1.0 for more details.

sobota, 16 listopada 2024 o 03:00:53 UTC+1 Weikeng Chen napisał(a):

> I think we need a way to allow more opcodes without taking up the rest of 
> the NOPs.
>
> This is related to a point from Murch (
> https://groups.google.com/g/bitcoindev/c/usHmnXDuJQc/m/hhtvAjSdCgAJ) that 
> the reasoning of "its' compatible, why not" for adding 
> CHECKSIGFROMSTACK(VERIFY/ADD) is not solid because when we add a new 
> opcode, we usually have to give up a NOP. We do not have many NOPs left.
>
> We can, however, solve that by allowing multi-byte opcodes.
>
> Say, for example, we can have:
>     OP_OP { 0x1521 }
> which will set the current opcode to be the one with the assigned number 
> 0x1521.
>
> Another idea is maybe OP_OP takes a stack element as the opcode.
>     { 0x1521 } OP_OP
>
> We can enforce some sort of minimal rule, or not do so, to allow more 
> flexible use of existing opcodes.
>
> This, of course, runs at a cost as this opcode needs three bytes in total 
> to represent, but since the existing opcodes already take care of most of 
> the basic functionalities that we expect users to use very frequently, the 
> new opcodes that we want to add are likely those that complete something 
> important and are going to be used only a few times in a script.
>
> Similarly, we can require that multi-byte opcodes that have not been 
> enabled my result in OP_SUCCESS.
>
> OP_OP is not the best name as it could be confusing. OP_SETOP, OP_NEXT, 
> etc could be taken into consideration.
>
> The result of this is that we can worry less about whether it is worthy of 
> a NOP to do an opcode, but focus on if the opcode has enough use cases to 
> support it.
>
> I feel that someone must have brought this up before (but it is a little 
> bit hard to find the history in this mailing list at this moment).
>
> What do people think?
>
> Thanks,
> Weikeng
>

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups•com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/3b2707fe-0ddd-4c1a-8167-fccef47a9d2en%40googlegroups.com.

[-- Attachment #1.2: Type: text/html, Size: 3894 bytes --]

 permalink raw reply	[|nested]
2024-11-16  0:45 [bitcoindev] Multi-byte opcodes Weikeng Chen
  2024-11-18 15:10 ` [bitcoindev] " Garlo Nicon

  2024-11-18 18:54   ` Ethan Heilman
  2024-11-19 16:38   ` 'moonsettler' via Bitcoin Development Mailing List
  
From: Brandon Black @ 2024-11-18 17:15 UTC (permalink / raw)
  To: Weikeng Chen;  Bitcoin Development Mailing List

Hi Weikeng, thanks for your thoughts on this!

> We can, however, solve that by allowing multi-byte opcodes.
> 
> Say, for example, we can have:
>     OP_OP { 0x1521 }
> which will set the current opcode to be the one with the assigned number 
> 0x1521.
> 
> Another idea is maybe OP_OP takes a stack element as the opcode.
>     { 0x1521 } OP_OP

Another option that works for many cases is to have opcode families
where an argument is augmented with flags to determine the behavior. We
can consider this to already be the case for OP_CHECKSIG* where the
signature determines the behavior of the hashing portion of the opcode.

This is also how OP_CHECKTEMPLATEVERIFY is designed, and how
OP_CHECKSIGFROMSTACKVERIFY as currently spec'd in the PR is designed.
CTV and CSFSV only constrain 32-byte first arguments, but not other
lengths leaving open extensions using any other length, including using
other lengths of either opcode as OP_OP, or as variants on CTV and CSFSV
respectively.

The benefit of this approach is that it doesn't "waste" the length byte
only to specify the opcode behavior, but enables it to do double duty as
specifying the total length of the first argument including both flags
and data.

Best,

--Brandon

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups•com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/Zzt2OCE6Aj9H3DiY%40console.


 permalink raw reply	[|nested]
2024-11-18 17:15 ` [bitcoindev] " Brandon Black

  2024-11-19 16:38   ` 'moonsettler' via Bitcoin Development Mailing List
  
From: Ethan Heilman @ 2024-11-18 18:54 UTC (permalink / raw)
  To: Brandon Black;  Weikeng Chen, Bitcoin Development Mailing List

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

Couldn't we add opcodes contexts via the script version?

By context I mean an opcode that loads a 1 to N byte map rewriting the
mapping from opcode number to what instruction that number signifies. This
should let you have an infinite number of instructions. You could change
the context multiple times in a script as a cost of only two or three bytes.



On Mon, Nov 18, 2024, 1:36 PM Brandon Black <freedom@reardencode•com> wrote:

> Hi Weikeng, thanks for your thoughts on this!
>
> > We can, however, solve that by allowing multi-byte opcodes.
> >
> > Say, for example, we can have:
> >     OP_OP { 0x1521 }
> > which will set the current opcode to be the one with the assigned number
> > 0x1521.
> >
> > Another idea is maybe OP_OP takes a stack element as the opcode.
> >     { 0x1521 } OP_OP
>
> Another option that works for many cases is to have opcode families
> where an argument is augmented with flags to determine the behavior. We
> can consider this to already be the case for OP_CHECKSIG* where the
> signature determines the behavior of the hashing portion of the opcode.
>
> This is also how OP_CHECKTEMPLATEVERIFY is designed, and how
> OP_CHECKSIGFROMSTACKVERIFY as currently spec'd in the PR is designed.
> CTV and CSFSV only constrain 32-byte first arguments, but not other
> lengths leaving open extensions using any other length, including using
> other lengths of either opcode as OP_OP, or as variants on CTV and CSFSV
> respectively.
>
> The benefit of this approach is that it doesn't "waste" the length byte
> only to specify the opcode behavior, but enables it to do double duty as
> specifying the total length of the first argument including both flags
> and data.
>
> Best,
>
> --Brandon
>
> --
> You received this message because you are subscribed to the Google Groups
> "Bitcoin Development Mailing List" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to bitcoindev+unsubscribe@googlegroups•com.
> To view this discussion visit
> https://groups.google.com/d/msgid/bitcoindev/Zzt2OCE6Aj9H3DiY%40console.
>

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups•com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/CAEM%3Dy%2BVpeEwqWtXqs%2BRpOFrO%3DWGzbSkPEEqBqBxc-87Z4ruh2g%40mail.gmail.com.

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

 permalink raw reply	[|nested]
2024-11-18 17:15 ` [bitcoindev] " Brandon Black
  2024-11-18 18:54   ` Ethan Heilman

  2024-11-19 19:35     ` Brandon Black
  
From: 'moonsettler' via Bitcoin Development Mailing List @ 2024-11-19 16:38 UTC (permalink / raw)
  To: Brandon Black;  Weikeng Chen, Bitcoin Development Mailing List

Hi All,

I think we should discuss back-porting tapscript instead of coming up with a further divergent set of opcodes.

To sum up earlier discussion with Brandon, we could:

* Use a single upgradeable NOP for OP_TAPSCRIPTVERIFY
* <s1> .. <sn> | <faux-control-block> <tapscript> CTAPV
* Isolated execution environment
* Gets the entire stack below the top 2 elements
* Fails if it fails, does nothing if internal script succeeds.
* Require the last opcode executed by the script interpreter to be a push opcode, fails otherwise

The faux control block can be just a few bytes mainly for tapscript version.

BR,
moonsettler

Sent with Proton Mail secure email.

On Monday, November 18th, 2024 at 6:15 PM, Brandon Black <freedom@reardencode•com> wrote:

> Hi Weikeng, thanks for your thoughts on this!
> 
> > We can, however, solve that by allowing multi-byte opcodes.
> > 
> > Say, for example, we can have:
> > OP_OP { 0x1521 }
> > which will set the current opcode to be the one with the assigned number
> > 0x1521.
> > 
> > Another idea is maybe OP_OP takes a stack element as the opcode.
> > { 0x1521 } OP_OP
> 
> 
> Another option that works for many cases is to have opcode families
> where an argument is augmented with flags to determine the behavior. We
> can consider this to already be the case for OP_CHECKSIG* where the
> signature determines the behavior of the hashing portion of the opcode.
> 
> This is also how OP_CHECKTEMPLATEVERIFY is designed, and how
> OP_CHECKSIGFROMSTACKVERIFY as currently spec'd in the PR is designed.
> CTV and CSFSV only constrain 32-byte first arguments, but not other
> lengths leaving open extensions using any other length, including using
> other lengths of either opcode as OP_OP, or as variants on CTV and CSFSV
> respectively.
> 
> The benefit of this approach is that it doesn't "waste" the length byte
> only to specify the opcode behavior, but enables it to do double duty as
> specifying the total length of the first argument including both flags
> and data.
> 
> Best,
> 
> --Brandon
> 
> --
> You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups•com.
> To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/Zzt2OCE6Aj9H3DiY%40console.

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups•com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/E95uz4uyQgikJKtximyueqFTRs7cTJfpcdVvkrYEkfZ__DTpvwlsm0MSsX8BaqKg6KnONx6eQ5VueijeMqWQ8uI4iFKA--irKATjN1K4Fbg%3D%40protonmail.com.


 permalink raw reply	[|nested]
2024-11-19 16:38   ` 'moonsettler' via Bitcoin Development Mailing List

  
From: Brandon Black @ 2024-11-19 19:35 UTC ( / )
  To: moonsettler;  Weikeng Chen, Bitcoin Development Mailing List

On 2024-11-19 (Tue) at 16:38:21 +0000, moonsettler wrote:
> I think we should discuss back-porting tapscript instead of coming up with a further divergent set of opcodes.
> 
> To sum up earlier discussion with Brandon, we could:
> 
> * Use a single upgradeable NOP for OP_TAPSCRIPTVERIFY
> * <s1> .. <sn> | <faux-control-block> <tapscript> CTAPV
> * Isolated execution environment
> * Gets the entire stack below the top 2 elements
> * Fails if it fails, does nothing if internal script succeeds.
> * Require the last opcode executed by the script interpreter to be a push opcode, fails otherwise
> 
> The faux control block can be just a few bytes mainly for tapscript version.

Few additional points that came up in discussing this with moon earlier:

* Compared to enabling tapscript without a key spend path (i.e.
	potential for quantum resistance) via a new witnessv1 program length
	or a new witness version, this approach will be similar in weight.
* The biggest challenge with this approach that I came up with is the
	need to clean up the stack after execution (to satisfy witness v0
	clean stack).
* To keep it simple, it probably makes sense to make it a 1-primary
  argument opcode where the argument is `<tapscript||version>` to
	prevent the version from coming from spend-time witness elements.

Best,

--Brandon

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups•com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/ZzzohFCFjJebA8_2%40console.