Post
Topic
Board Development & Technical Discussion
Re: lightweight database, for brute force using publickeys-32Mk =3.81MB(secp256k1)
by
mcdouglasx
on 04/12/2023, 18:01:49 UTC
I wrote the both scripts:

create_database_arulbero.py
search_key_arulbero.py


parameters:

private key interval: from 1 to 2^32
keys stored: 2^32 / 2^7 = 2^25 (1 each 128)
bits for each key = 64
size of database: 257 MB

time to create the database: 3 min 55 s

time to find the private key of a single random public key in the db: 0.1 - 0.3 s




create_database_arulbero.py

Code:
#!/usr/bin/env python3
# 2023/Dec/03, create_database_arulbero.py
import secp256k1 as ice

#############################################################################
# Set the number of public keys to generate
#############################################################################
start_key = 1
num_public_keys = 2**32 #(about 4 billions of keys)
bits_to_store = 64
bytes_to_store = bits_to_store//8
rate_of_key_to_generate = 128
rate_of_key_to_store = rate_of_key_to_generate

interval_to_generate = range(start_key, start_key + num_public_keys, rate_of_key_to_store)
interval_to_store = range(start_key,start_key + num_public_keys,rate_of_key_to_store)

binary_mode = 1

#############################################################################


if (binary_mode == 1):

f = open("public_keys_database.bin", "wb") #binary mode

########################################generation#############################################
public_keys=[]


public_keys_complete=list(map(ice.scalar_multiplication,interval_to_generate)) #generates the public keys complete
public_keys=list(map(lambda w: int(w[33-bytes_to_store:33].hex(),16),public_keys_complete)) #extract only the last bytes_to_store



########################################writing the db##########################################
for i in range(0,len(interval_to_store)):
f.write(public_keys[i].to_bytes(bytes_to_store,byteorder='big'))  #writes each key

f.close()

else:

f = open("public_keys_database.txt", "w")

#generation
public_keys=[]

for i in interval_to_generate:
P4 = ice.scalar_multiplication(i)
public_keys.append(P4[33-bytes_to_store:33].hex())

#writing the db
for i in range(0,len(interval_to_store)):
f.write(public_keys[i])

f.close()

search_key_arulbero.py
Code:
# 2023/Dec/03, search_key_arulbero.py
import secp256k1 as ice
import random
import sys

#############################################################################
# Set the number of public keys to generate
#############################################################################

start_key = 1
num_public_keys = 2**32
bits_to_store = 64
bytes_to_store = bits_to_store//8
rate_of_key_to_generate = 128
rate_of_key_to_store = rate_of_key_to_generate

split_database = 16 #read only a fraction of the database to speedup the finding of the string

interval_to_generate = range(start_key,start_key + num_public_keys, rate_of_key_to_store)

interval_to_store = range(start_key,start_key + num_public_keys,rate_of_key_to_store)

binary_mode = 1



#########################################################################################

#pk = 0x3243 = 12867
#P = ice.scalar_multiplication(12867)
#P="0x6800b#b8a9dffe1709ceac95d7d06646188c2cb656c09cd2e717ec67487ce1be3"


#############generates random private key and public key#################################
pk= random.randint(start_key, start_key + num_public_keys)
P = ice.scalar_multiplication(pk)
print()
print("This is the public key: " + P[1:33].hex())
print("I need to find this private key: "+str(pk))


###################subtraction of : P - 1G,  P - 2G, ..., P - rate_of_key*G################
substract_pub = ice.scalar_multiplication(1)
complete_pub= ice.point_loop_subtraction(rate_of_key_to_generate, P, substract_pub)


partial_pub=[] #need only the last bytes_to_store
P2=int(P[33-bytes_to_store:33].hex(),16).to_bytes(bytes_to_store,byteorder='big')
partial_pub.append(P2)

for i in range(1,rate_of_key_to_store+1):
partial_pub.append(int(complete_pub[(i-1)*65+33-bytes_to_store:(i-1)*65+33].hex(),16).to_bytes(bytes_to_store,byteorder='big'))




################search in database##########################################################
with open("public_keys_database.bin", 'r+b') as f:

s = f.read()
l=len(s)

for k in range(0,l, l//split_database):
j=1
for i in partial_pub:
n = s[k:k+l//split_database].find(i)
if n > -1:
print()
print("Private key found!!!")
private_key = (n+k)//bytes_to_store*rate_of_key_to_generate + j
print(private_key)
P3 = ice.scalar_multiplication(private_key)
pub_key=P3[1:33].hex()
print((pub_key)[:])
f.close()
sys.exit(0)
j=j+1


print("string not found")


f.close()
 


Do you store fewer keys and more bits? When we use bytes we search in byte packets, so you are closer to traditional databases than to the idea presented here.
so you can take any pub, and store its first bytes without going through bit counting and it would give the same result because you have to find an explicit pk that meets certain parameters, which was the main problem.