Good morning vjudeu,

> Typical P2PK looks like that: "<signature> <pubkey> OP_CHECKSIG". In a 
> typical scenario, we have "<signature>" in out input and "<pubkey> 
> OP_CHECKSIG" in our output. I wonder if it is possible to use covenants right 
> here and right now, with no consensus changes, just by requiring a specific 
> signature. To start with, I am trying to play with P2PK and legacy 
> signatures, but it may turn out, that doing such things with Schnorr 
> signatures will be more flexible and will allow more use cases.
>
>
> The simplest "pay to signature" script I can think of is: "<signature> 
> OP_SWAP OP_CHECKSIG". Then, any user can provide just a "<pubkey>" in some 
> input, as a part of a public key recovery. The problem with such scheme is 
> that it is insecure. Another problem is that we should handle it carefully, 
> because signatures are removed from outputs. However, we could replace it 
> with some signature hash, then it will be untouched, for example: 
> "OP_TOALTSTACK OP_DUP OP_HASH160 <signatureHash> OP_EQUALVERIFY 
> OP_FROMALTSTACK OP_CHECKSIG".
>
> And then, signatures are more flexible than public keys, because we can use 
> many different sighashes to decide, what kind of transaction is allowed and 
> what should be rejected. Then, if we could use the right signature with 
> correct sighashes, it could be possible to disable key recovery and require 
> some specific public key, then that scheme could be safely used again. I 
> still have no idea, how to complete that puzzle, but it seems to be possible 
> to use that trick, to restrict destination address. Maybe I should wrap such 
> things in some kind of multisig or somehow combine it with OP_CHECKSIGADD, 
> any ideas?

You can do the same thing with P2SH, P2WSH, and P2TR (in a Tapscript) as well.

Note that it is generally known that you *can* use pre-signed transactions to 
implement vaults.
Usually what we refer to by "covenant" is something like "this output will 
definitely be constructed here" without necessarily requiring a signature.

HOWEVER, what you are proposing is not ***quite*** pre-signed transactions!
Instead, you are (ab)using signatures in order to commit to particular 
sighashes.

First, let me point out that you do not need to hash the signature and *then* 
use a raw `scriptPubKey`, which I should *also* point it is not going to pass 
`IsStandard` checks (and will not propagate on the mainnet network reliably, 
only on testnet).
Instead, you can use P2WSH and *include* the signature outright in the 
`redeemScript`.
Since the output `scriptPubKey` is really just the hash of the `redeemScript`, 
this is automatically a hash of a signature (plus a bunch of other bytes).

So your proposal boils down to using P2WSH and having a `redeemScript`:

    redeemScript = <fixedSignature> <fixPubKey> OP_CHECKSIG

Why include the `fixPubKey` in the `redeemScript`?
In your scheme, you would provide the signature and pubkey in the `scriptSig` 
that spends the `scriptPubKey`.
But in a post-P2WSH world, `redeemScript` will also be provided in the 
`witness`, so you *also* provide both the signature and the pubkey, and both 
are hashed before appearing on the `scriptPubKey` --- which is exactly what you 
are proposing anyway.

The above pre-commits to a particular transaction, depending on the `SIGHASH` 
flags of the `fixedSignature`.
Of note is that the `fixPubKey` can have a throwaway privkey, or even a 
***publicly-shared*** privkey.
Even if an alternate signature is created from  well-known privkey, the 
`redeemScript` will not allow any other signature to be accepted, it will only 
use the one that is hardcoded into the script.
Using a publicly-shared privkey would allow us to compute just the expected 
`sighash`. them derove the `fixedSignature` that should be in the 
`redeemScript`.

In particular, this scheme would work just as well for the "congestion control" 
application proposed for `OP_CTV`.
`OP_CTV` still wins in raw WUs spent (just the 32-WU hash), but in the absence 
of `OP_CTV` because raisins, this would also work (but you reveal a 33-WU 
pubkey, and a 73-WU/64-WU signature, which is much larger).
Validation speed is also better for `OP_CTV`, as it is just a hash, while this 
scheme uses signature validation in order to commit to a specific hash anyway 
(a waste of CPU time, since you could just check the hash directly instead of 
going through the rigmarole of a signature, but one which allows us to make 
non-recursive covenants with some similarities to `OP_CTV`).

A purported `OP_CHECKSIGHASHVERIFY` which accepts a `SIGHASH` flag and a hash, 
and checks that the sighash of the transaction (as modified by the flags) is 
equal to the hash, would be more efficient, and would also not differ by much 
from `OP_CTV`.

This can be used in a specific branch of an `OP_IF` to allow, say, a cold 
privkey to override this branch, to start a vault construction.

The same technique should work with Tapscripts inside Taproot (but the 
`fixedPubKey` CANNOT be the same as the internal Taproot key!).

Regards,
ZmnSCPxj
_______________________________________________
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev

Reply via email to