You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

椭圆曲线间公钥转换未达预期:原因及修正方案

椭圆曲线公钥跨曲线转换问题排查与修复

问题背景

尝试将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: (
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 14:51:00