<p><em>z</em> can be calculated more easily from the raw transaction. </p>

<p>To get <em>z</em> this way, you have to simply delete all the script signatures in the raw transaction. Then place the script_pubkey of the input you are trying to evaluate where the script_sig used to be. (in the case of a multi-signature transaction you have to replace the scriptSigs for the correspondent redeem script). </p>

<p>This has to be done for each input, so the raw transaction will contain no script_sigs at all, and only one script_pubkey (where the script_sig was for the input being evaluated).</p>

<p>Then, you have to append the type of sig_hash which is almost always SIGHASH_ALL at the end of the raw transaction. The sighash field has 4 bytes of length and SIGHASH_ALL has the code value of 1, which is represented by <code>01000000</code> in hexadecimal which is 1 in little endian. </p>

<p>After you empty all the script_sigs, and put the script_pubkey of the input being evaluated, and also append the <code>01000000</code> at the end of the raw transaction, you can procede to calculate the double SHA256 (HASH256) of the modified raw transaction. Check out <a href="https://en.bitcoin.it/wiki/OP_CHECKSIG" rel="nofollow noreferrer">https://en.bitcoin.it/wiki/OP_CHECKSIG</a>.</p>

<p>The outcome of this hash will be interpreted as a big-endian integer, and that will be your <em>z</em> for the particular input.</p>

<p>You have to repeat this for every input, so there is a different <em>z</em> for each input. </p>

<p>To evaluate your signatures (r,s), you will have to use the mathematical formula of the ECDSA which is:</p>

<p>A)  uG + vP = R.</p>

<p>B)  kG = R.</p>

<p>where:<br>
C)  u=z/s; v=r/s</p>

<p><strong>G</strong> is the originating point of the secp256k1. <a href="https://en.bitcoin.it/wiki/Secp256k1" rel="nofollow noreferrer">https://en.bitcoin.it/wiki/Secp256k1</a></p>

<p><strong>P</strong> is the point of the public key on the curve.</p>

<p><em>u</em> and <em>v</em> are integer scalars and, therefore, <em>uG</em> and <em>vP</em> are points on the curve.</p>

<p><strong>R</strong> is just another point in the curve as a result of the addition of the other 2 points <em>uG</em> and <em>vP</em> , and will be the point that will verify the signature.</p>

<p>If you already have <em>r</em> and <em>s</em> (as is implied from your question), and you already calculated <em>z</em>, then you can calculate <em>u</em> and <em>v</em> from the formulas in C. Once you get <em>u</em> and <em>v</em>, and since you have your Public key <em>P</em> and <em>G</em> is defined by the secp256k1, then you can procede to calculate R from formula A. Just remember that this addition happens on the curve which is also on a finite field.</p>

<p>Once you get <em>R</em>, you will extract the x coordinate of this point on the curve which has to be exactly the same as <em>r</em> from the signature. If they match, the signature is correct.</p>

<p>If you want some code to get <em>z</em>, here is a function from an excellent book called Programming Bitcoin by Jimmy Song :</p>

<pre><code>def sig_hash(self, input_index):
    s = int_to_little_endian(self.version, 4)
    s += encode_varint(len(self.tx_ins))
    for i, tx_in in enumerate(self.tx_ins):
        if i == input_index:
            s += TxIn(
                prev_tx=tx_in.prev_tx,
                prev_index=tx_in.prev_index,
                script_sig=tx_in.script_pubkey(self.testnet),
                sequence=tx_in.sequence,
            ).serialize()
        else:
            s += TxIn(
                prev_tx=tx_in.prev_tx,
                prev_index=tx_in.prev_index,
                sequence=tx_in.sequence,
            ).serialize()
    s += encode_varint(len(self.tx_outs))
    for tx_out in self.tx_outs:
        s += tx_out.serialize()
    s += int_to_little_endian(self.locktime, 4)
    s += int_to_little_endian(SIGHASH_ALL, 4)
    h256 = hash256(s)
    return int.from_bytes(h256, 'big')
</code></pre>

<p>However, you will have to take into account that this is just for the basic case of a P2PKH. In a P2SH transaction you will have a small variation.</p>

CC BY-SA 4.0
2020-05-06T06:29:47.383Z
2020-05-06T07:43:24.520Z
2020-05-06T07:43:24.520Z
Oscar Serna
<p>Can anyone explain me any clearly answer or code in python with examples how we can calculate Z value from r and s and inputs outputs order ?? I search in google and youtube and i not saw any correctly answer i just see scam posts or video in youtube.
I tried different methods in python and i can’t get right results. 2coin.org is closed and I want to know how to calculate manually.</p>

<p>thank you in advance</p>

<hash><signature><ecdsa>
Calculate Z from r and s
Elpanxaaa
# Calculate Z from r and s

(Asked by: username_0 on 2020-05-05)

Can anyone explain me any clearly answer or code in python with examples how we can calculate Z value from r and s and inputs outputs order ?? I search in google and youtube and i not saw any correctly answer i just see scam posts or video in youtube.
I tried different methods in python and i can’t get right results. 2coin.org is closed and I want to know how to calculate manually.

thank you in advance

**Tags:** hash, signature, ecdsa


---

## 1 answers

### Answer by username_1 on 2020-05-06. Score: 1

*z* can be calculated more easily from the raw transaction.

To get *z* this way, you have to simply delete all the script signatures in the raw transaction. Then place the script\_pubkey of the input you are trying to evaluate where the script\_sig used to be. (in the case of a multi-signature transaction you have to replace the scriptSigs for the correspondent redeem script).

This has to be done for each input, so the raw transaction will contain no script\_sigs at all, and only one script\_pubkey (where the script\_sig was for the input being evaluated).

Then, you have to append the type of sig\_hash which is almost always SIGHASH\_ALL at the end of the raw transaction. The sighash field has 4 bytes of length and SIGHASH\_ALL has the code value of 1, which is represented by `01000000` in hexadecimal which is 1 in little endian.

After you empty all the script\_sigs, and put the script\_pubkey of the input being evaluated, and also append the `01000000` at the end of the raw transaction, you can procede to calculate the double SHA256 (HASH256) of the modified raw transaction. Check out <https://en.bitcoin.it/wiki/OP_CHECKSIG>.

The outcome of this hash will be interpreted as a big-endian integer, and that will be your *z* for the particular input.

You have to repeat this for every input, so there is a different *z* for each input.

To evaluate your signatures (r,s), you will have to use the mathematical formula of the ECDSA which is:

A) uG + vP = R.

B) kG = R.

where:  
C) u=z/s; v=r/s

**G** is the originating point of the secp256k1. <https://en.bitcoin.it/wiki/Secp256k1>

**P** is the point of the public key on the curve.

*u* and *v* are integer scalars and, therefore, *uG* and *vP* are points on the curve.

**R** is just another point in the curve as a result of the addition of the other 2 points *uG* and *vP* , and will be the point that will verify the signature.

If you already have *r* and *s* (as is implied from your question), and you already calculated *z*, then you can calculate *u* and *v* from the formulas in C. Once you get *u* and *v*, and since you have your Public key *P* and *G* is defined by the secp256k1, then you can procede to calculate R from formula A. Just remember that this addition happens on the curve which is also on a finite field.

Once you get *R*, you will extract the x coordinate of this point on the curve which has to be exactly the same as *r* from the signature. If they match, the signature is correct.

If you want some code to get *z*, here is a function from an excellent book called Programming Bitcoin by Jimmy Song :

```
def sig_hash(self, input_index):
    s = int_to_little_endian(self.version, 4)
    s += encode_varint(len(self.tx_ins))
    for i, tx_in in enumerate(self.tx_ins):
        if i == input_index:
            s += TxIn(
                prev_tx=tx_in.prev_tx,
                prev_index=tx_in.prev_index,
                script_sig=tx_in.script_pubkey(self.testnet),
                sequence=tx_in.sequence,
            ).serialize()
        else:
            s += TxIn(
                prev_tx=tx_in.prev_tx,
                prev_index=tx_in.prev_index,
                sequence=tx_in.sequence,
            ).serialize()
    s += encode_varint(len(self.tx_outs))
    for tx_out in self.tx_outs:
        s += tx_out.serialize()
    s += int_to_little_endian(self.locktime, 4)
    s += int_to_little_endian(SIGHASH_ALL, 4)
    h256 = hash256(s)
    return int.from_bytes(h256, 'big')

```

However, you will have to take into account that this is just for the basic case of a P2PKH. In a P2SH transaction you will have a small variation.


---

