Skip to content

Instantly share code, notes, and snippets.

@nlitsme
Last active November 9, 2024 14:43
Show Gist options
  • Save nlitsme/f3c9953a420012bd413a684068a770ff to your computer and use it in GitHub Desktop.
Save nlitsme/f3c9953a420012bd413a684068a770ff to your computer and use it in GitHub Desktop.
How to calculate the bitcoin messagehash

Demonstrate how to calculate the messagehash for the two signatures in this transaction

See ecdsa_demo.py for code showing how to use this to crack the bitcoin secret key.

These are the values extracted from the example transaction below:

pk="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"
r="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"
s1="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"
s2="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"
m1="c0 e2 d0 a8 9a 34 8d e8 8f da 08 21 1c 70 d1 d7 e5 2c ce f2 eb 94 59 91 1b f9 77 d5 87 78 4c 6e"
m2="17 b0 f4 1c 8c 33 7a c1 e1 8c 98 75 9e 83 a8 cc cb c3 68 dd 9d 89 e5 f0 3c b6 33 c2 65 fd 0d dc"
eccalc crack2 "$pk" "$r" "$s1" "$s2" "$m1" "$m2"


note that the output script for both inputs is the same in this case: 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


----- hexdump of https://bitaps.com/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1

 01 00 00 00
 02  -- inputs
 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  -- r
          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  -- s1
          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 public key
    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  -- r
          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  -- s2
          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 public key
    ff ff ff ff
 01  -- outputs
     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

now calculate the messagehash like this:
  - replace one inputscript by the corresponding output script
  - replace the other input scripts by '00'
  - append '01 00 00 00' for the hash type at the end of the transaction
  - calculate the 'shasha'

## calculate m1

shasha(
     01 00 00 00
     02  -- inputs
     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  -- replaced the first with output script, see 'txnsrc 1' below
        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  -- replaced the second with empty script
        ff ff ff ff
     01  -- outputs
         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
    -- and the hashtype
     01 00 00 00
) = c0 e2 d0 a8 9a 34 8d e8 8f da 08 21 1c 70 d1 d7 e5 2c ce f2 eb 94 59 91 1b f9 77 d5 87 78 4c 6e

## calculate m2
shasha(
     01 00 00 00
     02  -- inputs
     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  -- replaced the first with empty script
        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 -- replaced the second with output script, see 'txnsrc 2' below
        ff ff ff ff
     01  -- outputs
         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
    -- and the hashtype
     01 00 00 00
) = 17 b0 f4 1c 8c 33 7a c1 e1 8c 98 75 9e 83 a8 cc cb c3 68 dd 9d 89 e5 f0 3c b6 33 c2 65 fd 0d dc


-------

## txnsrc 1
shasha(
     01 00 00 00
     01
     c4 c8 6a e5 40 d3 40 47 1b 03 83 3c b6 73 86 b0 60 a7 a5 63 2f 1e e7 30 c7 1e f6 90 9e 90 eb 9c 00 00 00 00
        8b 48 30 45 02 21 00 87 87 14 0a 00 fd b0 5e 55 ef 66 0f 54 c3 f5 1d 84 99 35 d1 4b c2 e2 c6 0f b9 7a 05 1a 1d a3 c7 02 20 79 7b 5e b2 65 24 6e 63 cb 06 1a b2 77 c5 41 a3 ba 42 37 d5 b3 c5 fe 94 b6 af 94 00 72 3a 87 90 01 41 04 04 c6 d6 28 a1 2e 1c bf 01 b1 d8 31 6c b1 c0 9a 38 16 33 69 f1 11 3a 26 51 35 65 a1 a2 44 5e 2e 12 fd ac 74 8c ec 24 34 42 c6 18 5e 5e 2c 26 47 f9 93 c8 8a ff 95 d9 22 f6 51 17 d7 3d a5 66 cc
        ff ff ff ff
     02 -- outputs
         d0 dc f7 05 00 00 00 00  19 76 a9 14 fc 41 ce e3 55 d1 0b 86 31 37 00 63 82 c8 09 ae c1 dd f3 3c 88 ac  --- output #0
         d0 fb 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  --- output #1
     00 00 00 00
) = 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

## txnsrc 2
shasha(
     01 00 00 00
     01
     c4 c8 6a e5 40 d3 40 47 1b 03 83 3c b6 73 86 b0 60 a7 a5 63 2f 1e e7 30 c7 1e f6 90 9e 90 eb 9c 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 12 a8 c1 d5 c6 02 e3 82 c1 78 fb fc b9 57 e8 ec c3 47 f1 ba f7 8a 20 6f 20 a9 7f f4 c4 33 e1 46 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
     02 -- outputs
         50 c3 00 00 00 00 00 00  19 76 a9 14 01 94 53 ca 35 e7 cd c4 31 18 dd a7 bc 81 ee 98 1b d6 f9 24 88 ac  --- output #0
         20 4e 00 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  --- output #1
     00 00 00 00
) = 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

A old (before witness) style transaction has the following structure:

  1. first a 4 byte version: 01 00 00 00
  2. a varint encoding the number of inputs: 02
  3. the inputs
  4. a varint encoding the number of outputs: 01
  5. the outputs
  6. a 4 byte locktime: 00 00 00 00

An input is structured like this:

  1. a 32 byte transaction hash
  2. a 4 byte zero-based output index
  3. a varint encoding the input script size
  4. the input script
  5. a 4 byte sequence number: ff ff ff ff

Note that the transaction hash as used on most blockexplorers is byte-reversed from the hash as it is stored in the input, or calculated using the shasha algorithm.

The input script commonly contains:

  1. a signature: a asn-1 BER encoded 'r' and 's' value followed by a 01.
  2. a public key.

An output is structured like this:

  1. a 8 byte bitcoin value
  2. a varint encoding the output script size
  3. the output script

The output script commonly contains:

  1. 76 - dup
  2. a9 - hash160
  3. 14 ... - the address hash
  4. 88 - equalverify
  5. ac - checksig

The asn1-BER encoded signature:

  1. 30 - a sequence tag
  2. a length, typically in range: 0x40 - 0x48
  3. 02 - a 'int' tag, the type of the 'r' value
  4. a length, typically in range: 0x1e - 0x21
  5. the bytes for the 'r' value
  6. 02 - a 'int' tag, the type of the 's' value
  7. a length, typically in range: 0x1e - 0x21
  8. the bytes for the 's' value

See wikipedia for details on the BER encoding.

@abadon666
Copy link

you have in math something like:

r1,s1,z1 of addres1 and r1,s2,z2 of addres2

and you have equation:

aaddres1 = baddres2

so:
addres1 = baddres2/a
addres2 = a
addres1/b

addres1-addres2 = baddres2/a - aaddres1/b

after computional of this equation
in this example you have bs1/a=as2/b -> is the same - when you make perdorm calc -> you have zero.

but there can be chance if and only if linear distance beetween addres 1 and adress 2 is less than 127 bit.

@nlitsme
Copy link
Author

nlitsme commented Oct 31, 2022

you made a typo in the r-value, it should be: r=0x6bcc247f1259262b4035bfa84f0397a69f69baa01659daaf94fe1164b650c86a

@fad98
Copy link

fad98 commented Nov 3, 2022

a6cf0e5dc1c63e5ddc15d04f79343542dba1d2ffa3a7f1687cd34f39b790fe51

@nlitsme how for 4 équation to calculate?

@nlitsme
Copy link
Author

nlitsme commented Nov 3, 2022

You can google for it: look for linear algebra, solving systems of equations.

@nlitsme
Copy link
Author

nlitsme commented Nov 3, 2022

Did you also notice that https://www.blockchain.com/btc/address/1FpnTpnyeGRUFFWJuMonwZq6vK83Rbxufa has the same x-coordinate as the r-value of the two transactions you mentioned before?

6bcc247f1259262b4035bfa84f0397a69f69baa01659daaf94fe1164b650c86a

see for instance:
https://www.blockchain.com/btc/tx/e8b5324b24fd408b7f0eab6699c6e3499569bd0d79913db41d0dedf4eb273e67

@amadhurkant
Copy link

The wallet is multisig 3/5; do you have info about the former two keys?

@fad98
Copy link

fad98 commented Nov 4, 2022

@nlitsme how to get k or pvk for this
M4=1ae2d12f17122d84b05ce4b1e592fd09e577aafed9254039945b97bc812cbf3d
S4=00b0e065e2be68db53dea287a1701e78bfb5c31499083ea448052ec7d2b9110f4b
R4=00d013ef56fcdd849b662790e019d8e031227a92be20cc6661061704f66a539412
M3=bc8099370aa76089da48ce76f880bce26420ebebcc14a5f1821f4448cfbd3926
S3=3cbfe771b826b28f079e5bdca10cb2e69514dfabec7d77ed459c09d7399e27b9
R3=4966fdef30284e5626cd82c2bac66e9b2b5c455986fb6b2f7bb5308ca37d07b8
M2=92601e62953eb2688bbd5376fa810eea9ea6b851238d5fe9d539c30df3cb3eb2
S2=319d8c7aa4ec74df4666d8f21d5a660260af977b33db0e0f854271a4c9b401a0
R2=008e448b0509bad3e06b7026ce59a331fbed38127b64e0a6270f0d925027c9199d
M1=5172f6e4de00e47979582b3e0028b4e9c3bad42004e3909ad406754f03f72fd3
S1=600802e2e0b320a4c34c487598fe0e0928cec662e1266726568a6cbb6c69390b
R1=5d6c52025be6f7961a504fb8c39b5aec491fb2e9269f86b9a0d0c09195474293

@Nakimatu
Copy link

Nakimatu commented Nov 7, 2022

Hello.
I'm making a mistake somewhere, the result is wrong, can you please review it? Where am I doing wrong?

My source is not a single output as here. : 9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1

They are two different outputs of the same address.

Address = 1A8TY7dxURcsRtPBs7fP6bDVzAgpgP4962
tx 1 = 7424dede873f656bce9d44caf611d911fe3a81a2d3420119a5f39e4a30a9fea6
tx 2 = aa85c2dd8bc29ef4015ed110ba543ea8adbccee2d1f3f51af33fc145c4aa1623

Sigscript 1 = 30450220 0f18c2d1fe6513b90f44513e975e05cc498e7f5a565b46c65b1d448734392c6f 022100 917766d14f2e9933eb269c83b3ad440ed8432da8beb5733f34046509e48b1d85 01
Sigscript 2 = 30450220 0f18c2d1fe6513b90f44513e975e05cc498e7f5a565b46c65b1d448734392c6f 022100 b29a06f2e30064542b298d711c315dca9ca99756180219699f776dd3d6a6bbc9 01

tx 1

01000000
02
85e5bee5d731dc32227eae939aa2d93ae9712b0413617572ed3bd2264cbc812300000000
1976a9147a2a3b481ca80c4ba7939c54d9278e50189d94f988ac
ffffffff
85e5bee5d731dc32227eae939aa2d93ae9712b0413617572ed3bd2264cbc812301000000
00
ffffffff
01
80841e0000000000
1976a9147a2a3b481ca80c4ba7939c54d9278e50189d94f988ac
00000000
01000000

m1 = b6b26446c0df7ca1572a0198a1f034074f1332abf9101474da69c266fd7fcc19

tx 2
01000000
01
ba988c49d024d5ec33b49f74071b2157b1530e1301c3210d92c5dc08e04b63d001000000
1976a9147a2a3b481ca80c4ba7939c54d9278e50189d94f988ac
ffffffff
01
c0c62d0000000000
1976a9147a2a3b481ca80c4ba7939c54d9278e50189d94f988ac
00000000
01000000

m2= e313835f7fdffb94bcd13a9e92261d0d81e7673ff99162a76dce5ae828bed5fe

m1=0xb6b26446c0df7ca1572a0198a1f034074f1332abf9101474da69c266fd7fcc19
m2=0xe313835f7fdffb94bcd13a9e92261d0d81e7673ff99162a76dce5ae828bed5fe
r= 0x0f18c2d1fe6513b90f44513e975e05cc498e7f5a565b46c65b1d448734392c6f
s1=0x917766d14f2e9933eb269c83b3ad440ed8432da8beb5733f34046509e48b1d85
s2=0xb29a06f2e30064542b298d711c315dca9ca99756180219699f776dd3d6a6bbc9

Priv Key = 8f9a592a8c0c6eb7013707e13868d4beb484be58e883b5ca7bc78680d91e0d37
Address 187bJgoKx7ymJjpwZrHYhqojdkfte7P6cf
Address 14uCw9QSLney6BAotfqKyb8Khvy6sC5Afy

@nlitsme
Copy link
Author

nlitsme commented Nov 7, 2022

@fad98, I don't see an easy solution there.
They are all for address: 189cKpEVEa8nnUf4hC7qvgV65z9GBHD3oq

Here I made a graph of how those transactions are related.
green marks the r-values from your values., blue marks the pubkeys for your values.

Screenshot_20221107_161106

@nlitsme
Copy link
Author

nlitsme commented Nov 7, 2022

@Nakimatu

when calculating the message hash, you should use the output from the source transaction to replace the input script,
so, in tx2 instead of '1976a9147a2a3b481ca80c4ba7939c54d9278e50189d94f988ac', you should put: '19 76a914 642231ff7596dd1664e909f2a6fa84c77ade42b8 88ac', then for tx2 you will get m=0d9dd44880b58f3e12c66978fc4651f20442a0b47731f6bcc9af594a67dcfb7e

I did not check tx1, but I think it is the same mistake.

@Nakimatu
Copy link

Nakimatu commented Nov 7, 2022

@Nakimatu

when calculating the message hash, you should use the output from the source transaction to replace the input script, so, in tx2 instead of '1976a9147a2a3b481ca80c4ba7939c54d9278e50189d94f988ac', you should put: '19 76a914 642231ff7596dd1664e909f2a6fa84c77ade42b8 88ac', then for tx2 you will get m=0d9dd44880b58f3e12c66978fc4651f20442a0b47731f6bcc9af594a67dcfb7e

I did not check tx1, but I think it is the same mistake.

Hello, I made changes as you said, but I made a mistake again. Wrong result :(

tx 1
01000000
02
85e5bee5d731dc32227eae939aa2d93ae9712b0413617572ed3bd2264cbc812300000000
1976a914642231ff7596dd1664e909f2a6fa84c77ade42b888ac
ffffffff
85e5bee5d731dc32227eae939aa2d93ae9712b0413617572ed3bd2264cbc812301000000
00
ffffffff
01
80841e0000000000
1976a914642231ff7596dd1664e909f2a6fa84c77ade42b888ac
00000000
01000000

tx 2
01000000
01
ba988c49d024d5ec33b49f74071b2157b1530e1301c3210d92c5dc08e04b63d001000000
1976a914642231ff7596dd1664e909f2a6fa84c77ade42b888ac
ffffffff
01
c0c62d0000000000
1976a914642231ff7596dd1664e909f2a6fa84c77ade42b888ac
00000000
01000000

m1= 80c44827ab5b0c1766824d14349a34b6f5bec7173bfd374c81d388a74e2d1c3b
m2= 85ef3c926ac51ddfc89b2eff23e99a1ba593172980a7e78a2798673d4c5b9a64

m1=0x80c44827ab5b0c1766824d14349a34b6f5bec7173bfd374c81d388a74e2d1c3b
m2=0x85ef3c926ac51ddfc89b2eff23e99a1ba593172980a7e78a2798673d4c5b9a64
r= 0x0f18c2d1fe6513b90f44513e975e05cc498e7f5a565b46c65b1d448734392c6f
s2=0x917766d14f2e9933eb269c83b3ad440ed8432da8beb5733f34046509e48b1d85
s1=0xb29a06f2e30064542b298d711c315dca9ca99756180219699f776dd3d6a6bbc9

To search = 1A8TY7dxURcsRtPBs7fP6bDVzAgpgP4962
found Uncompressed address = 13wFf62PR92zCoyqyz4ijRWjQHB85AVMDv
found Compressed address= 1CPrr44n8oDcYm3HFzFfysozzGbptFGfKE

Please show the solution with an example. I can't see where I made a mistake :((

@nlitsme
Copy link
Author

nlitsme commented Nov 8, 2022

now you changed both the output and input script to 642231ff7596dd1664e909f2a6fa84c77ade42b8, you should keep the output script at what it was in the txn. only the inputs need to be modified.

 01000000
 02
   85e5bee5d731dc32227eae939aa2d93ae9712b0413617572ed3bd2264cbc8123  00000000
     19 76a914 642231ff7596dd1664e909f2a6fa84c77ade42b8 88ac
     ffffffff
   85e5bee5d731dc32227eae939aa2d93ae9712b0413617572ed3bd2264cbc8123  01000000
     00
     ffffffff
 01
   80841e0000000000
     19 76a914 7a2a3b481ca80c4ba7939c54d9278e50189d94f9 88ac
 00000000
 01000000
)

@Nakimatu
Copy link

Nakimatu commented Nov 8, 2022

now you changed both the output and input script to 642231ff7596dd1664e909f2a6fa84c77ade42b8, you should keep the output script at what it was in the txn. only the inputs need to be modified.

 01000000
 02
   85e5bee5d731dc32227eae939aa2d93ae9712b0413617572ed3bd2264cbc8123  00000000
     19 76a914 642231ff7596dd1664e909f2a6fa84c77ade42b8 88ac
     ffffffff
   85e5bee5d731dc32227eae939aa2d93ae9712b0413617572ed3bd2264cbc8123  01000000
     00
     ffffffff
 01
   80841e0000000000
     19 76a914 7a2a3b481ca80c4ba7939c54d9278e50189d94f9 88ac
 00000000
 01000000
)

Thank you very much. I tested myself on another example. Reached the Goal.
I love learning. Thank you very much for educating me.

Address1ENrnLCxp9srcWCCE3kQFNqHRGDijespb9

tx 1 = 1412ee11d3d68e4bd98877612028e84f497716ffe814551d1a6b9a1e7b10dabc
tx 2 = 29235b4047a6308df49202a207c78b0e943d20559b0fc05c5fcd98503e7bac13

01000000
01
13ac7b3e5098cd5f5cc00f9b55203d940e8bc707a20292f48d30a647405b232901000000
1976a91492bbed0b0b72bf3313b61e26861fedba6c36a45088ac
ffffffff
01
a025260000000000
1976a914cf3aaf67c964d5c239f4cf2d9c2d2a7257d85b5d88ac
00000000
01000000

010000000113ac7b3e5098cd5f5cc00f9b55203d940e8bc707a20292f48d30a647405b2329010000001976a91492bbed0b0b72bf3313b61e26861fedba6c36a45088acffffffff01a0252600000000001976a914cf3aaf67c964d5c239f4cf2d9c2d2a7257d85b5d88ac0000000001000000
1402d3fc9d108c09b52db331151260261e1634fcf2906c53e9346f4985a89a9f

01000000
01
0f62d40b4ec2ea8463f648e946a91b18efe6d15c4e1a89b2bc6ae93af345c9ae00000000
1976a91492bbed0b0b72bf3313b61e26861fedba6c36a45088ac
ffffffff
02
a025260000000000 1976a914cf3aaf67c964d5c239f4cf2d9c2d2a7257d85b5d88ac
a025260000000000 1976a91492bbed0b0b72bf3313b61e26861fedba6c36a45088ac
00000000
01000000

30450220 17972526103d817b735ce23ebe6505d3f0800b765acdf2a5d296e95c38408e9a 022100 f87141e921580bdea17367b5661c52e5ea48fbd000dd3b8bdf95becac9124715 01
30450220 17972526103d817b735ce23ebe6505d3f0800b765acdf2a5d296e95c38408e9a 022100 c4effe6a140d7205d6ea0f3f23a004677a34941a9864c0b7e1d5498daec3f86d 01

m1=0x1402d3fc9d108c09b52db331151260261e1634fcf2906c53e9346f4985a89a9f
m2=0x8b49882655bb6ff0021775e67201ed312b0204923798aba2e27422e9acb0013d
r= 0x17972526103d817b735ce23ebe6505d3f0800b765acdf2a5d296e95c38408e9a
s1=0xf87141e921580bdea17367b5661c52e5ea48fbd000dd3b8bdf95becac9124715
s2=0xc4effe6a140d7205d6ea0f3f23a004677a34941a9864c0b7e1d5498daec3f86d

@JoeBrar
Copy link

JoeBrar commented Nov 21, 2022

hello, checkout this transaction https://www.blockchain.com/btc/tx/3138b8fe88342f2414272c935e2e0885ea777cbcc824a2b807f710196a71b77

here the wallet address '35ipDTBWHU7C7rE6mTfysoZYCHkyqugaXf' makes multiple inputs in the same transaction and they have the same sigscript which leads me to believe that its private key can be cracked. But I can't find r,s or z values for it. Please help

The two transactions are -
image
image

I think the value in sigscript is r. But how to find s1,s2 and z1,z2 from the witness.

@nlitsme
Copy link
Author

nlitsme commented Nov 21, 2022

That is how pay-to-script transactions work, and because of the witness part, this is a P2SH+P2WSH transaction.

The address:
35ipDTBWHU7C7rE6mTfysoZYCHkyqugaXf = base58(5, 2c378fb269e524d6778a74b287fa457da26d1838)

is the has of the SigScript:
2c378fb269e524d6778a74b287fa457da26d1838 = sharip(0020 d8793be235d12d1cde8b0144647ae0695580b3892a27d7294b56aaf5de6ba602)

The has in the SigScript, is the has of the P2SH script.
d8793be235d12d1cde8b0144647ae0695580b3892a27d7294b56aaf5de6ba602 = sha256(
52
210260e173e8b3f1039eb860210576b85609c5695ce90e9f8711a147466c24e3eb45
21026673d16ae7a751952064e42715d52831a0ecca70e8e794a121c55eec134c4abc
2102ece72a894cdafb8c2aa469ce357f5a8049d9699e3e114fbe538f372f80aab7f8
53
ae -- CHECKMULTISIG
)

This last part has 3 pubkeys, you need 2-out-of-3 signatures in the witness part.

The numbers starting with 304.... are the signatures in the witness part.
The last item in the witness list is the (multisig) P2SH script.

@JoeBrar
Copy link

JoeBrar commented Nov 22, 2022

Thanks you for the insight.
So as I understand, this wallet will have the same SigScript in all its transactions.
So the signatures in the witness part (starting with 304....) will have to be same for this wallet to be cracked. Or is there some way it can still be cracked with the same SigScript.

Also, how can we find r,s and z values from the witness.

@JoeBrar
Copy link

JoeBrar commented Nov 22, 2022

...?

@nlitsme
Copy link
Author

nlitsme commented Nov 22, 2022

How to hash a witness transaction is specified here: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#specification

@JoeBrar
Copy link

JoeBrar commented Nov 23, 2022

Thanks.
So the signatures in the witness part (starting with 304....) will have to be same for this wallet to be cracked. Or is there some way it can still be cracked with the same SigScript?

@nlitsme
Copy link
Author

nlitsme commented Nov 23, 2022

The easy crack, where you have two different signatures with the same r-value for the same pubkey then yes.

But there are other ways to crack keys. You could for instance try to bruteforce them, some keys have week passwords.

for instance this one: https://blockchair.com/bitcoin/address/1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm
it has private key: 00...01

In this transaction you can see that the pubkey is the ecdsa generator point:
https://bitaps.com/57bd645d11fc3404ec7d24277e9fa5dbce3c68d17bff0e15a9e1914eb910d829/1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm

@Ruby3434
Copy link

Ruby3434 commented Nov 23, 2022

@nlitsme Hello, I didn't understand why it's not working for https://www.blockchain.com/explorer/transactions/btc/e0377229deb9dcd2e0aabd3c56deb397eb24b762c5c0eca8cfaf2c268e48c4f6.

I can't find correct private key for 1K3iZPSqMCxtMd5o5hw4gfpFq3i9zqL61o.

I used 4,5 inputs to find s1, s2, z1, z2. Here the values:

30440220 1cf895af787f8d897cbb72bf9d39d3edbd603c4b23ea8f2f3dfaafc9e3fa5907 0220 62f8260583709b26b102af5ab4c615073921a0af1d21b9a0e96969307ff3a44e

30440220 1cf895af787f8d897cbb72bf9d39d3edbd603c4b23ea8f2f3dfaafc9e3fa5907 0220 17d4a1b146b7dcebbb604574f90f4569e18f7ab7f828cdd9ee5a2cce59cb09a4

0100000005e75a72a15d95a874e05531f005c5dff4047c6b6f25990baf54045209e10f97130200000000ffffffff8ea572f15ad54edec3a9d3a0f57eeafa179810254f060a54bfeedf3d4269f13a0000000000ffffffff5531bbd9c004c69fff9374918f9eb64a3603c045d38362002e25a06316e7d73f0000000000ffffffff6f116755042b1b1aef9d809ab04f79afa63f71aa31616c2daa1a7d82d305b13a000000001976a9142926402d832870745c37979bdff8f030e6a2d75988acffffffffef1a5d83a8cd639224c9876fe1e157a3ed239d596d2bb62c556c9dcc1bb550370000000000ffffffff01ccba0f00000000001976a9142926402d832870745c37979bdff8f030e6a2d75988ac0000000001000000

0100000005e75a72a15d95a874e05531f005c5dff4047c6b6f25990baf54045209e10f97130200000000ffffffff8ea572f15ad54edec3a9d3a0f57eeafa179810254f060a54bfeedf3d4269f13a0000000000ffffffff5531bbd9c004c69fff9374918f9eb64a3603c045d38362002e25a06316e7d73f0000000000ffffffff6f116755042b1b1aef9d809ab04f79afa63f71aa31616c2daa1a7d82d305b13a0000000000ffffffffef1a5d83a8cd639224c9876fe1e157a3ed239d596d2bb62c556c9dcc1bb55037000000001976a9142926402d832870745c37979bdff8f030e6a2d75988acffffffff01ccba0f00000000001976a9142926402d832870745c37979bdff8f030e6a2d75988ac0000000001000000

p  = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
r  = 0x1cf895af787f8d897cbb72bf9d39d3edbd603c4b23ea8f2f3dfaafc9e3fa5907
s1 = 0x62f8260583709b26b102af5ab4c615073921a0af1d21b9a0e96969307ff3a44e
s2 = 0x17d4a1b146b7dcebbb604574f90f4569e18f7ab7f828cdd9ee5a2cce59cb09a4
z1 = 0x40ea4996d6395deb065a93d66424901513bddfb2ddf405493a41bf7a0bbb7384
z2 = 0xe6b7ebcd68dcf20b83d238e04d6601dd9a070b5b65b941529e2074c10888efe8

K = GF(p)
K((z1*s2 - z2*s1)/(r*(s1-s2)))

But in summary I getting this value of PK:

dec: 40047461853181506903710401524154105044947235713778347330990385830425961756207
hex: 588a0f66409dc2d17a2f1c3ec2d1d1bf515da3edbfccb945d6c5078944f4f62f
wif: 5JVHCVnzJQdarD46gtoQzaj6x1cAkkamNXgYjmtt4uNAyDcdUMu

But this PK wrong. Maybe I should use different value for p(eliptic curve) or try other inputs?

@Ruby3434
Copy link

Ruby3434 commented Nov 24, 2022

@nlitsme Can you help please?

@nlitsme
Copy link
Author

nlitsme commented Nov 24, 2022

your message hashes are wrong:
z1 = 0xc3d27af32c188f3698c62e6c67c6ea866a7bf0ec49cfc6a78b7bc6b2e84c15f5
z2 = 0x91a1a1bfb6409d876258bc25f610309354d37e15bb84b3e1e6b34d419bfad663

@Ruby3434
Copy link

@nlitsme How did you calculated them?

@nlitsme
Copy link
Author

nlitsme commented Nov 27, 2022

like this:

shasha(
 01000000
 05  -- inputs
   e75a72a15d95a874e05531f005c5dff4047c6b6f25990baf54045209e10f9713 02000000  00  ffffffff
   8ea572f15ad54edec3a9d3a0f57eeafa179810254f060a54bfeedf3d4269f13a 00000000  00  ffffffff
   5531bbd9c004c69fff9374918f9eb64a3603c045d38362002e25a06316e7d73f 00000000  00  ffffffff
   6f116755042b1b1aef9d809ab04f79afa63f71aa31616c2daa1a7d82d305b13a 00000000  19 76a914c5f5c988280fb5794f56421f8368ef8456c3872b88ac   ffffffff
   ef1a5d83a8cd639224c9876fe1e157a3ed239d596d2bb62c556c9dcc1bb55037 00000000  00  ffffffff
 01  -- outputs
   ccba0f0000000000  1976a9142926402d832870745c37979bdff8f030e6a2d75988ac
 00000000 -- locktime
 01000000
) = c3d27af32c188f3698c62e6c67c6ea866a7bf0ec49cfc6a78b7bc6b2e84c15f5


shasha(
 01000000
 05  -- inputs
   e75a72a15d95a874e05531f005c5dff4047c6b6f25990baf54045209e10f9713 02000000  00  ffffffff
   8ea572f15ad54edec3a9d3a0f57eeafa179810254f060a54bfeedf3d4269f13a 00000000  00  ffffffff
   5531bbd9c004c69fff9374918f9eb64a3603c045d38362002e25a06316e7d73f 00000000  00  ffffffff
   6f116755042b1b1aef9d809ab04f79afa63f71aa31616c2daa1a7d82d305b13a 00000000  00  ffffffff
   ef1a5d83a8cd639224c9876fe1e157a3ed239d596d2bb62c556c9dcc1bb55037 00000000  19 76a914c5f5c988280fb5794f56421f8368ef8456c3872b88ac ffffffff
 01  -- outputs
   ccba0f0000000000  1976a9142926402d832870745c37979bdff8f030e6a2d75988ac
 00000000 -- locktime
 01000000
) = 91a1a1bfb6409d876258bc25f610309354d37e15bb84b3e1e6b34d419bfad663

you used the output of this transaction to replace in the input, instead, you should use the output of the referenced transaction.

@debruss
Copy link

debruss commented Nov 8, 2024

Maybe a bit late, I am currently writing my own parser for these bitcoin transactions, but I cannot seem to find the message hash value in the case of a P2PK input. For example, I am trying to decode the following transaction: 99f44a1e654e57c0d9918d2d2df728093cde0ed9e768c50737b3b77a37a656fb. Which will look like this:

01000000
07
06b0efadaca4766a7d2e5427f9a803b151cbc4486205d5248806870ce7de8e8e
	00000000
	8b
		483045
			02205706a053d30e90def1e863b2c8ec0f0c462e565cc19090c4926f105664d1bdf0
			022100c264b37bdf4ffb6174c13c6cd9f22ed3f8b66fc15ae37408a22902fb07175acc
			01
		4104d6597d465408e6e11264c116dd98b539740e802dc756d7eb88741696e20dfe7d3588695d2e7ad23cbf0aa056d42afada63036d66a1d9b97070dd6bc0c87ceb0d
	ffffffff
8d48030e9030168697d03541206be1368365693ce8077ecaf18c0d717776fac1
	00000000
	48
		473044
			02204b9e098bcc5deb14ec868f53bf6ed38d2a45b4f13a13bb10e9b3b67a633b47b6
			0220468e7fd9c901c6201eced5abfc4a52522f6e0e7dd60bbfc7c71a213b5ace1712
			01
	ffffffff
978697cf864708dc8e1690b1dd0cf3f7c8d660de46ec4b65cd2c8d22240a04aa
	00000000
	49
		483045
			022100d55c0ec773f417e37b4958c6e4564f19e7ce562cebef555ff80e7ca78e4d04aa
			02201ce8ef31dc40cdd6b46986db9d5267292b9fdc150e03603cbd7499aee0c0f814
			01
		ffffffff
a7739658a9b0c3b35a46fa0062db7a0077d012ce57ce68c3fa366694e3314fa4
	00000000
	49
		483045
			022100ab57dd743e0fdea93389f7a3ba65855d47000a789cdea3245f9e7834faadd6d4
			022016998895ab0d73cb88f1ac900c80aba2ebe2e852c0a53159d937b73f4ad42b76
			01
		ffffffff
e978ce3d437cd840fb272037b34022285a12a3ec4ebc61ff1e1bbf232887d4de
	00000000
	48
		473044
			022012523db1c172ca4b63208d4289a70b1e17b23e082ad06086ed5fb24b4e116252
			0220484b1a52abe13f1b47c447d6003bca0c0c786a5fe978c45d3c59eccc8cf9474b
			01
		ffffffff
f87adde1214e4d1dc2b167eb7961294beecf0c11a02fb1712ba875c2ba9d2e7f
	00000000
	4a
		493046
			022100d423dd7705b1881d7398109fdc1119681cc2f91ee4baa38d7a78f96d43884f11
			0221009d0cb81043bf95f47fb3e508e2ee9fec999cfbdc03f3ffdbe320058f8676de61
			01
		ffffffff
faef25ac1a490387b13148a713df92fb170180d1980a20233812d75716351fcc
	00000000
	49
		483045
			02206a58f73b4964d70897f434440dc39b5bce7838d6dcdeff2c64d628b48cb28d43
			0221009b1808a574626953f907170eeaf8de2c03c4b4df46e64377a5fd699709a4a2c2
			01
		ffffffff
		
01
	00e8764817000000
	19
	76a9140366041c1c1e5dfe19bbfdef94fe25a9340ab24588ac
00000000

How would you calculate the corresponding message hash? Thank you in advance!

@nlitsme
Copy link
Author

nlitsme commented Nov 8, 2024

I will answer the rest later, but here are the messagehashes you are looking for:

d7e2d1625a7daaa8e7efdd9d8e1b0140b8846ab3c465fd9499139ecd2639946a
c8059ab8d05bc82d46020d868e0a918408432081431059f681c178df811b8765
5e0d6b232ca796370e0e75d961b94e838657b88c5d7d6462054496c8454ac20a
8d6a5c54d27b2b67b2f5684d8efac7611aed7958a8a31bfc3c13796b22d320e8
c12d9c63a5354988b6e8e3e363ff02f862885b52744c0a7afd6eb565bb4a278d
c4ff1e486700de85a35c68c3d3f4fc2a004ca50e201e2cecedf7ee2ba2d6004e
f8a51cee5cf36846c37f2668ff48b91a977b2701781c8eff954a2aa7dc8bf293

@nlitsme
Copy link
Author

nlitsme commented Nov 9, 2024

shasha {  -- calculate the transaction hash
01000000
07  -- inputs
  06b0efadaca4766a7d2e5427f9a803b151cbc4486205d5248806870ce7de8e8e00000000  8b48304502205706a053d30e90def1e863b2c8ec0f0c462e565cc19090c4926f105664d1bdf0022100c264b37bdf4ffb6174c13c6cd9f22ed3f8b66fc15ae37408a22902fb07175acc014104d6597d465408e6e11264c116dd98b539740e802dc756d7eb88741696e20dfe7d3588695d2e7ad23cbf0aa056d42afada63036d66a1d9b97070dd6bc0c87ceb0d  ffffffff
  8d48030e9030168697d03541206be1368365693ce8077ecaf18c0d717776fac100000000  4847304402204b9e098bcc5deb14ec868f53bf6ed38d2a45b4f13a13bb10e9b3b67a633b47b60220468e7fd9c901c6201eced5abfc4a52522f6e0e7dd60bbfc7c71a213b5ace171201  ffffffff
  978697cf864708dc8e1690b1dd0cf3f7c8d660de46ec4b65cd2c8d22240a04aa00000000  49483045022100d55c0ec773f417e37b4958c6e4564f19e7ce562cebef555ff80e7ca78e4d04aa02201ce8ef31dc40cdd6b46986db9d5267292b9fdc150e03603cbd7499aee0c0f81401  ffffffff
  a7739658a9b0c3b35a46fa0062db7a0077d012ce57ce68c3fa366694e3314fa400000000  49483045022100ab57dd743e0fdea93389f7a3ba65855d47000a789cdea3245f9e7834faadd6d4022016998895ab0d73cb88f1ac900c80aba2ebe2e852c0a53159d937b73f4ad42b7601  ffffffff
  e978ce3d437cd840fb272037b34022285a12a3ec4ebc61ff1e1bbf232887d4de00000000  48473044022012523db1c172ca4b63208d4289a70b1e17b23e082ad06086ed5fb24b4e1162520220484b1a52abe13f1b47c447d6003bca0c0c786a5fe978c45d3c59eccc8cf9474b01  ffffffff
  f87adde1214e4d1dc2b167eb7961294beecf0c11a02fb1712ba875c2ba9d2e7f00000000  4a493046022100d423dd7705b1881d7398109fdc1119681cc2f91ee4baa38d7a78f96d43884f110221009d0cb81043bf95f47fb3e508e2ee9fec999cfbdc03f3ffdbe320058f8676de6101  ffffffff
  faef25ac1a490387b13148a713df92fb170180d1980a20233812d75716351fcc00000000  4948304502206a58f73b4964d70897f434440dc39b5bce7838d6dcdeff2c64d628b48cb28d430221009b1808a574626953f907170eeaf8de2c03c4b4df46e64377a5fd699709a4a2c201  ffffffff
01  -- outputs
  00e8764817000000  1976a9140366041c1c1e5dfe19bbfdef94fe25a9340ab24588ac
00000000 -- locktime
} = fb56a6377ab7b33707c568e7d90ede3c0928f72d2d8d91d9c0574e651e4af499



shasha {  -- calculate the first message hash
01000000
07 -- inputs
06b0efadaca4766a7d2e5427f9a803b151cbc4486205d5248806870ce7de8e8e 00000000 19 76a91412d5a845f2b212ce0c3bd65a4035881d9219090e88ac ffffffff
8d48030e9030168697d03541206be1368365693ce8077ecaf18c0d717776fac1 00000000 00 ffffffff
978697cf864708dc8e1690b1dd0cf3f7c8d660de46ec4b65cd2c8d22240a04aa 00000000 00 ffffffff
a7739658a9b0c3b35a46fa0062db7a0077d012ce57ce68c3fa366694e3314fa4 00000000 00 ffffffff
e978ce3d437cd840fb272037b34022285a12a3ec4ebc61ff1e1bbf232887d4de 00000000 00 ffffffff
f87adde1214e4d1dc2b167eb7961294beecf0c11a02fb1712ba875c2ba9d2e7f 00000000 00 ffffffff
faef25ac1a490387b13148a713df92fb170180d1980a20233812d75716351fcc 00000000 00 ffffffff
01 -- outputs
	00e8764817000000 19 76a9140366041c1c1e5dfe19bbfdef94fe25a9340ab24588ac
00000000 -- locktime
01000000 -- hashtype
} = d7e2d1625a7daaa8e7efdd9d8e1b0140b8846ab3c465fd9499139ecd2639946a

shasha {  -- calculate the second message hash
01000000
07 -- inputs
06b0efadaca4766a7d2e5427f9a803b151cbc4486205d5248806870ce7de8e8e 00000000 00 ffffffff
8d48030e9030168697d03541206be1368365693ce8077ecaf18c0d717776fac1 00000000 43 410400c8c1c85fad0268352e67bd6c7db759d37fe943ec84578f843e6568e7f6ca5dd6d4c0da32105861cd8a19fa807919dda7fe28269714d502369d243faf96be3cac ffffffff
978697cf864708dc8e1690b1dd0cf3f7c8d660de46ec4b65cd2c8d22240a04aa 00000000 00 ffffffff
a7739658a9b0c3b35a46fa0062db7a0077d012ce57ce68c3fa366694e3314fa4 00000000 00 ffffffff
e978ce3d437cd840fb272037b34022285a12a3ec4ebc61ff1e1bbf232887d4de 00000000 00 ffffffff
f87adde1214e4d1dc2b167eb7961294beecf0c11a02fb1712ba875c2ba9d2e7f 00000000 00 ffffffff
faef25ac1a490387b13148a713df92fb170180d1980a20233812d75716351fcc 00000000 00 ffffffff
01 -- outputs
	00e8764817000000 19 76a9140366041c1c1e5dfe19bbfdef94fe25a9340ab24588ac
00000000 -- locktime
01000000 -- hashtype
} = c8059ab8d05bc82d46020d868e0a918408432081431059f681c178df811b8765

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment