from fastecdsa import curve
from fastecdsa.point import Point
import bit
G = curve.secp256k1.G
N = curve.secp256k1.q
def pub2point(pub_hex):
x = int(pub_hex[2:66], 16)
if len(pub_hex) < 70:
y = bit.format.x_to_y(x, int(pub_hex[:2], 16) % 2)
else:
y = int(pub_hex[66:], 16)
return Point(x, y, curve=curve.secp256k1)
# This function makes all the downscaled pubkeys obtained from subtracting
# numbers between 0 and divisor, before dividing the pubkeys by divisor.
def shiftdown(pubkey, divisor, file, convert=True):
Q = pub2point(pubkey) if convert else pubkey
# k = 1/divisor
k = pow(divisor, N - 2, N)
for i in range(divisor):
P = Q - (i * G)
P = k * P
if (P.y % 2 == 0):
prefix = "02"
else:
prefix = "03"
hx = hex(P.x)[2:].zfill(64)
hy = hex(P.y)[2:].zfill(64)
file.write(prefix+ " " + hx+"\n") # Writes compressed key to file
file.write("\n") # Writes compressed key to file
with open("input.txt", "r") as f, open("output.txt", "w") as outf:
line = f.readline().strip()
while line != '':
outf.write("original: " +line + "\n")
shiftdown(line, pow(2,1), outf)
line = f.readline().strip()
input:
02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13
022f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4
..d13 is 4 and ...fe4 is 5
output:
original: 02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13
02 c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5
02 c62c910e502cb615a27c58512b6cc2c94f5742f76cb3d12ec993400a3695d413
original: 022f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4
03 5699b93fc6e1bd29e09a328d657a607b4155b61a6b5fcbedd7c12df7c67df8f5
02 c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5
02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5 is 2
Because i know 4 is even, i know it has to be the first pubkey. Because i know 5 is odd, I know it has to be the second key.
The problem is, that in bigger numbers, you can not determine if it is odd or even.
See,if I add the pubkey of 3
original: 02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9 -> pubkey of 3
02 c62c910e502cb615a27c58512b6cc2c94f5742f76cb3d12ec993400a3695d413 -> not the halve
02 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 -> pubkey of 1
original: 02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13 -> pubkey of 4
02 c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5 -> odd pubkey of 5
02 c62c910e502cb615a27c58512b6cc2c94f5742f76cb3d12ec993400a3695d413 -> even pubkey of 3
original: 022f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4 -> pubkey of 5
03 5699b93fc6e1bd29e09a328d657a607b4155b61a6b5fcbedd7c12df7c67df8f5 -> not the halve
02 c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5-> pubkey of 2
You see... You can not determine from the halve if it is the correct one.
It is possible to automatically printed output number of decimal; which are reduced.