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