0

it was asked few times in BSE and they were pointing the problem to the sighash which was not appended to the transaction but i did it and still have problem. i had a problem with amount of fee and transaction which got fixed and now i get "Code: -26, Error: non-mandatory-script-verify-flag (Non-canonical DER signature)" error.

this was the previous transaction and the address i working with it is the first one.

this is my transaction data structure before signing it:

01000000
01
14
fe532eec4ddc9bfd8686a7234300c24a47c60e437ae26e966a43e47f947def
00000000
16
00140429fc6e543ff7b4b75d0c6a60013c125827aa66
ffffffff
02
a00f000000000000
16
00140429fc6e543ff7b4b75d0c6a60013c125827aa66
b80b000000000000
16
00145951ac8720b1865ba633d19eaa6473afae7c46b3
00000000
01000000

and this the transaction after signing it:

01000000
0001
01
14
fe532eec4ddc9bfd8686a7234300c24a47c60e437ae26e966a43e47f947def
00000000
00
ffffffff
02
a00f000000000000
16
00140429fc6e543ff7b4b75d0c6a60013c125827aa66
b80b000000000000
16
00145951ac8720b1865ba633d19eaa6473afae7c46b3
02
48
30
4402201be50603dbb4a163572bf98b25f7d90d663de5b439e0cb311fe4ec9ec497a4760220200c123c3af9155ce87971ce496bf415975fb63675d339329e18fe3e3eaa190d54
01 ------> SIGHASH 
21
0280a1bfa268074c9171ed0e30f332706789c5138e1428e92506e671b1997eb874
00000000

so what is the problem, even after adding the sighash i still have problem. thanks in advance.

UPDATE

after ava's anwser i tried to fix the problem, now my signed transaction is something like this but i still have same problem:

01000000
0001
01
14fe532eec4ddc9bfd8686a7234300c24a47c60e437ae26e966a43e47f947def
00000000
00
ffffffff
02
a00f000000000000
16
00140429fc6e543ff7b4b75d0c6a60013c125827aa66
b80b000000000000
16
00145951ac8720b1865ba633d19eaa6473afae7c46b3

02
47
30
44

02
20
3004f27fbf1920f0f8fb6cb477244793b6e34940be7be8d1da044ade669dfb1d

02
20
1f838de3759267f4384639d0e715978e29d294ec84ce6880cd240165178e4d25

01

21
0280a1bfa268074c9171ed0e30f332706789c5138e1428e92506e671b1997eb874
00000000

1 Answer 1

0

As the error message says, your signature is not DER encoded.

An ECDSA signature is composed of two integers, R and s. DER is a method of encoding them. DER for a signature specifies that the signature begin with the byte 0x30, followed by the length in bytes of the rest of the signature, then we have a 0x02 byte followed by R's length in bytes followed by R itself as a signed integer, and lastly we have a 0x02 byte followed by s's length in bytes, followed by s itself as a signed integer.

For Bitcoin specifically, this is then followed by a single byte to indicate the sighash type.

Let's try to decode your signature to see where it went wrong:

  • 30 - That's good, that's the prefix we expect for proper DER encoding
  • 46 - The length of the signature should be 70 bytes. This looks correct as 70 bytes later we are at the end of the signature
  • 02 - This is the correct prefix for an integer
  • 21 - This tells us the length of R, 33 bytes
  • 009b3beae48e8b1cf4224c2b608815fb67a26f5f006feed0a66ec50e17863175c4 - R itself
  • 02 - This is the correct prefix for an integer
  • 20 - This tells us the length of s, 32 bytes
  • 2029edc4dcb9d7545185c56490ae44b3fad5da1df67d5b773b1fb14a9723e68f - s itself

But we're actually not at the end of the signature, we have an extra byte of 0x05.

The question is, is one of the lengths wrong, or is the s wrong. My supposition is that the s is wrong. For the secp256k1 curve that Bitcoin uses, both R and s are 256 bit integers. This means that their maximum value is 32 bytes long. Since DER uses signed integers where it interprets the most significant bit as the signedness indicator, we can get 33 byte R and s values only when that MSB is set, and the resulting 33 bytes will always begin with a 0x00 byte. That most significant byte cannot be anything other than 0, otherwise the value would be larger than 256 bits.

Since your s begins with a 0x20 byte, it could not have actually been a 33 byte s. That would mean it's larger than 256 bits and therefore invalid. However, considering that it is 0x20 I think what could have happened is that you've accidentally duplicated the 0x20 size prefix for DER encoding.

If that is what happened, then dropping that first 0x20 from your s should fix the problem. Don't forget that doing so will change the size of your signature, so you will need to modify the DER size value as well as the size in the Bitcoin script.


Original Answer

As the error message says, your signature is not DER encoded. The length of the DER sequence is short by one byte. You have 0x44 but it should be 0x45.

However I think your signature just has an actual extra 0x20 in it prefixing the second integer, rather than your signature actually being one byte short.

3
  • thanks for anwsering, the problem you mentioned about the size 0x45 actually was caused by a bug in my code now i fixed that part, i still have the same problem and i tried to verify my signature and the result is true meaning my signature is correct and, i did not understand your second paragraph.i would happy if you answer it. thanks in advance.
    – user148205
    Feb 9 at 15:11
  • @Watchdog I've updated my answer with a detailed breakdown of what I think went wrong.
    – Ava Chow
    Feb 9 at 18:30
  • thanks for your time, you were exactly correct and it was a bug in my code. i updated the signature which seems to be correct in "Update" section of question. now i get a completely different error which is Signature must be zero for failed CHECK(MULTI)SIG operation . i think its problem with input script because i'm not sure that i picked the right script. the unsigned tx exist on top of question, the prev. tx : mempool.space/tx/…
    – user148205
    Feb 9 at 20:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.