1

I'm studying segwit and I'm doing some experiment in regtest. I create a raw transaction with P2SH address.

My Transaction data without signature is:

0200000001faf19017fe7e20747535ac41009922e4beb76e17a7fd5423bc60e75fbc8381c40000000000ffffffff01606b042a0100000017a914b63007b51b936175644dcf654f77c528e35f01178700000000

that's my message to sign, instead to use signrawtransactionwithkey I try to use signmessagewithprivkey and I expect the signature that I can find in txwitness field (first row).

signmessagewithprivkey return base64 signature then I convert it in hex. result is:

20db4febb769c43c9072daf30934a345b2327b6107e701f21c7fe052a040180d4129dc3079dc7dad29db37c31fa6401013819e386beb9396e330b3b6e9f7fbcf5b

signrawtransactionwithkey return:

"txinwitness": [
      "3044022077f49ad0371ea5baf0ce60d3d15175c9bb5e37ff7f3bc023b76863b2a91d379e022073010deba5eef8619745cd79d94a73c4a4527391253731104fc734449322d85b01",            "02985586bf43d26229a97092f76086cfe6f9bf09d93bef16a92f65185c8f7f0b17"
      ],

I wonder, why the result of signmessagewithprivkey isn't equal at first raw of txwitness?

trckster
  • 103
  • 4
monkeyUser
  • 960
  • 1
  • 7
  • 18

1 Answers1

3

From Elliptic Curve Cryptography perspective everything you sign is a "message" but the term "message" in bitcoin context means a random string that user wants to sign with his key (usually used for proof of ownership or something similar).
This means when you use sign*message*withprivkey the code interprets the input as a string and signs it with a different method that generates and entirely different digest ("some_fixed_string" + UTF8.Decode("0200000001f...")). But when you use sign*rawtransaction*withkey the code interprets the given string as a transaction and signs it based on its input scripts with different methods ("Transaction.Decode("0200000001f...") then Serialize() based on BIP143 for SegWit).

Coding Enthusiast
  • 1,418
  • 4
  • 22
  • Thanks for reply. If I understand correctly, before sign with `sign*rawtransaction*withkey` the string (transaction data) is altered by some serialization right? – monkeyUser Jan 21 '20 at 14:23
  • That is correct. You can see the details of the process in BIP143 for SegWit and [here](https://en.bitcoin.it/wiki/OP_CHECKSIG#How_it_works) for legacy transactions `OP_CheckSig`. – Coding Enthusiast Jan 21 '20 at 14:26
  • In legacy transaction if we use SIGHASH_NONE we will sign the whole transaction data (already serialized). If I Sign this transaction with method sign*message*withprivkey I didn't give the same digest. Where can I find in Github the code apply on transaction data before sign? I didn't find. – monkeyUser Jan 21 '20 at 15:23
  • 2
    You will never be able to get the same signature from `signmessagewithprivkey` because a fixed string is being added to the "message" before hashing *intentionally* to make the result different. (not sure where the code is in bitcoin core project though). – Coding Enthusiast Jan 21 '20 at 19:21
  • https://github.com/bitcoin/bitcoin/blob/af05bd9e1e362c3148e3b434b7fac96a9a5155a1/src/util/validation.cpp#L25 – monkeyUser Jan 21 '20 at 21:01
  • 1
    In addition to the difference in the input data, txn sigs are in ASN.1 DER (variable) format plus a sighash byte at the end while msg sigs are in P1363/PKCS11 (fixed) format plus a recovery byte at the beginning; see https://bitcoin.stackexchange.com/questions/90799/difference-between-sign-message-and-sign-transaction – dave_thompson_085 Jan 22 '20 at 10:43