Can you please explain in details for us noobs how this works and what we need to change when searching for our desired keys?
Also what do you mean by solving 65 without needing a public key, do you search for address or something?
Do you happen to have a python code for it, even if it's slow. Or isn't it better to ask ai to convert the code into python? Is that even possible?
Edit:
Here is a working script which divides 2 points by start/end range and then subtracts the results of division from each other.
No external module/ library needed, just run the script.
# Define the EllipticCurve class
class EllipticCurve:
def __init__(self, a, b, p):
self.a = a
self.b = b
self.p = p
def contains(self, point):
x, y = point.x, point.y
return (y * y) % self.p == (x * x * x + self.a * x + self.b) % self.p
def __str__(self):
return f"y^2 = x^3 + {self.a}x + {self.b} mod {self.p}"
# Define the Point class
class Point:
def __init__(self, x, y, curve):
self.x = x
self.y = y
self.curve = curve
def __eq__(self, other):
return self.x == other.x and self.y == other.y and self.curve == other.curve
def __ne__(self, other):
return not self == other
def __add__(self, other):
if self.curve != other.curve:
raise ValueError("Cannot add points on different curves")
# Case when one point is zero
if self == Point.infinity(self.curve):
return other
if other == Point.infinity(self.curve):
return self
if self.x == other.x and self.y != other.y:
return Point.infinity(self.curve)
p = self.curve.p
s = 0
if self == other:
s = ((3 * self.x * self.x + self.curve.a) * pow(2 * self.y, -1, p)) % p
else:
s = ((other.y - self.y) * pow(other.x - self.x, -1, p)) % p
x = (s * s - self.x - other.x) % p
y = (s * (self.x - x) - self.y) % p
return Point(x, y, self.curve)
def __sub__(self, other):
if self.curve != other.curve:
raise ValueError("Cannot subtract points on different curves")
# Case when one point is zero
if self == Point.infinity(self.curve):
return other
if other == Point.infinity(self.curve):
return self
return self + Point(other.x, (-other.y) % self.curve.p, self.curve)
def __mul__(self, n):
if not isinstance(n, int):
raise ValueError("Multiplication is defined for integers only")
n = n % (self.curve.p - 1)
res = Point.infinity(self.curve)
addend = self
while n:
if n & 1:
res += addend
addend += addend
n >>= 1
return res
def __str__(self):
return f"({self.x}, {self.y}) on {self.curve}"
@staticmethod
def from_hex(s, curve):
if len(s) == 66 and s.startswith("02") or s.startswith("03"):
compressed = True
elif len(s) == 130 and s.startswith("04"):
compressed = False
else:
raise ValueError("Hex string is not a valid compressed or uncompressed point")
if compressed:
is_odd = s.startswith("03")
x = int(s[2:], 16)
# Calculate y-coordinate from x and parity bit
y_square = (x * x * x + curve.a * x + curve.b) % curve.p
y = pow(y_square, (curve.p + 1) // 4, curve.p)
if is_odd != (y & 1):
y = -y % curve.p
return Point(x, y, curve)
else:
s_bytes = bytes.fromhex(s)
uncompressed = s_bytes[0] == 4
if not uncompressed:
raise ValueError("Only uncompressed or compressed points are supported")
num_bytes = len(s_bytes) // 2
x_bytes = s_bytes[1 : num_bytes + 1]
y_bytes = s_bytes[num_bytes + 1 :]
x = int.from_bytes(x_bytes, byteorder="big")
y = int.from_bytes(y_bytes, byteorder="big")
return Point(x, y, curve)
def to_hex(self, compressed=True):
if self.x is None and self.y is None:
return "00"
elif compressed:
prefix = "03" if self.y & 1 else "02"
return prefix + hex(self.x)[2:].zfill(64)
else:
x_hex = hex(self.x)[2:].zfill(64)
y_hex = hex(self.y)[2:].zfill(64)
return "04" + x_hex + y_hex
@staticmethod
def infinity(curve):
return Point(None, None, curve)
# Define the ec_mul function
def ec_mul(point, scalar, base_point):
result = Point.infinity(point.curve)
addend = point
while scalar:
if scalar & 1:
result += addend
addend += addend
scalar >>= 1
return result
# Define the ec_operations function
def ec_operations(start_range, end_range, target_1, target_2, curve):
# Define parameters for secp256k1 curve
n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
G = Point(
0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8,
curve
)
# Open the files for writing
with open("target1_division_results.txt", "a") as file1, \
open("target2_division_results.txt", "a") as file2, \
open("subtract_results.txt", "a") as file3:
for i in range(start_range, end_range + 1):
try:
# Compute the inverse of i modulo n
i_inv = pow(i, n-2, n)
# Divide the targets by i modulo n
result_1 = ec_mul(target_1, i_inv, G)
result_2 = ec_mul(target_2, i_inv, G)
# Subtract the results
sub_result = result_2 - result_1
# Write the results to separate files
file1.write(f"{result_1.to_hex()}\n")
file2.write(f"{result_2.to_hex()}\n")
file3.write(f"Subtracting results for {i}:\n")
file3.write(f"Target 1 / {i}: {result_1.to_hex()}\n")
file3.write(f"Target 2 / {i}: {result_2.to_hex()}\n")
file3.write(f"Subtraction: {sub_result.to_hex()}\n")
file3.write("="*50 + "\n")
print(f"Completed calculation for divisor {i}")
except ZeroDivisionError:
print(f"Error: division by zero for {i}")
print("Calculation completed. Results saved in separate files.")
if __name__ == "__main__":
# Set the targets and range for the operations
curve = EllipticCurve(0, 7, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
target_1 = Point.from_hex("0230210C23B1A047BC9BDBB13448E67DEDDC108946DE6DE639BCC75D47C0216B1B", curve)
target_2 = Point.from_hex("02F6B787195159544330085C6014DBA627FF5B14F3203FF05D12482F76261F4FC3", curve)
start_range = 2
end_range = 200
ec_operations(start_range, end_range, target_1, target_2, curve)
Note that on previous page there is one similar script but operating over scalar not points.
Also the credit for the division by a range part goes to @mcdouglasx, the rest goes to anyone here helping and of course the biggest idiot AI made by mankind ( all of them are for now ) aka deep.ai chatbot.
As a test sample I have used puzzle 65 in target1 and target 2 is an offset after subtracting the following scalar from puzzle 65.
0x0000000000000000000000000000000000000000000000020000000000000000
The script is really slow because I had problem using multiprocessing in the code, so I decided to remove it, it also first calculates everything and then writes them to the files, since I'm not a coder, I don't know whether doing that requires more RAM or not.
Feel free to optimize, improve and add other functions/operations as you see fit and please do share.
Thanks.
import gmpy2 as mpz
from gmpy2 import powmod
# Define the EllipticCurve class
class EllipticCurve:
def __init__(self, a, b, p):
self.a = mpz.mpz(a)
self.b = mpz.mpz(b)
self.p = mpz.mpz(p)
def contains(self, point):
x, y = point.x, point.y
return (y * y) % self.p == (x * x * x + self.a * x + self.b) % self.p
def __str__(self):
return f"y^2 = x^3 + {self.a}x + {self.b} mod {self.p}"
# Define the Point class
class Point:
def __init__(self, x, y, curve):
self.x = mpz.mpz(x)
self.y = mpz.mpz(y)
self.curve = curve
def __eq__(self, other):
return self.x == other.x and self.y == other.y and self.curve == other.curve
def __ne__(self, other):
return not self == other
def __add__(self, other):
if self.curve != other.curve:
raise ValueError("Cannot add points on different curves")
# Case when one point is zero
if self == Point.infinity(self.curve):
return other
if other == Point.infinity(self.curve):
return self
if self.x == other.x and self.y != other.y:
return Point.infinity(self.curve)
p = self.curve.p
s = 0
if self == other:
s = ((3 * self.x * self.x + self.curve.a) * pow(2 * self.y, -1, p)) % p
else:
s = ((other.y - self.y) * pow(other.x - self.x, -1, p)) % p
x = (s * s - self.x - other.x) % p
y = (s * (self.x - x) - self.y) % p
return Point(x, y, self.curve)
def __sub__(self, other):
if self.curve != other.curve:
raise ValueError("Cannot subtract points on different curves")
# Case when one point is zero
if self == Point.infinity(self.curve):
return other
if other == Point.infinity(self.curve):
return self
return self + Point(other.x, (-other.y) % self.curve.p, self.curve)
def __mul__(self, n):
if not isinstance(n, int):
raise ValueError("Multiplication is defined for integers only")
n = n % (self.curve.p - 1)
res = Point.infinity(self.curve)
addend = self
while n:
if n & 1:
res += addend
addend += addend
n >>= 1
return res
def __str__(self):
return f"({self.x}, {self.y}) on {self.curve}"
@staticmethod
def from_hex(s, curve):
if len(s) == 66 and s.startswith("02") or s.startswith("03"):
compressed = True
elif len(s) == 130 and s.startswith("04"):
compressed = False
else:
raise ValueError("Hex string is not a valid compressed or uncompressed point")
if compressed:
is_odd = s.startswith("03")
x = mpz.mpz(s[2:], 16)
# Calculate y-coordinate from x and parity bit
y_square = (x * x * x + curve.a * x + curve.b) % curve.p
y = powmod(y_square, (curve.p + 1) // 4, curve.p)
if is_odd != (y & 1):
y = -y % curve.p
return Point(x, y, curve)
else:
s_bytes = bytes.fromhex(s)
uncompressed = s_bytes[0] == 4
if not uncompressed:
raise ValueError("Only uncompressed or compressed points are supported")
num_bytes = len(s_bytes) // 2
x_bytes = s_bytes[1 : num_bytes + 1]
y_bytes = s_bytes[num_bytes + 1 :]
x = mpz.mpz(int.from_bytes(x_bytes, byteorder="big"))
y = mpz.mpz(int.from_bytes(y_bytes, byteorder="big"))
return Point(x, y, curve)
def to_hex(self, compressed=True):
if self.x is None and self.y is None:
return "00"
elif compressed:
prefix = "03" if self.y & 1 else "02"
return prefix + hex(self.x)[2:].zfill(64)
else:
x_hex = hex(self.x)[2:].zfill(64)
y_hex = hex(self.y)[2:].zfill(64)
return "04" + x_hex + y_hex
@staticmethod
def infinity(curve):
return Point(-1, -1, curve)
# Define the ec_mul function
def ec_mul(point, scalar, base_point):
result = Point.infinity(point.curve)
addend = point
while scalar:
if scalar & 1:
result += addend
addend += addend
scalar >>= 1
return result
# Define the ec_operations function
def ec_operations(start_range, end_range, target_1, target_2, curve):
# Define parameters for secp256k1 curve
n = mpz.mpz("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141")
G = Point(
mpz.mpz("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),
mpz.mpz("0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"),
curve
)
# Open the files for writing
with open("target1_division_results.txt", "a") as file1, \
open("target2_division_results.txt", "a") as file2, \
open("subtract_results.txt", "a") as file3:
for i in range(start_range, end_range + 1):
try:
# Compute the inverse of i modulo n
i_inv = powmod(i, n-2, n)
# Divide the targets by i modulo n
result_1 = ec_mul(target_1, i_inv, G)
result_2 = ec_mul(target_2, i_inv, G)
# Subtract the results
sub_result = result_2 - result_1
# Write the results to separate files
file1.write(f"{result_1.to_hex()}\n")
file2.write(f"{result_2.to_hex()}\n")
file3.write(f"Subtracting results for {i}:\n")
file3.write(f"Target 1 / {i}: {result_1.to_hex()}\n")
file3.write(f"Target 2 / {i}: {result_2.to_hex()}\n")
file3.write(f"Subtraction: {sub_result.to_hex()}\n")
file3.write("="*50 + "\n")
print(f"Completed calculation for divisor {i}")
except ZeroDivisionError:
print(f"Error: division by zero for {i}")
print("Calculation completed. Results saved in separate files.")
if __name__ == "__main__":
# Set the targets and range for the operations
curve = EllipticCurve(
mpz.mpz(0),
mpz.mpz(7),
mpz.mpz("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")
)
target_1 = Point.from_hex("0230210C23B1A047BC9BDBB13448E67DEDDC108946DE6DE639BCC75D47C0216B1B", curve)
target_2 = Point.from_hex("02F6B787195159544330085C6014DBA627FF5B14F3203FF05D12482F76261F4FC3", curve)
start_range = 2
end_range = 200
ec_operations(start_range, end_range, target_1, target_2, curve)
The first thing I do is install gmpy2 in everything where large numbers are used.
gmpy2 is a highly optimized library for arbitrary-precision arithmetic. It is written in C and provides low-level access to the GMP (GNU Multiple Precision) library, which is known for its efficiency in handling large integers.