public inbox for bitcoindev@googlegroups.com
 help / color / mirror / Atom feed
From: Jeremy <jlrubin@mit•edu>
To: "Russell O'Connor" <roconnor@blockstream•io>
Cc: Bitcoin Protocol Discussion <bitcoin-dev@lists•linuxfoundation.org>
Subject: Re: [bitcoin-dev] OP_SECURETHEBAG (supersedes OP_CHECKOUTPUTSVERIFY)
Date: Sun, 2 Jun 2019 14:32:20 -0700	[thread overview]
Message-ID: <CAD5xwhieGt3n+PrnZaqpSGM-fXUnEP_BWMtXH77KuPzSLGF79A@mail.gmail.com> (raw)
In-Reply-To: <CAMZUoKm9aZMCnJzP3YvLZ5oycDG-pss8cYZwan2N71_gc95GDg@mail.gmail.com>

[-- 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 --]

  reply	other threads:[~2019-06-02 21:32 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-01  5:35 Jeremy
2019-06-02  5:35 ` ZmnSCPxj
2019-06-02 14:32 ` Russell O'Connor
2019-06-02 21:32   ` Jeremy [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAD5xwhieGt3n+PrnZaqpSGM-fXUnEP_BWMtXH77KuPzSLGF79A@mail.gmail.com \
    --to=jlrubin@mit$(echo .)edu \
    --cc=bitcoin-dev@lists$(echo .)linuxfoundation.org \
    --cc=roconnor@blockstream$(echo .)io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox