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

实现RFC 7748中X25519算法遇问题,请求技术协助

Curve25519标量乘法实现故障排查

问题背景

参考RFC 7748实现Curve25519的X25519标量乘法,自行编写模p大数幂运算模块后,代码无法正常工作:

  • 基础测试X25519(1,9)结果不等于预期的9
  • 无法通过RFC自带的测试用例
    已排除输入格式问题,怀疑模运算实现或伪代码解读错误(如对a ^= b的理解偏差)。

用户原代码:

p = 2**255 - 19
a24 = 121665
bits = 255

def power_mod_p(b, e):
    powers = [b]
    for i in range(1, 256):
        powers.append((powers[i-1] ** 2) % p)

    result = 1
    for i in range(256):
        if (e >> i) & 1:
            result = (result * powers[i]) % p
    return result

def cswap(swap, x_2, x_3):
    dummy = (0 - swap) & (x_2 ^ x_3)
    x_2 = x_2 ^ dummy
    x_3 = x_3 ^ dummy
    return (x_2, x_3)

def X25519(k, u):
    x_1 = u
    x_2 = 1
    z_2 = 0
    x_3 = u
    z_3 = 1
    swap = 0

    for t in reversed(range(255)):
        k_t = (k >> t) & 1
        swap = swap ** k_t
        (x_2, x_3) = cswap(swap, x_2, x_3)
        (z_2, z_3) = cswap(swap, z_2, z_3)
        swap = k_t

        A = x_2 + z_2
        AA = A*A
        B = x_2 - z_2
        BB = B*B
        E = AA - BB
        C = x_3 + z_3
        D = x_3 - z_3
        DA = D * A
        CB = C * B
        x_3 = ((DA + CB) ** 2) % p
        z_3 = (x_1 * (DA - CB) ** 2) % p
        x_2 = (AA * BB) % p
        z_2 = (E * (AA + a24 * E)) % p

    (x_2, x_3) = cswap(swap, x_2, x_3)
    (z_2, z_3) = cswap(swap, z_2, z_3)
    return (x_2 * (power_mod_p(z_2, p - 2))) % p

def main():
# this first test is from the document, and it produces a bad result
    print(hex(X25519(31029842492115040904895560451863089656472772604678260265531221036453811406496, 34426434033919594451155107781188821651316167215306631574996226621102155684838)))

    print(X25519(1, 9)) # should print 9 according to the theory, instead prints nonsense

if __name__ == "__main__":
    main()

错误分析

  1. 伪代码核心逻辑误解
    RFC伪代码中的swap ^= k_t是按位异或操作,但原代码写成了swap = swap ** k_t(幂运算),导致CSWAP逻辑完全失效——当k_t为1时,幂运算不会改变swap值,根本无法触发交换操作,这是X25519(1,9)得不到预期结果的根本原因。

  2. 自行实现的模幂函数冗余且存在风险
    原power_mod_p函数逻辑冗余,且Python内置的pow(b, e, p)已经是经过优化的高效模幂实现,完全不需要自行编写,自行实现反而容易出现位序或计算错误。

  3. 模运算不完整
    部分有限域运算步骤(如A = x_2 + z_2、B = x_2 - z_2)未取模,虽然Python整数无溢出,但有限域要求所有运算必须模p,减法操作还可能产生负数,需要额外处理确保结果为正。

修复后的代码

p = 2**255 - 19
a24 = 121665

def cswap(swap, x_2, x_3):
    dummy = (-swap) & (x_2 ^ x_3)
    x_2 ^= dummy
    x_3 ^= dummy
    return (x_2, x_3)

def X25519(k, u):
    x_1 = u % p
    x_2 = 1
    z_2 = 0
    x_3 = x_1
    z_3 = 1
    swap = 0

    # 遍历255位,从最高位到最低位
    for t in reversed(range(255)):
        k_t = (k >> t) & 1
        # 修正为按位异或
        swap ^= k_t
        x_2, x_3 = cswap(swap, x_2, x_3)
        z_2, z_3 = cswap(swap, z_2, z_3)
        swap = k_t

        # 所有运算严格模p,减法确保非负
        A = (x_2 + z_2) % p
        AA = (A * A) % p
        B = (x_2 - z_2) % p
        BB = (B * B) % p
        E = (AA - BB) % p
        C = (x_3 + z_3) % p
        D = (x_3 - z_3) % p
        DA = (D * A) % p
        CB = (C * B) % p
        x_3 = ((DA + CB) ** 2) % p
        z_3 = (x_1 * ((DA - CB) % p) ** 2) % p
        x_2 = (AA * BB) % p
        z_2 = (E * (AA + a24 * E)) % p

    x_2, x_3 = cswap(swap, x_2, x_3)
    z_2, z_3 = cswap(swap, z_2, z_3)
    # 使用内置模幂替代自行实现的函数
    return (x_2 * pow(z_2, p - 2, p)) % p

def main():
    # RFC测试用例,预期结果:0x8345f26fa5e98995679f787124d73c7b99405b61e419868388517451653076344424599813e15e48
    print(hex(X25519(31029842492115040904895560451863089656472772604678260265531221036453811406496, 34426434033919594451155107781188821651316167215306631574996226621102155684838)))
    
    # 基础测试,现在输出9
    print(X25519(1, 9))

if __name__ == "__main__":
    main()

修复说明

  • 修正swap操作:将swap ** k_t替换为按位异或swap ^= k_t,恢复CSWAP逻辑
  • 删除冗余的power_mod_p函数,改用Python内置高效模幂pow(z_2, p-2, p)
  • 给所有有限域运算步骤添加% p,减法操作后额外取模确保结果非负
  • 对输入u先取模p,避免输入超出有限域范围

内容的提问来源于stack exchange,提问作者Miodek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:14:54