For now digest this and penetrate order of the group n.
On line 27, change (result_2 - result_1) % n to +, then compare the results starting with 7, a, 6 etc with both targets. Then Ask me what is scalar torsion, and I will give you another script to work with, remember to work with the results by sub/adding them with different values to find a short cut, I simply subtracted target 2 from n and then removed all leading Fs from it, both targets can be divided by each other, you just need to find the right divisor, also remember to remove # from line 30 and 31 separately to see each target's division results as well.
import gmpy2 as mpz
from gmpy2 import powmod
# Define the ec_operations function
def ec_operations(start_range, end_range, scalar_1, scalar_2, n, divide_1_by_odd=True, divide_1_by_even=True, divide_2_by_odd=True, divide_2_by_even=True):
for i in range(start_range + (start_range%2), end_range, 1):
# divide scalar 1 by odd or even numbers
if i%2 == 0 and not divide_1_by_even:
continue
elif i%2 == 1 and not divide_1_by_odd:
continue
try:
# calculate inverse modulo of i
i_inv = powmod(i, n-2, n)
# multiply the scalar targets by i modulo n
result_1 = scalar_2 * i_inv % n
result_2 = scalar_1 * i_inv % n
# divide scalar 2 by odd or even numbers
if i%2 == 0 and not divide_2_by_even:
continue
elif i%2 == 1 and not divide_2_by_odd:
continue
# subtract the results
sub_result = (result_2 - result_1) % n
# print results separately
# print(f"{hex(result_1)[2:]}")
# print(f"{hex(result_2)[2:]}")
print(f"{hex(sub_result)[2:]}")
except ZeroDivisionError:
pass
if __name__ == "__main__":
# Set the targets and range for the operations
scalar_1 = 0x0000000000000000000000000000000b011d90a8cba60d550a2e332b5ef58546
scalar_2 = 0x00000000000000000000000000000003b9914c3de3a292e6b5a42b617140bbfb
n = mpz.mpz("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141")
start_range = 57896044618658097711785492504343953926418782139537452191302581570759080747160
end_range = 57896044618658097711785492504343953926418782139537452191302581570759080747180
ec_operations(start_range, end_range, scalar_1, scalar_2, n)
When you are done, go for this one :
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) * powmod(2 * self.y, -1, p)) % p
else:
s = ((other.y - self.y) * powmod(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, divide_1_by_odd=True, divide_1_by_even=True, divide_2_by_odd=True, divide_2_by_even=True):
# Define parameters for secp256k1 curve
n = mpz.mpz("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141")
G = Point(
mpz.mpz("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),
mpz.mpz("0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"),
curve
)
for i in range(start_range + ( start_range%2), end_range, 1):
# divide target 1 by odd or even numbers
if i%2 == 0 and not divide_1_by_even:
continue
elif i%2 == 1 and not divide_1_by_odd:
continue
try:
# calculate inverse modulo of i
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)
# divide target 2 by odd or even numbers
if i%2 == 0 and not divide_2_by_even:
continue
elif i%2 == 1 and not divide_2_by_odd:
continue
# subtract the results
sub_result = result_2 - result_1
# print the results separately
# print(f"{result_1.to_hex()}")
# print(f"{result_1.to_hex()}")
print(f"{sub_result.to_hex()}")
# data = open("result.txt","a")
# data.write(str(sub_result.to_hex()) +"\n")
# data.close()
except ZeroDivisionError:
pass
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("03439acdf494f8ed30baa5f465da96c62625dbf0f474535ad9bedefd3f23663f4d", curve)
target_2 = Point.from_hex("02617125f42749f748bd047f3688f79f8e2a1bf5ef9eca7929bb2daa6fa467b8e1", curve)
start_range = 57896044618658097711785492504343953926418782139537452191302581570759080747160
end_range = 57896044618658097711785492504343953926418782139537452191302581570759080747180
ec_operations(start_range, end_range, target_2, target_1, curve)
When you are done, repeat the same with unknown points, whatever you do with scalars on first script and whatever results you get, perform them on the points as well, all results will be the same.