В блокчейне недавно появился ЕЩЁ ОДИН адрес начинающийся с цифры 3, причём на нем более 134к
BTC.
https://blockchain.info/ru/address/3HyULbPVM739jPVk4i3PKZ4LibhYP1HsLc,
а также новый лидер по количеству
BTChttps://blockchain.info/ru/address/1JoktQJhCzuCQkt3GnQ8Xddcq4mUgNyXEa 217к+
BTCЕщё попалась интересная транзакция:
https://blockchain.info/ru/tx/57d43778ff225de4dbcfeeb6a37b72b8d05d356f3340b15fe6baa7eeba556245В которой отправляются битки на очень необычные адреса вида 1BitcoinKicksAss1111111111114BbAUx, хотя все они не израсходованы, видимо приватных ключей нигде для них нет...
Из различных сообщений форума на питоне накропал генератор адресов, который сравнивает сгенерированные адреса со списком адресов из файла (выложен
https://bitcointalksearch.org/topic/m.3885194).
Для работы файл с адресами должен называться BTC2.txt.
Генерация 1000 адресов на моём ноуте примерно 70 секунд. Сравнение этих адресов с базой 350к адресов (переменная count) примерно 12 секунд.
Ведётся лог через каждые 1000 адресов. В случае совпадения, сохранится файл result.txt с адресом и его приватным ключём в формате ECDSA (т.е. секретной экспоненты).
Вероятность нахождения совпадения в триллиарды триллиардов раз меньше, чем отыскать блок с помощью тогоже процессора (хотя надо посчитать, это так, навскидку), но ОНА ЕСТЬ!!!
Для запуска кода нужен питон, версии 2.7 достаточно.
Здесьбы ещё генератор из андроида подключить...
За код сильно не бейте.
А собранным парсером под Win никто не поделится, боюсь что сам собрать не смогу...
#! /usr/bin/env python
# -*- coding: utf-8 -*-
b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
import hashlib
import time
import random
def hex_open_key_to_hex_hesh160(hex_open_key):
h160 = hashlib.new('ripemd160')
h160.update(hashlib.sha256(('04'+hex_open_key).decode('hex')).hexdigest().decode('hex'))
return h160.hexdigest()
def hex_hesh160_to_hex_addr_v0(hex_hesh160):
return '00'+hex_hesh160+hashlib.sha256(hashlib.sha256(('00'+hex_hesh160).decode('hex')).hexdigest().decode('hex')).hexdigest()[0:8]
def hex_addr_v0_to_hex_hesh160(hex_addr_v0):
return hex_addr_v0[2:-8]
def hex_to_base58(hex_data):
base58 = ''
int_data = int(hex_data, 16)
while int_data >= len(b58chars):
base58 = b58chars[int_data%len(b58chars)] + base58
int_data = int_data/len(b58chars)
base58 = b58chars[int_data%len(b58chars)] + base58
for i in xrange(len(hex_data)/2):
if hex_data[i*2:i*2+2] == '00':
base58 = '1' + base58
else:
break
return base58
def base58_to_hex(base58):
hex_data = ''
int_data = 0
for i in xrange(-1, -len(base58)-1, -1):
int_data += (b58chars.index(base58[i]))*58**(-i-1)
hex_data = hex(int_data)[2:-1]
for i in xrange(len(base58)):
if base58[i] == '1':
hex_data = '00' + hex_data
else:
break
return hex_data
class CurveFp( object ):
def __init__( self, p, a, b ):
self.__p = p
self.__a = a
self.__b = b
def p( self ):
return self.__p
def a( self ):
return self.__a
def b( self ):
return self.__b
def contains_point( self, x, y ):
return ( y * y - ( x * x * x + self.__a * x + self.__b ) ) % self.__p == 0
class Point( object ):
def __init__( self, curve, x, y, order = None ):
self.__curve = curve
self.__x = x
self.__y = y
self.__order = order
if self.__curve: assert self.__curve.contains_point( x, y )
if order: assert self * order == INFINITY
def __add__( self, other ):
if other == INFINITY: return self
if self == INFINITY: return other
assert self.__curve == other.__curve
if self.__x == other.__x:
if ( self.__y + other.__y ) % self.__curve.p() == 0:
return INFINITY
else:
return self.double()
p = self.__curve.p()
l = ( ( other.__y - self.__y ) * \
inverse_mod( other.__x - self.__x, p ) ) % p
x3 = ( l * l - self.__x - other.__x ) % p
y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
return Point( self.__curve, x3, y3 )
def __mul__( self, other ):
def leftmost_bit( x ):
assert x > 0
result = 1
while result <= x: result = 2 * result
return result / 2
e = other
if self.__order: e = e % self.__order
if e == 0: return INFINITY
if self == INFINITY: return INFINITY
assert e > 0
e3 = 3 * e
negative_self = Point( self.__curve, self.__x, -self.__y, self.__order )
i = leftmost_bit( e3 ) / 2
result = self
while i > 1:
result = result.double()
if ( e3 & i ) != 0 and ( e & i ) == 0: result = result + self
if ( e3 & i ) == 0 and ( e & i ) != 0: result = result + negative_self
i = i / 2
return result
def __rmul__( self, other ):
return self * other
def __str__( self ):
if self == INFINITY: return "infinity"
return "(%d,%d)" % ( self.__x, self.__y )
def double( self ):
if self == INFINITY:
return INFINITY
p = self.__curve.p()
a = self.__curve.a()
l = ( ( 3 * self.__x * self.__x + a ) * \
inverse_mod( 2 * self.__y, p ) ) % p
x3 = ( l * l - 2 * self.__x ) % p
y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
return Point( self.__curve, x3, y3 )
def x( self ):
return self.__x
def y( self ):
return self.__y
def curve( self ):
return self.__curve
def order( self ):
return self.__order
INFINITY = Point( None, None, None )
def inverse_mod( a, m ):
if a < 0 or m <= a: a = a % m
c, d = a, m
uc, vc, ud, vd = 1, 0, 0, 1
while c != 0:
q, c, d = divmod( d, c ) + ( c, )
uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc
assert d == 1
if ud > 0: return ud
else: return ud + m
class Signature( object ):
def __init__( self, r, s ):
self.r = r
self.s = s
class Public_key( object ):
def __init__( self, generator, point ):
self.curve = generator.curve()
self.generator = generator
self.point = point
n = generator.order()
if not n:
raise RuntimeError, "Generator point must have order."
# if not n * point == INFINITY:
# raise RuntimeError, "Generator point order is bad."
if point.x() < 0 or n <= point.x() or point.y() < 0 or n <= point.y():
raise RuntimeError, "Generator point has x or y out of range."
def verifies( self, hash, signature ):
G = self.generator
n = G.order()
r = signature.r
s = signature.s
if r < 1 or r > n-1: return False
if s < 1 or s > n-1: return False
c = inverse_mod( s, n )
u1 = ( hash * c ) % n
u2 = ( r * c ) % n
xy = u1 * G + u2 * self.point
v = xy.x() % n
return v == r
class Private_key( object ):
def __init__( self, public_key, secret_multiplier ):
self.public_key = public_key
self.secret_multiplier = secret_multiplier
def der( self ):
hex_der_key = '06052b8104000a30740201010420' + \
'%064x' % self.secret_multiplier + \
'a00706052b8104000aa14403420004' + \
'%064x' % self.public_key.point.x() + \
'%064x' % self.public_key.point.y()
return hex_der_key.decode('hex')
def sign( self, hash, random_k ):
G = self.public_key.generator
n = G.order()
k = random_k % n
p1 = k * G
r = p1.x()
if r == 0: raise RuntimeError, "amazingly unlucky random number r"
s = ( inverse_mod( k, n ) * \
( hash + ( self.secret_multiplier * r ) % n ) ) % n
if s == 0: raise RuntimeError, "amazingly unlucky random number s"
return Signature( r, s )
# secp256k1
_p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
_r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
_b = 0x0000000000000000000000000000000000000000000000000000000000000007
_a = 0x0000000000000000000000000000000000000000000000000000000000000000
_Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
_Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
curve_256 = CurveFp( _p, _a, _b )
generator_256 = Point( curve_256, _Gx, _Gy, _r )
g = generator_256
if __name__ == "__main__":
print '======================================================================='
time.clock()
randrange = random.SystemRandom().randrange
n = g.order()
count = 350000
f = open('BTC2.txt')
print 'Open file...'
lines = f.readlines()
print 'Reads', len (lines), 'lines'
print 'Close file'
print 'view fist', count, 'wallets'
f.close()
lines = lines [0:count]
for m in xrange (0, len (lines)):
lines[m] = lines[m] [0:-1]
keys_number = 0
found = 0
while 1:
secret = randrange( 1, n )
sec = [secret]
pubkey = Public_key( g, g * secret)
hex_open_key_x = '%s' % (hex (pubkey.point.x()))
hex_open_key_x = hex_open_key_x [2:-1]
while len (hex_open_key_x) != 64:
hex_open_key_x = '0'+ hex_open_key_x
hex_open_key_y = '%s' % (hex (pubkey.point.y()))
hex_open_key_y = hex_open_key_y [2:-1]
while len (hex_open_key_y) != 64:
hex_open_key_y = '0'+ hex_open_key_y
hex_open_k = '%s' % (hex_open_key_x)
hex_open_key = [hex_open_k + '%s' % (hex_open_key_y)]
# if (hex_open_key) != 128:
# hex_open_key [0] = '40f9f833a25c725402e242965410b5bb992dc4fea1328681f0a74571c3104e360882ea6ae14b6b1316e71e76cc51867cba20cafabd349753058b8c4677be50ca'
keys_number += 1
k = 1000
print 'Start generation', k, 'keys', time.strftime("%H:%M:%S",time.localtime())
for x in xrange (1,k):
secret = randrange( 1, n )
sec.append (secret)
pubkey = Public_key( g, g * secret)
hex_open_key_x = '%s' % (hex (pubkey.point.x()))
hex_open_key_x = hex_open_key_x [2:-1]
while len (hex_open_key_x) != 64:
hex_open_key_x = '0'+ hex_open_key_x
hex_open_key_y = '%s' % (hex (pubkey.point.y()))
hex_open_key_y = hex_open_key_y [2:-1]
while len (hex_open_key_y) != 64:
hex_open_key_y = '0'+ hex_open_key_y
hex_open_k = '%s' % (hex_open_key_x)
hex_open_k = hex_open_k + '%s' % (hex_open_key_y)
hex_open_key.append (hex_open_k)
keys_number += 1
# sec.append (0x1111111fffffff)
# hex_open_k = '3def92212183d5ebad9aeeff151e3af583c92ca7a96ed48be026fe9e5bd9a57ec4cd5170a41e2a3b6e4cf1c1489f95b8ee46404f4b536adab9d51cd3019761e0'
# hex_open_key.append (hex_open_k)
# print sec
# print 'Massiv=', len (sec), len (hex_open_key), 'elements'
print 'Stop generation', k, 'keys', time.strftime("%H:%M:%S",time.localtime())
print 'Verifing...'
for x in xrange (0, len (sec)):
adress = hex_to_base58(hex_hesh160_to_hex_addr_v0(hex_open_key_to_hex_hesh160(hex_open_key [x])))
if (adress in lines) :
temp_sec = '%s' % (hex (sec[x]))
temp_sec = temp_sec [2:-1]
print 'Found exponent for', adress, ' ', temp_sec
f = open ('result.txt', 'a')
line_to_wr = adress + ' ' + temp_sec +'\n'
f.writelines(line_to_wr)
f.close()
found += 1
print 'verifies', keys_number, 'keys on', time.strftime("%H:%M:%S",time.localtime()), 'Found', found, 'keys'
print '======================================================================='
Примерный лог:
=======================================================================
Open file...
Reads 789983 lines
Close file
view fist 350000 wallets
Start generation 1000 keys 12:02:28
Stop generation 1000 keys 12:03:41
Verifing...
verifies 1000 keys on 12:03:53 Found 0 keys
=======================================================================
Start generation 1000 keys 12:03:53
Stop generation 1000 keys 12:05:06
Verifing...
verifies 2000 keys on 12:05:15 Found 0 keys
=======================================================================
Start generation 1000 keys 12:05:15
Stop generation 1000 keys 12:06:30
Verifing...
verifies 3000 keys on 12:06:39 Found 0 keys
=======================================================================
Start generation 1000 keys 12:06:39
Stop generation 1000 keys 12:08:01
Verifing...
verifies 4000 keys on 12:08:11 Found 0 keys
=======================================================================
Start generation 1000 keys 12:08:11
Stop generation 1000 keys 12:09:35
Verifing...
verifies 5000 keys on 12:09:45 Found 0 keys
=======================================================================
Start generation 1000 keys 12:09:45
Stop generation 1000 keys 12:11:11
Verifing...
verifies 6000 keys on 12:11:21 Found 0 keys
=======================================================================
Start generation 1000 keys 12:11:21
Stop generation 1000 keys 12:12:47
Verifing...
verifies 7000 keys on 12:12:57 Found 0 keys
=======================================================================
Start generation 1000 keys 12:12:57
Stop generation 1000 keys 12:14:23
Verifing...
verifies 8000 keys on 12:14:34 Found 0 keys
=======================================================================
Start generation 1000 keys 12:14:34
Stop generation 1000 keys 12:16:06
Verifing...
verifies 9000 keys on 12:16:17 Found 0 keys
=======================================================================
Start generation 1000 keys 12:16:17
Stop generation 1000 keys 12:18:04
Verifing...
verifies 10000 keys on 12:18:14 Found 0 keys
=======================================================================
Start generation 1000 keys 12:18:14
Stop generation 1000 keys 12:19:47
Verifing...
verifies 11000 keys on 12:19:58 Found 0 keys
=======================================================================