<oembed><type>rich</type><version>1.0</version><author_name>npub1g5zswf6y48f7fy90jf3tlcuwdmjn8znhzaa4vkmtxaeskca8hpss23ms3l</author_name><author_url>https://nostr.ae/npub1g5zswf6y48f7fy90jf3tlcuwdmjn8znhzaa4vkmtxaeskca8hpss23ms3l</author_url><provider_name>njump</provider_name><provider_url>https://nostr.ae</provider_url><html>📅 Original date posted:2019-10-04&#xA;📝 Original message:Good morning Jeremy,&#xA;&#xA;&gt; Awhile back, Ethan and I discussed having, rather than OP_CAT, an OP_SHA256STREAM that uses the streaming properties of a SHA256 hash function to allow concatenation of an unlimited amount of data, provided the only use is to hash it.&#xA;&gt;&#xA;&gt; You can then use it perhaps as follows:&#xA;&gt;&#xA;&gt; // start a new hash with item&#xA;&gt; OP_SHA256STREAM  (-1) -&gt; [state]&#xA;&gt; // Add item to the hash in state&#xA;&gt; OP_SHA256STREAM n [item] [state] -&gt; [state]&#xA;&gt; // Finalize&#xA;&gt; OP_SHA256STREAM (-2) [state] -&gt; [Hash]&#xA;&gt;&#xA;&gt; &lt;-1&gt; OP_SHA256STREAM &lt;tag&gt; &lt;subnode 2&gt; &lt;subnode 3&gt; &lt;3&gt; OP_SHA256STREAM &lt;-2&gt; OP_SHA256STREAM&#xA;&gt;&#xA;&gt; Or it coul&#xA;&gt;&#xA;&#xA;This seems a good idea.&#xA;&#xA;Though it brings up the age-old tension between:&#xA;&#xA;* Generically-useable components, but due to generalization are less efficient.&#xA;* Specific-use components, which are efficient, but which may end up not being useable in the future.&#xA;&#xA;In particular, `OP_SHA256STREAM` would no longer be useable if SHA256 eventually is broken, while the `OP_CAT` will still be useable in the indefinite future.&#xA;In the future a new hash function can simply be defined and the same technique with `OP_CAT` would still be useable.&#xA;&#xA;&#xA;Regards,&#xA;ZmnSCPxj&#xA;&#xA;&gt; --&#xA;&gt; @JeremyRubin&#xA;&gt;&#xA;&gt; On Thu, Oct 3, 2019 at 8:04 PM Ethan Heilman &lt;eth3rs at gmail.com&gt; wrote:&#xA;&gt;&#xA;&gt; &gt; I hope you are having an great afternoon ZmnSCPxj,&#xA;&gt; &gt;&#xA;&gt; &gt; You make an excellent point!&#xA;&gt; &gt;&#xA;&gt; &gt; I had thought about doing the following to tag nodes&#xA;&gt; &gt;&#xA;&gt; &gt; || means OP_CAT&#xA;&gt; &gt;&#xA;&gt; &gt; `node = SHA256(type||SHA256(data))`&#xA;&gt; &gt; so a subnode would be&#xA;&gt; &gt; `subnode1 = SHA256(1||SHA256(subnode2||subnode3))`&#xA;&gt; &gt; and a leaf node would be&#xA;&gt; &gt; `leafnode = SHA256(0||SHA256(leafdata))`&#xA;&gt; &gt;&#xA;&gt; &gt; Yet, I like your idea better. Increasing the size of the two inputs to&#xA;&gt; &gt; OP_CAT to be 260 Bytes each where 520 Bytes is the maximum allowable&#xA;&gt; &gt; size of object on the stack seems sensible and also doesn&#39;t special&#xA;&gt; &gt; case the logic of OP_CAT.&#xA;&gt; &gt;&#xA;&gt; &gt; It would also increase performance. SHA256(tag||subnode2||subnode3)&#xA;&gt; &gt; requires 2 compression function calls whereas&#xA;&gt; &gt; SHA256(1||SHA256(subnode2||subnode3)) requires 2+1=3 compression&#xA;&gt; &gt; function calls (due to padding).&#xA;&gt; &gt;&#xA;&gt; &gt; &gt;Or we could implement tagged SHA256 as a new opcode...&#xA;&gt; &gt;&#xA;&gt; &gt; I agree that tagged SHA256 as an op code that would certainty be&#xA;&gt; &gt; useful, but OP_CAT provides far more utility and is a simpler change.&#xA;&gt; &gt;&#xA;&gt; &gt; Thanks,&#xA;&gt; &gt; Ethan&#xA;&gt; &gt;&#xA;&gt; &gt; On Thu, Oct 3, 2019 at 7:42 PM ZmnSCPxj &lt;ZmnSCPxj at protonmail.com&gt; wrote:&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; &gt; Good morning Ethan,&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; To avoid derailing the NO_INPUT conversation, I have changed the&#xA;&gt; &gt; &gt; &gt; subject to OP_CAT.&#xA;&gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; Responding to:&#xA;&gt; &gt; &gt; &gt; &#34;&#34;&#34;&#xA;&gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; -   `SIGHASH` flags attached to signatures are a misdesign, sadly&#xA;&gt; &gt; &gt; &gt;     retained from the original BitCoin 0.1.0 Alpha for Windows design, on&#xA;&gt; &gt; &gt; &gt;     par with:&#xA;&gt; &gt; &gt; &gt;     [..]&#xA;&gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; -   `OP_CAT` and `OP_MULT` and `OP_ADD` and friends&#xA;&gt; &gt; &gt; &gt;     [..]&#xA;&gt; &gt; &gt; &gt;     &#34;&#34;&#34;&#xA;&gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt;     OP_CAT is an extremely valuable op code. I understand why it was&#xA;&gt; &gt; &gt; &gt;     removed as the situation at the time with scripts was dire. However&#xA;&gt; &gt; &gt; &gt;     most of the protocols I&#39;ve wanted to build on Bitcoin run into the&#xA;&gt; &gt; &gt; &gt;     limitation that stack values can not be concatenated. For instance&#xA;&gt; &gt; &gt; &gt;     TumbleBit would have far smaller transaction sizes if OP_CAT was&#xA;&gt; &gt; &gt; &gt;     supported in Bitcoin. If it happens to me as a researcher it is&#xA;&gt; &gt; &gt; &gt;     probably holding other people back as well. If I could wave a magic&#xA;&gt; &gt; &gt; &gt;     wand and turn on one of the disabled op codes it would be OP_CAT. Of&#xA;&gt; &gt; &gt; &gt;     course with the change that size of each concatenated value must be 64&#xA;&gt; &gt; &gt; &gt;     Bytes or less.&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; &gt; Why 64 bytes in particular?&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; &gt; It seems obvious to me that this 64 bytes is most suited for building Merkle trees, being the size of two SHA256 hashes.&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; &gt; However we have had issues with the use of Merkle trees in Bitcoin blocks.&#xA;&gt; &gt; &gt; Specifically, it is difficult to determine if a hash on a Merkle node is the hash of a Merkle subnode, or a leaf transaction.&#xA;&gt; &gt; &gt; My understanding is that this is the reason for now requiring transactions to be at least 80 bytes.&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; &gt; The obvious fix would be to prepend the type of the hashed object, i.e. add at least one byte to determine this type.&#xA;&gt; &gt; &gt; Taproot for example uses tagged hash functions, with a different tag for leaves, and tagged hashes are just prepend-this-32-byte-constant-twice-before-you-SHA256.&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; &gt; This seems to indicate that to check merkle tree proofs, an `OP_CAT` with only 64 bytes max output size would not be sufficient.&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; &gt; Or we could implement tagged SHA256 as a new opcode...&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; &gt; Regards,&#xA;&gt; &gt; &gt; ZmnSCPxj&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt;     On Tue, Oct 1, 2019 at 10:04 PM ZmnSCPxj via bitcoin-dev&#xA;&gt; &gt; &gt; &gt;     bitcoin-dev at lists.linuxfoundation.org wrote:&#xA;&gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; &gt; Good morning lists,&#xA;&gt; &gt; &gt; &gt; &gt; Let me propose the below radical idea:&#xA;&gt; &gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; &gt; -   `SIGHASH` flags attached to signatures are a misdesign, sadly retained from the original BitCoin 0.1.0 Alpha for Windows design, on par with:&#xA;&gt; &gt; &gt; &gt; &gt;     -   1 RETURN&#xA;&gt; &gt; &gt; &gt; &gt;     -   higher-`nSequence` replacement&#xA;&gt; &gt; &gt; &gt; &gt;     -   DER-encoded pubkeys&#xA;&gt; &gt; &gt; &gt; &gt;     -   unrestricted `scriptPubKey`&#xA;&gt; &gt; &gt; &gt; &gt;     -   Payee-security-paid-by-payer (i.e. lack of P2SH)&#xA;&gt; &gt; &gt; &gt; &gt;     -   `OP_CAT` and `OP_MULT` and `OP_ADD` and friends&#xA;&gt; &gt; &gt; &gt; &gt;     -   transaction malleability&#xA;&gt; &gt; &gt; &gt; &gt;     -   probably many more&#xA;&gt; &gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; &gt; So let me propose the more radical excision, starting with SegWit v1:&#xA;&gt; &gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; &gt; -   Remove `SIGHASH` from signatures.&#xA;&gt; &gt; &gt; &gt; &gt; -   Put `SIGHASH` on public keys.&#xA;&gt; &gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; &gt; Public keys are now encoded as either 33-bytes (implicit `SIGHASH_ALL`) or 34-bytes (`SIGHASH` byte, followed by pubkey type, followed by pubkey coordinate).&#xA;&gt; &gt; &gt; &gt; &gt; `OP_CHECKSIG` and friends then look at the public key to determine sighash algorithm rather than the signature.&#xA;&gt; &gt; &gt; &gt; &gt; As we expect public keys to be indirectly committed to on every output `scriptPubKey`, this is automatically output tagging to allow particular `SIGHASH`.&#xA;&gt; &gt; &gt; &gt; &gt; However, we can then utilize the many many ways to hide public keys away until they are needed, exemplified in MAST-inside-Taproot.&#xA;&gt; &gt; &gt; &gt; &gt; I propose also the addition of the opcode:&#xA;&gt; &gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; &gt;     &lt;sighash&gt; &lt;pubkey&gt; OP_SETPUBKEYSIGHASH&#xA;&gt; &gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; &gt; -   `sighash` must be one byte.&#xA;&gt; &gt; &gt; &gt; &gt; -   `pubkey` may be the special byte `0x1`, meaning &#34;just use the Taproot internal pubkey&#34;.&#xA;&gt; &gt; &gt; &gt; &gt; -   `pubkey` may be 33-byte public key, in which case the `sighash` byte is just prepended to it.&#xA;&gt; &gt; &gt; &gt; &gt; -   `pubkey` may be 34-byte public key with sighash, in which case the first byte is replaced with `sighash` byte.&#xA;&gt; &gt; &gt; &gt; &gt; -   If `sighash` is `0x00` then the result is a 33-byte public key (the sighash byte is removed) i.e. `SIGHASH_ALL` implicit.&#xA;&gt; &gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; &gt; This retains the old feature where the sighash is selected at time-of-spending rather than time-of-payment.&#xA;&gt; &gt; &gt; &gt; &gt; This is done by using the script:&#xA;&gt; &gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; &gt;     &lt;pubkey&gt; OP_SETPUBKEYSIGHASH OP_CHECKSIG&#xA;&gt; &gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; &gt; Then the sighash can be put in the witness stack after the signature, letting the `SIGHASH` flag be selected at time-of-signing, but only if the SCRIPT specifically is formed to do so.&#xA;&gt; &gt; &gt; &gt; &gt; This is malleability-safe as the signature still commits to the `SIGHASH` it was created for.&#xA;&gt; &gt; &gt; &gt; &gt; However, by default, public keys will not have an attached `SIGHASH` byte, implying `SIGHASH_ALL` (and disallowing-by-default non-`SIGHASH_ALL`).&#xA;&gt; &gt; &gt; &gt; &gt; This removes the problems with `SIGHASH_NONE` `SIGHASH_SINGLE`, as they are allowed only if the output specifically says they are allowed.&#xA;&gt; &gt; &gt; &gt; &gt; Would this not be a superior solution?&#xA;&gt; &gt; &gt; &gt; &gt; Regards,&#xA;&gt; &gt; &gt; &gt; &gt; ZmnSCPxj&#xA;&gt; &gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; &gt; bitcoin-dev mailing list&#xA;&gt; &gt; &gt; &gt; &gt; bitcoin-dev at lists.linuxfoundation.org&#xA;&gt; &gt; &gt; &gt; &gt; https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev&#xA;&gt; &gt; &gt; &gt;&#xA;&gt; &gt; &gt; &gt; Lightning-dev mailing list&#xA;&gt; &gt; &gt; &gt; Lightning-dev at lists.linuxfoundation.org&#xA;&gt; &gt; &gt; &gt; https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; &gt;&#xA;&gt; &gt; _______________________________________________&#xA;&gt; &gt; Lightning-dev mailing list&#xA;&gt; &gt; Lightning-dev at lists.linuxfoundation.org&#xA;&gt; &gt; https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev</html></oembed>