* [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) @ 2019-06-01 5:35 Jeremy 2019-06-02 5:35 ` ZmnSCPxj ` (2 more replies) 0 siblings, 3 replies; 17+ messages in thread From: Jeremy @ 2019-06-01 5:35 UTC (permalink / raw) To: Bitcoin development mailing list [-- Attachment #1: Type: text/plain, Size: 1116 bytes --] Hi All, OP_CHECKOUTPUTSHASHVERIFY is retracted in favor of OP_SECURETHEBAG*. OP_SECURETHEBAG does more or less the same thing, but fixes malleability issues and lifts the single output restriction to a known number of inputs restriction. OP_CHECKOUTPUTSVERIFY had some issues with malleability of version and locktime. OP_SECURETHEBAG commits to both of these values. OP_SECURETHEBAG also lifts the restriction that OP_CHECKOUTPUTSVERIFY had to be spent as only a single input, and instead just commits to the number of inputs. This allows for more flexibility, but keeps it easy to get the same single output restriction. BIP: https://github.com/JeremyRubin/bips/blob/op-secure-the-bag/bip-secure-the-bag.mediawiki Implementation: https://github.com/JeremyRubin/bitcoin/tree/secure_the_bag A particularly useful topic of discussion is how best to eliminate the PUSHDATA and treat OP_SECURETHEBAG like a pushdata directly. I thought about how the interpreter works and is implemented and couldn't come up with something noninvasive. Thank you for your review and discussion, Jeremy * Plus the name is better [-- Attachment #2: Type: text/html, Size: 3438 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-06-01 5:35 [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) Jeremy @ 2019-06-02 5:35 ` ZmnSCPxj 2019-06-02 14:32 ` Russell O'Connor 2019-06-05 9:30 ` Anthony Towns 2 siblings, 0 replies; 17+ messages in thread From: ZmnSCPxj @ 2019-06-02 5:35 UTC (permalink / raw) To: Jeremy, Bitcoin Protocol Discussion > Using an OP_SECURETHEBAG Taproot, the recipient may even give the sender an address which makes a channel unbeknownst to them. This requires special design to be safe. Every offchain protocol requires a backout transaction to be created before the funding transaction output is committed onchain. This backout transaction ensures that the funder of the channel can back out if the other side aborts the protocol. For Poon-Dryja channels this is the initial commitment transaction. The continued operation of the protocol requires the initial commitment to be revoked at the next update. So we need a plausible backout for the receiver first. To do so, we make the funding transaction address a Taproot with internal pubkey 2-of-2 of the receiver and its channel counterparty. The Taproot hides a single script alternative, a `OP_SECURETHEBAG` that ensures it is paid out to a pure script (i.e. Taproot internal key is a NUMS point), the scripts forming a revocable output to the receiver (let receiver claim with `OP_CHECKSEQUENCEVERIFY`, or counterparty to revoke immediately if it knows revocation key). This is essentially a walletless channel open, which I described before with `SIGHASH_NOINPUT`. Channel factories using `OP_SECURETHEBAG` cannot be updated (i.e. not able to close channels and reuse funds to open new channels offchain), i.e. close-only factories. The above revocation trick only works with two participants, and it would be largely pointless to have 2-participant factories (unless you were e.g. transporting HTLCs separately from DLCs in two channels of the same factory). Channel factories based on the Decker-Russell-Osuntokun mechanism ("eltoo") allow reorganizing channels offchain, without hitting the chain at all. These need `SIGHASH_NOINPUT`/`SIGHASH_ANYPREVOUT`. For channel factories, `SIGHASH_NOINPUT` is better. `OP_SECURETHEBAG` requires the funding output to commit to a particular output set. `SIGHASH_NOINPUT` lets the signatories introduce a new possible output set later. One might compare `OP_SECURETHEBAG` to MAST, while `SIGHASH_NOINPUT` is comparable to Graftroot. MAST has a fixed set of alternatives, while Graftroot allows signatories to add new alternatives later. Regards, ZmnSCPxj Sent with ProtonMail Secure Email. ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Saturday, June 1, 2019 1:35 PM, Jeremy via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> wrote: > Hi All, > > OP_CHECKOUTPUTSHASHVERIFY is retracted in favor of OP_SECURETHEBAG*. OP_SECURETHEBAG does more or less the same thing, but fixes malleability issues and lifts the single output restriction to a known number of inputs restriction. > > OP_CHECKOUTPUTSVERIFY had some issues with malleability of version and locktime. OP_SECURETHEBAG commits to both of these values. > > OP_SECURETHEBAG also lifts the restriction that OP_CHECKOUTPUTSVERIFY had to be spent as only a single input, and instead just commits to the number of inputs. This allows for more flexibility, but keeps it easy to get the same single output restriction. > > BIP: https://github.com/JeremyRubin/bips/blob/op-secure-the-bag/bip-secure-the-bag.mediawiki > Implementation: https://github.com/JeremyRubin/bitcoin/tree/secure_the_bag > > A particularly useful topic of discussion is how best to eliminate the PUSHDATA and treat OP_SECURETHEBAG like a pushdata directly. I thought about how the interpreter works and is implemented and couldn't come up with something noninvasive. > > Thank you for your review and discussion, > > Jeremy > > * Plus the name is better ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-06-01 5:35 [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) Jeremy 2019-06-02 5:35 ` ZmnSCPxj @ 2019-06-02 14:32 ` Russell O'Connor 2019-06-02 21:32 ` Jeremy 2019-06-05 9:30 ` Anthony Towns 2 siblings, 1 reply; 17+ messages in thread From: Russell O'Connor @ 2019-06-02 14:32 UTC (permalink / raw) To: Jeremy, Bitcoin Protocol Discussion [-- Attachment #1: Type: text/plain, Size: 2473 bytes --] On Sat, Jun 1, 2019 at 12:47 PM Jeremy via bitcoin-dev < bitcoin-dev@lists.linuxfoundation.org> wrote: > Hi All, > > OP_CHECKOUTPUTSHASHVERIFY is retracted in favor of OP_SECURETHEBAG*. > OP_SECURETHEBAG does more or less the same thing, but fixes malleability > issues and lifts the single output restriction to a known number of inputs > restriction. > > OP_CHECKOUTPUTSVERIFY had some issues with malleability of version and > locktime. OP_SECURETHEBAG commits to both of these values. > Can you elaborate a bit more on what the issues were? > OP_SECURETHEBAG also lifts the restriction that OP_CHECKOUTPUTSVERIFY had > to be spent as only a single input, and instead just commits to the number > of inputs. This allows for more flexibility, but keeps it easy to get the > same single output restriction. > > BIP: > https://github.com/JeremyRubin/bips/blob/op-secure-the-bag/bip-secure-the-bag.mediawiki > Implementation: https://github.com/JeremyRubin/bitcoin/tree/secure_the_bag > > A particularly useful topic of discussion is how best to eliminate the > PUSHDATA and treat OP_SECURETHEBAG like a pushdata directly. I thought > about how the interpreter works and is implemented and couldn't come up > with something noninvasive. > I'm not a Core developer but from what I understand, I'd be inclined to to treat OP_SECURETHEBAG as with an immediate 32-byte parameter by modifying GetScriptOp to return the 32-byte parameter through pvchRet. bool GetScriptOp(CScriptBase::const_iterator& pc, CScriptBase::const_iterator end, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet) { opcodeRet = OP_INVALIDOPCODE; if (pvchRet) pvchRet->clear(); if (pc >= end) return false; // Read instruction if (end - pc < 1) return false; unsigned int opcode = *pc++; // Immediate operand if (opcode <= OP_PUSHDATA4) { // ... } if (opcode == OP_SECURETHEBAG) { if (end - pc < 0 || (unsigned int)(end - pc) < 32) return false; if (pvchRet) pvchRet->assign(pc, pc + 32); pc += 32; } opcodeRet = static_cast<opcodetype>(opcode); return true; } and go from there. Thank you for your review and discussion, > > Jeremy > > * Plus the name is better > > _______________________________________________ > bitcoin-dev mailing list > bitcoin-dev@lists.linuxfoundation.org > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev > [-- Attachment #2: Type: text/html, Size: 6318 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-06-02 14:32 ` Russell O'Connor @ 2019-06-02 21:32 ` Jeremy 0 siblings, 0 replies; 17+ messages in thread From: Jeremy @ 2019-06-02 21:32 UTC (permalink / raw) To: Russell O'Connor; +Cc: Bitcoin Protocol Discussion [-- Attachment #1: Type: text/plain, Size: 3403 bytes --] Hi Russell, Thanks for the response. I double checked my work in drafting my response and realized I didn't address all the malleability concerns, I believe I have now (fingers crossed) addressed all points of malleability. *The malleability concerns are as follows:* A TXID is computed as: def txid(self): r = b"" r += struct.pack("<i", self.nVersion) r += ser_vector(self.vin) r += ser_vector(self.vout) r += struct.pack("<I", self.nLockTime) return sha256(r) if the bag hash is just: def get_bag_hash(self): r = b"" r += ser_vector(self.vout) return TaggedHash("BagHash", r) We allow changing a few things: nVersion, nLockTime, scriptSig (per input), number of inputs, nSequence (per input) which can change the TXID/what the transaction does. changing nVersion: can disable BIP68, change TXID changing nLockTime: can change TXID changing nSequence: can change TXID changing number of inputs: half spend problem, change TXID changing scriptsigs: change TXID if co-spent with legacy input Instead, we can use the following digest: def get_bag_hash(self): r = b"" r += struct.pack("<i", self.nVersion) r += struct.pack("<I", self.nLockTime) r += sha256(b"".join(out.serialize() for out in self.vout)) r += sha256(b"".join(struct.pack("<I", inp.nSequence) for inp in self.vin)) r += struct.pack("<Q", len(self.vin)) for inp in self.vin: r += ser_string(inp.scriptSig) return TaggedHash("BagHash", r) which should lock in all the relevant bits. The only part left out is the COutpoint, which can't be known ahead of time (because it depends on the creating txn). Technically, len(vin) is redundant with sha256(b"".join(struct.pack("<I", inp.nSequence) for inp in self.vin)), because the length padding on the hash implied the number of inputs, but I figured it's best to err on explicit. A further benefit (in a CISC sense) of committing to all these values is that we enforce CLTV and CSV semantics for free on OP_SECURETHEBAG scripts, which helps with channels. *Treating OP_SECURETHEBAG as a PUSHDATA:* I agree in theory it's nicer, and am 100% open to implementing it that way. The only concern I have with doing it this way is that it means that a flags must be added to GetOp (or GetOp must be modularized to be per-script version) because it affects script parsing, as opposed to using a multibyte opcode which contains a pushdata, which remain compatible with prior script parsing. I'd like to get rough consensus on the best approach for compatibility with downstream software, hence choosing this option for the draft. Personally, my preference is to *not* do flags and just have a separate parser version which cleans up some of our past sins. We can experiment with a fancier parser (as you've shown in Haskell/Rust/Coq), perhaps even bitwise huffman encoding opcodes to save space on scripts (i.e. the 7 most common opcodes could fit within 3 bits) or whatever else we like. I just didn't want to have the scope creep too far on this particular BIP, but I'm with you that lookahead is a hack compared to an actual parametrized argument. I think you'd also appreciate the template script expansion approach mentioned in the BIP -- it gets around some of these concerns, but requires changes to Taproot. [-- Attachment #2: Type: text/html, Size: 9384 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-06-01 5:35 [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) Jeremy 2019-06-02 5:35 ` ZmnSCPxj 2019-06-02 14:32 ` Russell O'Connor @ 2019-06-05 9:30 ` Anthony Towns 2019-06-06 7:30 ` ZmnSCPxj 2 siblings, 1 reply; 17+ messages in thread From: Anthony Towns @ 2019-06-05 9:30 UTC (permalink / raw) To: Jeremy, Bitcoin Protocol Discussion On Fri, May 31, 2019 at 10:35:45PM -0700, Jeremy via bitcoin-dev wrote: > OP_CHECKOUTPUTSHASHVERIFY is retracted in favor of OP_SECURETHEBAG*. I think you could generalise that slightly and make it fit in with the existing opcode naming by calling it something like "OP_CHECKTXDIGESTVERIFY" and pull a 33-byte value from the stack, consisting of a sha256 hash and a sighash-byte, and adding a new sighash value corresponding to the set of info you want to include in the hash, which I think sounds a bit like "SIGHASH_EXACTLY_ONE_INPUT | SIGHASH_ALL" FWIW, I'm not really seeing any reason to complicate the spec to ensure the digest is precommitted as part of the opcode. Cheers, aj ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-06-05 9:30 ` Anthony Towns @ 2019-06-06 7:30 ` ZmnSCPxj 2019-06-18 20:57 ` Russell O'Connor 0 siblings, 1 reply; 17+ messages in thread From: ZmnSCPxj @ 2019-06-06 7:30 UTC (permalink / raw) To: Anthony Towns, Bitcoin Protocol Discussion Good morning aj, Sent with ProtonMail Secure Email. ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Wednesday, June 5, 2019 5:30 PM, Anthony Towns via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> wrote: > On Fri, May 31, 2019 at 10:35:45PM -0700, Jeremy via bitcoin-dev wrote: > > > OP_CHECKOUTPUTSHASHVERIFY is retracted in favor of OP_SECURETHEBAG*. > > I think you could generalise that slightly and make it fit in > with the existing opcode naming by calling it something like > "OP_CHECKTXDIGESTVERIFY" and pull a 33-byte value from the stack, > consisting of a sha256 hash and a sighash-byte, and adding a new sighash > value corresponding to the set of info you want to include in the hash, > which I think sounds a bit like "SIGHASH_EXACTLY_ONE_INPUT | SIGHASH_ALL" > > FWIW, I'm not really seeing any reason to complicate the spec to ensure > the digest is precommitted as part of the opcode. > I believe in combination with `OP_LEFT` and `OP_CAT` this allows Turing-complete smart contracts, in much the same way as `OP_CHECKSIGFROMSTACK`? Pass in the spent transaction (serialised for txid) and the spending transaction (serialised for sighash) as part of the witness of the spending transaction. Script verifies that the spending transaction witness value is indeed the spending transaction by `OP_SHA256 <SIGHASH_ALL> OP_SWAP OP_CAT OP_CHECKTXDIGESTVERIFY`. Script verifies the spent transaction witness value is indeed the spent transaction by hashing it, then splitting up the hash with `OP_LEFT` into bytes, and comparing the bytes to the bytes in the input of the spending transaction witness value (txid being the bytes in reversed order). Then the Script can extract a commitment of itself by extracting the output of the spent transaction. This lets the Script check that the spending transaction also pays to the same script. The Script can then access a state value, for example from an `OP_RETURN` output of the spent transaction, and enforce that a correct next-state is used in the spending transaction. If the state is too large to fit in a standard `OP_RETURN`, then the current state can be passed in as a witness and validated against a hash commitment in an `OP_RETURN` output. I believe this is the primary reason against not pulling data from the stack. Regards, ZmnSCPxj ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-06-06 7:30 ` ZmnSCPxj @ 2019-06-18 20:57 ` Russell O'Connor 2019-06-20 22:05 ` Anthony Towns [not found] ` <CAD5xwhj8o8Vbrk2KADBOFGfkD3fW3eMZo5aHJytGAj_5LLhYCg@mail.gmail.com> 0 siblings, 2 replies; 17+ messages in thread From: Russell O'Connor @ 2019-06-18 20:57 UTC (permalink / raw) To: ZmnSCPxj, Bitcoin Protocol Discussion [-- Attachment #1: Type: text/plain, Size: 3324 bytes --] Just to be clear, while OP_CHECKTXDIGESTVERIFY would enable this style of covenants if it pulled data from the stack, the OP_SECURETHEBAG probably cannot create covenants even if it were to pull the data from the stack unless some OP_TWEEKPUBKEY operation is added to Script because the "commitment of the script itself" isn't part of the OP_SECURETHEBAG. So with regards to OP_SECURETHEBAG, I am also "not really seeing any reason to complicate the spec to ensure the digest is precommitted as part of the opcode." On Thu, Jun 6, 2019 at 3:33 AM ZmnSCPxj via bitcoin-dev < bitcoin-dev@lists.linuxfoundation.org> wrote: > Good morning aj, > > > Sent with ProtonMail Secure Email. > > ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ > On Wednesday, June 5, 2019 5:30 PM, Anthony Towns via bitcoin-dev < > bitcoin-dev@lists.linuxfoundation.org> wrote: > > > On Fri, May 31, 2019 at 10:35:45PM -0700, Jeremy via bitcoin-dev wrote: > > > > > OP_CHECKOUTPUTSHASHVERIFY is retracted in favor of OP_SECURETHEBAG*. > > > > I think you could generalise that slightly and make it fit in > > with the existing opcode naming by calling it something like > > "OP_CHECKTXDIGESTVERIFY" and pull a 33-byte value from the stack, > > consisting of a sha256 hash and a sighash-byte, and adding a new sighash > > value corresponding to the set of info you want to include in the hash, > > which I think sounds a bit like "SIGHASH_EXACTLY_ONE_INPUT | SIGHASH_ALL" > > > > FWIW, I'm not really seeing any reason to complicate the spec to ensure > > the digest is precommitted as part of the opcode. > > > > I believe in combination with `OP_LEFT` and `OP_CAT` this allows > Turing-complete smart contracts, in much the same way as > `OP_CHECKSIGFROMSTACK`? > > Pass in the spent transaction (serialised for txid) and the spending > transaction (serialised for sighash) as part of the witness of the spending > transaction. > > Script verifies that the spending transaction witness value is indeed the > spending transaction by `OP_SHA256 <SIGHASH_ALL> OP_SWAP OP_CAT > OP_CHECKTXDIGESTVERIFY`. > Script verifies the spent transaction witness value is indeed the spent > transaction by hashing it, then splitting up the hash with `OP_LEFT` into > bytes, and comparing the bytes to the bytes in the input of the spending > transaction witness value (txid being the bytes in reversed order). > > Then the Script can extract a commitment of itself by extracting the > output of the spent transaction. > This lets the Script check that the spending transaction also pays to the > same script. > > The Script can then access a state value, for example from an `OP_RETURN` > output of the spent transaction, and enforce that a correct next-state is > used in the spending transaction. > If the state is too large to fit in a standard `OP_RETURN`, then the > current state can be passed in as a witness and validated against a hash > commitment in an `OP_RETURN` output. > > I believe this is the primary reason against not pulling data from the > stack. > > Regards, > ZmnSCPxj > _______________________________________________ > bitcoin-dev mailing list > bitcoin-dev@lists.linuxfoundation.org > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev > [-- Attachment #2: Type: text/html, Size: 4332 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-06-18 20:57 ` Russell O'Connor @ 2019-06-20 22:05 ` Anthony Towns 2019-06-23 6:43 ` Jeremy [not found] ` <CAD5xwhj8o8Vbrk2KADBOFGfkD3fW3eMZo5aHJytGAj_5LLhYCg@mail.gmail.com> 1 sibling, 1 reply; 17+ messages in thread From: Anthony Towns @ 2019-06-20 22:05 UTC (permalink / raw) To: Russell O'Connor; +Cc: Bitcoin Protocol Discussion On Tue, Jun 18, 2019 at 04:57:34PM -0400, Russell O'Connor wrote: > So with regards to OP_SECURETHEBAG, I am also "not really seeing any reason to > complicate the spec to ensure the digest is precommitted as part of the > opcode." Also, I think you can simulate OP_SECURETHEBAG with an ANYPREVOUT (NOINPUT) sighash (Johnson Lau's mentioned this before, but not sure if it's been spelled out anywhere); ie instead of constructing X = Hash_BagHash( version, locktime, [outputs], [sequences], num_in ) and having the script be "<X> OP_SECURETHEBAG" you calculate an ANYPREVOUT sighash for SIGHASH_ANYPREVOUTANYSCRIPT | SIGHASH_ALL: Y = Hash_TapSighash( 0, 0xc1, version, locktime, [outputs], 0, amount, sequence) and calculate a signature sig = Schnorr(P,m) for some pubkey P, and make your script be "<sig> <P> CHECKSIG". That loses the ability to commit to the number of inputs or restrict the nsequence of other inputs, and requires a bigger script (sig and P are ~96 bytes instead of X's 32 bytes), but is otherwise pretty much the same as far as I can tell. Both scripts are automatically satisfied when revealed (with the correct set of outputs), and don't need any additional witness data. If you wanted to construct "X" via script instead of hardcoding a value because it got you generalised covenants or whatever; I think you could get the same effect with CAT,LEFT, and RIGHT: you'd construct Y in much the same way you construct X, but you'd then need to turn that into a signature. You could do so by using pubkey P=G and nonce R=G, which means you need to calculate s=1+hash(G,G,Y)*1 -- calculating the hash part is easy, multiplying it by 1 is easy, and to add 1 you can probably do something along the lines of: OP_DUP 4 OP_RIGHT 1 OP_ADD OP_SWAP 28 OP_LEFT OP_SWAP OP_CAT (ie, take the last 4 bytes, increment it using 4-byte arithmetic, then cat the first 28 bytes and the result. There's overflow issues, but I think they can be worked around either by allowing you to choose different locktimes, or by more complicated script) Cheers, aj ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-06-20 22:05 ` Anthony Towns @ 2019-06-23 6:43 ` Jeremy 2019-07-08 10:26 ` Dmitry Petukhov 0 siblings, 1 reply; 17+ messages in thread From: Jeremy @ 2019-06-23 6:43 UTC (permalink / raw) To: Anthony Towns, Bitcoin Protocol Discussion [-- Attachment #1: Type: text/plain, Size: 2750 bytes --] This is insufficient: sequences must be committed to because they affect TXID. As with scriptsigs (witness data fine to ignore). NUM_IN too. Any malleability makes this much less useful. -- @JeremyRubin <https://twitter.com/JeremyRubin> <https://twitter.com/JeremyRubin> On Fri, Jun 21, 2019 at 10:31 AM Anthony Towns via bitcoin-dev < bitcoin-dev@lists.linuxfoundation.org> wrote: > On Tue, Jun 18, 2019 at 04:57:34PM -0400, Russell O'Connor wrote: > > So with regards to OP_SECURETHEBAG, I am also "not really seeing any > reason to > > complicate the spec to ensure the digest is precommitted as part of the > > opcode." > > Also, I think you can simulate OP_SECURETHEBAG with an ANYPREVOUT > (NOINPUT) sighash (Johnson Lau's mentioned this before, but not sure if > it's been spelled out anywhere); ie instead of constructing > > X = Hash_BagHash( version, locktime, [outputs], [sequences], num_in ) > > and having the script be "<X> OP_SECURETHEBAG" you calculate an > ANYPREVOUT sighash for SIGHASH_ANYPREVOUTANYSCRIPT | SIGHASH_ALL: > > Y = Hash_TapSighash( 0, 0xc1, version, locktime, [outputs], 0, > amount, sequence) > > and calculate a signature sig = Schnorr(P,m) for some pubkey P, and > make your script be "<sig> <P> CHECKSIG". > > That loses the ability to commit to the number of inputs or restrict > the nsequence of other inputs, and requires a bigger script (sig and P > are ~96 bytes instead of X's 32 bytes), but is otherwise pretty much the > same as far as I can tell. Both scripts are automatically satisfied when > revealed (with the correct set of outputs), and don't need any additional > witness data. > > If you wanted to construct "X" via script instead of hardcoding a value > because it got you generalised covenants or whatever; I think you could > get the same effect with CAT,LEFT, and RIGHT: you'd construct Y in much > the same way you construct X, but you'd then need to turn that into a > signature. You could do so by using pubkey P=G and nonce R=G, which > means you need to calculate s=1+hash(G,G,Y)*1 -- calculating the hash > part is easy, multiplying it by 1 is easy, and to add 1 you can probably > do something along the lines of: > > OP_DUP 4 OP_RIGHT 1 OP_ADD OP_SWAP 28 OP_LEFT OP_SWAP OP_CAT > > (ie, take the last 4 bytes, increment it using 4-byte arithmetic, > then cat the first 28 bytes and the result. There's overflow issues, > but I think they can be worked around either by allowing you to choose > different locktimes, or by more complicated script) > > Cheers, > aj > > _______________________________________________ > bitcoin-dev mailing list > bitcoin-dev@lists.linuxfoundation.org > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev > [-- Attachment #2: Type: text/html, Size: 4010 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-06-23 6:43 ` Jeremy @ 2019-07-08 10:26 ` Dmitry Petukhov 2019-10-03 23:22 ` Jeremy 0 siblings, 1 reply; 17+ messages in thread From: Dmitry Petukhov @ 2019-07-08 10:26 UTC (permalink / raw) To: bitcoin-dev If you make ANYPREVOUTANYSCRIPT signature not the only signature that controls this UTXO, but use it solely for restricting the spending conditions such as the set of outputs, and require another signature that would commit to the whole transaction, you can eliminate malleability, for the price of additional signature, of course. <control-sig> <control-P> CHECKSIG <P> CHECKSIG (CHECKMULTISIG/CHECKSIGADD might be used instead) where control-P can even be a pubkey of a key that is publicly known, and the whole purpose of control-sig would be to restrict the outputs (control-sig would be created with flags meaning ANYPREVOUTANYSCRIPT). Because control-sig does not depend on the script and on the current input, there should be no circular dependency, and it can be part of the redeem script. P would be the pubkey of the actual key that is needed to spend this UTXO, and the signature of P can commit to all the inputs and outputs, preventing malleability. I would like to add that it may make sense to just have 2 additional flags for sighash: NOPREVOUT and NOSCRIPT. NOPREVOUT would mean that previous output is not committed to, and when combined with ANYONECANPAY, this will mean ANYPREVOUT/NOINPUT: ANYONECANPAY means exclude all inputs except the current, and NOPREVOUT means exclude the current input. Thus NOPREVOUT|ANYONECANPAY = NOINPUT With NOPREVOUT|ANYONECANPAY|NOSCRIPT you would have ANYPREVOUTANYSCRIPT with NOPREVOUT|NOSCRIPT you can commit to "all the inputs beside the current one", which would allow to create a spending restriction like "this UTXO, and also one (or more) other UTXO", which might be useful to retroactively revoke or transfer the rights to spend certain UTXO without actually moving it: think 'vault' UTXO that is controlled by Alice, but requires additional 'control' UTXO to spend. Alice have keys for both 'vault' UTXO, and 'control' UTXO, but Bob have only key for 'control' UTXO. If Bob learnsthat Alice's vault UTXO key is at risk of compromize, he spends the control UTXO, and then Alice's ability to spend vault UTXO vanishes. You can use this mechanism to transfer this right to spend if you prepare a number of taproot branches with different pairs of (vault, control) keys and a chain of transactions that each spend the previous control UTXO such that the newly created UTXO becomes controlled by the control key of the next pair, together with vault key in that pair. В Sat, 22 Jun 2019 23:43:22 -0700 Jeremy via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> wrote: > This is insufficient: sequences must be committed to because they > affect TXID. As with scriptsigs (witness data fine to ignore). NUM_IN > too. > > Any malleability makes this much less useful. > -- > @JeremyRubin <https://twitter.com/JeremyRubin> > <https://twitter.com/JeremyRubin> > > > On Fri, Jun 21, 2019 at 10:31 AM Anthony Towns via bitcoin-dev < > bitcoin-dev@lists.linuxfoundation.org> wrote: > > > On Tue, Jun 18, 2019 at 04:57:34PM -0400, Russell O'Connor wrote: > > > So with regards to OP_SECURETHEBAG, I am also "not really seeing > > > any > > reason to > > > complicate the spec to ensure the digest is precommitted as part > > > of the opcode." > > > > Also, I think you can simulate OP_SECURETHEBAG with an ANYPREVOUT > > (NOINPUT) sighash (Johnson Lau's mentioned this before, but not > > sure if it's been spelled out anywhere); ie instead of constructing > > > > X = Hash_BagHash( version, locktime, [outputs], [sequences], > > num_in ) > > > > and having the script be "<X> OP_SECURETHEBAG" you calculate an > > ANYPREVOUT sighash for SIGHASH_ANYPREVOUTANYSCRIPT | SIGHASH_ALL: > > > > Y = Hash_TapSighash( 0, 0xc1, version, locktime, [outputs], 0, > > amount, sequence) > > > > and calculate a signature sig = Schnorr(P,m) for some pubkey P, and > > make your script be "<sig> <P> CHECKSIG". > > > > That loses the ability to commit to the number of inputs or restrict > > the nsequence of other inputs, and requires a bigger script (sig > > and P are ~96 bytes instead of X's 32 bytes), but is otherwise > > pretty much the same as far as I can tell. Both scripts are > > automatically satisfied when revealed (with the correct set of > > outputs), and don't need any additional witness data. > > > > If you wanted to construct "X" via script instead of hardcoding a > > value because it got you generalised covenants or whatever; I think > > you could get the same effect with CAT,LEFT, and RIGHT: you'd > > construct Y in much the same way you construct X, but you'd then > > need to turn that into a signature. You could do so by using pubkey > > P=G and nonce R=G, which means you need to calculate > > s=1+hash(G,G,Y)*1 -- calculating the hash part is easy, multiplying > > it by 1 is easy, and to add 1 you can probably do something along > > the lines of: > > > > OP_DUP 4 OP_RIGHT 1 OP_ADD OP_SWAP 28 OP_LEFT OP_SWAP OP_CAT > > > > (ie, take the last 4 bytes, increment it using 4-byte arithmetic, > > then cat the first 28 bytes and the result. There's overflow issues, > > but I think they can be worked around either by allowing you to > > choose different locktimes, or by more complicated script) > > > > Cheers, > > aj > > > > _______________________________________________ > > bitcoin-dev mailing list > > bitcoin-dev@lists.linuxfoundation.org > > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev > > ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-07-08 10:26 ` Dmitry Petukhov @ 2019-10-03 23:22 ` Jeremy 0 siblings, 0 replies; 17+ messages in thread From: Jeremy @ 2019-10-03 23:22 UTC (permalink / raw) To: Dmitry Petukhov; +Cc: Bitcoin development mailing list [-- Attachment #1: Type: text/plain, Size: 7002 bytes --] I've updated the BIP to no longer be based on Taproot, and instead based on a OP_NOP upgrade. The example implementation and tests have also been updated. BIP: https://github.com/JeremyRubin/bips/blob/op-secure-the-bag/bip-secure-the-bag.mediawiki Implementation: https://github.com/bitcoin/bitcoin/compare/master...JeremyRubin:securethebag_master The BIP defines OP_NOP4 with the same semantics as previously presented. This enables OP_SECURETHEBAG for segwit and bare script, but not p2sh (because of hash cycle, it's impossible to put the redeemscript on the scriptSig without changing the bag hash). The implementation also makes a bare OP_SECURETHEBAG script standard as that is a common use case. To address Russel's feedback, once Tapscript is fully prepared (with more thorough script parsing improvements), multibyte opcodes can be more cleanly specified. Best, Jeremy n.b. the prior BIP version remains at https://github.com/JeremyRubin/bips/blob/op-secure-the-bag-taproot/bip-secure-the-bag.mediawiki -- @JeremyRubin <https://twitter.com/JeremyRubin> <https://twitter.com/JeremyRubin> On Mon, Jul 8, 2019 at 3:25 AM Dmitry Petukhov <dp@simplexum.com> wrote: > If you make ANYPREVOUTANYSCRIPT signature not the only signature that > controls this UTXO, but use it solely for restricting the spending > conditions such as the set of outputs, and require another signature > that would commit to the whole transaction, you can eliminate > malleability, for the price of additional signature, of course. > > <control-sig> <control-P> CHECKSIG <P> CHECKSIG > > (CHECKMULTISIG/CHECKSIGADD might be used instead) > > where control-P can even be a pubkey of a key that is publicly known, > and the whole purpose of control-sig would be to restrict the outputs > (control-sig would be created with flags meaning ANYPREVOUTANYSCRIPT). > Because control-sig does not depend on the script and on the current > input, there should be no circular dependency, and it can be part of > the redeem script. > > P would be the pubkey of the actual key that is needed to spend this > UTXO, and the signature of P can commit to all the inputs and outputs, > preventing malleability. > > I would like to add that it may make sense to just have 2 additional > flags for sighash: NOPREVOUT and NOSCRIPT. > > NOPREVOUT would mean that previous output is not committed to, and when > combined with ANYONECANPAY, this will mean ANYPREVOUT/NOINPUT: > ANYONECANPAY means exclude all inputs except the current, and NOPREVOUT > means exclude the current input. Thus NOPREVOUT|ANYONECANPAY = NOINPUT > > With NOPREVOUT|ANYONECANPAY|NOSCRIPT you would have ANYPREVOUTANYSCRIPT > > with NOPREVOUT|NOSCRIPT you can commit to "all the inputs beside the > current one", which would allow to create a spending restriction like > "this UTXO, and also one (or more) other UTXO", which might be useful > to retroactively revoke or transfer the rights to spend certain UTXO > without actually moving it: > > think 'vault' UTXO that is controlled by Alice, but requires additional > 'control' UTXO to spend. Alice have keys for both 'vault' UTXO, and > 'control' UTXO, but Bob have only key for 'control' UTXO. > > If Bob learnsthat Alice's vault UTXO key is at risk of compromize, > he spends the control UTXO, and then Alice's ability to spend vault > UTXO vanishes. > > You can use this mechanism to transfer this right to spend if you > prepare a number of taproot branches with different pairs of (vault, > control) keys and a chain of transactions that each spend the previous > control UTXO such that the newly created UTXO becomes controlled by the > control key of the next pair, together with vault key in that pair. > > В Sat, 22 Jun 2019 23:43:22 -0700 > Jeremy via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> wrote: > > > This is insufficient: sequences must be committed to because they > > affect TXID. As with scriptsigs (witness data fine to ignore). NUM_IN > > too. > > > > Any malleability makes this much less useful. > > -- > > @JeremyRubin <https://twitter.com/JeremyRubin> > > <https://twitter.com/JeremyRubin> > > > > > > On Fri, Jun 21, 2019 at 10:31 AM Anthony Towns via bitcoin-dev < > > bitcoin-dev@lists.linuxfoundation.org> wrote: > > > > > On Tue, Jun 18, 2019 at 04:57:34PM -0400, Russell O'Connor wrote: > > > > So with regards to OP_SECURETHEBAG, I am also "not really seeing > > > > any > > > reason to > > > > complicate the spec to ensure the digest is precommitted as part > > > > of the opcode." > > > > > > Also, I think you can simulate OP_SECURETHEBAG with an ANYPREVOUT > > > (NOINPUT) sighash (Johnson Lau's mentioned this before, but not > > > sure if it's been spelled out anywhere); ie instead of constructing > > > > > > X = Hash_BagHash( version, locktime, [outputs], [sequences], > > > num_in ) > > > > > > and having the script be "<X> OP_SECURETHEBAG" you calculate an > > > ANYPREVOUT sighash for SIGHASH_ANYPREVOUTANYSCRIPT | SIGHASH_ALL: > > > > > > Y = Hash_TapSighash( 0, 0xc1, version, locktime, [outputs], 0, > > > amount, sequence) > > > > > > and calculate a signature sig = Schnorr(P,m) for some pubkey P, and > > > make your script be "<sig> <P> CHECKSIG". > > > > > > That loses the ability to commit to the number of inputs or restrict > > > the nsequence of other inputs, and requires a bigger script (sig > > > and P are ~96 bytes instead of X's 32 bytes), but is otherwise > > > pretty much the same as far as I can tell. Both scripts are > > > automatically satisfied when revealed (with the correct set of > > > outputs), and don't need any additional witness data. > > > > > > If you wanted to construct "X" via script instead of hardcoding a > > > value because it got you generalised covenants or whatever; I think > > > you could get the same effect with CAT,LEFT, and RIGHT: you'd > > > construct Y in much the same way you construct X, but you'd then > > > need to turn that into a signature. You could do so by using pubkey > > > P=G and nonce R=G, which means you need to calculate > > > s=1+hash(G,G,Y)*1 -- calculating the hash part is easy, multiplying > > > it by 1 is easy, and to add 1 you can probably do something along > > > the lines of: > > > > > > OP_DUP 4 OP_RIGHT 1 OP_ADD OP_SWAP 28 OP_LEFT OP_SWAP OP_CAT > > > > > > (ie, take the last 4 bytes, increment it using 4-byte arithmetic, > > > then cat the first 28 bytes and the result. There's overflow issues, > > > but I think they can be worked around either by allowing you to > > > choose different locktimes, or by more complicated script) > > > > > > Cheers, > > > aj > > > > > > _______________________________________________ > > > bitcoin-dev mailing list > > > bitcoin-dev@lists.linuxfoundation.org > > > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev > > > > > [-- Attachment #2: Type: text/html, Size: 10668 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
[parent not found: <CAD5xwhj8o8Vbrk2KADBOFGfkD3fW3eMZo5aHJytGAj_5LLhYCg@mail.gmail.com>]
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) [not found] ` <CAD5xwhj8o8Vbrk2KADBOFGfkD3fW3eMZo5aHJytGAj_5LLhYCg@mail.gmail.com> @ 2019-06-23 13:11 ` ZmnSCPxj 2019-06-24 14:34 ` Russell O'Connor 1 sibling, 0 replies; 17+ messages in thread From: ZmnSCPxj @ 2019-06-23 13:11 UTC (permalink / raw) To: Jeremy Rubin; +Cc: Bitcoin development mailing list Good morning Jeremy, While `OP_SECURETHEBAG` commits to the desired output script of the spending TX, what is being referred to here is the ability to verify the output script being spent, i.e. the script that actually contains the `OP_SECURETHEBAG`. By this, we are able to create a contract that ensures that it is paid again (covenants), which in combination with a little more introspection of TX data, allows us to verify the execution of steps of a Turing-complete program. It is surprisingly easy to make a language inadvertently Turing-complete, which is basically the argument here, That is, with just a little more power and some additional operations that would appear reasonable to add by themselves (`OP_CAT`, `OP_LEFT`, `OP_TWEAKPUBKEY`) on top of some form of requiring a particular output script, it is possible to validate the execution of Turing-complete programs on the Bitcoin blockchain. Thus, with quining (a script which gets the text of its own code as part of the static data it has), `OP_TWEAKPUBKEY`, and a `OP_SECURETHEBAG` that gets its argument from the stack, it will be possible to make Turing-complete Bitcoin SCRIPT. I would mildly suggest that we might very well want to consider creating a well-designed way of injecting Turing-completeness into Bitcoin SCRIPT (requiring it to be behind a Taproot, so that bugs in Turing-complete code at least have a chance to be bugfixed by agreement of the Taproot signing set) since we might eventually find ourselves introducing it inadvertently later in any case. Regards, ZmnSCPxj Sent with ProtonMail Secure Email. ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Sunday, June 23, 2019 6:41 AM, Jeremy Rubin <jeremy.l.rubin@gmail.com> wrote: > Can you clarify this comment? > > We do in fact commit to the script and scriptsig itself (not the witness stack) in OP_SECURETHEBAG (unless I'm missing what you meant)? > > On Thu, Jun 20, 2019, 10:59 AM Russell O'Connor via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> wrote: > > > Just to be clear, while OP_CHECKTXDIGESTVERIFY would enable this style of covenants if it pulled data from the stack, the OP_SECURETHEBAG probably cannot create covenants even if it were to pull the data from the stack unless some OP_TWEEKPUBKEY operation is added to Script because the "commitment of the script itself" isn't part of the OP_SECURETHEBAG. > > > > So with regards to OP_SECURETHEBAG, I am also "not really seeing any reason to complicate the spec to ensure the digest is precommitted as part of the opcode." > > > > On Thu, Jun 6, 2019 at 3:33 AM ZmnSCPxj via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> wrote: > > > > > Good morning aj, > > > > > > Sent with ProtonMail Secure Email. > > > > > > ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ > > > On Wednesday, June 5, 2019 5:30 PM, Anthony Towns via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> wrote: > > > > > > > On Fri, May 31, 2019 at 10:35:45PM -0700, Jeremy via bitcoin-dev wrote: > > > > > > > > > OP_CHECKOUTPUTSHASHVERIFY is retracted in favor of OP_SECURETHEBAG*. > > > > > > > > I think you could generalise that slightly and make it fit in > > > > with the existing opcode naming by calling it something like > > > > "OP_CHECKTXDIGESTVERIFY" and pull a 33-byte value from the stack, > > > > consisting of a sha256 hash and a sighash-byte, and adding a new sighash > > > > value corresponding to the set of info you want to include in the hash, > > > > which I think sounds a bit like "SIGHASH_EXACTLY_ONE_INPUT | SIGHASH_ALL" > > > > > > > > FWIW, I'm not really seeing any reason to complicate the spec to ensure > > > > the digest is precommitted as part of the opcode. > > > > > > > > > > I believe in combination with `OP_LEFT` and `OP_CAT` this allows Turing-complete smart contracts, in much the same way as `OP_CHECKSIGFROMSTACK`? > > > > > > Pass in the spent transaction (serialised for txid) and the spending transaction (serialised for sighash) as part of the witness of the spending transaction. > > > > > > Script verifies that the spending transaction witness value is indeed the spending transaction by `OP_SHA256 <SIGHASH_ALL> OP_SWAP OP_CAT OP_CHECKTXDIGESTVERIFY`. > > > Script verifies the spent transaction witness value is indeed the spent transaction by hashing it, then splitting up the hash with `OP_LEFT` into bytes, and comparing the bytes to the bytes in the input of the spending transaction witness value (txid being the bytes in reversed order). > > > > > > Then the Script can extract a commitment of itself by extracting the output of the spent transaction. > > > This lets the Script check that the spending transaction also pays to the same script. > > > > > > The Script can then access a state value, for example from an `OP_RETURN` output of the spent transaction, and enforce that a correct next-state is used in the spending transaction. > > > If the state is too large to fit in a standard `OP_RETURN`, then the current state can be passed in as a witness and validated against a hash commitment in an `OP_RETURN` output. > > > > > > I believe this is the primary reason against not pulling data from the stack. > > > > > > Regards, > > > ZmnSCPxj > > > _______________________________________________ > > > bitcoin-dev mailing list > > > bitcoin-dev@lists.linuxfoundation.org > > > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev > > > > _______________________________________________ > > bitcoin-dev mailing list > > bitcoin-dev@lists.linuxfoundation.org > > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) [not found] ` <CAD5xwhj8o8Vbrk2KADBOFGfkD3fW3eMZo5aHJytGAj_5LLhYCg@mail.gmail.com> 2019-06-23 13:11 ` ZmnSCPxj @ 2019-06-24 14:34 ` Russell O'Connor 2019-06-24 18:07 ` Jeremy 1 sibling, 1 reply; 17+ messages in thread From: Russell O'Connor @ 2019-06-24 14:34 UTC (permalink / raw) To: Jeremy Rubin; +Cc: Bitcoin development mailing list [-- Attachment #1: Type: text/plain, Size: 4607 bytes --] OP_SECURETHEBAG doesn't include the script being executed (i.e the scriptPubKey specified in the output that is redeemed by this input) in its hash like ordinary signatures do <https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L1271>. Of course, this ScriptPubKey is indirectly committed to through the input's prevoutpoint. However Script isn't able to reconstruct this script being executed from the prevoutpoint in tapscript without an implementation of public key tweeking in Bitcoin Script. On Sun, Jun 23, 2019 at 2:41 AM Jeremy Rubin <jeremy.l.rubin@gmail.com> wrote: > Can you clarify this comment? > > We do in fact commit to the script and scriptsig itself (not the witness > stack) in OP_SECURETHEBAG (unless I'm missing what you meant)? > > On Thu, Jun 20, 2019, 10:59 AM Russell O'Connor via bitcoin-dev < > bitcoin-dev@lists.linuxfoundation.org> wrote: > >> Just to be clear, while OP_CHECKTXDIGESTVERIFY would enable this style >> of covenants if it pulled data from the stack, the OP_SECURETHEBAG >> probably cannot create covenants even if it were to pull the data from the >> stack unless some OP_TWEEKPUBKEY operation is added to Script because the >> "commitment of the script itself" isn't part of the OP_SECURETHEBAG. >> >> So with regards to OP_SECURETHEBAG, I am also "not really seeing any >> reason to complicate the spec to ensure the digest is precommitted as part >> of the opcode." >> >> On Thu, Jun 6, 2019 at 3:33 AM ZmnSCPxj via bitcoin-dev < >> bitcoin-dev@lists.linuxfoundation.org> wrote: >> >>> Good morning aj, >>> >>> >>> Sent with ProtonMail Secure Email. >>> >>> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ >>> On Wednesday, June 5, 2019 5:30 PM, Anthony Towns via bitcoin-dev < >>> bitcoin-dev@lists.linuxfoundation.org> wrote: >>> >>> > On Fri, May 31, 2019 at 10:35:45PM -0700, Jeremy via bitcoin-dev wrote: >>> > >>> > > OP_CHECKOUTPUTSHASHVERIFY is retracted in favor of OP_SECURETHEBAG*. >>> > >>> > I think you could generalise that slightly and make it fit in >>> > with the existing opcode naming by calling it something like >>> > "OP_CHECKTXDIGESTVERIFY" and pull a 33-byte value from the stack, >>> > consisting of a sha256 hash and a sighash-byte, and adding a new >>> sighash >>> > value corresponding to the set of info you want to include in the hash, >>> > which I think sounds a bit like "SIGHASH_EXACTLY_ONE_INPUT | >>> SIGHASH_ALL" >>> > >>> > FWIW, I'm not really seeing any reason to complicate the spec to ensure >>> > the digest is precommitted as part of the opcode. >>> > >>> >>> I believe in combination with `OP_LEFT` and `OP_CAT` this allows >>> Turing-complete smart contracts, in much the same way as >>> `OP_CHECKSIGFROMSTACK`? >>> >>> Pass in the spent transaction (serialised for txid) and the spending >>> transaction (serialised for sighash) as part of the witness of the spending >>> transaction. >>> >>> Script verifies that the spending transaction witness value is indeed >>> the spending transaction by `OP_SHA256 <SIGHASH_ALL> OP_SWAP OP_CAT >>> OP_CHECKTXDIGESTVERIFY`. >>> Script verifies the spent transaction witness value is indeed the spent >>> transaction by hashing it, then splitting up the hash with `OP_LEFT` into >>> bytes, and comparing the bytes to the bytes in the input of the spending >>> transaction witness value (txid being the bytes in reversed order). >>> >>> Then the Script can extract a commitment of itself by extracting the >>> output of the spent transaction. >>> This lets the Script check that the spending transaction also pays to >>> the same script. >>> >>> The Script can then access a state value, for example from an >>> `OP_RETURN` output of the spent transaction, and enforce that a correct >>> next-state is used in the spending transaction. >>> If the state is too large to fit in a standard `OP_RETURN`, then the >>> current state can be passed in as a witness and validated against a hash >>> commitment in an `OP_RETURN` output. >>> >>> I believe this is the primary reason against not pulling data from the >>> stack. >>> >>> Regards, >>> ZmnSCPxj >>> _______________________________________________ >>> bitcoin-dev mailing list >>> bitcoin-dev@lists.linuxfoundation.org >>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev >>> >> _______________________________________________ >> bitcoin-dev mailing list >> bitcoin-dev@lists.linuxfoundation.org >> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev >> > [-- Attachment #2: Type: text/html, Size: 7523 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-06-24 14:34 ` Russell O'Connor @ 2019-06-24 18:07 ` Jeremy 2019-06-24 18:48 ` Russell O'Connor 0 siblings, 1 reply; 17+ messages in thread From: Jeremy @ 2019-06-24 18:07 UTC (permalink / raw) To: Russell O'Connor; +Cc: Bitcoin development mailing list [-- Attachment #1: Type: text/plain, Size: 5749 bytes --] Do you think the following hypothesis is more or less true: H: There is no set of pure extensions* to script E such that enabling E and OP_SECURETHEBAG as proposed enables recursive covenants, but E alone does not enable recursive covenants? * Of course there are things that specifically are specifically designed to switch on if OP_SECURETHEBAG, so pure means normal things like OP_CAT that are a function of the arguments on the stack or hashed txn data. This is the main draw of the design I proposed, it should be highly improbable or impossible to accidentally introduce more behavior than intended with a new opcode. I think that given that H is not true for the stack reading version of the opcode, we should avoid doing it unless strongly motivated, so as to permit more flexibility for which opcodes we can add in the future without introducing recursion unless it is explicitly intended. On Mon, Jun 24, 2019, 7:35 AM Russell O'Connor <roconnor@blockstream.io> wrote: > OP_SECURETHEBAG doesn't include the script being executed (i.e the > scriptPubKey specified in the output that is redeemed by this input) in its > hash like ordinary signatures do > <https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L1271>. > Of course, this ScriptPubKey is indirectly committed to through the input's > prevoutpoint. However Script isn't able to reconstruct this script being > executed from the prevoutpoint in tapscript without an implementation of > public key tweeking in Bitcoin Script. > > On Sun, Jun 23, 2019 at 2:41 AM Jeremy Rubin <jeremy.l.rubin@gmail.com> > wrote: > >> Can you clarify this comment? >> >> We do in fact commit to the script and scriptsig itself (not the witness >> stack) in OP_SECURETHEBAG (unless I'm missing what you meant)? >> >> On Thu, Jun 20, 2019, 10:59 AM Russell O'Connor via bitcoin-dev < >> bitcoin-dev@lists.linuxfoundation.org> wrote: >> >>> Just to be clear, while OP_CHECKTXDIGESTVERIFY would enable this style >>> of covenants if it pulled data from the stack, the OP_SECURETHEBAG >>> probably cannot create covenants even if it were to pull the data from the >>> stack unless some OP_TWEEKPUBKEY operation is added to Script because the >>> "commitment of the script itself" isn't part of the OP_SECURETHEBAG. >>> >>> So with regards to OP_SECURETHEBAG, I am also "not really seeing any >>> reason to complicate the spec to ensure the digest is precommitted as part >>> of the opcode." >>> >>> On Thu, Jun 6, 2019 at 3:33 AM ZmnSCPxj via bitcoin-dev < >>> bitcoin-dev@lists.linuxfoundation.org> wrote: >>> >>>> Good morning aj, >>>> >>>> >>>> Sent with ProtonMail Secure Email. >>>> >>>> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ >>>> On Wednesday, June 5, 2019 5:30 PM, Anthony Towns via bitcoin-dev < >>>> bitcoin-dev@lists.linuxfoundation.org> wrote: >>>> >>>> > On Fri, May 31, 2019 at 10:35:45PM -0700, Jeremy via bitcoin-dev >>>> wrote: >>>> > >>>> > > OP_CHECKOUTPUTSHASHVERIFY is retracted in favor of OP_SECURETHEBAG*. >>>> > >>>> > I think you could generalise that slightly and make it fit in >>>> > with the existing opcode naming by calling it something like >>>> > "OP_CHECKTXDIGESTVERIFY" and pull a 33-byte value from the stack, >>>> > consisting of a sha256 hash and a sighash-byte, and adding a new >>>> sighash >>>> > value corresponding to the set of info you want to include in the >>>> hash, >>>> > which I think sounds a bit like "SIGHASH_EXACTLY_ONE_INPUT | >>>> SIGHASH_ALL" >>>> > >>>> > FWIW, I'm not really seeing any reason to complicate the spec to >>>> ensure >>>> > the digest is precommitted as part of the opcode. >>>> > >>>> >>>> I believe in combination with `OP_LEFT` and `OP_CAT` this allows >>>> Turing-complete smart contracts, in much the same way as >>>> `OP_CHECKSIGFROMSTACK`? >>>> >>>> Pass in the spent transaction (serialised for txid) and the spending >>>> transaction (serialised for sighash) as part of the witness of the spending >>>> transaction. >>>> >>>> Script verifies that the spending transaction witness value is indeed >>>> the spending transaction by `OP_SHA256 <SIGHASH_ALL> OP_SWAP OP_CAT >>>> OP_CHECKTXDIGESTVERIFY`. >>>> Script verifies the spent transaction witness value is indeed the spent >>>> transaction by hashing it, then splitting up the hash with `OP_LEFT` into >>>> bytes, and comparing the bytes to the bytes in the input of the spending >>>> transaction witness value (txid being the bytes in reversed order). >>>> >>>> Then the Script can extract a commitment of itself by extracting the >>>> output of the spent transaction. >>>> This lets the Script check that the spending transaction also pays to >>>> the same script. >>>> >>>> The Script can then access a state value, for example from an >>>> `OP_RETURN` output of the spent transaction, and enforce that a correct >>>> next-state is used in the spending transaction. >>>> If the state is too large to fit in a standard `OP_RETURN`, then the >>>> current state can be passed in as a witness and validated against a hash >>>> commitment in an `OP_RETURN` output. >>>> >>>> I believe this is the primary reason against not pulling data from the >>>> stack. >>>> >>>> Regards, >>>> ZmnSCPxj >>>> _______________________________________________ >>>> bitcoin-dev mailing list >>>> bitcoin-dev@lists.linuxfoundation.org >>>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev >>>> >>> _______________________________________________ >>> bitcoin-dev mailing list >>> bitcoin-dev@lists.linuxfoundation.org >>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev >>> >> [-- Attachment #2: Type: text/html, Size: 9448 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-06-24 18:07 ` Jeremy @ 2019-06-24 18:48 ` Russell O'Connor 2019-06-24 22:47 ` Jeremy 0 siblings, 1 reply; 17+ messages in thread From: Russell O'Connor @ 2019-06-24 18:48 UTC (permalink / raw) To: Jeremy; +Cc: Bitcoin development mailing list [-- Attachment #1: Type: text/plain, Size: 3682 bytes --] I suspect that your conjecture is true. And given that it is plausible that we would want to add an opcode to tweak public keys, it seems like a reason design to avoid accidental covenants. (That said, I strongly prefer that the SECURETHEBAG data be the 32-bytes immediately following the opcode rather than a OP_PUSHDATA, and I'd be willing to help code this up (see below)). On Mon, Jun 24, 2019 at 2:07 PM Jeremy <jlrubin@mit.edu> wrote: > Do you think the following hypothesis is more or less true: > > H: There is no set of pure extensions* to script E such that enabling E > and OP_SECURETHEBAG as proposed enables recursive covenants, but E alone > does not enable recursive covenants? > > * Of course there are things that specifically are specifically designed > to switch on if OP_SECURETHEBAG, so pure means normal things like OP_CAT > that are a function of the arguments on the stack or hashed txn data. > > This is the main draw of the design I proposed, it should be highly > improbable or impossible to accidentally introduce more behavior than > intended with a new opcode. > > I think that given that H is not true for the stack reading version of the > opcode, we should avoid doing it unless strongly motivated, so as to permit > more flexibility for which opcodes we can add in the future without > introducing recursion unless it is explicitly intended. > On Sat, Jun 1, 2019 at 12:47 PM Jeremy via bitcoin-dev < bitcoin-dev@lists.linuxfoundation.org> wrote: > A particularly useful topic of discussion is how best to eliminate the > PUSHDATA and treat OP_SECURETHEBAG like a pushdata directly. I thought > about how the interpreter works and is implemented and couldn't come up > with something noninvasive. > We shouldn't be using the complexity of the changes to the Bitcoin Core a measure of the complexity of a proposal. That is looking the issue from the wrong side. If we measure the complexity of Script proposals by how hard it is to change Bitcoin Core, what will happen is more and more of the incidental details of Bitcoin Core's implementation will be pulled into the semantics of Script (e.g. the fact that surrounding opcode values are readily available in Bitcoin Core's particular implementation of its Script interpreter). Instead we should use the complexity of how hard it is to reason about the new Script semantics. The peeking semantics of OP_SECURETHEBAG is particularly awful because it more-or-less breaks the fact that Bitcoin Script can be decomposed into individual units of "opcodes" whose semantics and be individually described, and it harms the composability of Bitcoin Script where you can divide the script between any opcodes and the semantics of the concatenation of those two scripts is simply the composition of the semantics of the two halves. (For those interested in formal semantics, what we have here is a monoid homomorphism from list of opcodes (syntax) to stack transformation functions (with side-effects) under (Kleisli) composition (semantics).) Being able to decompose a Bitcoin Script this way and reasoning about components is how one would reason about Bitcoin Script in practice. (Technically the structure is more involved than a list of opcodes due to OP_IF, and instead you get a railroad diagram <https://en.wikipedia.org/wiki/Syntax_diagram>). Putting the 32 bytes of data required by OP_SECURETHEBAG immediately after the opcode, like how OP_PUSHDATA* works, is a superior design choice. It lets us treat the opcodes and its immediate data as an atomic unit when reasoning about Script and removes the need to define what happens when OP_SECURETHEBAG is not followed by an OP_PUSDATA. [-- Attachment #2: Type: text/html, Size: 4794 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-06-24 18:48 ` Russell O'Connor @ 2019-06-24 22:47 ` Jeremy 2019-06-25 17:05 ` Russell O'Connor 0 siblings, 1 reply; 17+ messages in thread From: Jeremy @ 2019-06-24 22:47 UTC (permalink / raw) To: Russell O'Connor; +Cc: Bitcoin development mailing list [-- Attachment #1: Type: text/plain, Size: 3277 bytes --] I agree in principal, but I think that's just a bit of 'how things are' versus how they should be. I disagree that we get composability semantics because of OP_IF. E.g., the script "OP_IF .... " and "OP_END" are two scripts that separately are invalid as parsed, but together are valid. OP_IF already imposes some lookahead functionality... but as I understand it, it may be feasible to get rid of OP_IF for tapscripts anyways. Also in this bucket are P2SH and segwit, which I think breaks this because the concat of two p2sh scripts or segwit scripts is not the same as them severally. I also think that the OP_SECURETHEBAG use of pushdata is a backwards compatible hack: we can always later redefine the parser to parse OP_SECURETHEBAG as the 34 byte opcode, recapturing the purity of the semantics. We can also fix it to not use an extra byte in a future tapleaf version. ==== In any case, I don't disagree with figuring out what patching the parser to handle multibyte opcodes would look like. If that sort of upgrade-path were readily available when I wrote this, it's how I would have done it. There are two approaches I looked at mostly: 1) Adding flags to GetOp to change how it parses a) Most of the same code paths used for new and old script b) Higher risk of breaking something in old script style/downstream c) Cleans up only one issue (multibyte opcodes) leaves other warts in place d) less bikesheddable design (mostly same as old script) e) code not increased in size 2) Adding a completely new interpreter for Tapscript a) Fork the existing interpreter code b) For all places where scripts are run, switch based on if it is tapscript or not c) Can clean up various semantics, can even do fancier things like huffman encode opcodes to less than a byte d) Can clearly separate parsing the script from executing it e) Can improve versioning techniques f) Low risk of breaking something in old script style/downstream g) Increases amount of code substantially h) Bikesheddable design (everything is on the table). i) probably a better general mechanism for future changes to script parsing, less consensus risk j) More compatible with templated script as well. If not clear, I think that 2 is probably a better approach, but I'm worried that 2.h means this would take a much longer time to implement. 2 can be segmented into two components: 1) the architecture of script parser versioning 2) the actual new script version I think that component 1 can be relatively non controversial, thankfully, using tapleaf versions (the architecture question is more around code structure). A proof of concept of this would be to have a fork that uses two independent, but identical, script parsers. Part two of this plan would be to modify one of the versions substantially. I'm not sure what exists on the laundry list, but I think it would be possible to pick a few worthwhile cleanups. E.g.: 1) Multibyte opcodes 2) Templated scripts 3) Huffman Encoding opcodes 4) OP_IF handling (maybe just get rid of it in favor of conditional Verify semantics) And make it clear that because we can add future script versions fairly easily, this is a sufficient step. Does that seem in line with your understanding of how this might be done? [-- Attachment #2: Type: text/html, Size: 8839 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) 2019-06-24 22:47 ` Jeremy @ 2019-06-25 17:05 ` Russell O'Connor 0 siblings, 0 replies; 17+ messages in thread From: Russell O'Connor @ 2019-06-25 17:05 UTC (permalink / raw) To: Jeremy; +Cc: Bitcoin development mailing list [-- Attachment #1: Type: text/plain, Size: 5271 bytes --] Bitcoin Core is somewhat outside my core competence, but the various OP_PUSHDATA are already multi-byte opcodes and GetOp already has a data return parameter that is suitable for returning the payload of an immediate 32-byte data variant of OP_SECURETHEBAG. All that I expect is needed is to ensure that nowhere else is using a non-empty data-field as a proxy for a non-empty push operation and fixing any such occurrences if they exist. (AFAIKT there are only a handful of calls to GetOp). It is probably worth updating the tapscript implementation to better prepare it for new uses of OP_SUCCESSx. Parsing should halt when an OP_SUCCESSx is encountered, by having GetScriptOp advance the pc to end after encountering such a code (decoding Script is no longer meaningful after an OP_SUCCESS is encountered). However, that means that GetScriptOp needs to know what version of script it is expected to be parsing. This could be done by sending down some versioning flags, possibly by adding a versioning field to CScript that can be initialized @ https://github.com/sipa/bitcoin/blob/7ddc7027b2cbdd11416809400c588e585a8b44ed/src/script/interpreter.cpp#L1679 or some other mechanism (and at the same time perhaps having GetSigOpCount return 0 for tapscript, since counting sigops is not really meaningful in tapscript). There are probably other reasonable approaches too (e.g your option 2 below). I could write some code to illustrate what I'm thinking if you feel that would be helpful and I do think such changes around OP_SUCCESS should be implemented regardless of whether we move forward with OP_SECURETHEBAG or not. It is probably worth doing this properly the first time around if we are going to do it at all. P.S. OP_RESERVED1 has been renamed to OP_SUCCESS137 in bip-tapscript. > > On Mon, Jun 24, 2019 at 6:47 PM Jeremy <jlrubin@mit.edu> wrote: > I agree in principal, but I think that's just a bit of 'how things are' > versus how they should be. > > I disagree that we get composability semantics because of OP_IF. E.g., the > script "OP_IF .... " and "OP_END" are two scripts that separately are > invalid as parsed, but together are valid. OP_IF already imposes some > lookahead functionality... but as I understand it, it may be feasible to > get rid of OP_IF for tapscripts anyways. Also in this bucket are P2SH and > segwit, which I think breaks this because the concat of two p2sh scripts or > segwit scripts is not the same as them severally. > > I also think that the OP_SECURETHEBAG use of pushdata is a backwards > compatible hack: we can always later redefine the parser to parse > OP_SECURETHEBAG as the 34 byte opcode, recapturing the purity of the > semantics. We can also fix it to not use an extra byte in a future tapleaf > version. > > In any case, I don't disagree with figuring out what patching the parser > to handle multibyte opcodes would look like. If that sort of upgrade-path > were readily available when I wrote this, it's how I would have done it. > There are two approaches I looked at mostly: > > 1) Adding flags to GetOp to change how it parses > a) Most of the same code paths used for new and old script > b) Higher risk of breaking something in old script style/downstream > c) Cleans up only one issue (multibyte opcodes) leaves other warts in > place > d) less bikesheddable design (mostly same as old script) > e) code not increased in size > 2) Adding a completely new interpreter for Tapscript > a) Fork the existing interpreter code > b) For all places where scripts are run, switch based on if it is > tapscript or not > c) Can clean up various semantics, can even do fancier things like > huffman encode opcodes to less than a byte > d) Can clearly separate parsing the script from executing it > e) Can improve versioning techniques > f) Low risk of breaking something in old script style/downstream > g) Increases amount of code substantially > h) Bikesheddable design (everything is on the table). > i) probably a better general mechanism for future changes to script > parsing, less consensus risk > j) More compatible with templated script as well. > > If not clear, I think that 2 is probably a better approach, but I'm > worried that 2.h means this would take a much longer time to implement. > > 2 can be segmented into two components: > > 1) the architecture of script parser versioning > 2) the actual new script version > > I think that component 1 can be relatively non controversial, thankfully, > using tapleaf versions (the architecture question is more around code > structure). A proof of concept of this would be to have a fork that uses > two independent, but identical, script parsers. > > Part two of this plan would be to modify one of the versions > substantially. I'm not sure what exists on the laundry list, but I think it > would be possible to pick a few worthwhile cleanups. E.g.: > > 1) Multibyte opcodes > 2) Templated scripts > 3) Huffman Encoding opcodes > 4) OP_IF handling (maybe just get rid of it in favor of conditional Verify > semantics) > > And make it clear that because we can add future script versions fairly > easily, this is a sufficient step. > > > Does that seem in line with your understanding of how this might be done? > [-- Attachment #2: Type: text/html, Size: 10622 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2019-10-03 23:23 UTC | newest] Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-06-01 5:35 [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY) Jeremy 2019-06-02 5:35 ` ZmnSCPxj 2019-06-02 14:32 ` Russell O'Connor 2019-06-02 21:32 ` Jeremy 2019-06-05 9:30 ` Anthony Towns 2019-06-06 7:30 ` ZmnSCPxj 2019-06-18 20:57 ` Russell O'Connor 2019-06-20 22:05 ` Anthony Towns 2019-06-23 6:43 ` Jeremy 2019-07-08 10:26 ` Dmitry Petukhov 2019-10-03 23:22 ` Jeremy [not found] ` <CAD5xwhj8o8Vbrk2KADBOFGfkD3fW3eMZo5aHJytGAj_5LLhYCg@mail.gmail.com> 2019-06-23 13:11 ` ZmnSCPxj 2019-06-24 14:34 ` Russell O'Connor 2019-06-24 18:07 ` Jeremy 2019-06-24 18:48 ` Russell O'Connor 2019-06-24 22:47 ` Jeremy 2019-06-25 17:05 ` Russell O'Connor
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox