# Calculate Z from r and s

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.

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.