OP_PUSH_KEY_* & BIP-118 0x01 Pun

OP_PUSH_KEY_* & BIP-118 0x01 Pun
2022-01-13  1:45 ` Jeremy
  
From: Jeremy @ 2022-01-13  0:35 UTC (permalink / raw)
  To: Bitcoin development mailing list

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

Hi Devs,

Two small transaction introspection opcodes that are worth considering are
OP_PUSH_KEY_INTERNAL or OP_PUSH_KEY_EXTERNAL which can return the taproot
key for the current input.

While the internal key could be included in the tree already, and this is
just a performance improvement, the external key creates a hash cycle and
is not possible to include directly.

This came up as a potential nicety while looking at how BIP-118 "puns" a
single 0x01 byte as a key argument to refer to the Internal key for
compactness. It would be more general if instead of 0x01, there were an
opcode that actually put the Internal key on the stack.

There is a small incompatibility with BIP-118 with this approach, which is
that keys are not tagged for APO-enablement. Thus, there should either be a
version of this opcode for APO tagged or not, or, APO should instead define
some CheckSig2 which has APO if tagging is still desired. (Or we could
abandon tagging keys too...)

It might be worth pursuing simplifying APO to use these OP_PUSH_KEY opcodes
because future plans for more generalized covenant might benefit from being
able to get the current key off the stack. For example, TLUV might be able
to be decomposed into simpler (RISC) opcodes for getting the internal key,
getting the current merkel path, and then manipulating it, then tweaking
the internal key.

The internal key might be useful for signing in a path not just for APO,
but also because you might want to sign e.g. a transaction that is
contingent on a HTLC scriptcode being satisfied. Because it is cheaper to
use the 0x01 CHECKSIG than doing a separate key (<pk> CHECKSIG), it also
causes an unintended side effect from APO of incentivizing not using a
unique key per branch (privacy loss) and incentivizing enabling an APO
tagged key where one is not required (unless 0x00, as I've noted elsewhere
is added to the 118 spec as a pun for an untagged key).

Pushing the external key's use is less obvious, but with the development of
future opcodes it would be helpful for some recursive covenants.

Both opcodes are very design specific -- there's only one choice of what
data they could push.

Of course, we could keep 118 spec'd as is, and add these PUSH_KEYs later if
ever desired redundantly with the Checksig puns.

Cheers,

Jeremy







--
@JeremyRubin <https://twitter.com/JeremyRubin>
<https://twitter.com/JeremyRubin>

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

 permalink raw reply	[|nested]
2022-01-13  0:35 [bitcoin-dev] OP_PUSH_KEY_* & BIP-118 0x01 Pun Jeremy

  
From: Jeremy @ 2022-01-13  1:45 UTC ( / )
  To: Jeremy;  Bitcoin development mailing list



Note:

BIP-118 as-is enables something similar to OP_PUSH_KEY_INTERNAL_TAGGED via
the following script fragment:

witness: <internal pk> <sig>
program: DUP 0x01 CHECKSIG SWAP DUP TOALTSTACK CHECKSIG FROMALTSTACK


It's unclear how useful this might be, since the signature already covers
the transaction.

--
@JeremyRubin <https://twitter.com/JeremyRubin>
<https://twitter.com/JeremyRubin>


On Wed, Jan 12, 2022 at 4:35 PM Jeremy <jlrubin@mit•edu> wrote:

> Hi Devs,
>
> Two small transaction introspection opcodes that are worth considering are
> OP_PUSH_KEY_INTERNAL or OP_PUSH_KEY_EXTERNAL which can return the taproot
> key for the current input.
>
> While the internal key could be included in the tree already, and this is
> just a performance improvement, the external key creates a hash cycle and
> is not possible to include directly.
>
> This came up as a potential nicety while looking at how BIP-118 "puns" a
> single 0x01 byte as a key argument to refer to the Internal key for
> compactness. It would be more general if instead of 0x01, there were an
> opcode that actually put the Internal key on the stack.
>
> There is a small incompatibility with BIP-118 with this approach, which is
> that keys are not tagged for APO-enablement. Thus, there should either be a
> version of this opcode for APO tagged or not, or, APO should instead define
> some CheckSig2 which has APO if tagging is still desired. (Or we could
> abandon tagging keys too...)
>
> It might be worth pursuing simplifying APO to use these OP_PUSH_KEY
> opcodes because future plans for more generalized covenant might benefit
> from being able to get the current key off the stack. For example, TLUV
> might be able to be decomposed into simpler (RISC) opcodes for getting the
> internal key, getting the current merkel path, and then manipulating it,
> then tweaking the internal key.
>
> The internal key might be useful for signing in a path not just for APO,
> but also because you might want to sign e.g. a transaction that is
> contingent on a HTLC scriptcode being satisfied. Because it is cheaper to
> use the 0x01 CHECKSIG than doing a separate key (<pk> CHECKSIG), it also
> causes an unintended side effect from APO of incentivizing not using a
> unique key per branch (privacy loss) and incentivizing enabling an APO
> tagged key where one is not required (unless 0x00, as I've noted elsewhere
> is added to the 118 spec as a pun for an untagged key).
>
> Pushing the external key's use is less obvious, but with the development
> of future opcodes it would be helpful for some recursive covenants.
>
> Both opcodes are very design specific -- there's only one choice of what
> data they could push.
>
> Of course, we could keep 118 spec'd as is, and add these PUSH_KEYs later
> if ever desired redundantly with the Checksig puns.
>
> Cheers,
>
> Jeremy
>
>
>
>
>
>
>
> --
> @JeremyRubin <https://twitter.com/JeremyRubin>
> <https://twitter.com/JeremyRubin>
>