gpt4 book ai didi

python - 从压缩公钥导出 ECDSA 未压缩公钥

转载 作者:太空狗 更新时间:2023-10-29 20:18:00 24 4
gpt4 key购买 nike

我目前正在尝试从压缩的 ECDSA 公钥中导出比特币未压缩的 ECDSA 公钥。

根据这个link on the Bitcoin wiki , 这样做是可能的……但是怎么做呢?

为您提供更多详细信息:截至目前,我已经在比特币网络上收集了压缩 key (33 字节长)。

它们的格式如下:<1-bytes-long prefix><32-bytes-long X>。从那里,我想获得一个未压缩的 key (65 字节长),其格式为:<1 字节长前缀><32 字节长 X><32 字节长 Y>

根据这个other link on the Bitcoin wiki ,它应该像解方程一样简单:

Y^2 = X^3 + 7

但是,我似乎无法到达那里。我对 Y 的值(value)简直是遥不可及。这是我的代码(公钥的值来自 Bitcoin wiki example ):

import binascii
from decimal import *

expected_uncompressed_key_hex = '0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6'
expected_y_hex = expected_uncompressed_key_hex[-64:]
expected_y_dec = int(expected_y_hex, 16)
x_hex = expected_uncompressed_key_hex[2:66]
if expected_y_dec % 2 == 0:
prefix = "02"
else:
prefix = "03"

artificial_compressed_key = prefix + x_hex

getcontext().prec = 500
test_dec = Decimal(int(x_hex, 16))
y_square_dec = test_dec**3 + 7
if prefix == "02":
y_dec = - Decimal(y_square_dec).sqrt()
else:
y_dec = Decimal(y_square_dec).sqrt()

computed_y_hex = hex(int(y_dec))
computed_uncompressed_key = "04" + x + computed_y_hex

有关信息,我的输出是:

computed_y_hex = '0X2D29684BD207BF6D809F7D0EB78E4FD61C3C6700E88AB100D1075EFA8F8FD893080F35E6C7AC2E2214F8F4D088342951'
expected_y_hex = '2CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6'

感谢您的帮助!

最佳答案

需要在字段中计算Z_p ,这主要意味着您必须在每次计算后除以 p 后将您的数字减少到余数。计算这个称为取模,在 python 中写为 %p

在这个领域求幂比单纯的乘法和减法更有效。这称为模幂运算。 Python 的内置指数函数 pow(n,e,p) 可以解决这个问题。

剩下的问题是求平方根。幸运的是 secp256k1 以特殊方式选择 ( p%4=3 ),因此求平方根很容易:x 的平方根是 x^((p+1)/4)%p .

因此您的代码的简化版本变为:

import binascii

p_hex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F'
p = int(p_hex, 16)
compressed_key_hex = '0250863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B2352'
x_hex = compressed_key_hex[2:66]
x = int(x_hex, 16)
prefix = compressed_key_hex[0:2]

y_square = (pow(x, 3, p) + 7) % p
y_square_square_root = pow(y_square, (p+1)/4, p)
if (prefix == "02" and y_square_square_root & 1) or (prefix == "03" and not y_square_square_root & 1):
y = (-y_square_square_root) % p
else:
y = y_square_square_root

computed_y_hex = format(y, '064x')
computed_uncompressed_key = "04" + x_hex + computed_y_hex

print computed_uncompressed_key

关于python - 从压缩公钥导出 ECDSA 未压缩公钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43629265/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com