Last active
October 5, 2025 15:33
-
-
Save Goatghosts/0c4aa8dd6f0ce1a61f484b655b6664ac to your computer and use it in GitHub Desktop.
Я попросил chatGPT написать код для получения публичного ключа из приватного ключа. Она написала. Вот и все, в принципе.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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