Saturday, 11 August 2018

OP_CHECKDATASIG is copying Blockstream, and is inferior to OP_DATASIGVERIFY

Hi all,

Bitcoin-ABC's implementation of Bitcoin Cash is set to hard fork on November 18th, activating a bunch of features aimed at enhencing the usability of the currency.

One of the proposed improvements is OP_CHECKDATASIG, which can be used to run a verify operation on a (signature, message hash, pubkey) triplet. By itself, this is an extremely useful opcode to have. It allows one to embed an arbitrary message to the transaction, and these messages can then be used in applications external to the chain, or as an way to allow delegated signatures on top of the script itself that is being verified. Pretty cool.

OP_CHECKDATASIG is also exceptional for a different reason. In particular, it is an almost exact line-by-line copy of a little-known, yet fairly mature opcode called OP_CHECKSIGFROMSTACK, implemented here :
https://github.com/ElementsProject/elements/commit/c35693257ca59b80659cfc4a965311f028c2d751#diff-be2905e2f5218ecdbe4e55637dac75f3R1328

For those who haven't been following, Elements is a project created by Blockstream, and elements alpha is a sidechain where experimental features can be added and tested. This commit from October 2016 shows (among other things) the addition of OP_CHECKSIGFROMSTACK to the elements alpha chain. Compared to the recent addition of OP_CHECKDATASIG to the bitcoin-abc client, the similarity is obvious :
https://reviews.bitcoinabc.org/source/bitcoin-abc/change/master/src/script/interpreter.cpp;9ba4bfca513d6386ee3d313b15bdd4584da7633d

On the other hand, consider Bitcoin Unlimited's OP_DATASIGVERIFY :
https://github.com/BitcoinUnlimited/BitcoinUnlimited/commit/1bf53307cab5d96076721ef5a238a63b03aca07d#diff-be2905e2f5218ecdbe4e55637dac75f3R970

This looks more like an independent development. It allows the same functionality as OP_CHECKDATASIG, but it does so in a way which is more transparent and also accessible for normal users.
What I mean by that is, recall the verification parameters passed to OP_CHECKDATASIG, these were (signature, message hash, pubkey). For OP_DATASIGVERIFY, the parameters are slightly different: (signature, message, pubkey hash).
The difference is subtle, but important. OP_DATASIGVERIFY follows the same design pattern as the widely known signmessage and verifymessage features that are implemented by various wallets (and in use by services like https://vote.bitcoin.com/ ). That is, a raw message is signed for and published by the user to the world, and independent verifiers are able to match the published signature and message to a specific pubkey hash - the data that makes up the user's on-chain address.
If you've ever used this message signing and verifying feature of your wallet, you probably know how useful it can be.
In contrast, OP_CHECKDATASIG verifies a message hash, not a plaintext message, against a pubkey, not a public address. This means that for a verifymessage-like operation, the script used in the transaction would become quite cumbersome:

<signature> <plaintext_message> OP_HASH256[1] <pubkey> OP_DUP OP_TOALTSTACK[2] OP_CHECKDATASIGVERIFY[3] OP_FROMALTSTACK OP_HASH160[4] <pubkey_hash> OP_EQUALVERIFY 
  1. We want to publish a plaintext message, but we have to "feed" its hash to OP_CHECKDATASIGVERIFY, so we have to use an OP_HASH256
  2. The pubkey we provide for verification will be "used up" by OP_CHECKDATASIGVERIFY, so we must both duplicate it and keep the copy in altstack
  3. OP_CHECKDATASIGVERIFY behaves exactly like OP_CHECKDATASIG, except that it fails the entire script immediately if the signature fails to verify
  4. We have the pubkey, but we still have to check that its hash matches the address, so we use OP_HASH160 and test for equality. Note that this means that we have to publis both public key /and/ its hash in the same transaction. Almost too wasteful.

Using OP_DATASIGVERIFY instead, the script is simply:

<plaintext_message> <signature> <pubkey_hash> OP_DATASIGVERIFY 

Hashing of the plaintext message is done internally by the OP_DATASIGVERIFY operation, and the same is also true for the hashing of the resulting public key against the provided pubkey hash (the data that makes up the address).
A second not-so-obvious difference is the actual content of <plaintext_message> in the two scripts.
For the OP_DATASIGVERIFY script, this message is actually parsed and verified using the exact same format as verifymessage in the wallet. This means that services like blockchain explorers can then simply decode the data in such a transaction and present it to users in a manner that enables them to run local verification of the message using their own wallet, simply by copy+pasting the information!
Using OP_CHECKDATASIG instead, the <plaintext_message> does not follow the same semantics and format as the one in verifymessage, and no wallet exists today which support such a verifying operation in the UI. It is also hard to expect something like verifydatasigmessage to be implemented on absolutely all wallets.

I think it benefits of OP_DATASIGVERIFY when measured against OP_CHECKDATASIG are obvious, and am curious to hear your opinions.

submitted by /u/moosapor
[link] [comments]

source https://www.reddit.com/r/btc/comments/96fxvy/op_checkdatasig_is_copying_blockstream_and_is/

No comments:

Post a Comment