椭圆曲线间公钥转换未达预期:原因及修正方案
椭圆曲线公钥跨曲线转换问题排查与修复
问题背景
尝试将secp256k1椭圆曲线上的公钥转换至自定义椭圆曲线E1,期望转换后的E1公钥与同一私钥直接在E1生成的预期公钥一致,但转换结果不符合预期。
原代码
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()}")
原终端输出
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)
预期结果
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)
问题原因
当前转换逻辑完全错误:
- 椭圆曲线公钥的生成规则是私钥乘以曲线的生成元,不同曲线的生成元、群阶、素域参数完全独立,公钥坐标之间没有直接的模运算对应关系。
- 原代码将secp256k1公钥的X坐标取模E1的素数后作为E1的X坐标,再通过Y坐标奇偶性选点,这种操作没有任何密码学依据,自然无法得到与同一私钥对应的E1公钥。
修复方案
场景说明
如果是测试场景(私钥已知):直接使用已知私钥在E1上生成公钥即可,这是唯一能保证结果正确的方式。
如果是生产场景(私钥未知):跨曲线公钥转换是不可能的——因为椭圆曲线离散对数问题是密码学难题,无法从公钥反推私钥,也就无法在另一曲线上生成对应公钥。
修改后的代码
替换原transform_public_key函数,针对测试场景直接基于私钥生成目标曲线公钥:
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, g1, private_key): # 本质是用同一私钥在目标曲线生成公钥 return g1 * private_key # 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, G1, expected_private_key) # 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()}")
修改后终端输出
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: (
相关产品推荐
相关产品推荐

