updated 08/03/2024.
The Baby Step Giant Step (BSGS) algorithm is used to solve the discrete logarithm problem efficiently in a cyclic group. The algorithm works by breaking down the problem into two steps:
Baby Steps In this step, we calculate a list of baby steps by iteratively raising the generator g to different powers. We start with j = 0 and calculate g^j for values of j from 0 up to m-1 , where m is typically chosen as the square root of the group order n . We store each calculation in
1 bit per key, this is the highlight because it considerably minimizes the size of our database.
binary baby step200000 Keys
#by mcdouglasx
import secp256k1 as ice
from bitstring import BitArray
print("creating Baby Step")
#create baby step
num = 200000 # Keys number in Binary Babystep. same m in search script
Low_m= 20
lm= num // Low_m
Add = 1
Add_pub= ice.scalar_multiplication(Add)
res= ice.point_sequential_increment(lm, Add_pub)
binary = ''
for t in range (lm):
h= (res[t*65:t*65+65]).hex()
hc= int(h[2:], 16)
if hc % 2 == 0:
A="0"
binary+= ''.join(str(A))
else:
A="1"
binary+= ''.join(str(A))
my_str = (BitArray(bin=binary))#bin=binary
binary_file = open('baby_steps__binary.bin', 'ab')
my_str.tofile(binary_file)
binary_file.close()
for i in range (1,Low_m):
print("stage: "+ str(i+1)+"/"+str(20))
lm_upub= ice.scalar_multiplication((lm*i))
res= ice.point_sequential_increment(lm, lm_upub)
binary = ''
for t in range (lm):
h= (res[t*65:t*65+65]).hex()
hc= int(h[2:], 16)
if hc % 2 == 0:
A="0"
binary+= ''.join(str(A))
else:
A="1"
binary+= ''.join(str(A))
my_str = (BitArray(bin=binary))#bin=binary
binary_file = open('baby_steps__binary.bin', 'ab')
my_str.tofile(binary_file)
binary_file.close()
Giant Steps In this step, we perform giant steps by multiplying, this approach is efficient because it reduces the search space for the discrete logarithm from O(n) to O(sqrt(n)) , significantly speeding up the computation for large cyclic groups.
search script#@author: iceland, modified by @mcdouglasx
import secp256k1 as ice
import time
import random
import os
from bitstring import BitArray
import numpy as np
#Pk: 1033162084 puzzle #30
Target = '030d282cf2ff536d2c42f105d0b8588821a915dc3f9a05bd98bb23af67a2e92a5b'
start= 536870911
end= 1073741823
m = 200000 # Keys number in Binary Babystep
Add = 1
Add_pub = ice.scalar_multiplication(Add)
Cm = 64
public_key = ice.pub2upub(Target)
bs_file = 'baby_steps__binary.bin'
Q = public_key
Pi = ice.pub2upub("020000000000000000000000000000000000000000000000000000000000000000")
# Find baby step file
valid = os.path.isfile(bs_file)
if valid:
print(f'Found the Baby Steps Table file: {bs_file}. Will be used directly')
file = bytes(np.fromfile(bs_file))
baby_steps = BitArray(file)
else:
print(f'Not Found {bs_file}. You must create this file now.')
k1 = random.randint(start, end)
k2 = k1 + m * m
print(f'Checking {m * m} keys from {(k1)}')
# Start time
st = time.time()
k1G = ice.scalar_multiplication(k1)
mG = ice.scalar_multiplication(m)
# Find key
def findkey(onePoint):
S = ice.point_subtraction(onePoint, k1G)
if S == Pi:
return k1 # Point at Infinity
found = False
step = 0
while not found and step < (1 + k2 - k1):
Sx_1 = ice.point_sequential_increment(Cm, S)
binary = ''
for t in range(Cm):
h = (Sx_1[t * 65:t * 65 + 65]).hex()
hc = int(h[2:], 16)
A = "0" if hc % 2 == 0 else "1"
binary += A
b = BitArray(bin=binary)
c = bytes(b)
Sw = c
if b in baby_steps:
s = c
f = BitArray(baby_steps)
inx = f.find(s)
inx_1 = str(inx).replace(",", "").replace("(", "").replace(")", "")
b = int(inx_1)
found = True
break
else:
# Giant step
S = ice.point_subtraction(S, mG)
step += m
if found:
final_key = (k1 + step + b + 1) - 1
else:
final_key = -1
return final_key
final_key = findkey(Q)
if final_key > 0:
print(f'BSGS FOUND PrivateKey: {final_key}')
with open("win.txt", "a") as data:
A0 = ice.scalar_multiplication(final_key)
A1 = ice.pubkey_to_address(0,1, A0)
data.write(f"private key = {final_key}\n")
data.write(f"address = {A1}\n")
data.write(f"Time Spent: {time.time() - st:.2f} seconds\n")
else:
print('PrivateKey Not Found')
print(f"Time Spent: {time.time() - st:.2f} seconds")
This script is just an idea, it is not intended to be fast.
Make your own version in C.
This is a modification of Iceland's work.