ZmnSCPxj [ARCHIVE] on Nostr: š
Original date posted:2022-05-11 š Original message:Good morning vjudeu, > > ...
š
Original date posted:2022-05-11
š Original message:Good morning vjudeu,
> > Looks like `OP_CAT` is not getting enabled until after we are reasonably sure that recursive covenants are not really unsafe.
>
> Maybe we should use OP_SUBSTR instead of OP_CAT. Or even better: OP_SPLIT. Then, we could have OP_SPLIT <n> <pos1> <pos2> ... <posN> that would split a string N times (so there will be N+1 pieces). Or we could have just OP_SPLIT <pos> to split one string into two. Or maybe OP_2SPLIT and OP_3SPLIT, just to split into two or three pieces (as we have OP_2DUP and OP_3DUP). I think OP_SUBSTR or OP_SPLIT is better than OP_CAT, because then things always get smaller and we can be always sure that we will have one byte as the smallest unit in our Script.
Unfortunately `OP_SUBSTR` can be used to synthesize an effective `OP_CAT`.
Instead of passing in two items on the witness stack to be `OP_CAT`ted together, you instead pass in the two items to concatenate, and *then* the concatenation.
Then you can synthesize a SCRIPT which checks that the supposed concatenation is indeed the two items to be concatenated.
Recursive covenants DO NOT arise from the increasing amounts of memory the trivial `OP_DUP OP_CAT OP_DUP OP_CAT` repetition allocates.
REMEMBER: `OP_CAT` BY ITSELF DOES NOT ENABLE COVENANTS, WHETHER RECURSIVE OR NOT.
Instead, `OP_CAT` enable recursive covenants (which we are not certain are safe) because `OP_CAT` allows quining to be done.
Quining is a technique to pass a SCRIPT with a copy of its code, so that it can then enforce that the output is passed to the exact same input SCRIPT.
`OP_SUBSTR` allows a SCRIPT to validate that it is being passed a copy of itself and that the complete SCRIPT contains its copy as an `OP_PUSH` and the rest of the SCRIPT as actual code.
This is done by `OP_SUBSTR` the appropriate parts of the supposed complete SCRIPT and comparing them to a reference value we have access to (because our own SCRIPT was passed to us inside an `OP_PUSH`).
# Assume that the witness stack top is the concatenation of
# `OP_PUSH`, the SCRIPT below, then the`SCRIPT below.
# Assume this SCRIPT is prepended with an OP_PUSH of our own code.
OP_TOALTSTACK # save our reference
OP_DUP 1 <scriptlength> OP_SUBSTR # Get the OP_PUSH argument
OP_FROMALTSTACK OP_DUP OP_TOALTSTACK # Get our reference
OP_EQUALVERIFY # check they are the same
OP_DUP <1 + scriptlength> <scriptlength> OP_SUBSTR # Get the SCRIPT body
OP_FROMALTSTACK # Get our reference
OP_EQUALVERIFY # check they are the same
# At this point, we have validated that the top of the witness stack
# is the quine of this SCRIPT.
# TODO: validate the `OP_PUSH` instruction, left as an exercise for the
# reader.
Thus, `OP_SUBSTR` is enough to enable quining and is enough to implement recursive covenants.
We cannot enable `OP_SUBSTR` either, unless we are reasonably sure that recursive covenants are safe.
(FWIW recursive covenants are probably safe, as they are not in fact Turing-complete, they are a hair less powerful, equivalent to the total functional programming with codata.)
Regards,
ZmnSCPxj
Published at
2023-06-07 23:09:19Event JSON
{
"id": "0b10917fbf3c54a548fdedbc32e31a8b8a51569fa2d8a70728cb8fc9896cacc9",
"pubkey": "4505072744a9d3e490af9262bfe38e6ee5338a77177b565b6b37730b63a7b861",
"created_at": 1686179359,
"kind": 1,
"tags": [
[
"e",
"cbc59e6bdcc1bf5eb00c43b304431e89f4d455fde09436058aad561d6b24579e",
"",
"root"
],
[
"e",
"8d3ff3d2b3b64f93b42d1c8036e5ecce04fa7c26b973a2ea250815199e5f4f23",
"",
"reply"
],
[
"p",
"8d3cf7eba921036409f1fec074cf8cfd8925bc7cb18e35d358b1ccc89752ee32"
]
],
"content": "š
Original date posted:2022-05-11\nš Original message:Good morning vjudeu,\n\n\n\u003e \u003e Looks like `OP_CAT` is not getting enabled until after we are reasonably sure that recursive covenants are not really unsafe.\n\u003e\n\u003e Maybe we should use OP_SUBSTR instead of OP_CAT. Or even better: OP_SPLIT. Then, we could have OP_SPLIT \u003cn\u003e \u003cpos1\u003e \u003cpos2\u003e ... \u003cposN\u003e that would split a string N times (so there will be N+1 pieces). Or we could have just OP_SPLIT \u003cpos\u003e to split one string into two. Or maybe OP_2SPLIT and OP_3SPLIT, just to split into two or three pieces (as we have OP_2DUP and OP_3DUP). I think OP_SUBSTR or OP_SPLIT is better than OP_CAT, because then things always get smaller and we can be always sure that we will have one byte as the smallest unit in our Script.\n\nUnfortunately `OP_SUBSTR` can be used to synthesize an effective `OP_CAT`.\n\nInstead of passing in two items on the witness stack to be `OP_CAT`ted together, you instead pass in the two items to concatenate, and *then* the concatenation.\nThen you can synthesize a SCRIPT which checks that the supposed concatenation is indeed the two items to be concatenated.\n\nRecursive covenants DO NOT arise from the increasing amounts of memory the trivial `OP_DUP OP_CAT OP_DUP OP_CAT` repetition allocates.\n\nREMEMBER: `OP_CAT` BY ITSELF DOES NOT ENABLE COVENANTS, WHETHER RECURSIVE OR NOT.\n\nInstead, `OP_CAT` enable recursive covenants (which we are not certain are safe) because `OP_CAT` allows quining to be done.\nQuining is a technique to pass a SCRIPT with a copy of its code, so that it can then enforce that the output is passed to the exact same input SCRIPT.\n\n`OP_SUBSTR` allows a SCRIPT to validate that it is being passed a copy of itself and that the complete SCRIPT contains its copy as an `OP_PUSH` and the rest of the SCRIPT as actual code.\nThis is done by `OP_SUBSTR` the appropriate parts of the supposed complete SCRIPT and comparing them to a reference value we have access to (because our own SCRIPT was passed to us inside an `OP_PUSH`).\n\n # Assume that the witness stack top is the concatenation of\n # `OP_PUSH`, the SCRIPT below, then the`SCRIPT below.\n # Assume this SCRIPT is prepended with an OP_PUSH of our own code.\n OP_TOALTSTACK # save our reference\n OP_DUP 1 \u003cscriptlength\u003e OP_SUBSTR # Get the OP_PUSH argument\n OP_FROMALTSTACK OP_DUP OP_TOALTSTACK # Get our reference\n OP_EQUALVERIFY # check they are the same\n OP_DUP \u003c1 + scriptlength\u003e \u003cscriptlength\u003e OP_SUBSTR # Get the SCRIPT body\n OP_FROMALTSTACK # Get our reference\n OP_EQUALVERIFY # check they are the same\n # At this point, we have validated that the top of the witness stack\n # is the quine of this SCRIPT.\n # TODO: validate the `OP_PUSH` instruction, left as an exercise for the\n # reader.\n\nThus, `OP_SUBSTR` is enough to enable quining and is enough to implement recursive covenants.\n\nWe cannot enable `OP_SUBSTR` either, unless we are reasonably sure that recursive covenants are safe.\n\n(FWIW recursive covenants are probably safe, as they are not in fact Turing-complete, they are a hair less powerful, equivalent to the total functional programming with codata.)\n\nRegards,\nZmnSCPxj",
"sig": "fb17cc349f440a4a48fb3a5eec5548ad860bd4ac11e36917132be8fc2b7ae61f0154fe761468bd9dbbb5694ae9561ddffc06dc0670116e28ddb0894e3980aca9"
}