<p>note: what Nils Schneider calls 'z',  i call 'm'.</p>
<p>this gist implements all this: <a href="https://gist.github.com/nlitsme/dda36eeef541de37d996" rel="nofollow noreferrer">https://gist.github.com/nlitsme/dda36eeef541de37d996</a></p>
<h1>the calculation</h1>
<p>ecdsa signing is done as follows:</p>
<p>given a message 'm', a sign-secret 'k', a private key 'x'</p>
<pre><code> R = G*k  (elliptic curve scalar multiplication)
 r = xcoordinate(R)
 s = (m + x * r) / k     (mod q)
</code></pre>
<p>q = the group order of secp256k1 = 2^256 - 432420386565659656852420866394968145599</p>
<p>now if we have 2 signatures with identical k, we can write this as follows:</p>
<pre><code> s1 * k = ( m1 + x * r ) (mod q)
 s2 * k = ( m2 + x * r ) (mod q)
</code></pre>
<p>substract these two equations, leading to:</p>
<pre><code>(s1-s2)*k = (m1-m2)      (mod q)
</code></pre>
<p>so the sign-secret 'k'  can now be calculated like this:</p>
<pre><code>k = (m1-m2)/(s1-s2)      (mod q)
</code></pre>
<p>and given k, the private key can be calculated like this:</p>
<pre><code>x = (s1*k-m1) / r        (mod q)
</code></pre>
<h1>practical example</h1>
<p>This example uses <a href="https://www.blockchain.com/btc/tx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1" rel="nofollow noreferrer">this</a> transaction from 2012.</p>
<h2>the original transaction</h2>
<p>the lines below represent:</p>
<ul>
<li><p>the version field</p>
</li>
<li><p>the nr of inputs (02)</p>
</li>
<li><p>the 2 inputs</p>
</li>
<li><p>the nr of outputs (01)</p>
</li>
<li><p>the output</p>
</li>
<li><p>the locktime field</p>
<pre><code>01 00 00 00
02
 f6 4c 60 3e 2f 9f 4d af 70 c2 f4 25 2b 2d cd b0 7c c0 19 2b 72 38 bc 9c 3d ac ba e5 55 ba f7 01 01 00 00 00  8a 47 30 44 02 20 d4 7c e4 c0 25 c3 5e c4 40 bc 81 d9 98 34 a6 24 87 51 61 a2 6b f5 6e f7 fd c0 f5 d5 2f 84 3a d1 02 20 44 e1 ff 2d fd 81 02 cf 7a 47 c2 1d 5c 9f d5 70 16 10 d0 49 53 c6 83 65 96 b4 fe 9d d2 f5 3e 3e 01 41 04 db d0 c6 15 32 27 9c f7 29 81 c3 58 4f c3 22 16 e0 12 76 99 63 5c 27 89 f5 49 e0 73 0c 05 9b 81 ae 13 30 16 a6 9c 21 e2 3f 18 59 a9 5f 06 d5 2b 7b f1 49 a8 f2 fe 4e 85 35 c8 a8 29 b4 49 c5 ff  ff ff ff ff
 29 f8 41 db 2b a0 ca fa 3a 2a 89 3c d1 d8 c3 e9 62 e8 67 8f c6 1e be 89 f4 15 a4 6b c8 d9 85 4a 01 00 00 00  8a 47 30 44 02 20 d4 7c e4 c0 25 c3 5e c4 40 bc 81 d9 98 34 a6 24 87 51 61 a2 6b f5 6e f7 fd c0 f5 d5 2f 84 3a d1 02 20 9a 5f 1c 75 e4 61 d7 ce b1 cf 3c ab 90 13 eb 2d c8 5b 6d 0d a8 c3 c6 e2 7e 3a 5a 5b 3f aa 5b ab 01 41 04 db d0 c6 15 32 27 9c f7 29 81 c3 58 4f c3 22 16 e0 12 76 99 63 5c 27 89 f5 49 e0 73 0c 05 9b 81 ae 13 30 16 a6 9c 21 e2 3f 18 59 a9 5f 06 d5 2b 7b f1 49 a8 f2 fe 4e 85 35 c8 a8 29 b4 49 c5 ff  ff ff ff ff
01
 a0 86 01 00 00 00 00 00 19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac
00 00 00 00
</code></pre>
</li>
</ul>
<h2>the input scripts</h2>
<p>the input script consists of:</p>
<ul>
<li><p>the total length (8a)</p>
</li>
<li><p>the signature</p>
</li>
<li><p>the public key</p>
<p>8a<br />
47  30 44 02 20 d4 7c e4 c0 25 c3 5e c4 40 bc 81 d9 98 34 a6 24 87 51 61 a2 6b f5 6e f7 fd c0 f5 d5 2f 84 3a d1 02 20 44 e1 ff 2d fd 81 02 cf 7a 47 c2 1d 5c 9f d5 70 16 10 d0 49 53 c6 83 65 96 b4 fe 9d d2 f5 3e 3e 01
41  04 db d0 c6 15 32 27 9c f7 29 81 c3 58 4f c3 22 16 e0 12 76 99 63 5c 27 89 f5 49 e0 73 0c 05 9b 81 ae 13 30 16 a6 9c 21 e2 3f 18 59 a9 5f 06 d5 2b 7b f1 49 a8 f2 fe 4e 85 35 c8 a8 29 b4 49 c5 ff</p>
</li>
</ul>
<p>the signature is an asn1 encoded r+s value + a hashtype indicator (01)</p>
<pre><code>30 44 
    02 20  d4 7c e4 c0 25 c3 5e c4 40 bc 81 d9 98 34 a6 24 87 51 61 a2 6b f5 6e f7 fd c0 f5 d5 2f 84 3a d1
    02 20  44 e1 ff 2d fd 81 02 cf 7a 47 c2 1d 5c 9f d5 70 16 10 d0 49 53 c6 83 65 96 b4 fe 9d d2 f5 3e 3e
01
</code></pre>
<p>so now we can extract these values from the transaction:</p>
<pre><code>pk 04dbd0c61532279cf72981c3584fc32216e0127699635c2789f549e0730c059b81ae133016a69c21e23f1859a95f06d52b7bf149a8f2fe4e8535c8a829b449c5ff
r  d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1
s1 44e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e
s2 9a5f1c75e461d7ceb1cf3cab9013eb2dc85b6d0da8c3c6e27e3a5a5b3faa5bab
</code></pre>
<p>next we need to calculate the message hashes.</p>
<h2>prepare</h2>
<p>Strip the input scripts, and add the hashtype</p>
<pre><code>01 00 00 00
02
 f6 4c 60 3e 2f 9f 4d af 70 c2 f4 25 2b 2d cd b0 7c c0 19 2b 72 38 bc 9c 3d ac ba e5 55 ba f7 01 01 00 00 00  00  ff ff ff ff
 29 f8 41 db 2b a0 ca fa 3a 2a 89 3c d1 d8 c3 e9 62 e8 67 8f c6 1e be 89 f4 15 a4 6b c8 d9 85 4a 01 00 00 00  00  ff ff ff ff
01
 a0 86 01 00 00 00 00 00 19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac
00 00 00 00
01 00 00 00   &lt;&lt;&lt; hashtype
</code></pre>
<h2>calculating m1</h2>
<p>replace the first input with the corresponding output script</p>
<pre><code>01 00 00 00
02
 f6 4c 60 3e 2f 9f 4d af 70 c2 f4 25 2b 2d cd b0 7c c0 19 2b 72 38 bc 9c 3d ac ba e5 55 ba f7 01 01 00 00 00  19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac  ff ff ff ff
 29 f8 41 db 2b a0 ca fa 3a 2a 89 3c d1 d8 c3 e9 62 e8 67 8f c6 1e be 89 f4 15 a4 6b c8 d9 85 4a 01 00 00 00  00  ff ff ff ff
01
 a0 86 01 00 00 00 00 00 19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac
00 00 00 00
01 00 00 00
</code></pre>
<p>then do sha256(sha256(modified transaction))</p>
<p>this will result in : c0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e</p>
<h2>calculating m2</h2>
<p>replace the second input with the corresponding output script</p>
<pre><code>01 00 00 00
02
 f6 4c 60 3e 2f 9f 4d af 70 c2 f4 25 2b 2d cd b0 7c c0 19 2b 72 38 bc 9c 3d ac ba e5 55 ba f7 01 01 00 00 00  00  ff ff ff ff
 29 f8 41 db 2b a0 ca fa 3a 2a 89 3c d1 d8 c3 e9 62 e8 67 8f c6 1e be 89 f4 15 a4 6b c8 d9 85 4a 01 00 00 00  19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac  ff ff ff ff
01
 a0 86 01 00 00 00 00 00 19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac
00 00 00 00
01 00 00 00
</code></pre>
<p>then do sha256(sha256(modified transaction))</p>
<p>this will result in : 17b0f41c8c337ac1e18c98759e83a8cccbc368dd9d89e5f03cb633c265fd0ddc</p>
<p>Note that the redeemed output scripts and the output script of this transaction are all identical in this case. That is not usually so.</p>
<p>so our message hashes are:</p>
<pre><code>m1 c0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e
m2 17b0f41c8c337ac1e18c98759e83a8cccbc368dd9d89e5f03cb633c265fd0ddc
s1 44e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e
s2 9a5f1c75e461d7ceb1cf3cab9013eb2dc85b6d0da8c3c6e27e3a5a5b3faa5bab
</code></pre>
<p>m1-m2 = 0xA931DC8C0E011326AE4D6FAB7DED290B196966154E0A73A0DF434413217B3E92<br>
s1-s2 = 0xAA82E2B8191F2B00C8788571CC8BEA41086440225A4B5CBED84D02CF638123D4</p>
<p>modulare inverse of s1-s2 = 0xf7d5417b3844fd8f4b3d909979fa7480ce094fb233d759274fd6c3aa6cf86593</p>
<p>so our secret 'k' value is:</p>
<p>-&gt; (m1-m2)/(s1-s2) = 0x7a1a7e52797fc8caaa435d2a4dace39158504bf204fbe19f14dbb427faee50ae</p>
<p>the private key can then be calculated :</p>
<p>s1*k-m1 = 0x797035d79964e4b74fbbef4460379c410261cd01de43278bc2a7efaa541dd8e9 - 0xc0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e<br>
= 0xB88D652EFF3056CEBFE1E72343C6CA67D7E3DAF5A1F76E366680D6619CDBCDBC</p>
<p>(s1*k-m1)/r = 0xc477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96</p>
<p>You can experiment with these calculations <a href="http://rawcdn.githack.com/nlitsme/bitcoinexplainer/aa50e86e8c72c04a7986f5f7c43bc2f98df94107/calculator.html#bTE9MHhjMGUyZDBhODlhMzQ4ZGU4OGZkYTA4MjExYzcwZDFkN2U1MmNjZWYyZWI5NDU5OTExYmY5NzdkNTg3Nzg0YzZlCm0yPTB4MTdiMGY0MWM4YzMzN2FjMWUxOGM5ODc1OWU4M2E4Y2NjYmMzNjhkZDlkODllNWYwM2NiNjMzYzI2NWZkMGRkYwpzMT0weDQ0ZTFmZjJkZmQ4MTAyY2Y3YTQ3YzIxZDVjOWZkNTcwMTYxMGQwNDk1M2M2ODM2NTk2YjRmZTlkZDJmNTNlM2UKczI9MHg5YTVmMWM3NWU0NjFkN2NlYjFjZjNjYWI5MDEzZWIyZGM4NWI2ZDBkYThjM2M2ZTI3ZTNhNWE1YjNmYWE1YmFiCnI9MHhkNDdjZTRjMDI1YzM1ZWM0NDBiYzgxZDk5ODM0YTYyNDg3NTE2MWEyNmJmNTZlZjdmZGMwZjVkNTJmODQzYWQxCgprPShtMS1tMikvKHMxLXMyKQoKeD0oczEqay1tMSkvcgo=" rel="nofollow noreferrer">here</a>.</p>
<h1>Explanation of Transaction Contents</h1>
<p>A transaction consists of a number of inputs, and a number of outputs.</p>
<p>An input refers to one of the outputs from another transaction, and contains a script which proofs that this transaction is allowed to redeem that output.</p>
<p>An output consists of a BTC value, and a script which will be used to validate the proof presented in the input script at the time this output will be redeemed.</p>
<p>When an output is redeemed, the input and output scripts are concatenated, and evaluated by the bitcoin client. the result must be 'TRUE'.</p>
<p>The script language is a very simple, non-turing complete, stack based language.</p>
<p>The most common script looks like this:</p>
<pre><code>---- input script ( aka scriptSig )
PUSH signature
PUSH publickey
---- output script ( aka scriptPubKey )
DUP
HASH160
PUSH pubkeyhash
EQUALVERIFY
CHECKSIG
</code></pre>
<p>Note that the 'PUSH' is not explicitly labeled as PUSH in the bitcoin script description.</p>
<p>In the output script, first it is verified that the addresshash ( which is the bitcoin address in binary format ) corresponds to the public key from the input.
Then with <code>CHECKSIG</code> it is verified that the specified signature is valid for this transaction.</p>

CC BY-SA 3.0
2014-06-15T23:50:18.037Z
Still trying to make sense of this answer, quite complex.  What is the definition of an "input" for a transaction?  That the number of addresses being sent from?  And whats the def of an "output"?  Number of addresses being sent to?  Perhaps I should ask something similar.  What info do I need, and how would I use it to simply submit my own transaction to the network?  Private Key point multiplied to itself K times, public key and ....the hash.  I think my main difficulty is "m" or the "message" the whole "output" "input" and "script" are throwing me off
Mine
CC BY-SA 3.0
2014-06-17T00:10:55.847Z
Now of the equations you showed, which items are already shown on http://blockexplorer.com/rawtx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1 and or https://blockchain.info/tx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1 ? Meaning, lets say I have K and want to solve for x (private key) as simply as possible, what variables for your original equations are already shown to me? (I know this might seem to have been answered in your post already but I'm confused on some parts of it because I've heard so many definitions for so many of these things). –
Mine
CC BY-SA 3.0
2014-06-17T07:06:46.023Z
the public key, 'r' and 's' value can directly be obtained from the input script ( scriptSig ).  the 'm' value needs to be calculated.  the 'q' and 'G' are constants specified by the secp256k1 curve used in bitcoin
Willem Hengeveld
CC BY-SA 3.0
2014-11-19T02:43:39.357Z
I'm trying this again.  I copied and pasted the contents of the code window below "calculating m1 - replace the first input with the corresponding output script" and put it into a sha 256d algorithm calculator, then took that result and hashed it too, per the instructions, the results did not coincide with the correct results
Mine
CC BY-SA 3.0
2014-12-12T06:04:55.337Z
modulare inverse of s1-s2? doesn't mod has 2 operands?
lontivero
CC BY-SA 3.0
2014-12-12T08:00:08.313Z
All calculations are modulo q
Willem Hengeveld
CC BY-SA 3.0
2014-12-12T15:34:35.703Z
I'm blocked in the invmod step. This is what I get: http://prntscr.com/5fzzys. What am I doing wrong? I cannot get modulare inverse of s1-s2 = 0xf7d5417b3844fd8f4b3d909979fa7480ce094fb233d759274fd6c3aa6cf86593
lontivero
CC BY-SA 3.0
2014-12-12T20:24:23.390Z
the value in your screenshot of s1-s2 is already wrong,  maybe check your inputs.  here is working code: http://ideone.com/bjSai7
Willem Hengeveld
CC BY-SA 3.0
2014-12-14T21:06:40.597Z
.NET bigint class is a bit tricky but I did it with your help! Thank you @WillemHengeveld
lontivero
CC BY-SA 3.0
2014-12-15T04:01:15.570Z
@WillemHengeveld what if there are more than just one output? How do i calculate the M values? I mean, what should I change in the section *Calculating m1*??
lontivero
CC BY-SA 3.0
2014-12-15T06:43:45.390Z
More outputs of what?
Willem Hengeveld
CC BY-SA 3.0
2014-12-15T22:26:41.173Z
In your practical example the transaction has 2 inputs and 1 output but the tx can have _n_ outputs. Am I misunderstanding something?
lontivero
CC BY-SA 3.0
2014-12-15T22:41:55.053Z
the signature is in the input script, and uses the output script of it's source transaction when calculating the message hash. So the nr of outputs to the transaction does not matter, they are always hashed unmodified into the messagehash for each input.
Willem Hengeveld
CC BY-SA 4.0
2022-04-21T01:56:33.290Z
2xoin.com is gone now too, which is unfortunate. But thank you for the detailed description of your calculations and not just the links.
ambitiousdonut
CC BY-SA 4.0
2014-06-07T23:59:48.130Z
2022-05-10T14:49:39.240Z
2022-05-10T14:49:39.240Z
Willem Hengeveld
<blockquote>
  <p>We just need to find z1 and z2! These are the hashes of the outputs to be signed. Let’s fetch the output transations and calculate them (it is calculated by OP_CHECKSIG):</p>
</blockquote>

<p>The Bitcoin wiki's page on <a href="https://en.bitcoin.it/wiki/OP_CHECKSIG" rel="nofollow">OP_CHECKSIG</a> and the <a href="https://en.bitcoin.it/w/images/en/7/70/Bitcoin_OpCheckSig_InDetail.png" rel="nofollow">picture</a> there show what is signed: essentially, the new transaction with the txin's removed and the transaction output inserted. It's the hash of these bytes that is actually signed, which are <code>z1</code> and <code>z2</code>.</p>

<p>This pseudocode might help clarify how the <code>z</code>s are used:</p>

<pre><code>def sign(priv_key, txin_index):
    z = get_data_to_sign(txin_index) # uses algorithm at https://en.bitcoin.it/w/images/en/7/70/Bitcoin_OpCheckSig_InDetail.png
    r = super_secure_random()
    s = ECDSA_sign(priv_key, z, r)
    return r, s

def verify(pub_key, txin_index, r, s):
    z = get_data_to_sign(txin_index)
    ECDSA_verify(pub_key, z, r, s)

def super_secure_random():
    return 4
</code></pre>

CC BY-SA 3.0
2014-06-07T13:35:18.227Z
2014-06-07T13:46:20.243Z
2014-06-07T13:46:20.243Z
Tim S.
<p>Calculating the Z values is quite complicated for the average Joe, so i've made a website to do it for you.</p>
<hr />
<p>The Z values for the above example can be found on this page.</p>
<p><a href="https://2xoin.com/tx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1" rel="nofollow noreferrer">https://2xoin.com/tx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1</a></p>
<p>I've also separated the R and S values to make it easier for you.</p>
<p>You can find the R, S, and Z values for all bitcoin transactions on this site.</p>
<p>Other examples,</p>
<p><a href="https://2xoin.com/tx/9312ccafb8aa624afe7fb7b4201a0ccc2a14ca2b8b8a3253093b975a6a85a280" rel="nofollow noreferrer">https://2xoin.com/tx/9312ccafb8aa624afe7fb7b4201a0ccc2a14ca2b8b8a3253093b975a6a85a280</a></p>
<p><a href="https://2xoin.com/tx/a963c57ba8a384bf708d5cf83c932e9174ebd0f82f3820e25dcc8a3d508aed54" rel="nofollow noreferrer">https://2xoin.com/tx/a963c57ba8a384bf708d5cf83c932e9174ebd0f82f3820e25dcc8a3d508aed54</a></p>
<p><a href="https://2xoin.com/tx/19d66411a5aa716a04b37197c11c93c9446a54694a2d2302093d8b0a93ed5d83" rel="nofollow noreferrer">https://2xoin.com/tx/19d66411a5aa716a04b37197c11c93c9446a54694a2d2302093d8b0a93ed5d83</a></p>
<p><a href="https://2xoin.com/tx/9778355a53f295a4ffd592af170badda4e9ad3153e15a4afd76655dac387abb2" rel="nofollow noreferrer">https://2xoin.com/tx/9778355a53f295a4ffd592af170badda4e9ad3153e15a4afd76655dac387abb2</a></p>
<p>The response returns the standard JSON response that you find in the bitcoin core client, plus some extra bits I added that show the R,S and Z values for each transaction input.</p>
<p>eg, see SizR, SigS and SigZ nodes below.</p>
<pre><code>{
  &quot;rawtx&quot;: &quot;01000000028370ef64eb83519fd14f9d74826059b4ce00eae33b5473629486076c5b3bf215000000008c4930460221009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9022100c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6cffffffffb0385cd9a933545628469aa1b7c151b85cc4a087760a300e855af079eacd25c5000000008b48304502210094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45022007eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6cffffffff01404b4c00000000001976a91402d8103ac969fe0b92ba04ca8007e729684031b088ac00000000&quot;
}
{
  &quot;txid&quot;: &quot;82e5e1689ee396c8416b94c86aed9f4fe793a0fa2fa729df4a8312a287bc2d5e&quot;,
  &quot;version&quot;: 1,
  &quot;locktime&quot;: 0,
  &quot;vin&quot;: [
    {
      &quot;txid&quot;: &quot;15f23b5b6c0786946273543be3ea00ceb4596082749d4fd19f5183eb64ef7083&quot;,
      &quot;vout&quot;: 0,
      &quot;scriptSig&quot;: {
        &quot;asm&quot;: &quot;30460221009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9022100c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622[ALL] 04e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c&quot;,
        &quot;hex&quot;: &quot;4930460221009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9022100c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c&quot;
      },
      &quot;sequence&quot;: 4294967295,
      &quot;n&quot;: 0,
      &quot;addr&quot;: &quot;1KtjBE8yDxoqNTSyLG2re4qtKK19KpvVLT&quot;,
      &quot;valueSat&quot;: 2500000,
      &quot;value&quot;: 0.025,
      &quot;doubleSpentTxID&quot;: null,
      &quot;sigR&quot;: &quot;009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9&quot;,
      &quot;sigS&quot;: &quot;00c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622&quot;,
      &quot;sigZ&quot;: &quot;9f4503ab6cae01b9fc124e40de9f3ec3cb7a794129aa3a5c2dfec3809f04c354&quot;
    },
    {
      &quot;txid&quot;: &quot;c525cdea79f05a850e300a7687a0c45cb851c1b7a19a4628565433a9d95c38b0&quot;,
      &quot;vout&quot;: 0,
      &quot;scriptSig&quot;: {
        &quot;asm&quot;: &quot;304502210094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45022007eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb[ALL] 04e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c&quot;,
        &quot;hex&quot;: &quot;48304502210094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45022007eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c&quot;
      },
      &quot;sequence&quot;: 4294967295,
      &quot;n&quot;: 1,
      &quot;addr&quot;: &quot;1KtjBE8yDxoqNTSyLG2re4qtKK19KpvVLT&quot;,
      &quot;valueSat&quot;: 2500000,
      &quot;value&quot;: 0.025,
      &quot;doubleSpentTxID&quot;: null,
      &quot;sigR&quot;: &quot;0094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45&quot;,
      &quot;sigS&quot;: &quot;07eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb&quot;,
      &quot;sigZ&quot;: &quot;94bbf25ba5b93ba78ee017eff80c986ee4e87804bee5770fae5b486f05608d95&quot;
    }
  ],
  &quot;vout&quot;: [
    {
      &quot;value&quot;: &quot;0.05000000&quot;,
      &quot;n&quot;: 0,
      &quot;scriptPubKey&quot;: {
        &quot;hex&quot;: &quot;76a91402d8103ac969fe0b92ba04ca8007e729684031b088ac&quot;,
        &quot;asm&quot;: &quot;OP_DUP OP_HASH160 02d8103ac969fe0b92ba04ca8007e729684031b0 OP_EQUALVERIFY OP_CHECKSIG&quot;,
        &quot;addresses&quot;: [
          &quot;1G3BjSLWsWH6tbPYs29fYMYaz9k8EStQM&quot;
        ],
        &quot;type&quot;: &quot;pubkeyhash&quot;
      },
      &quot;spentTxId&quot;: &quot;9778355a53f295a4ffd592af170badda4e9ad3153e15a4afd76655dac387abb2&quot;,
      &quot;spentIndex&quot;: 0,
      &quot;spentHeight&quot;: 175915
    }
  ],
  &quot;blockhash&quot;: &quot;00000000000006467ae1708979d38dcb6d6fcafbab4c6eccf7414da950379243&quot;,
  &quot;blockheight&quot;: 175915,
  &quot;confirmations&quot;: 309447,
  &quot;time&quot;: 1334602008,
  &quot;blocktime&quot;: 1334602008,
  &quot;valueOut&quot;: 0.05,
  &quot;size&quot;: 405,
  &quot;valueIn&quot;: 0.05,
  &quot;fees&quot;: 0
}
</code></pre>
<hr />
<p>When I was researching all of the information on this thread, I created some little helper equations that I used heavily while experimenting.</p>
<p>K = ((Z + (X * R)) / S) % N</p>
<p>X = (((S * K) - Z) / R) % N</p>
<p>Z = ((S * K) - (X * R)) % N</p>
<p>S = ((Z + (X * R)) / K) % N</p>
<p>R = (((S * K) - Z) / X) % N</p>
<p>In my equations above,</p>
<p>X is the private key hex,</p>
<p>K multiplied by the sep256k1 G value produces an ECPoint whos x value = R</p>
<p>So from R, you can verify you have the correct K value,
and if you have the correct K value, then you can get the correct X value, which is the hex of the private key of the address in the transaction input.</p>
<p>And here is some sample C# code.</p>
<pre>
using System;
using System.Linq;
using Org.BouncyCastle.Math;

namespace SeansECDSAtest
{
    class Program
    {
        static void Main(string[] args)
        {
            BigInteger R = new BigInteger(StringToByteArray("00d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1"));
            BigInteger S = new BigInteger(StringToByteArray("0044e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e"));
            BigInteger Z = new BigInteger(StringToByteArray("00c0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e"));
            BigInteger X = new BigInteger(StringToByteArray("00c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96"));
            BigInteger K = new BigInteger(StringToByteArray("007a1a7e52797fc8caaa435d2a4dace39158504bf204fbe19f14dbb427faee50ae"));
            BigInteger N = new BigInteger(StringToByteArray("00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"));

            //proving R = (((S * K) - Z) / X) % N
            var verifyR = S.Multiply(K).Subtract(Z).Multiply(X.ModInverse(N)).Mod(N);
            Console.WriteLine("R = " + string.Concat(verifyR.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            //proving S = ((Z + (X * R)) / K) % N
            var verifyS = Z.Add(X.Multiply(R)).Multiply(K.ModInverse(N)).Mod(N);
            Console.WriteLine("S = " + string.Concat(verifyS.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            //proving Z = ((S * K) - (X * R)) % N
            var verifyZ = S.Multiply(K).Subtract(X.Multiply(R)).Mod(N);
            Console.WriteLine("Z = " + string.Concat(verifyZ.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            //proving X = (((S * K) - Z) / R) % N
            var verifyX = S.Multiply(K).Subtract(Z).Multiply(R.ModInverse(N)).Mod(N);
            Console.WriteLine("X = " + string.Concat(verifyX.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            //proving K = ((Z + (X * R)) / S) % N
            var verifyK = Z.Add(X.Multiply(R)).Multiply(S.ModInverse(N)).Mod(N);
            Console.WriteLine("K = " + string.Concat(verifyK.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            Console.ReadLine();
        }

        public static byte[] StringToByteArray(string hex)
        {
            return Enumerable.Range(0, hex.Length)
                             .Where(x => x % 2 == 0)
                             .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                             .ToArray();
        }
    }
}

</pre>
<p>And the same code in python</p>
<pre><code>def extended_gcd(aa, bb):
    lastremainder, remainder = abs(aa), abs(bb)
    x, lastx, y, lasty = 0, 1, 1, 0
    while remainder:
        lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder)
        x, lastx = lastx - quotient*x, x
        y, lasty = lasty - quotient*y, y
    return lastremainder, lastx * (-1 if aa &lt; 0 else 1), lasty * (-1 if bb &lt; 0 else 1)

def modinv(a, m):
    g, x, y = extended_gcd(a, m)
    if g != 1:
        raise ValueError
    return x % m

R = 0x00d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1
S = 0x0044e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e
Z = 0x00c0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e
X = 0x00c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96
K = 0x007a1a7e52797fc8caaa435d2a4dace39158504bf204fbe19f14dbb427faee50ae

N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

#proving R = (((S * K) - Z) / X) % N
print hex((((S * K) - Z) * modinv(X,N)) % N)

#proving S = ((Z + (X * R)) / K) % N
print hex(((Z + (X * R)) * modinv(K,N)) % N)

#proving Z = ((S * K) - (X * R)) % N
print hex(((S * K) - (X * R)) % N)

#proving X = (((S * K) - Z) / R) % N
print hex((((S * K) - Z) * modinv(R,N)) % N)

#proving K = ((Z + (X * R)) / S) % N
print hex(((Z + (X * R)) * modinv(S,N)) % N)
</code></pre>

CC BY-SA 3.0
2014-11-19T02:48:16.300Z
Thank you, but all I seek is making sense of how to get Z, the hash.  The rest of the algorithm I get.  I just don't understand how to get "Z".  That's it.  Problem is, most answers are exceedingly complex.  I'd be very happy if there was just something I had to copy from the transaction page of a given transaction and paste into some website, click a button, and, BAM, Z value.  In fact, at this time, I'd actually prefer the latter.
Mine
CC BY-SA 3.0
2014-11-22T21:16:54.500Z
Visit 2coin.org. It shows the Z values that you can copy and paste. 
eg.
http://2coin.org/txInfo.aspx?txid=c687eb88fdc883892cbd3982495714072b5662c78f6d71bc1c5ae44630045800
In the 'inputs' section, it separates the R, S, Z and Public key values.
If you think an API might be useful for you, I could put one together pretty quickly.
Sean Bradley
CC BY-SA 3.0
2014-11-23T09:35:58.037Z
I have created an API to easily get the Z values from transactions. I've added the details to my original post above.
Sean Bradley
CC BY-SA 3.0
2014-12-12T16:27:15.757Z
@SeanBradley take a look at my comment in the Willem's answer. Could you help me, please? I cannot get the invmod (s1-s2), it is not  0xf7d5417b3844fd8f4b3d909979fa7480ce094fb233d759274fd6c3aa6cf86593 in my case.
lontivero
CC BY-SA 3.0
2014-12-12T18:19:36.960Z
@SeanBradley your result: 0xb440675bdc7cd712ea08fc875df4a8e9f50991650625f25a3a474b6bd6cdb89eL
my result: 0x4188f2f2de07b663f48dd0fc2f0d00953fa26c5cb977d374f2a2beac7d459498L
Willem's result: 0xf7d5417b3844fd8f4b3d909979fa7480ce094fb233d759274fd6c3aa6cf86593L. I don't understand. Thank you
lontivero
CC BY-SA 3.0
2014-12-12T20:31:19.403Z
@lontivero, see my demo at http://ideone.com/o624rX
Sean Bradley
CC BY-SA 3.0
2014-12-12T23:37:40.083Z
@lontivero, when i put code in these comments, it never works, so i've created a print screen. This gives me the correct result.
http://prntscr.com/5g67tf
Sean Bradley
CC BY-SA 3.0
2014-12-14T21:07:38.523Z
It was my mistake, Sean. Thank for your help.
lontivero
CC BY-SA 3.0
2017-05-27T00:00:48.473Z
@SeanBradley Thank you (though late on my part) for all the help you provided to me. Though I can't seem to get those APIs to work that you posted. They just error out and show nothing.  I know its been a while, but could you check those out again please?
Mine
CC BY-SA 4.0
2014-11-16T13:02:30.723Z
2020-12-27T15:42:01.573Z
2020-12-27T15:42:01.573Z
Sean Bradley
<p>The following link contains details on how to reverse the ECDSA signature if given two identical "R" values.</p>

<p><a href="http://www.nilsschneider.net/2013/01/28/recovering-bitcoin-private-keys.html">http://www.nilsschneider.net/2013/01/28/recovering-bitcoin-private-keys.html</a></p>

<p>I have read over this and there's one part I don't understand; how he got the "z" values.</p>

<p>Does a copy and paste of
"OP_DUP OP_HASH160 70792fb74a5df745bac07df6fe020f871cbb293b OP_EQUALVERIFY OP_CHECKSIG" (minus the quotations) into a ripemod-160 hashing function produce that result? </p>

<p>Did he have to essentially copy and paste some other string?  Did he just ripemod or sha 256d?  Did he have to do it more than once?</p>

<p>I've read up on these things but I just cannot decipher their programming description of how to do it.  The non-programming descriptions don't show "hey this 'xyzx' is what I'm referring to when I say 'message to be signed'" or whatever.  Many things on that page and on the </p>

<p><a href="https://blockchain.info/tx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1">https://blockchain.info/tx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1</a></p>

<p>Seem as though they could adequately be described as the "message to be signed" besides the fact I don't know what type of hash is being applied to even compare my calculations with the ones shown on the first link.</p>

<signature><hash><ecdsa>
ECDSA Signature and the "z" value
Mine
# ECDSA Signature and the "z" value

(Asked by: username_0 on 2014-06-07)

The following link contains details on how to reverse the ECDSA signature if given two identical "R" values.

<http://www.nilsschneider.net/2013/01/28/recovering-bitcoin-private-keys.html>

I have read over this and there's one part I don't understand; how he got the "z" values.

Does a copy and paste of
"OP\_DUP OP\_HASH160 70792fb74a5df745bac07df6fe020f871cbb293b OP\_EQUALVERIFY OP\_CHECKSIG" (minus the quotations) into a ripemod-160 hashing function produce that result?

Did he have to essentially copy and paste some other string? Did he just ripemod or sha 256d? Did he have to do it more than once?

I've read up on these things but I just cannot decipher their programming description of how to do it. The non-programming descriptions don't show "hey this 'xyzx' is what I'm referring to when I say 'message to be signed'" or whatever. Many things on that page and on the

<https://blockchain.info/tx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1>

Seem as though they could adequately be described as the "message to be signed" besides the fact I don't know what type of hash is being applied to even compare my calculations with the ones shown on the first link.

**Tags:** signature, hash, ecdsa


---

## 3 answers

### Answer by username_5 on 2014-11-16. Score: 5 | Accepted answer

Calculating the Z values is quite complicated for the average Joe, so i've made a website to do it for you.

---

The Z values for the above example can be found on this page.

<https://2xoin.com/tx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1>

I've also separated the R and S values to make it easier for you.

You can find the R, S, and Z values for all bitcoin transactions on this site.

Other examples,

<https://2xoin.com/tx/9312ccafb8aa624afe7fb7b4201a0ccc2a14ca2b8b8a3253093b975a6a85a280>

<https://2xoin.com/tx/a963c57ba8a384bf708d5cf83c932e9174ebd0f82f3820e25dcc8a3d508aed54>

<https://2xoin.com/tx/19d66411a5aa716a04b37197c11c93c9446a54694a2d2302093d8b0a93ed5d83>

<https://2xoin.com/tx/9778355a53f295a4ffd592af170badda4e9ad3153e15a4afd76655dac387abb2>

The response returns the standard JSON response that you find in the bitcoin core client, plus some extra bits I added that show the R,S and Z values for each transaction input.

eg, see SizR, SigS and SigZ nodes below.

```
{
  "rawtx": "01000000028370ef64eb83519fd14f9d74826059b4ce00eae33b5473629486076c5b3bf215000000008c4930460221009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9022100c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6cffffffffb0385cd9a933545628469aa1b7c151b85cc4a087760a300e855af079eacd25c5000000008b48304502210094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45022007eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6cffffffff01404b4c00000000001976a91402d8103ac969fe0b92ba04ca8007e729684031b088ac00000000"
}
{
  "txid": "82e5e1689ee396c8416b94c86aed9f4fe793a0fa2fa729df4a8312a287bc2d5e",
  "version": 1,
  "locktime": 0,
  "vin": [
    {
      "txid": "15f23b5b6c0786946273543be3ea00ceb4596082749d4fd19f5183eb64ef7083",
      "vout": 0,
      "scriptSig": {
        "asm": "30460221009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9022100c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622[ALL] 04e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c",
        "hex": "4930460221009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9022100c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c"
      },
      "sequence": 4294967295,
      "n": 0,
      "addr": "1KtjBE8yDxoqNTSyLG2re4qtKK19KpvVLT",
      "valueSat": 2500000,
      "value": 0.025,
      "doubleSpentTxID": null,
      "sigR": "009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9",
      "sigS": "00c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622",
      "sigZ": "9f4503ab6cae01b9fc124e40de9f3ec3cb7a794129aa3a5c2dfec3809f04c354"
    },
    {
      "txid": "c525cdea79f05a850e300a7687a0c45cb851c1b7a19a4628565433a9d95c38b0",
      "vout": 0,
      "scriptSig": {
        "asm": "304502210094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45022007eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb[ALL] 04e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c",
        "hex": "48304502210094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45022007eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c"
      },
      "sequence": 4294967295,
      "n": 1,
      "addr": "1KtjBE8yDxoqNTSyLG2re4qtKK19KpvVLT",
      "valueSat": 2500000,
      "value": 0.025,
      "doubleSpentTxID": null,
      "sigR": "0094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45",
      "sigS": "07eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb",
      "sigZ": "94bbf25ba5b93ba78ee017eff80c986ee4e87804bee5770fae5b486f05608d95"
    }
  ],
  "vout": [
    {
      "value": "0.05000000",
      "n": 0,
      "scriptPubKey": {
        "hex": "76a91402d8103ac969fe0b92ba04ca8007e729684031b088ac",
        "asm": "OP_DUP OP_HASH160 02d8103ac969fe0b92ba04ca8007e729684031b0 OP_EQUALVERIFY OP_CHECKSIG",
        "addresses": [
          "1G3BjSLWsWH6tbPYs29fYMYaz9k8EStQM"
        ],
        "type": "pubkeyhash"
      },
      "spentTxId": "9778355a53f295a4ffd592af170badda4e9ad3153e15a4afd76655dac387abb2",
      "spentIndex": 0,
      "spentHeight": 175915
    }
  ],
  "blockhash": "00000000000006467ae1708979d38dcb6d6fcafbab4c6eccf7414da950379243",
  "blockheight": 175915,
  "confirmations": 309447,
  "time": 1334602008,
  "blocktime": 1334602008,
  "valueOut": 0.05,
  "size": 405,
  "valueIn": 0.05,
  "fees": 0
}

```

---

When I was researching all of the information on this thread, I created some little helper equations that I used heavily while experimenting.

K = ((Z + (X \* R)) / S) % N

X = (((S \* K) - Z) / R) % N

Z = ((S \* K) - (X \* R)) % N

S = ((Z + (X \* R)) / K) % N

R = (((S \* K) - Z) / X) % N

In my equations above,

X is the private key hex,

K multiplied by the sep256k1 G value produces an ECPoint whos x value = R

So from R, you can verify you have the correct K value,
and if you have the correct K value, then you can get the correct X value, which is the hex of the private key of the address in the transaction input.

And here is some sample C# code.

```

using System;
using System.Linq;
using Org.BouncyCastle.Math;

namespace SeansECDSAtest
{
    class Program
    {
        static void Main(string[] args)
        {
            BigInteger R = new BigInteger(StringToByteArray("00d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1"));
            BigInteger S = new BigInteger(StringToByteArray("0044e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e"));
            BigInteger Z = new BigInteger(StringToByteArray("00c0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e"));
            BigInteger X = new BigInteger(StringToByteArray("00c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96"));
            BigInteger K = new BigInteger(StringToByteArray("007a1a7e52797fc8caaa435d2a4dace39158504bf204fbe19f14dbb427faee50ae"));
            BigInteger N = new BigInteger(StringToByteArray("00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"));

            //proving R = (((S * K) - Z) / X) % N
            var verifyR = S.Multiply(K).Subtract(Z).Multiply(X.ModInverse(N)).Mod(N);
            Console.WriteLine("R = " + string.Concat(verifyR.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            //proving S = ((Z + (X * R)) / K) % N
            var verifyS = Z.Add(X.Multiply(R)).Multiply(K.ModInverse(N)).Mod(N);
            Console.WriteLine("S = " + string.Concat(verifyS.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            //proving Z = ((S * K) - (X * R)) % N
            var verifyZ = S.Multiply(K).Subtract(X.Multiply(R)).Mod(N);
            Console.WriteLine("Z = " + string.Concat(verifyZ.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            //proving X = (((S * K) - Z) / R) % N
            var verifyX = S.Multiply(K).Subtract(Z).Multiply(R.ModInverse(N)).Mod(N);
            Console.WriteLine("X = " + string.Concat(verifyX.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            //proving K = ((Z + (X * R)) / S) % N
            var verifyK = Z.Add(X.Multiply(R)).Multiply(S.ModInverse(N)).Mod(N);
            Console.WriteLine("K = " + string.Concat(verifyK.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            Console.ReadLine();
        }

        public static byte[] StringToByteArray(string hex)
        {
            return Enumerable.Range(0, hex.Length)
                             .Where(x => x % 2 == 0)
                             .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                             .ToArray();
        }
    }
}

```

And the same code in python

```
def extended_gcd(aa, bb):
    lastremainder, remainder = abs(aa), abs(bb)
    x, lastx, y, lasty = 0, 1, 1, 0
    while remainder:
        lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder)
        x, lastx = lastx - quotient*x, x
        y, lasty = lasty - quotient*y, y
    return lastremainder, lastx * (-1 if aa < 0 else 1), lasty * (-1 if bb < 0 else 1)

def modinv(a, m):
    g, x, y = extended_gcd(a, m)
    if g != 1:
        raise ValueError
    return x % m

R = 0x00d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1
S = 0x0044e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e
Z = 0x00c0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e
X = 0x00c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96
K = 0x007a1a7e52797fc8caaa435d2a4dace39158504bf204fbe19f14dbb427faee50ae

N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

#proving R = (((S * K) - Z) / X) % N
print hex((((S * K) - Z) * modinv(X,N)) % N)

#proving S = ((Z + (X * R)) / K) % N
print hex(((Z + (X * R)) * modinv(K,N)) % N)

#proving Z = ((S * K) - (X * R)) % N
print hex(((S * K) - (X * R)) % N)

#proving X = (((S * K) - Z) / R) % N
print hex((((S * K) - Z) * modinv(R,N)) % N)

#proving K = ((Z + (X * R)) / S) % N
print hex(((Z + (X * R)) * modinv(S,N)) % N)

```

> **Comments:**
> **username_0**: Thank you, but all I seek is making sense of how to get Z, the hash.  The rest of the algorithm I get.  I just don't understand how to get "Z".  That's it.  Problem is, most answers are exceedingly complex.  I'd be very happy if there was just something I had to copy from the transaction page of a given transaction and paste into some website, click a button, and, BAM, Z value.  In fact, at this time, I'd actually prefer the latter.  
> **username_5**: Visit 2coin.org. It shows the Z values that you can copy and paste.  eg. http://2coin.org/txInfo.aspx?txid=c687eb88fdc883892cbd3982495714072b5662c78f6d71bc1c5ae44630045800 In the 'inputs' section, it separates the R, S, Z and Public key values. If you think an API might be useful for you, I could put one together pretty quickly.  
> **username_5**: I have created an API to easily get the Z values from transactions. I've added the details to my original post above.  
> **username_2**: @username_5 take a look at my comment in the username_1's answer. Could you help me, please? I cannot get the invmod (s1-s2), it is not  0xf7d5417b3844fd8f4b3d909979fa7480ce094fb233d759274fd6c3aa6cf86593 in my case.  
> **username_2**: @username_5 your result: 0xb440675bdc7cd712ea08fc875df4a8e9f50991650625f25a3a474b6bd6cdb89eL my result: 0x4188f2f2de07b663f48dd0fc2f0d00953fa26c5cb977d374f2a2beac7d459498L username_1's result: 0xf7d5417b3844fd8f4b3d909979fa7480ce094fb233d759274fd6c3aa6cf86593L. I don't understand. Thank you  
> **username_5**: @username_2, see my demo at http://ideone.com/o624rX  
> **username_5**: @username_2, when i put code in these comments, it never works, so i've created a print screen. This gives me the correct result. http://prntscr.com/5g67tf  
> **username_2**: It was my mistake, username_5. Thank for your help.  
> **username_0**: @username_5 Thank you (though late on my part) for all the help you provided to me. Though I can't seem to get those APIs to work that you posted. They just error out and show nothing.  I know its been a while, but could you check those out again please?  

---

### Answer by username_1 on 2014-06-07. Score: 12

note: what Nils Schneider calls 'z', i call 'm'.

this gist implements all this: <https://gist.github.com/nlitsme/dda36eeef541de37d996>

# the calculation

ecdsa signing is done as follows:

given a message 'm', a sign-secret 'k', a private key 'x'

```
 R = G*k  (elliptic curve scalar multiplication)
 r = xcoordinate(R)
 s = (m + x * r) / k     (mod q)

```

q = the group order of secp256k1 = 2^256 - 432420386565659656852420866394968145599

now if we have 2 signatures with identical k, we can write this as follows:

```
 s1 * k = ( m1 + x * r ) (mod q)
 s2 * k = ( m2 + x * r ) (mod q)

```

substract these two equations, leading to:

```
(s1-s2)*k = (m1-m2)      (mod q)

```

so the sign-secret 'k' can now be calculated like this:

```
k = (m1-m2)/(s1-s2)      (mod q)

```

and given k, the private key can be calculated like this:

```
x = (s1*k-m1) / r        (mod q)

```

# practical example

This example uses [this](https://www.blockchain.com/btc/tx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1) transaction from 2012.

## the original transaction

the lines below represent:

* the version field
* the nr of inputs (02)
* the 2 inputs
* the nr of outputs (01)
* the output
* the locktime field

  ```
  01 00 00 00
  02
   f6 4c 60 3e 2f 9f 4d af 70 c2 f4 25 2b 2d cd b0 7c c0 19 2b 72 38 bc 9c 3d ac ba e5 55 ba f7 01 01 00 00 00  8a 47 30 44 02 20 d4 7c e4 c0 25 c3 5e c4 40 bc 81 d9 98 34 a6 24 87 51 61 a2 6b f5 6e f7 fd c0 f5 d5 2f 84 3a d1 02 20 44 e1 ff 2d fd 81 02 cf 7a 47 c2 1d 5c 9f d5 70 16 10 d0 49 53 c6 83 65 96 b4 fe 9d d2 f5 3e 3e 01 41 04 db d0 c6 15 32 27 9c f7 29 81 c3 58 4f c3 22 16 e0 12 76 99 63 5c 27 89 f5 49 e0 73 0c 05 9b 81 ae 13 30 16 a6 9c 21 e2 3f 18 59 a9 5f 06 d5 2b 7b f1 49 a8 f2 fe 4e 85 35 c8 a8 29 b4 49 c5 ff  ff ff ff ff
   29 f8 41 db 2b a0 ca fa 3a 2a 89 3c d1 d8 c3 e9 62 e8 67 8f c6 1e be 89 f4 15 a4 6b c8 d9 85 4a 01 00 00 00  8a 47 30 44 02 20 d4 7c e4 c0 25 c3 5e c4 40 bc 81 d9 98 34 a6 24 87 51 61 a2 6b f5 6e f7 fd c0 f5 d5 2f 84 3a d1 02 20 9a 5f 1c 75 e4 61 d7 ce b1 cf 3c ab 90 13 eb 2d c8 5b 6d 0d a8 c3 c6 e2 7e 3a 5a 5b 3f aa 5b ab 01 41 04 db d0 c6 15 32 27 9c f7 29 81 c3 58 4f c3 22 16 e0 12 76 99 63 5c 27 89 f5 49 e0 73 0c 05 9b 81 ae 13 30 16 a6 9c 21 e2 3f 18 59 a9 5f 06 d5 2b 7b f1 49 a8 f2 fe 4e 85 35 c8 a8 29 b4 49 c5 ff  ff ff ff ff
  01
   a0 86 01 00 00 00 00 00 19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac
  00 00 00 00

  ```

## the input scripts

the input script consists of:

* the total length (8a)
* the signature
* the public key

  8a  
  47 30 44 02 20 d4 7c e4 c0 25 c3 5e c4 40 bc 81 d9 98 34 a6 24 87 51 61 a2 6b f5 6e f7 fd c0 f5 d5 2f 84 3a d1 02 20 44 e1 ff 2d fd 81 02 cf 7a 47 c2 1d 5c 9f d5 70 16 10 d0 49 53 c6 83 65 96 b4 fe 9d d2 f5 3e 3e 01
  41 04 db d0 c6 15 32 27 9c f7 29 81 c3 58 4f c3 22 16 e0 12 76 99 63 5c 27 89 f5 49 e0 73 0c 05 9b 81 ae 13 30 16 a6 9c 21 e2 3f 18 59 a9 5f 06 d5 2b 7b f1 49 a8 f2 fe 4e 85 35 c8 a8 29 b4 49 c5 ff

the signature is an asn1 encoded r+s value + a hashtype indicator (01)

```
30 44 
    02 20  d4 7c e4 c0 25 c3 5e c4 40 bc 81 d9 98 34 a6 24 87 51 61 a2 6b f5 6e f7 fd c0 f5 d5 2f 84 3a d1
    02 20  44 e1 ff 2d fd 81 02 cf 7a 47 c2 1d 5c 9f d5 70 16 10 d0 49 53 c6 83 65 96 b4 fe 9d d2 f5 3e 3e
01

```

so now we can extract these values from the transaction:

```
pk 04dbd0c61532279cf72981c3584fc32216e0127699635c2789f549e0730c059b81ae133016a69c21e23f1859a95f06d52b7bf149a8f2fe4e8535c8a829b449c5ff
r  d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1
s1 44e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e
s2 9a5f1c75e461d7ceb1cf3cab9013eb2dc85b6d0da8c3c6e27e3a5a5b3faa5bab

```

next we need to calculate the message hashes.

## prepare

Strip the input scripts, and add the hashtype

```
01 00 00 00
02
 f6 4c 60 3e 2f 9f 4d af 70 c2 f4 25 2b 2d cd b0 7c c0 19 2b 72 38 bc 9c 3d ac ba e5 55 ba f7 01 01 00 00 00  00  ff ff ff ff
 29 f8 41 db 2b a0 ca fa 3a 2a 89 3c d1 d8 c3 e9 62 e8 67 8f c6 1e be 89 f4 15 a4 6b c8 d9 85 4a 01 00 00 00  00  ff ff ff ff
01
 a0 86 01 00 00 00 00 00 19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac
00 00 00 00
01 00 00 00   <<< hashtype

```

## calculating m1

replace the first input with the corresponding output script

```
01 00 00 00
02
 f6 4c 60 3e 2f 9f 4d af 70 c2 f4 25 2b 2d cd b0 7c c0 19 2b 72 38 bc 9c 3d ac ba e5 55 ba f7 01 01 00 00 00  19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac  ff ff ff ff
 29 f8 41 db 2b a0 ca fa 3a 2a 89 3c d1 d8 c3 e9 62 e8 67 8f c6 1e be 89 f4 15 a4 6b c8 d9 85 4a 01 00 00 00  00  ff ff ff ff
01
 a0 86 01 00 00 00 00 00 19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac
00 00 00 00
01 00 00 00

```

then do sha256(sha256(modified transaction))

this will result in : c0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e

## calculating m2

replace the second input with the corresponding output script

```
01 00 00 00
02
 f6 4c 60 3e 2f 9f 4d af 70 c2 f4 25 2b 2d cd b0 7c c0 19 2b 72 38 bc 9c 3d ac ba e5 55 ba f7 01 01 00 00 00  00  ff ff ff ff
 29 f8 41 db 2b a0 ca fa 3a 2a 89 3c d1 d8 c3 e9 62 e8 67 8f c6 1e be 89 f4 15 a4 6b c8 d9 85 4a 01 00 00 00  19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac  ff ff ff ff
01
 a0 86 01 00 00 00 00 00 19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac
00 00 00 00
01 00 00 00

```

then do sha256(sha256(modified transaction))

this will result in : 17b0f41c8c337ac1e18c98759e83a8cccbc368dd9d89e5f03cb633c265fd0ddc

Note that the redeemed output scripts and the output script of this transaction are all identical in this case. That is not usually so.

so our message hashes are:

```
m1 c0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e
m2 17b0f41c8c337ac1e18c98759e83a8cccbc368dd9d89e5f03cb633c265fd0ddc
s1 44e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e
s2 9a5f1c75e461d7ceb1cf3cab9013eb2dc85b6d0da8c3c6e27e3a5a5b3faa5bab

```

m1-m2 = 0xA931DC8C0E011326AE4D6FAB7DED290B196966154E0A73A0DF434413217B3E92  
s1-s2 = 0xAA82E2B8191F2B00C8788571CC8BEA41086440225A4B5CBED84D02CF638123D4

modulare inverse of s1-s2 = 0xf7d5417b3844fd8f4b3d909979fa7480ce094fb233d759274fd6c3aa6cf86593

so our secret 'k' value is:

-> (m1-m2)/(s1-s2) = 0x7a1a7e52797fc8caaa435d2a4dace39158504bf204fbe19f14dbb427faee50ae

the private key can then be calculated :

s1\*k-m1 = 0x797035d79964e4b74fbbef4460379c410261cd01de43278bc2a7efaa541dd8e9 - 0xc0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e  
= 0xB88D652EFF3056CEBFE1E72343C6CA67D7E3DAF5A1F76E366680D6619CDBCDBC

(s1\*k-m1)/r = 0xc477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96

You can experiment with these calculations [here](http://rawcdn.githack.com/nlitsme/bitcoinexplainer/aa50e86e8c72c04a7986f5f7c43bc2f98df94107/calculator.html#bTE9MHhjMGUyZDBhODlhMzQ4ZGU4OGZkYTA4MjExYzcwZDFkN2U1MmNjZWYyZWI5NDU5OTExYmY5NzdkNTg3Nzg0YzZlCm0yPTB4MTdiMGY0MWM4YzMzN2FjMWUxOGM5ODc1OWU4M2E4Y2NjYmMzNjhkZDlkODllNWYwM2NiNjMzYzI2NWZkMGRkYwpzMT0weDQ0ZTFmZjJkZmQ4MTAyY2Y3YTQ3YzIxZDVjOWZkNTcwMTYxMGQwNDk1M2M2ODM2NTk2YjRmZTlkZDJmNTNlM2UKczI9MHg5YTVmMWM3NWU0NjFkN2NlYjFjZjNjYWI5MDEzZWIyZGM4NWI2ZDBkYThjM2M2ZTI3ZTNhNWE1YjNmYWE1YmFiCnI9MHhkNDdjZTRjMDI1YzM1ZWM0NDBiYzgxZDk5ODM0YTYyNDg3NTE2MWEyNmJmNTZlZjdmZGMwZjVkNTJmODQzYWQxCgprPShtMS1tMikvKHMxLXMyKQoKeD0oczEqay1tMSkvcgo=).

# Explanation of Transaction Contents

A transaction consists of a number of inputs, and a number of outputs.

An input refers to one of the outputs from another transaction, and contains a script which proofs that this transaction is allowed to redeem that output.

An output consists of a BTC value, and a script which will be used to validate the proof presented in the input script at the time this output will be redeemed.

When an output is redeemed, the input and output scripts are concatenated, and evaluated by the bitcoin client. the result must be 'TRUE'.

The script language is a very simple, non-turing complete, stack based language.

The most common script looks like this:

```
---- input script ( aka scriptSig )
PUSH signature
PUSH publickey
---- output script ( aka scriptPubKey )
DUP
HASH160
PUSH pubkeyhash
EQUALVERIFY
CHECKSIG

```

Note that the 'PUSH' is not explicitly labeled as PUSH in the bitcoin script description.

In the output script, first it is verified that the addresshash ( which is the bitcoin address in binary format ) corresponds to the public key from the input.
Then with `CHECKSIG` it is verified that the specified signature is valid for this transaction.

> **Comments:**
> **username_0**: Still trying to make sense of this answer, quite complex.  What is the definition of an "input" for a transaction?  That the number of addresses being sent from?  And whats the def of an "output"?  Number of addresses being sent to?  Perhaps I should ask something similar.  What info do I need, and how would I use it to simply submit my own transaction to the network?  Private Key point multiplied to itself K times, public key and ....the hash.  I think my main difficulty is "m" or the "message" the whole "output" "input" and "script" are throwing me off  
> **username_0**: Now of the equations you showed, which items are already shown on http://blockexplorer.com/rawtx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1 and or https://blockchain.info/tx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1 ? Meaning, lets say I have K and want to solve for x (private key) as simply as possible, what variables for your original equations are already shown to me? (I know this might seem to have been answered in your post already but I'm confused on some parts of it because I've heard so many definitions for so many of these things). –  
> **username_1**: the public key, 'r' and 's' value can directly be obtained from the input script ( scriptSig ).  the 'm' value needs to be calculated.  the 'q' and 'G' are constants specified by the secp256k1 curve used in bitcoin  
> **username_0**: I'm trying this again.  I copied and pasted the contents of the code window below "calculating m1 - replace the first input with the corresponding output script" and put it into a sha 256d algorithm calculator, then took that result and hashed it too, per the instructions, the results did not coincide with the correct results  
> **username_2**: modulare inverse of s1-s2? doesn't mod has 2 operands?  
> **username_1**: All calculations are modulo q  
> **username_2**: I'm blocked in the invmod step. This is what I get: http://prntscr.com/5fzzys. What am I doing wrong? I cannot get modulare inverse of s1-s2 = 0xf7d5417b3844fd8f4b3d909979fa7480ce094fb233d759274fd6c3aa6cf86593  
> **username_1**: the value in your screenshot of s1-s2 is already wrong,  maybe check your inputs.  here is working code: http://ideone.com/bjSai7  
> **username_2**: .NET bigint class is a bit tricky but I did it with your help! Thank you @username_1  
> **username_2**: @username_1 what if there are more than just one output? How do i calculate the M values? I mean, what should I change in the section *Calculating m1*??  
> **username_1**: More outputs of what?  
> **username_2**: In your practical example the transaction has 2 inputs and 1 output but the tx can have _n_ outputs. Am I misunderstanding something?  
> **username_1**: the signature is in the input script, and uses the output script of it's source transaction when calculating the message hash. So the nr of outputs to the transaction does not matter, they are always hashed unmodified into the messagehash for each input.  
> **username_3**: 2xoin.com is gone now too, which is unfortunate. But thank you for the detailed description of your calculations and not just the links.  

---

### Answer by username_4 on 2014-06-07. Score: 1

> We just need to find z1 and z2! These are the hashes of the outputs to be signed. Let’s fetch the output transations and calculate them (it is calculated by OP\_CHECKSIG):

The Bitcoin wiki's page on [OP\_CHECKSIG](https://en.bitcoin.it/wiki/OP_CHECKSIG) and the [picture](https://en.bitcoin.it/w/images/en/7/70/Bitcoin_OpCheckSig_InDetail.png) there show what is signed: essentially, the new transaction with the txin's removed and the transaction output inserted. It's the hash of these bytes that is actually signed, which are `z1` and `z2`.

This pseudocode might help clarify how the `z`s are used:

```
def sign(priv_key, txin_index):
    z = get_data_to_sign(txin_index) # uses algorithm at https://en.bitcoin.it/w/images/en/7/70/Bitcoin_OpCheckSig_InDetail.png
    r = super_secure_random()
    s = ECDSA_sign(priv_key, z, r)
    return r, s

def verify(pub_key, txin_index, r, s):
    z = get_data_to_sign(txin_index)
    ECDSA_verify(pub_key, z, r, s)

def super_secure_random():
    return 4

```


---

