Skip to content

Instantly share code, notes, and snippets.

@Goatghosts
Last active October 5, 2025 15:33
Show Gist options
  • Save Goatghosts/0c4aa8dd6f0ce1a61f484b655b6664ac to your computer and use it in GitHub Desktop.
Save Goatghosts/0c4aa8dd6f0ce1a61f484b655b6664ac to your computer and use it in GitHub Desktop.
Я попросил chatGPT написать код для получения публичного ключа из приватного ключа. Она написала. Вот и все, в принципе.
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
a = 0x0000000000000000000000000000000000000000000000000000000000000000
b = 0x0000000000000000000000000000000000000000000000000000000000000007
Gx = int(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
Gy = int(0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
def is_on_secp256k1(x, y):
return (y**2 - x**3 - a * x - b) % p == 0
def find_y(x):
y_squared = (x**3 + a * x + b) % p
y1 = pow(y_squared, (p + 1) // 4, p)
if (y1**2) % p != y_squared:
raise ValueError("No y value for this x on this curve")
y2 = p - y1
return y1, y2
def int_to_hex(a):
return int.to_bytes(a, 32, "big").hex()
def to_public_key(x, y, compressed=True):
if x is None or y is None:
raise ValueError("The point at infinity has no public key.")
if not isinstance(x, int) or not isinstance(y, int):
raise TypeError("Coordinates must be integers.")
x_bytes = x.to_bytes(32, "big")
y_bytes = y.to_bytes(32, "big")
if compressed:
prefix = b"\x02" if (y & 1) == 0 else b"\x03"
return (prefix + x_bytes).hex().upper()
else:
return (b"\x04" + x_bytes + y_bytes).hex().upper()
def add_point(x1, y1, x2, y2):
if x1 is None or y1 is None:
return (x2, y2)
if x2 is None or y2 is None:
return (x1, y1)
if x1 == x2 and (y1 + y2) % p == 0:
return (None, None)
if x1 == x2 and y1 == y2:
return double_point(x1, y1)
s = ((y2 - y1) * pow((x2 - x1) % p, p - 2, p)) % p
x3 = (s * s - x1 - x2) % p
y3 = (s * (x1 - x3) - y1) % p
return (x3, y3)
def double_point(x, y):
if x is None or y is None:
return (None, None)
if y % p == 0:
return (None, None)
s = ((3 * x * x + a) * pow((2 * y) % p, p - 2, p)) % p
x3 = (s * s - 2 * x) % p
y3 = (s * (x - x3) - y) % p
return (x3, y3)
def scalar_mult(scalar, x, y):
k = scalar % n
if k == 0 or x is None or y is None:
return (None, None)
rx, ry = (None, None)
px, py = (x, y)
while k > 0:
if k & 1:
rx, ry = add_point(rx, ry, px, py)
px, py = double_point(px, py)
k >>= 1
return (rx, ry)
def divide_by_two_point(x, y):
inv2 = (n + 1) // 2
return scalar_mult(inv2, x, y)
if __name__ == "__main__":
private_key = 2
public_key = scalar_mult(private_key, Gx, Gy)
print("G point:", hex(Gx), hex(Gy))
print("2 * G point:", hex(public_key[0]), hex(public_key[1]))
print("Private key (DEC):", private_key)
print("Private key (HEX):", int_to_hex(private_key).upper())
print("Uncompressed public key:", to_public_key(public_key[0], public_key[1], compressed=False))
print("Compressed public key:", to_public_key(public_key[0], public_key[1], compressed=True))
hx, hy = divide_by_two_point(public_key[0], public_key[1])
print("half(2G) -> G:", hex(hx), hex(hy))
four_g = scalar_mult(4, Gx, Gy)
two_g_from_four = divide_by_two_point(four_g[0], four_g[1])
print("4G:", hex(four_g[0]), hex(four_g[1]))
print("half(4G) -> 2G:", hex(two_g_from_four[0]), hex(two_g_from_four[1]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment