vjudeu
Copper Member
Legendary
Offline
Activity: 909
Merit: 2342
|
 |
June 28, 2022, 04:30:54 AM |
|
I don't see how. In exactly the same way, how you don't have to provide a public key in your output. You don't have to use "<pubkey> OP_CHECKSIG" as your output and "<signature>" as your input, you can also use "OP_CHECKSIG" as your output, and "<signature> <pubkey>" as your input. So, in the same way, you can use "OP_CHECKLOCKTIMEVERIFY OP_DROP OP_TRUE" as your output, and "<locktime>" as your input. So yes, the hash of the previous transaction is now fixed, so you always commit to the whole script, but on the other hand, that script can be flexible enough to allow you to change the locktime. So, what about that script? OP_DUP <minLocktime> <maxLocktime> OP_WITHIN OP_VERIFY OP_CHECKLOCKTIMEVERIFY OP_DROP OP_TRUE Also note that there are only N possible valid input scripts, that means there are only N possible transaction hashes, that you can reach. You can imagine, how it could affect the next transaction, if it will be used as an input, and if there is no Segwit, so the input script affects the transaction hash (other inputs can use Segwit, only this input can be non-Segwit on purpose, just to reach N possible options, another option could require deterministic signatures, but it is hard to enforce in the current script).
|
I've moved on to other things.
|
|
|
pooya87 (OP)
Legendary
Offline
Activity: 4046
Merit: 12115
|
 |
June 28, 2022, 08:20:38 AM |
|
In exactly the same way, how you don't have to provide a public key in your output. You don't have to use "<pubkey> OP_CHECKSIG" as your output and "<signature>" as your input, you can also use "OP_CHECKSIG" as your output, and "<signature> <pubkey>" as your input.
True, but the problem is that such scripts make no sense since anybody could spend a OP_CHECKSIG output script. So, in the same way, you can use "OP_CHECKLOCKTIMEVERIFY OP_DROP OP_TRUE" as your output, and "<locktime>" as your input.
Similarly it won't make sense to use OP_CHECKLOCKTIMEVERIFY in first place if the spender is setting it and it can be changed specially if you add OP_CODESEPERATOR which would mean it would also make the transaction malleable. So, what about that script? OP_DUP <minLocktime> <maxLocktime> OP_WITHIN OP_VERIFY OP_CHECKLOCKTIMEVERIFY OP_DROP OP_TRUE That would work fine since the locking script is defining a strict condition of the locktime so it can't be arbitrary. Although I'm not sure you need the final OP_TRUE though.
|
|
|
|
garlonicon
Copper Member
Legendary
Offline
Activity: 944
Merit: 2309
|
What about conditional multisig? It is non-standard, but it is possible with OP_CODESEPARATOR.
In a non-segwit transaction, any change in the signature can change the transaction ID. It is usually not desired, but it can be useful in some cases, for example: it is possible to make a conditional multisig, where coins will be signed by one key, or by two keys, and when they will be signed only by one key, the second key will be entirely hidden.
The output script is: "<pubkeyAlice> OP_CHECKSIG". And then, the whole magic is in using OP_CODESEPARATOR inside the input script. The input script is: "<signatureBob> <pubkeyBob> OP_CHECKSIGVERIFY OP_CODESEPARATOR <signatureAlice>".
Then, both parties can make their signatures upfront, so the next transaction could use the previous transaction hash as an input. And that transaction could trigger something, and will be valid only if both parties will sign everything with their upfront-prepared, deterministic signatures. But if anyone will refuse to sign, or use another signature, then this transaction will not be confirmed, because of no matching txid.
The benefit is that if Alice will use any signature on such output, it will be perfectly valid and standard, so nobody will notice that any multisig was even planned.
|
|
|
|
|
pooya87 (OP)
Legendary
Offline
Activity: 4046
Merit: 12115
|
 |
July 08, 2022, 02:43:36 AM |
|
The output script is: "<pubkeyAlice> OP_CHECKSIG". And then, the whole magic is in using OP_CODESEPARATOR inside the input script. The input script is: "<signatureBob> <pubkeyBob> OP_CHECKSIGVERIFY OP_CODESEPARATOR <signatureAlice>".
The bold part of the signature script can be discarded or be replaced by anything else and the transaction would still be valid. In other words your scripts are examples of the malleability attack.
|
|
|
|
garlonicon
Copper Member
Legendary
Offline
Activity: 944
Merit: 2309
|
 |
July 08, 2022, 04:13:23 AM |
|
or be replaced by anything else Any signature can be replaced by anything else, because we don't have deterministic signatures, so "<signatureAlice>" can be also replaced. Anyone using legacy addresses should be aware of that. The bold part of the signature script can be discarded It can be discarded in the same way, as any pushes in P2SH before the script itself can be discarded, and in the same way, as all Segwit inputs can be. So, they can be discarded, because there is no soft-fork preventing people from doing so. But I can imagine a Taproot implementation, where some part of the input is committed to the public key, then that system would be safe. So, historically, P2SH could be introduced as a OP_CODESEPARATOR commitment to the public key, instead of creating a new address type. It is all about privacy, where you can hide anything behind some output that looks the same. But yes, in Taproot, we can currently reach the same thing.
|
|
|
|
|
pooya87 (OP)
Legendary
Offline
Activity: 4046
Merit: 12115
|
 |
July 08, 2022, 06:18:21 AM |
|
or be replaced by anything else Any signature can be replaced by anything else, because we don't have deterministic signatures, so "<signatureAlice>" can be also replaced. Anyone using legacy addresses should be aware of that. By anything I meant literary anything not just another signature. For example it could be replaced by an arbitrary message like <foobar> OP_CODESEPARATOR The bold part of the signature script can be discarded It can be discarded in the same way, as any pushes in P2SH before the script itself can be discarded, and in the same way, as all Segwit inputs can be. If it can be discarded that means it is pointless and is not solving anything. You see, the locking script should be designed in a way that it mandates all the unlocking script parts. For example in a P2PKH locking script, it requires 2 items: a signature and a public key and neither one can change meaning you can't use someone else's public key or use a different script to spend that output.
|
|
|
|
garlonicon
Copper Member
Legendary
Offline
Activity: 944
Merit: 2309
|
 |
July 08, 2022, 10:39:24 AM |
|
By anything I meant literary anything not just another signature. For example it could be replaced by an arbitrary message like <foobar> OP_CODESEPARATOR Well, any miner can do that today on any legacy address, just because it is possible. If it can be discarded that means it is pointless and is not solving anything. It can be discarded in the current consensus. But OP_CODESEPARATOR can decide, what is signed, and what is not, so by introducing new sighashes, the signed parts of the input script can be controlled by signatures. you can't use someone else's public key or use a different script to spend that output You can always use a different script, because you can always extend it, if you are a miner. In Segwit, it just does not matter, because txid is not affected.
|
|
|
|
|
vjudeu
Copper Member
Legendary
Offline
Activity: 909
Merit: 2342
|
I found some clue, why OP_CODESEPARATOR is still in Taproot: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-February/021448.html[2] In Taproot, if you want to prevent signatures migrating to another branch or within a branch, you can use the CODESEPARATOR opcode which was redisegned in Taproot for exactly this purpose... we really did about witness malleation in its design!
|
I've moved on to other things.
|
|
|
pooya87 (OP)
Legendary
Offline
Activity: 4046
Merit: 12115
|
 |
February 11, 2023, 05:29:41 AM |
|
Thanks for the update. I need to investigate the implementation again but I don't think it works the way that is explained here because of how Taproot scripts were designed so that the leaf hash is covered by the signature.
|
|
|
|
|
stwenhao
|
 |
April 06, 2025, 02:07:35 PM Last edit: September 07, 2025, 07:47:12 AM by stwenhao |
|
While going through Taproot this OP code makes even less sense in Tapscripts and yet it is there. It seems that OP_SUCCESS makes the whole TapScript automatically valid, which makes it harder to do "partial Script execution". And for that reason, some Bitcoin developers want to introduce OP_SEGMENT: https://rusty.ozlabs.org/2024/01/04/OP_SEGMENT.htmlI wonder, why OP_CODESEPARATOR is not reused instead, but as you can see, people still want to split scripts into smaller parts. Edit: I found yet another use case for OP_CODESEPARATOR: https://asktom.cf/index.php?topic=5557305.msg65760050#msg65760050If you use it, then you can reuse existing signer, to sign new scripts, without modifying signing code that much. And then, you can for example sign some P2WSH in the same way, as you would sign P2WPKH, and then adjust some bytes, to make everything valid. Example Script: decodescript 7c8276937693b2757cab76a914751e76e8199196d454941c45d1b3a323f1433bd688ac { "asm": "OP_SWAP OP_SIZE OP_DUP OP_ADD OP_DUP OP_ADD OP_CHECKSEQUENCEVERIFY OP_DROP OP_SWAP OP_CODESEPARATOR OP_DUP OP_HASH160 751e76e8199196d454941c45d1b3a323f1433bd6 OP_EQUALVERIFY OP_CHECKSIG", "desc": "raw(7c8276937693b2757cab76a914751e76e8199196d454941c45d1b3a323f1433bd688ac)#9hnlfmtv", "type": "nonstandard", "p2sh": "2Mzw53ZN8wS8FXvNpMFkGjfP3i3hCTAhcbV", "segwit": { "asm": "0 3062edde70aad88f218ed97aa51f6003baeb94c4c4d876d86ddf8dce6f5d4c06", "desc": "addr(tb1qxp3wmhns4tvg7gvwm9a228mqqwawh9xycnv8dkrdm7xuum6afsrqcuzu88)#y06denaf", "hex": "00203062edde70aad88f218ed97aa51f6003baeb94c4c4d876d86ddf8dce6f5d4c06", "address": "tb1qxp3wmhns4tvg7gvwm9a228mqqwawh9xycnv8dkrdm7xuum6afsrqcuzu88", "type": "witness_v0_scripthash", "p2sh-segwit": "2N8BaDhNcPriSpqLqNKWBc1uPXhRMDuA7To" } } Example transaction: https://mempool.space/testnet4/tx/2f118ad613dc03defab7ec6078164357d37e1cfde64883d78de0dd11de9f962a02000000000101431d83d7af79e4ea4bc59cd43e5250891894142b5a685e2046b32c65b20d4b0b00000000002c01000001d8c2000000000000160014751e76e8199196d454941c45d1b3a323f1433bd603473044022057bd466515b398e3643bd290492e9af1e0a004e58017b7302e0a80b5ff186f0c02205aa84d9468e49c1128ece23dd5474883762e83663c53fa382575585b59dfeb7883210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798237c8276937693b2757cab76a914751e76e8199196d454941c45d1b3a323f1433bd688ac00000000
|
|
|
|
|