OP_CHECKDATASIGVERIFY not working

0

I'm trying to generate a signature and pass it through OP_CHECKDATASIGVERIFY as part of a P2SH address on a regtest network. This results in the following:

Public Key:

036ab9012ecc30c30f9220d862a56c5c99b1a08d783be605406fbde8ece2807b2f

Signature:

304402200ac548d1e8b03c7d0bdfe4aedb4b13daacf2b1c2fa265afafae5d963d66a7fa702202cdb383bb3b4b4bc88403337fb2922f5166670c8bccf246e9bd5c963de93fae2

Data Signed:

7f7f9af76890ca09afc49e458a1b23fdd2e29cc061693c4b326b16e40728091a

Clientside (bitcore-lib-cash) says the signature validates and complies with the LowS check, but when submitted to the network the signature fails:

bitcore-lib-cash 0.19.0 => The signature can be verified

Bitcoin-ABC v190100 => 16: mandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation)

Debugging via bch-deb: https://hastebin.com/gelitojuge.rb

Is there anything that looks out of the ordinary here?

UPDATE: 3/20/19 - note, this is a different, simplified full example tx

Raw TX: There are extra variables being passed in, but only a couple are currently used.

0200000001a2f391ddcecd79218bf16999986a9996d29dfd33105b2921a82c7ca801493dcf00000000fdf7034c770200000001a2f391ddcecd79218bf16999986a9996d29dfd33105b2921a82c7ca801493dcf00000000000000000002d557cd170000000017a9148bf4c913a5942cb96ee1c094cff066ec41d33b9187a2180a000000000017a914f3ce6d3eac22ecdb1df736f412f760811df60fac87000000000100000022143f8147b020f3351da2cf15f133eeb2d9da0724430076b2011479aa5d79785e79bb4cd43038303030303033414e3033303002efbfbdefbfbd70d3adefbfbdefbfbd1c414d08efbfbdefbfbd572e37efbfbdefbfbdefbfbd6cefbfbd35027550efbfbdefbfbd65efbfbdefbfbdefbfbdefbfbd1fefbfbdefbfbd4d49efbfbd5fefbfbdefbfbdefbfbd66efbfbd32efbfbdefbfbd47efbfbd0defbfbdefbfbdefbfbd36efbfbdefbfbdefbfbd49efbfbdefbfbdefbfbd4defbfbdc6be4b1c23efbfbd77efbfbdefbfbd10df92efbfbd32efbfbdefbfbdefbfbdefbfbd687e4464efbfbd3b24efbfbd0925efbfbdefbfbdefbfbd266defbfbd0831376437383430304cbb3038303030303033414e303330303fefbfbd47efbfbd20efbfbd351defbfbdefbfbd15efbfbd33efbfbdefbfbdefbfbdefbfbd0724431fefbfbdefbfbd4d49efbfbd5fefbfbdefbfbdefbfbd66efbfbd32efbfbdefbfbd47efbfbd0defbfbdefbfbdefbfbd36efbfbdefbfbdefbfbd49efbfbdefbfbdefbfbd4defbfbdc6be4b1c23efbfbd77efbfbdefbfbd10df92efbfbd32efbfbdefbfbdefbfbdefbfbd687e4464efbfbd3b24efbfbd0925efbfbdefbfbdefbfbd266defbfbd0561326332614cb73038304130413033414e30333036efbfbd521b44efbfbd0818efbfbdefbfbdefbfbdefbfbd1055efbfbd30efbfbd231975541fefbfbdefbfbd4d49efbfbd5fefbfbdefbfbdefbfbd66efbfbd32efbfbdefbfbd47efbfbd0defbfbdefbfbdefbfbd36efbfbdefbfbdefbfbd49efbfbdefbfbdefbfbd4defbfbdc6be4b1c23efbfbd77efbfbdefbfbd10df92efbfbd32efbfbdefbfbdefbfbdefbfbd687e4464efbfbd3b24efbfbd0925efbfbdefbfbdefbfbd266defbfbd0831376364353764354630440220095afd33cce778a91f78cd1e2125278bc4625eac1bde3567cc9c3a3e357c2b1c022068d61ae2d17b35f24645a4e10b66a33d319d6c7cf188233acf72195d6a63234d2103ca8a4eaca7201da793e7127737990e47d6c813db0b4aa9c729199d30f91a9a054c8c411feedf4d49945fdfeab9669032efc447ab0db6ae87369bbeca4994f9fc4dafc6be4b1c239d77ffb910df92b732858c9cc0687e44648a3b24bd0925b4a0d1266db32102a4b770d3adf69c1c414d08eed6572e37bdfe956c8d35027550b2d0659cf78c88000058535353143f8147b020f3351da2cf15f133eeb2d9da0724430076b2011479aa5d79785e79bb0000000002d557cd170000000017a9148bf4c913a5942cb96ee1c094cff066ec41d33b9187a2180a000000000017a914f3ce6d3eac22ecdb1df736f412f760811df60fac8700000000

Script ASM:

1feedf4d49945fdfeab9669032efc447ab0db6ae87369bbeca4994f9fc4dafc6be4b1c239d77ffb910df92b732858c9cc0687e44648a3b24bd0925b4a0d1266db3 02a4b770d3adf69c1c414d08eed6572e37bdfe956c8d35027550b2d0659cf78c88 0 0 8 3 3 3 3f8147b020f3351da2cf15f133eeb2d9da072443 0 OP_DUP OP_CHECKSEQUENCEVERIFY 20 OP_PICK OP_HASH256 13 OP_PICK OP_OVER 14 OP_PICK OP_CHECKDATASIGVERIFY

Input Script Hash:

bdb4b1cbd79af7137ff1771cea2c3f818bf35884962bbbea6013ec6c75b865b0

UPDATE 3/23

Simplified TX with only data pushes, OP_CDSV, and OP_true: https://hastebin.com/raw/retabokura

Update 3/29/19: My signing process: https://hastebin.com/magehodufu.js

circusdei

Posted 2019-03-18T00:07:14.510

Reputation: 69

1I'm voting to close this question as off-topic because it is not about bitcoin. – Anonymous – 2019-03-18T07:06:23.883

1

On the contrary, markedly on topic: https://bitcoin.stackexchange.com/help/on-topic

– circusdei – 2019-03-18T20:04:11.213

1Could you please post the transaction here? – MCCCS – 2019-03-19T14:19:44.537

Sure, but might be a couple hours until I can pull it together. Thanks for the response in advance. – circusdei – 2019-03-19T15:07:59.670

@MCCCS updated. Thanks. – circusdei – 2019-03-20T15:36:30.340

I think this might be caused because of the SCRIPT_ERR_CLEANSTACK, because there aren't exactly one element in the end, but I'll look at it more detailedly tomorrow. I could get rid of the error by adding LOTS of OP_DROP and an OP_1. – MCCCS – 2019-03-20T16:26:17.010

I'll clean up the stack at the end and see if there's any difference on my end...odd that it would throw a CHECKSIG error though. Thanks again. – circusdei – 2019-03-20T16:38:28.827

Here's a new TX with the added drops. Assuming that CHECKDATASIG pops three elements off, this should end up with a 1 on the stack: https://hastebin.com/raw/enohelegus (but still same result)

– circusdei – 2019-03-20T19:01:16.210

Just checking, but is it the case that your signature is missing a sighash flag at the end? – Ugam Kamat – 2019-03-23T10:30:14.293

@UgamKamat I tried adding that, but throws "Non-canonical DER signature" error – circusdei – 2019-03-23T15:42:14.137

OP_CHECKDATASIGVERIFY is correct, and your signature is wrong. It looks like you need help on fixing the signing process that you used, but you haven't included any information on your incorrect signing process. – Mark Lundeberg – 2019-03-29T01:33:01.747

@MarkLundeberg Here's my signing process: https://hastebin.com/magehodufu.js Thanks in advance.

– circusdei – 2019-03-29T16:10:25.877

Answers

1

checking from https://hastebin.com/raw/imodonelic

static void test_sig ( )
{
  const MyKey32 prv ( QByteArray::fromHex ( "39f8ca6c7e7c05aaf9c97e3253fd4c688730b4404d0f502441eb3aacea01b569" ) );
  const MyByteArray pub ( prv.getPublicKeyCompressed ( ) );
  const MyByteArray sig ( QByteArray::fromHex ( "3045022100aecf494d10f3696809972bad0546a7ea65802ebc40dd1f369185fd52eac016c902201b35692e40d6edb21c422a735f217d028da5f14447ccb31c27aec56ee26b426e" ) );
  const MyByteArray dat ( QByteArray::fromHex ( "0200000001f8f9599fc41346a68507bfbdb26b06af464d20ef709075660657b29b7bc6136c01000000000000000002d5b4eb050000000017a914064ebb4529c5cade492e1790ae1f19943e0c6bfd87d2100a000000000017a914064ebb4529c5cade492e1790ae1f19943e0c6bfd870000000001000000" ) );
  qDebug ( ) << "prv =" << prv.toHex ( ).constData ( );
  qDebug ( ) << "pub =" << pub.toHex ( ).constData ( );
  const MyKey32 digest ( dat.sha256d ( ) );
  qDebug ( ) << "hash=" << digest.toHex ( ).constData ( );
  qDebug ( ) << "your values=" << ( digest.verify ( pub, sig ) ? "passed" : "failed" );

// now create correct values

  const MyKey20 addr ( prv.getAddressHashCompressed ( ) );
  MyByteArray csig;
  MyByteArray cpub;
  prv.signHash ( addr, digest, csig, cpub );
  qDebug ( ) << "sig=" << csig.toHex ( ).constData ( );
  qDebug ( ) << "pub=" << cpub.toHex ( ).constData ( );
  qDebug ( ) << "my values=" << ( digest.verify ( cpub, csig ) ? "passed" : "failed" );
}

The output is:

prv = 39f8ca6c7e7c05aaf9c97e3253fd4c688730b4404d0f502441eb3aacea01b569
pub = 02118805dc4fc1bc36c86a606e760fcc3875e215b88306cca33cd549d3d5668339
hash= cc8fc76706ec95500d170cc01e915725e3c35979b00c27e8638b2ef3399f3ce1
your values= failed
sig= 30430220683555525c15dfc685580824d172890d16f24a996fa37ad4cd22d1a49ff61510021f60d78601ed827e0d46fe8043cbc36f054f4a9cb96c481714b8b6d21575d336
pub= 02118805dc4fc1bc36c86a606e760fcc3875e215b88306cca33cd549d3d5668339
my values= passed

Note: my code does not use dECDSA

amaclin

Posted 2019-03-18T00:07:14.510

Reputation: 6 140

Was finally able to get this working (unfortunately outside of the bounty limit). Thanks again! – circusdei – 2019-07-24T16:49:57.747

that is very helpful, thank you. – circusdei – 2019-03-27T14:29:18.543

Regarding not using ECDSA (I def am), is BCH on Schnorr sigs already (ABC 19)? – circusdei – 2019-03-27T14:50:30.357

this is ecdsa. i mean that i do not use deterministic ecdsa, so you will not be able to reproduce the same signature byte-by-byte – amaclin – 2019-03-27T15:26:24.727

OK, understood. Thanks for the clarification. – circusdei – 2019-03-27T15:54:30.883

0

static void test_sig ( )
{
  const MyByteArray pub ( QByteArray::fromHex ( "036ab9012ecc30c30f9220d862a56c5c99b1a08d783be605406fbde8ece2807b2f" ) );
  const MyByteArray sig ( QByteArray::fromHex ( "304402200ac548d1e8b03c7d0bdfe4aedb4b13daacf2b1c2fa265afafae5d963d66a7fa702202cdb383bb3b4b4bc88403337fb2922f5166670c8bccf246e9bd5c963de93fae2" ) );
  const MyKey32 hash ( MyKey32::fromHex ( "7f7f9af76890ca09afc49e458a1b23fdd2e29cc061693c4b326b16e40728091a" ) );
  qDebug ( ) << ( hash.verify ( pub, sig ) ? "passed" : "failed" );
}

The result of this code is passed

But! OP_CHECKDATASIGVERIFY needs the data itself, not a hash of it.

amaclin

Posted 2019-03-18T00:07:14.510

Reputation: 6 140

That hash of the scriptSig is what was originally signed (in order to mirror match OP_CHECKSIG's input). The scriptSig is the first value passed in, and get's hashed to match the value that was signed. Looks like it might be my ABC. – circusdei – 2019-03-22T14:38:26.660

Please, simplify your code. Remove OP_PICK, OP_OVER, OP_CSV and so on. Leave only push(signature) push(data) push(pubkey) OP_CHECKDATASIGVERIFY OP_TRUE. Note that CLEAN_STACK is mandatory rule for BCHABC – amaclin – 2019-03-22T15:04:47.923

OK -- will do and return with results. Thanks for the response. – circusdei – 2019-03-22T15:06:18.857

I have simplified the code to only data pushes, CDSV and OP_TRUE: https://hastebin.com/raw/retabokura (same result) I do see now that ABC expects the data before the hash.

– circusdei – 2019-03-23T15:45:28.327

0

static void test_sig ( )
{
  const MyByteArray pub ( QByteArray::fromHex ( "02118805dc4fc1bc36c86a606e760fcc3875e215b88306cca33cd549d3d5668339" ) );
  const MyByteArray sig ( QByteArray::fromHex ( "3045022100d06f815197d6a7af07e76ba312ab9496acb8aef3ec286098e123c26ce610e4950220547c84f3292b4f1be91ed0a0745c74c4622e3e2aa400e8f2de6d32aacbf7c591" ) );
  const MyByteArray dat ( QByteArray::fromHex ( "0200000001f8f9599fc41346a68507bfbdb26b06af464d20ef709075660657b29b7bc6136c01000000000000000002d5b4eb050000000017a914f60ae3ea9b07c104627a98f9bc03e7268f77a58d87d2100a000000000017a914f60ae3ea9b07c104627a98f9bc03e7268f77a58d870000000001000000" ) );
  const MyKey32 digest ( dat.sha256d ( ) );
  qDebug ( ) << ( digest.verify ( pub, sig ) ? "passed" : "failed" );
}

The result is failed. Your data is not valid for OP_CDSV opcode

amaclin

Posted 2019-03-18T00:07:14.510

Reputation: 6 140

Thanks for sticking with this: I'm beginning to think the issue is in how i'm generating the double-sha256. The following includes both the Data as submitted and the hash as signed: https://hastebin.com/raw/izefekopej. Bitcore-lib-cash continues to report that the sig is valid.

– circusdei – 2019-03-24T17:37:50.207

The signature can be valid, but not for these pubkey and message :) – amaclin – 2019-03-25T06:02:26.607

0

values from https://hastebin.com/raw/izefekopej

static void test_sig ( )
{
  const MyKey32 prv ( QByteArray::fromHex ( "0b08a58dd052baad2f342779271b0c8ef92273632dd630b3e1627fdac0e77963" ) );
  const MyByteArray pub ( prv.getPublicKeyCompressed ( ) );
  qDebug ( ) << pub.toHex ( ).constData ( );
}

The output is: 028b00a221a20da77938bacdd793b569728ff4974eeb6c496f30d90128ba939359 while expected is 02118805dc4fc1bc36c86a606e760fcc3875e215b88306cca33cd549d3d5668339

Your public key 02118805d... does not match your private key 0b08a58dd052...

You can easy check it on https://www.bitaddress.org/

amaclin

Posted 2019-03-18T00:07:14.510

Reputation: 6 140

Shoot...I miss-copied the Private Key..should have been 39f8ca6c7e7c05aaf9c97e3253fd4c688730b4404d0f502441eb3aacea01b569. Corrected paste: https://hastebin.com/raw/imodonelic (everything else is the same and private key checks out with bitaddress).

– circusdei – 2019-03-26T17:07:31.933