I am trying to transform a public key from the elliptic curve secp256k1 to another elliptic curve E1. My goal is for the transformed public key on E1 to match the expected public key on E1. However, the transformation is not yielding the expected result. Here is the code I am using:
from sage.all import *
# Define Curve 1 (E1)
p_curve1 = 146342959308321116811971925755107030665886144790416760473680521284326792696481
a_curve1 = 135658058746385641108542340400885922324792025802649031399015366732548709966253
b_curve1 = 86990617349586286537347678328401438793950609023018928382734574186863764823713
E1 = EllipticCurve(GF(p_curve1), [a_curve1, b_curve1])
G1 = E1.gen(0)
# Define Curve 2 (secp256k1)
p_curve2 = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
a_curve2 = GF(p_curve2)(0)
b_curve2 = GF(p_curve2)(7)
E2 = EllipticCurve(GF(p_curve2), [a_curve2, b_curve2])
G2 = E2(0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8)
def transform_public_key(pub_key_curve2, curve2, curve1):
x_curve2 = pub_key_curve2[0]
# Transform the X-coordinate
p1 = curve1.base_ring().characteristic()
x_curve1 = int(x_curve2) % p1
# Lift the transformed X-coordinate to Curve 1
possible_points_curve1 = curve1.lift_x(x_curve1, all=True)
# Select the corresponding Y-coordinate based on the parity of the original Y-coordinate
y_parity = int(pub_key_curve2[1]) % 2 # Ensure it's an integer
for point in possible_points_curve1:
if int(point[1]) % 2 == y_parity: # Ensure it's an integer
return point
return None
# Correct private key as provided
expected_private_key = 985
# Calculate public keys on both curves using the correct private key
public_key_curve1_expected = G1 * expected_private_key
public_key_curve2 = G2 * expected_private_key
# Print the generated public keys for verification
print("Public Key on Curve 1 (E1):", public_key_curve1_expected.xy())
print("Public Key on Curve 2 (secp256k1):", public_key_curve2.xy())
# Transform public key on Curve 2 to Curve 1
transformed_public_key_curve1 = transform_public_key(public_key_curve2, E2, E1)
# Check if transformation was successful
if transformed_public_key_curve1 is not None:
print("Transformed Public Key on Curve 1 from Curve 2:", transformed_public_key_curve1.xy())
else:
print("Failed to transform public key from Curve 2 to Curve 1")
# Verify if the transformation is correct
if public_key_curve1_expected.xy() == transformed_public_key_curve1.xy():
print("Transformation yielded the expected result!")
else:
print("Transformation did not yield the expected result!")
print(f"Expected Public Key on Curve 1: {public_key_curve1_expected.xy()}")
if transformed_public_key_curve1 is not None:
print(f"Transformed Public Key on Curve 1: {transformed_public_key_curve1.xy()}")
Results in Terminal:
Public Key on Curve 1 (E1): (103076836948435528159537041769195651314129756990526413586014035188374406831726, 50197109573124546681660355105353198192736625072060565291783127673374988182337)
Public Key on Curve 2 (secp256k1): (25935177870180013245232348874477019188904995313845255935526361518696786243502, 12930448731405114069817654651522904698686124551017304703731654496298770014782)
Transformed Public Key on Curve 1 from Curve 2: (25935177870180013245232348874477019188904995313845255935526361518696786243502, 65328089760063185246406439795354392570617391432547996288323164282225551936926)
Transformation did not yield the expected result!
Expected Public Key on Curve 1: (103076836948435528159537041769195651314129756990526413586014035188374406831726, 50197109573124546681660355105353198192736625072060565291783127673374988182337)
Transformed Public Key on Curve 1: (25935177870180013245232348874477019188904995313845255935526361518696786243502, 65328089760063185246406439795354392570617391432547996288323164282225551936926)
Expected Results:
Public Key on Curve 1 (E1): (103076836948435528159537041769195651314129756990526413586014035188374406831726, 50197109573124546681660355105353198192736625072060565291783127673374988182337)
Public Key on Curve 2 (secp256k1): (25935177870180013245232348874477019188904995313845255935526361518696786243502, 12930448731405114069817654651522904698686124551017304703731654496298770014782)
Transformed Public Key on Curve 1 from Curve 2: (103076836948435528159537041769195651314129756990526413586014035188374406831726, 50197109573124546681660355105353198192736625072060565291783127673374988182337)
Question:
Why is the transformed public key on Curve 1 not matching the expected public key on Curve 1? What modifications are needed in the code to ensure the transformation yields the correct result?