如何在python3中从私钥生成公钥而不导入任何模块

问题描述 投票:0回答:1

当我运行命令

btc_address_dump "0x0000000000000000000000000000000000000000000000000000000000000001"
时,输出的公钥是
0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
,然后当我运行命令
btc_address_dump "0x0000000000000000000000000000000000000000000000000000000000000002"
时,输出的公钥是
04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a
,但是当我使用上面的每个私钥来测试下面的python3脚本时私钥的输出
0x0000000000000000000000000000000000000000000000000000000000000001
=
0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
那么我输入私钥
0x0000000000000000000000000000000000000000000000000000000000000002
时从脚本中得到的公钥是
043cea112c8dbb47dbffdd56023c41ccf7f1f5a0ef8786d3b0f3f01871a6c8d557d0f0a997646d7e87ba593fed9f320dd1739c722c7b357d6586e9fb73f578c0e0

我使用的脚本如下:

# Define the elliptic curve parameters
p = 2**256 - 2**32 - 977
a = 0
b = 7
Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240
Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424

# Define the private key
private_key = 0x0000000000000000000000000000000000000000000000000000000000000002

# Convert the private key to decimal
private_key_decimal = int(private_key)

# Perform elliptic curve multiplication
Qx = Gx
Qy = Gy
for bit in bin(private_key_decimal)[3:]:
    Qx = (Qx**2 - Qy**2) % p
    Qy = (2*Qx*Qy) % p

    if bit == '1':
        Qx = (Qx*Gx - Qy*Gy) % p
        Qy = (Qx*Gy + Qy*Gx) % p

# Convert the x and y coordinates to hexadecimal
public_key_hex = '04' + format(Qx, '064x') + format(Qy, '064x')

# Print the uncompressed public key
print("Uncompressed Public Key:", public_key_hex)

我的问题是为什么脚本会输出错误的公钥

0x0000000000000000000000000000000000000000000000000000000000000002

python cryptography bitcoin public-key
1个回答
0
投票

以下脚本产生预期结果:

import collections

EllipticCurve = collections.namedtuple('EllipticCurve', 'name p a b g n h')

curve = EllipticCurve(
    'secp256k1',
    # Field characteristic.
    p=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,
    # Curve coefficients.
    a=0,
    b=7,
    # Base point.
    g=(0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
       0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8),
    # Subgroup order.
    n=0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,
    # Subgroup cofactor.
    h=1,
)

# Modular arithmetic ##########################################################

def inverse_mod(k, p):
    """Returns the inverse of k modulo p.

    This function returns the only integer x such that (x * k) % p == 1.

    k must be non-zero and p must be a prime.
    """
    if k == 0:
    raise ZeroDivisionError('division by zero')

    if k < 0:
    # k ** -1 = p - (-k) ** -1  (mod p)
    return p - inverse_mod(-k, p)

    # Extended Euclidean algorithm.
    s, old_s = 0, 1
    t, old_t = 1, 0
    r, old_r = p, k

    while r != 0:
    quotient = old_r // r
    old_r, r = r, old_r - quotient * r
    old_s, s = s, old_s - quotient * s
    old_t, t = t, old_t - quotient * t

    gcd, x, y = old_r, old_s, old_t

    assert gcd == 1
    assert (k * x) % p == 1

    return x % p


# Functions that work on curve points #########################################

def is_on_curve(point):
    """Returns True if the given point lies on the elliptic curve."""
    if point is None:
    # None represents the point at infinity.
    return True

    x, y = point

    return (y * y - x * x * x - curve.a * x - curve.b) % curve.p == 0


def point_neg(point):
    """Returns -point."""
    assert is_on_curve(point)

    if point is None:
    # -0 = 0
    return None

    x, y = point
    result = (x, -y % curve.p)

    assert is_on_curve(result)

    return result


def point_add(point1, point2):
    """Returns the result of point1 + point2 according to the group law."""
    assert is_on_curve(point1)
    assert is_on_curve(point2)

    if point1 is None:
    # 0 + point2 = point2
    return point2
    if point2 is None:
    # point1 + 0 = point1
    return point1

    x1, y1 = point1
    x2, y2 = point2

    if x1 == x2 and y1 != y2:
    # point1 + (-point1) = 0
    return None

    if x1 == x2:
    # This is the case point1 == point2.
    m = (3 * x1 * x1 + curve.a) * inverse_mod(2 * y1, curve.p)
    else:
    # This is the case point1 != point2.
    m = (y1 - y2) * inverse_mod(x1 - x2, curve.p)

    x3 = m * m - x1 - x2
    y3 = y1 + m * (x3 - x1)
    result = (x3 % curve.p,
          -y3 % curve.p)

    assert is_on_curve(result)

    return result


def scalar_mult(k, point):
    """Returns k * point computed using the double and point_add algorithm."""
    assert is_on_curve(point)

    if k % curve.n == 0 or point is None:
    return None

    if k < 0:
    # k * point = -k * (-point)
    return scalar_mult(-k, point_neg(point))

    result = None
    addend = point

    while k:
    if k & 1:
        # Add.
        result = point_add(result, addend)

    # Double.
    addend = point_add(addend, addend)

    k >>= 1

    assert is_on_curve(result)

    return result

#######################################################

private_key = 0x0000000000000000000000000000000000000000000000000000000000000001
public_key = scalar_mult(private_key, curve.g)
print('private key:')
print(hex(private_key))
print('public key:')
print(hex(public_key[0]), hex(public_key[1]))

print('---')

private_key = 0x0000000000000000000000000000000000000000000000000000000000000002
public_key = scalar_mult(private_key, curve.g)
print('private key:')
print(hex(private_key))
print('public key:')
print(hex(public_key[0]), hex(public_key[1]))

运行脚本会产生:

private key:
0x1
public key:
0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
---
private key:
0x2
public key:
0xc6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5 0x1ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a

参考资料:

https://andrea.corbellini.name/2015/05/30/elliptic-curve-cryptography-ecdh-and-ecdsa/

https://github.com/andreacorbellini/ecc/blob/master/scripts/ecdsa.py

© www.soinside.com 2019 - 2024. All rights reserved.