Johnson Lau [ARCHIVE] on Nostr: 📅 Original date posted:2018-12-21 📝 Original message:> On 21 Dec 2018, at 7:17 ...
đź“… Original date posted:2018-12-21
📝 Original message:> On 21 Dec 2018, at 7:17 AM, Rusty Russell <rusty at rustcorp.com.au> wrote:
>
> Johnson Lau <jl2012 at xbt.hk> writes:
>
>>> But I don't see how OP_CODESEPARATOR changes anything here, wrt NOINPUT?
>>> Remember, anyone can create an output which can be spent by any NOINPUT,
>>> whether we go for OP_MASK or simply not commiting to the input script.
>>>
>>
>> Let me elaborate more. Currently, scriptCode is truncated at the last executed CODESEPARATOR. If we have a very big script with many CODESEPARATORs and CHECKSIGs, there will be a lot of hashing to do.
>>
>> To fix this problem, it is proposed that the new sighash will always commit to the same H(script), instead of the truncated scriptCode. So we only need to do the H(script) once, even if the script is very big
>
> Yes, I read this as proposed, it is clever. Not sure we'd be
> introducing it if OP_CODESEPARATOR didn't already exist, but at least
> it's a simplfication.
>
>> In the case of NOINPUT with MASKEDSCRIPT, it will commit to the H(masked_script) instead of H(script).
>>
>> To make CODESEPARATOR works as before, the sighash will also commit to the position of the last executed CODESEPARATOR. So the semantics doesn’t change. For scripts without CODESEPARATOR, the committed value is a constant.
>>
>> IF NOINPUT does not commit to H(masked_script), technically it could still commit to the position of the last executed CODESEPARATOR. But since the wallet is not aware of the actual content of the script, it has to guess the meaning of such committed positions, like “with the HD key path m/x/y/z, I assume the script template is blah blah blah because I never use this path for another script template, and the meaning of signing the 3rd CODESEPARATOR is blah blah blah”. It still works if the assumptions hold, but sounds quite unreliable to me.
>
> My question is more fundamental. If NOINPUT doesn't commit to the input
> at all, no script, no code separator, nothing. I'm struggling to
> understand your original comment was "without signing the script or
> masked script, OP_CODESEPARATOR becomes unusable or insecure with
> NOINPUT."
>
> I mean, non-useful, sure. Its purpose is to alter signature behavior,
> and from the script POV there's no signature with this form of NOINPUT.
> But other than the already-established "I reused keys for multiple
> outputs" oops, I don't see any new dangers?
>
> Thanks,
> Rusty.
The question I would like to ask is: is OP_CODESEPARATOR useful under taproot? Generally speaking, CODESEPARATOR is useful only with conditional opcodes (OP_IF etc), and conditional opcodes are mostly replaced by merklized scripts. I am not sure how much usability is left with CODESEPARATOR
If no one needs CODESEPARATOR, we might just disable it, and makes the validation code a bit simpler
If CODESEPARATOR is useful, then we should find a way to make it works with NOINPUT. With H(masked_script) committed, the meaning of the CODESEPARATOR position is very clear. Without H(masked_script), the meaning of the position totally relies on the assumption that “this public key is only used in this script template”.
Ignore CODESEPARATOR and more generally, I agree with you that script masking does not help in the case of address (scriptPubKey) reuse, which is the commonest type of reuse. However, it prevents replayability when the same public key is reused in different scripts
Published at
2023-06-07 18:15:38Event JSON
{
"id": "82f6f7f8c1d3b6f390146b6c1a4504aa7fae1c41339d1598bb71d79eb3b5be18",
"pubkey": "492fa402e838904bdc8eb2c8fafa1aa895df26438bfd998c71b01cb9db550ff7",
"created_at": 1686161738,
"kind": 1,
"tags": [
[
"e",
"77c824d861e497590991b7dc940a75787db11a7b2eab6adcf5563d0847a4df18",
"",
"root"
],
[
"e",
"8082c76f2d39a207246242b8045134a7d671dc2d0921add1392422bdd8f7a207",
"",
"reply"
],
[
"p",
"13bd8c1c5e3b3508a07c92598647160b11ab0deef4c452098e223e443c1ca425"
]
],
"content": "📅 Original date posted:2018-12-21\n📝 Original message:\u003e On 21 Dec 2018, at 7:17 AM, Rusty Russell \u003crusty at rustcorp.com.au\u003e wrote:\n\u003e \n\u003e Johnson Lau \u003cjl2012 at xbt.hk\u003e writes:\n\u003e \n\u003e\u003e\u003e But I don't see how OP_CODESEPARATOR changes anything here, wrt NOINPUT?\n\u003e\u003e\u003e Remember, anyone can create an output which can be spent by any NOINPUT,\n\u003e\u003e\u003e whether we go for OP_MASK or simply not commiting to the input script.\n\u003e\u003e\u003e \n\u003e\u003e \n\u003e\u003e Let me elaborate more. Currently, scriptCode is truncated at the last executed CODESEPARATOR. If we have a very big script with many CODESEPARATORs and CHECKSIGs, there will be a lot of hashing to do.\n\u003e\u003e \n\u003e\u003e To fix this problem, it is proposed that the new sighash will always commit to the same H(script), instead of the truncated scriptCode. So we only need to do the H(script) once, even if the script is very big\n\u003e \n\u003e Yes, I read this as proposed, it is clever. Not sure we'd be\n\u003e introducing it if OP_CODESEPARATOR didn't already exist, but at least\n\u003e it's a simplfication.\n\u003e \n\u003e\u003e In the case of NOINPUT with MASKEDSCRIPT, it will commit to the H(masked_script) instead of H(script).\n\u003e\u003e \n\u003e\u003e To make CODESEPARATOR works as before, the sighash will also commit to the position of the last executed CODESEPARATOR. So the semantics doesn’t change. For scripts without CODESEPARATOR, the committed value is a constant.\n\u003e\u003e \n\u003e\u003e IF NOINPUT does not commit to H(masked_script), technically it could still commit to the position of the last executed CODESEPARATOR. But since the wallet is not aware of the actual content of the script, it has to guess the meaning of such committed positions, like “with the HD key path m/x/y/z, I assume the script template is blah blah blah because I never use this path for another script template, and the meaning of signing the 3rd CODESEPARATOR is blah blah blah”. It still works if the assumptions hold, but sounds quite unreliable to me.\n\u003e \n\u003e My question is more fundamental. If NOINPUT doesn't commit to the input\n\u003e at all, no script, no code separator, nothing. I'm struggling to\n\u003e understand your original comment was \"without signing the script or\n\u003e masked script, OP_CODESEPARATOR becomes unusable or insecure with\n\u003e NOINPUT.\"\n\u003e \n\u003e I mean, non-useful, sure. Its purpose is to alter signature behavior,\n\u003e and from the script POV there's no signature with this form of NOINPUT.\n\u003e But other than the already-established \"I reused keys for multiple\n\u003e outputs\" oops, I don't see any new dangers?\n\u003e \n\u003e Thanks,\n\u003e Rusty.\n\nThe question I would like to ask is: is OP_CODESEPARATOR useful under taproot? Generally speaking, CODESEPARATOR is useful only with conditional opcodes (OP_IF etc), and conditional opcodes are mostly replaced by merklized scripts. I am not sure how much usability is left with CODESEPARATOR\n\nIf no one needs CODESEPARATOR, we might just disable it, and makes the validation code a bit simpler\n\nIf CODESEPARATOR is useful, then we should find a way to make it works with NOINPUT. With H(masked_script) committed, the meaning of the CODESEPARATOR position is very clear. Without H(masked_script), the meaning of the position totally relies on the assumption that “this public key is only used in this script template”.\n\nIgnore CODESEPARATOR and more generally, I agree with you that script masking does not help in the case of address (scriptPubKey) reuse, which is the commonest type of reuse. However, it prevents replayability when the same public key is reused in different scripts",
"sig": "92a5b7e16ba91be6db3be39380d44e752b0420faf14a915a0129a613deb68a7a58adf829486b554f0affda7640d4cec0ab5524061927ed891aec5b048ba38fcd"
}