mandatory-script-verify-flag-failed (Non-canonical DER signature)
I am getting Non-canonical DER signature error when I try to send this transaction
{
"hash":"44f85c1446ad9808dd439f3231127ba1ab4dd833a3cfef96ceaaa60188cfa3d9",
"ver":1,
"vin_sz":1,
"vout_sz":1,
"lock_time":0,
"size":85,
"in":[
{
"prev_out":{
"hash":"d714b8cf06ffaeca3af3b94532d90391984d8469b59e33ddd1cea0d4f0046145",
"n":0
},
"scriptSig":"3043021f16ee9b194fc3b7a8a18d1b5800c2261e5526d892d97f4ddeda3415873308bd02205881370a49b3164cf37bbec5b25dfecafb060b89ec330dacb46424a8e785b611 3044022039f78cdf1be3b09c2d94b32cfea6aa98fa40b10d14dda147dc63ef2b6917b404022043b7f969b7a0a0b312c43d13d4f4dcda8d20441a5dc512112cec6c2aacf68015 1 63210246aa2141994cb42d55ac7273b0d7e9e2c7d54b9d1c1214264e18e916009fe12ead670393801cb1756821038279d8920c630baad74032aeeef5701687be55a38fb91d9962ec51bdea6702d3ac",
"sequence":0
}
],
"out":[
{
"value":"0.09900000",
"scriptPubKey":"OP_DUP OP_HASH160 66c031b0a1d237f835ce7d326be4d237fa111e68 OP_EQUALVERIFY OP_CHECKSIG"
}
]
}
}
I am trying to impelement and test CHECKLOCTIMEVERIFY(BIP 65) wit bitcoin-ruby.
# https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki#two-factor-wallets
redeem_script = "OP_IF 0246aa2141994cb42d55ac7273b0d7e9e2c7d54b9d1c1214264e18e916009fe12e OP_CHECKSIGVERIFY OP_ELSE 1867923 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_ENDIF 038279d8920c630baad74032aeeef5701687be55a38fb91d9962ec51bdea6702d3 OP_CHECKSIG"
sig_hash = unsigned_tx.signature_hash_for_input(0, redeem_script.to_payload)
service_key = Bitcoin::Key.new(OpenSSL::Digest::SHA256.digest('service-bob2').hth)
user_key = Bitcoin::Key.new(OpenSSL::Digest::SHA256.digest('user-alice2').hth)
sigs = [service_key, user_key].map { |k| k.sign(sig_hash) }
# Constructs a scriptSig for the locked contract. It has the following form:
# [sig] [sig..] [0|1] [serialized redeemScript]
# https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki#two-factor-wallets
clvt_script_sig =Bitcoin::Script.from_string("#{s1.hth} #{s2.hth} 1 #{@redeem_script.to_payload.hth}")
tx.in[0].script_sig = clvt_script_sig.to_payload
If I try to broadcast this tx, I am getting Non-canonical DER signature. I recreate same tx in bitcoinj and I saw only diffrences in key signatures.
If I sign keys with https://github.com/oleganza/btcruby/blob/master/lib/btcruby/openssl.rb#L270 ecdsa_signature method I can broadcast this tx and generated key signs are slightly diffrent.
# signs from BTC::OpenSSL.ecdsa_signature
3045022100d6ef40e321e55fd41fc56cafae503ebea2e78214de1bd9134abe9e32eba518290220065a782594030e3aec0a4a8b7d6dd7687e6d4515cd75da7f9e17c94a92c8cfbc01
304402207924540d5b301c841584d0d997102a35026d394b97783534617a7bc53a0d2f5302200cb6fecea509471383a39e2381bd9ac55e7bfa534aad9d66260ce22854a2489801
# signs from Key.sign
"304502210098507eda151d6c641edd84197d845221f926a7645b661fcf3397f4cb22a3c08a0220182ee7bcd76fa31cbfb59e5091c8533ddfa2c972664ef7d01ff5520b34b36a50"
"3045022100c817c1e7350b13de8ccfaa4fafb1b75d2cce72c905f0e30876042ca7484489df022025b57b537ed77dad893c77777c3f035d645fd4b79eb3e50140363174074d2624"
I am also seeing the occasional non-canonical DER signature from time to time. I have a check to reject non-canonical, but it may not be complete.
https://gist.github.com/inertia186/3e2949c1e5665f400a1e68c4554dfa7d
For anyone with the same issue : try to replace
sigs = [service_key, user_key].map { |k| k.sign(sig_hash) }
by
sigs = [service_key, user_key].map { |k| k.sign(sig_hash) + [Bitcoin::Script::SIGHASH_TYPE[:all]].pack("C") }
(or with any other valid SIGHASH_TYPE )