lightning-dev

OP_CAT was Re: Continuing the discussion about noinput / anyprevout

OP_CAT was Re: Continuing the discussion about noinput / anyprevout

Original Postby ZmnSCPxj

Posted on: October 4, 2019 07:00 UTC

ZmnSCPxj proposed a new opcode called OP_SHA256STREAM, which uses the streaming properties of a SHA256 hash function to allow concatenation of an unlimited amount of data that can only be hashed.

The idea was discussed with Ethan, who agreed that it could be useful, but also brought up the tension between generically-useable and specific-use components. The use of OP_SHA256STREAM would no longer be possible if SHA256 is eventually broken, while OP_CAT will still be usable in the future.In the past, Ethan had thought about using SHA256 to tag nodes as subnode or leaf node, but he liked ZmnSCPxj's idea better. They both agreed that increasing the size of the two inputs to OP_CAT to be 260 Bytes each where 520 Bytes is the maximum allowable size of object on the stack seems sensible and also doesn't special case the logic of OP_CAT. Additionally, ZmnSCPxj replied to Ethan's message regarding the limitation of concatenated values, suggesting that the 64 bytes limit is most suited for building Merkle trees, being the size of two SHA256 hashes. However, there have been issues with the use of Merkle trees in Bitcoin blocks, specifically when determining whether a hash on a Merkle node is the hash of a Merkle subnode or a leaf transaction. ZmnSCPxj suggested implementing tagged SHA256 as a new opcode instead.Separately, ZmnSCPxj proposed the radical idea of removing SIGHASH flags attached to signatures starting with SegWit v1, putting SIGHASH on public keys instead and encoding public keys as either 33-bytes (implicit SIGHASH_ALL) or 34-bytes, with SIGHASH byte followed by pubkey type, followed by pubkey coordinate. The proposal is to utilize the many ways to hide public keys away until they are needed, exemplified in MAST-inside-Taproot.Moreover, ZmnSCPxj proposed the addition of the opcode OP_SETPUBKEYSIGHASH, which must have one byte as sighash and may use either a special byte 0x1 to just use the Taproot internal pubkey or a 33-byte public key, allowing output tagging to allow particular SIGHASH. The email thread discusses the use of the sighash byte in Bitcoin transactions.The sighash byte is a one-byte value that specifies how parts of the transaction should be hashed to create the transaction digest, which is then signed by the sender's private key. The pubkey may be a 34-byte public key with sighash, in which case the first byte is replaced with the sighash byte. If sighash is 0x00, then the result is a 33-byte public key (SIGHASH_ALL implicit). This retains the old feature where the sighash is selected at time-of-spending rather than time-of-payment.To allow for selection of the SIGHASH flag at time-of-signing, the script OP_SETPUBKEYSIGHASH OP_CHECKSIG can be used. The sighash can then be put in the witness stack after the signature, but only if the script specifically forms it to do so. This is malleability-safe as the signature still commits to the SIGHASH it was created for. Public keys will not have an attached SIGHASH byte by default, implying SIGHASH_ALL (and disallowing-by-default non-SIGHASH_ALL). This removes the problems with SIGHASH_NONE and SIGHASH_SINGLE, as they are allowed only if the output specifically says so.