Subject: Re: [bitcoin-dev] CHECKSIGFROMSTACK/{Verify} BIP for Bitcoin

From: "Russell O'Connor" <[email-masked]>
Date: Sun, 4 Jul 2021 15:03:40 -0400

On Sun, Jul 4, 2021 at 1:30 PM Jeremy <[email-masked]> wrote:

> I don't really see the point of CHECKSIGFROMSTACKADD since it's not bound
> to the txdata? When might you use this?
>

I don't feel strongly about *ADD.  I just figured it might be useful to do
a 2-of-3 between Alice, Bob and an Oracle signed value.  But I don't have
any particular use case in mind.  Either way the *ADD functionality can be
replicated by various SWAPs and ADDs etc, so we could just leave it out
until it is wanted.

> And yes -- "Add OP_CHECKSIGFROMSTACK and OP_CHECKSIGFROMSTACKVERIFY to
> follow the semantics from bip340-342 when witness program is v1." is a bit
> light on detail for what the BIP would end up looking like. If you're able
> to open up the design process a bit more on that it would be good as I
> think there are some topics worth discussing at large before things proceed
> with Elements (assuming feature compatibility remains a goal).
>

I'm certainly open to a wider design process.  We can open a specific issue
on the Elements repo.  That said, I don't see a particularly wide design
space on this front.

> The non-prehashed argument seems OK (at the cost of an extra byte...) but
> are there specific applications for !=32 arguments? I can't think of a
> particular one beyond perhaps efficiency. Can we safely use 0-520 byte
> arguments?
>

One of the reasons given in the issue (yes, the thread there is very long)
was that hashing the message requires the hash to be collision resistant
while if you give the message directly it only requires the hash to be
"random-prefix" collision / preimage resistant.  For example SHA-1 is
clearly not collision resistant but it appears to still be random-prefix
collision resistant AFAIU.  Another reason is that it allows for extremely
fast signing oracles because and R value and the midstate of the hash can
be precomputed all the way upto the application prefix, and if the message
being signed is less than 55 bytes or so, the signing cost can be as low as
one compression function and a little bit of non-EC modular arithmetic to
compute S.  If the message were required to be prehashed, then it would
take a minimum of 2 compression function calls to sign, nearly doubling the
signing time needed for the fast oracle.

Even if BIP-0340 kept its requirements that the message be exactly 32
bytes, I would still be inclined to design CHECKSIGFROMSTACK for tapscript
to take the 32-byte message from the stack instead of hashing a message
itself (BIP-0340 does it's own hashing, so prehashing the message isn't a
security concern in the same way it is for ECDSA.)  This would keep the
message off the blockchain, saving space and adding some amount of privacy
and making the operation compatible with rolling SHA256 opcodes.  But given
that BIP-0340 is going to be extended to support non-32 byte messages, then
there is no reason to impose a message length restriction on
CHECKSIGFROMSTACK.  Yes the operation will still be subject to stack item
length restrictions.  This is something script writers will have to be
aware of, but I see little reason to support messages split across multiple
stack items when we expect, by far, most messages to be 32-bytes, and I
expect those rare non-32 byte messages are expected to be reasonably short.

> Also do you have thoughts on the other questions i posed above? E.g.
> splitting R/S could be helpful w/o CAT.
>

Regarding  internal pubkeys and invalid pubkeys, I see no reason to deviate
from whatever tapscript CHECKSIG* do.

Regarding splitting R/S, This is harder because Elements does have CAT and
I think we should add CAT to Bitcoin too.  This game of trying to prevent
covenants by restricting script to the point where we are not even allowed
to have a CAT operation is a losing game.  It's just a matter of time
before we accidently introduce some way to enable covenants anyways, and it
is not worth cutting off vast amounts of functionality in pursuit of this
questionable goal.  And I say this as someone who was originally of the
opinion that we should be very very cautious before enabling new
expressivity such as covenants.  All the scary scenarios of covenants that
I am aware of can be more easily, cheaply, and flexibility implemented by
just having a counterparty in a multi-party signature that enforces their
own policy that they only sign transactions that pay to outputs that they
remain a party to.  And even if scary covenants were scarier than what can
already be done by multisig and policy, I still don't think they are scary
enough to warrant keeping CAT disabled.

So I don't think we should get fancy with CHECKSIGFROMSTACK.  Just take a
normal 64-byte signature value as a stack item.  But I don't feel strongly
about this, and I wouldn't oppose splitting R and S in Bitcoin if that is
where consensus lies.