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

为何Python3无依赖脚本生成特定比特币私钥公钥错误?

问题:脚本生成的私钥对应公钥不符合预期的原因

执行命令btc_address_dump "0x0000000000000000000000000000000000000000000000000000000000000002"时,预期公钥为04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a,但你提供的Python脚本生成的公钥却不一致,核心问题是椭圆曲线点运算(加倍、加法)的公式完全错误,导致私钥乘基点的计算逻辑失效。

具体错误点

1. 点加倍(Double)公式错误

脚本中照搬了复数乘法的逻辑:

Qx = (Qx**2 - Qy**2) % p
Qy = (2*Qx*Qy) % p

这完全不符合secp256k1曲线的点加倍规则。针对secp256k1(参数a=0),正确的点加倍步骤为:

  • 计算斜率:λ = (3*x1²) * 模p下(2*y1)的逆元
  • 计算新x坐标:x3 = (λ² - 2*x1) % p
  • 计算新y坐标:y3 = (λ*(x1 - x3) - y1) % p

2. 点加法(Add)公式错误

脚本中的加法逻辑同样偏离椭圆曲线规则:

Qx = (Qx*Gx - Qy*Gy) % p
Qy = (Qx*Gy + Qy*Gx) % p

正确的点加法(针对两个不同点)步骤为:

  • 计算斜率:λ = (y2 - y1) * 模p下(x2 - x1)的逆元
  • 计算新x坐标:x3 = (λ² - x1 - x2) % p
  • 计算新y坐标:y3 = (λ*(x1 - x3) - y1) % p

3. 快速幂循环范围错误

脚本中循环遍历bin(private_key_decimal)[3:],会跳过私钥二进制的前三位(包括有效的最高位1)。比如私钥0x2的二进制是0b10,[3:]会得到空字符串,循环根本不会执行,这也是导致计算结果错误的原因之一。

修正后的脚本

以下是实现了正确椭圆曲线点运算的脚本,生成的公钥会与btc_address_dump的输出一致:

# secp256k1椭圆曲线参数
p = 2**256 - 2**32 - 977
a = 0
b = 7
Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240
Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424

def modinv(x):
    """计算模p下的逆元,利用费马小定理"""
    return pow(x, p-2, p)

def point_double(x1, y1):
    """椭圆曲线点加倍操作"""
    lam = (3 * x1**2 + a) * modinv(2 * y1) % p
    x3 = (lam**2 - 2 * x1) % p
    y3 = (lam * (x1 - x3) - y1) % p
    return (x3, y3)

def point_add(x1, y1, x2, y2):
    """椭圆曲线点加法操作"""
    if x1 == x2 and y1 == y2:
        return point_double(x1, y1)
    lam = (y2 - y1) * modinv(x2 - x1) % p
    x3 = (lam**2 - x1 - x2) % p
    y3 = (lam * (x1 - x3) - y1) % p
    return (x3, y3)

def scalar_mult(k, x, y):
    """标量乘法:计算k倍的基点(x,y)"""
    result_x, result_y = None, None  # 用(None, None)表示无穷远点
    current_x, current_y = x, y
    while k > 0:
        if k % 2 == 1:
            if result_x is None:
                result_x, result_y = current_x, current_y
            else:
                result_x, result_y = point_add(result_x, result_y, current_x, current_y)
        current_x, current_y = point_double(current_x, current_y)
        k = k // 2
    return (result_x, result_y)

# 目标私钥
private_key = 0x0000000000000000000000000000000000000000000000000000000000000002

# 计算公钥
Qx, Qy = scalar_mult(private_key, Gx, Gy)

# 转换为未压缩公钥格式
public_key_hex = '04' + format(Qx, '064x') + format(Qy, '064x')

print("Uncompressed Public Key:", public_key_hex)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:12:05