1

I am trying to debug an issue where i believe i might have a bad signature but i am trying to figure out how to approach it.

  1. What is this a signature of. Private key + what (redeem script? entire raw hex?)

  2. How can i verify that this is a correct partial signature (N 2 of 3) P2SH transaction.

I have 3 signatures. I want to test each signature separately to see which are bad or good. How would one approach that? I have read through many posts here but i have not found any solutions.

1 Answer 1

1

To answer your first question:

A P2SH transaction activates a special rule in Bitcoin nodes. When a Script_Publick_Key comes with this pattern: OP_HASH_160, <HASH>, <OP_EQUAL> then the node runs the information in a different way.

First, it runs as it usually does. It puts the ScriptSig on top of the Script_Public_Key. The ScriptSig must follow this form:

OP_0
<Signature 1>
<Signature 2>
...
<Signature (m)>
<SerializedRedeemScript>

Due to Script rules of evaluation, the first item to be evaluated is going to be the <SerializedRedeemScript>. If the hash160 of this serialized script matches the hash in the Script_Publick_Key then the first round is valid and older nodes would stop here. However, BIP0016-compliant nodes will later interpret the serialized version of the redeem script (<SerializedRedeemScript>) as actual Script commands, and the process will repeat this time with the redeem_script commands and the ScriptSig but without the <SerializedRedeemScript> since it was already consumed during the first round of validation. So, let's talk about this redeem_script.

The redeem script must specify how many private keys can sign a transaction (n), how many signatures are necessary to legitimately sign a transaction (m), and all the public keys that corresponds to the private keys that can sign the transaction. The form of the redeem script is as follows:

<OP_m>
<PublicKey 1>
<PublicKey 2>
...
< PublicKey (n)>
<OP_n>
<OP_CHECKMULTISIG>

Since we have only consumed the <SerializedRedeemScript> in the first round of validation, then we still have our OP_0 and signatures left, and the final stack of commands, which is a combination of the redeem script and what is left from the ScripSig, will look like this:

OP_0
<Signature 1>
<Signature 2>
...
<Signature (m)>
<OP_m>
<PublicKey 1>
<PublicKey 2>
...
< PublicKey (n)>
<OP_n>
<OP_CHECKMULTISIG>

The first OP_0 is necessary although it has no meaning at all. It is necessary because of a bug called Off-By-One bug. This was done by accident by Satoshi Nakamoto.

The signatures and public keys will be evaluated by the <OP_CHECKMULTISIG>.

How can i verify that this is a correct partial signature (N 2 of 3) P2SH transaction.

If you want to check signature by signature, then you can try to do this by first calculating the transaction hash (z) and then checking your single signature with each one of the public keys from the redeem script through OP_CHECKSIG instead of the OP_CHECKMULTISIG. If your signature is valid for a specific public key then your signature is valid. If your signature is not valid for any of the public keys then it is not valid.

4
  • Thanks for all the information. THat is a great background on how signatures are operated. I figured out that it's part of the scriptPubKey is what is being signed. I have found some tools to figure out how to generate the signature. But i still am not sure how i can verify that signature against a public key or address ? How would i go about doing that? Commented Apr 3, 2020 at 12:52
  • You will need to calculate z which is the transaction hash. To calculate this value, you will have to take the raw transaction's hexadecimal and replace all the inputs ScriptSigs with the redeem script + SIGHASH_ALL ("01000000" in hexadecimal). After you do this, you apply a double sha256 (also called Hash256), and that's it. You have your z. With this value you can check an individual signature and evaluate it against all the public keys from the redeem script but one by one. A signature is a pair of values (r,s). The formula you will have to evaluate is: Commented Apr 3, 2020 at 17:56
  • (z/s)G + (r/s)PublicKey = RandomPoint G is a point on the cryptographic curve: x: 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 y: 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 Commented Apr 3, 2020 at 17:58
  • The x coordinate from the resulted RandomPoint must be equal to (r) from the signature. Commented Apr 3, 2020 at 18:02

Your Answer

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

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