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

  • 1
    I'm voting to close this question as off-topic because it is not about bitcoin. – Anonymous Mar 18 at 7:06
  • 1
    On the contrary, markedly on topic: bitcoin.stackexchange.com/help/on-topic – circusdei Mar 18 at 20:04
  • 1
    Could you please post the transaction here? – MCCCS Mar 19 at 14:19
  • Sure, but might be a couple hours until I can pull it together. Thanks for the response in advance. – circusdei Mar 19 at 15:07
  • @MCCCS updated. Thanks. – circusdei Mar 20 at 15:36
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

  • that is very helpful, thank you. – circusdei Mar 27 at 14:29
  • Regarding not using ECDSA (I def am), is BCH on Schnorr sigs already (ABC 19)? – circusdei Mar 27 at 14:50
  • 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 Mar 27 at 15:26
  • OK, understood. Thanks for the clarification. – circusdei Mar 27 at 15:54
  • Was finally able to get this working (unfortunately outside of the bounty limit). Thanks again! – circusdei Jul 24 at 16:49
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.

  • 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 Mar 22 at 14:38
  • 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 Mar 22 at 15:04
  • OK -- will do and return with results. Thanks for the response. – circusdei Mar 22 at 15:06
  • I have simplified the code to only data pushes, CDSV and OP_TRUE: hastebin.com/raw/retabokura (same result) I do see now that ABC expects the data before the hash. – circusdei Mar 23 at 15:45
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

  • 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: hastebin.com/raw/izefekopej. Bitcore-lib-cash continues to report that the sig is valid. – circusdei Mar 24 at 17:37
  • The signature can be valid, but not for these pubkey and message :) – amaclin Mar 25 at 6:02
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/

  • Shoot...I miss-copied the Private Key..should have been 39f8ca6c7e7c05aaf9c97e3253fd4c688730b4404d0f502441eb3aacea01b569. Corrected paste: hastebin.com/raw/imodonelic (everything else is the same and private key checks out with bitaddress). – circusdei Mar 26 at 17:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.