Subject: [bitcoin-dev] An alternative: OP_CAT & OP_CHECKSIGFROMSTACK

From: "Russell O'Connor" <[email-masked]>
Date: Wed, 22 May 2019 17:01:21 -0400

Recently there have been some tapscript proposals, SIGHASH_ANYPREVOUT and
OP_CHECKOUTPUTHASHVERIFY, that aim to enable particular new features for
Bitcoin via new Script operations.  However, I think that these proposals
miss the mark when it comes to how they approach Bitcoin Script and
language features.

Bitcoin Script appears designed to be a flexible programmable system that
provides generic features to be composed to achieve various purposes.
Thus, when we design new language features for Script, we should be
striving, as much as possible, to similarly build general purpose tools
which can in turn be used for a variety of purposes.

I feel the SIGHASH_ANYPREVOUT and OP_CHECKOUTPUTHASHVERIFY proposals fail
to achieve these design goals.  They are both are designed with very narrow
applications in mind, while also going out of their way to extend the
semantic domain of the interpretation of Bitcoin operations in new ways
that complicate their specification.  In the case of SIGHASH_ANYPREVOUT,
the semantic domain is extended by adding new counters to track the use of
various v0 and v2 signature types.  In the case of
OP_CHECKOUTPUTHASHVERIFY, it employs a new context-sensitive operation that
peeks at the value of surrounding opcodes.

Instead, I propose that, for the time being, we simply implement OP_CAT and
OP_CHECKSIGFROMSTACKVERIFY.  OP_CAT pops two byte arrays off the stack and
pushes their concatenation back onto the stack.  OP_CHECKSIGFROMSTACKVERIFY
pops a signature, message, and pubkey off the stack and performs a
bip-schnorr verification on the SHA256 hash of the message.

In concert, these two operations enable:

* Oracle signature verification, including discrete log contracts.
* Amortized secure multiparty computations (see "Amortizing Secure
Computation with Penalties" by Kumaresan and Bentov).
* Transaction introspection including:
+ Simulated SIGHASH_ANYPREVOUT, which are necessarily chaperoned simply by
the nature of the construction.
+ Decide if a transaction has exactly one input or not. (etc.)
+ Weak covenants, which can verify output scripts to see if they are among
a set of predefined values or verify the output hash.

and presumably more applications as well.

For better or for worse, without an OP_PUBKEYTWEEK operation available, the
more interesting recursive-covenants remain largely out of reach, with the
exception of a recursive covenant that is only able to send back to its own
address, possibly abusing its own TXO value as a state variable.

All this is accomplished by two straightforward opcodes whose semantics are
pure computational operations on stack values.  The only semantic
side-effect is that OP_CHECKSIGFROMSTACKVERIFY would count towards the
existing 'sigops_passed' count.  Moreover, I feel that adding these
operations does not preclude adding more specialized opcodes in the future
as an optimization for whatever popular constructions come up, once we know
what those are.

I feel that this style of generic building blocks truly embodies what is
meant by "programmable money".