python-ecdsa签名大小是否正确?

问题描述 投票:2回答:2

在比特币维基上,我发现比特币使用ECDSA算法和Secp256k1曲线。

相关链接:

在第一个链接上,它表示私钥应为32字节,公钥为64字节,签名通常在71-73字节之间。它表示签名可以更小,概率更小。

但是,当我运行以下python3代码时

>>> from ecdsa import SigningKey, SECP256k1
>>> private_key = SigningKey.generate(curve=SECP256k1)
>>> public_key = private_key.get_verifying_key()
>>> signature = private_key.sign(b'message')
>>> print((len(private_key.to_string()), len(public_key.to_string()), len(signature)))

我得到(32,64,64)作为输出。我希望得到像(32,64,72)这样的东西。

我想到以下情况之一正在发生:

  • 我误解了维基文章。
  • 我错误地使用python-ecdsa
  • 比特币维基是不正确的
  • python-ecdsa未正确实现

前两个是更可能的。

任何人都可以向我解释为什么我的期望和我实际得到的不匹配?

python cryptography bitcoin ecdsa
2个回答
3
投票

ECDSA签名由两个数字r和s组成,它们是[1..n-1]范围内的数字,其中n是曲线的阶数。 n是[2 ^(k-1)... 2 ^ k-1]范围内的(已知)数,其中k是密钥大小。因此,r和s的大小通常是相同的,有时稍微小一些,以字节为单位的密钥大小。

现在r和s可以用多种方式编码,其中两种是常见的:

  1. r和s在一个ASN.1 SEQUENCE中被编码为两个ASN.1签名的INTEGER类型。
  2. r和s被编码为两个静态大小的无符号整数,其大小与八位字节或字节中的密钥大小(或顺序)相同。

因此,大小的差异仅仅是因为值r和s的编码方式不同。当然,在验证签名之前,您需要知道编码类型。

由于r和s完全相同的编码独立,因此在两个版本之间进行转换相对简单(如果你可以调用任何需要生成或解析DER编码的ASN.1结构的“简单”)。

类型1已在ANSI X9.62中标准化,类型2(通常称为平面编码)通常用于嵌入式平台或智能卡。


r和s很可能与n /密钥大小相同,但原则上它们可以是例如数字3.发生这种情况的可能性非常小。但是,您应该不对r和s的大小进行任何测试。如果它们中的任何一个小于8个字节,那么你可能会开始挠头,因为发生这种情况的可能性在1/2 ^ 63和1/2 ^ 64之间,即极不可能。


所以:

  • 我误解了维基文章。

不,维基文章假定ANSI X9.62的标准化编码。

  • 我错误地使用python-ecdsa

不,python-ecdsa包只使用不同的编码,你会感到惊讶。

  • 比特币维基是不正确的

不,比特币维基假定为其协议选择了特定的编码。

  • python-ecdsa未正确实现

当然不;至少不是关于签名的大小。


现在为实施细节;以下是在文档中:

还有多种方式来表示签名。默认的sk.sign()vk.verify()方法将其显示为短字符串,以简化和最小开销。要使用其他方案,请使用sk.sign(sigencode =)和vk.verify(sigdecode =)参数。 “ecdsa.util”模块中有辅助函数,可以在这里使用。

因此,尝试使用sigencode=sigencode_der来获取wiki文章所期望的格式。 util.py源码包含您可能需要的所有转换。它使用number_to_string创建静态大小的数字。此功能在PKCS#1(RSA)中也称为I2OSP或整数到八位字符串原语。请注意,代码中的“字符串”是指八位字节字符串,也称为字节数组 - 而不是文本字符串。


0
投票

python-ecdsa唯一的问题是性能,因为它太慢了。

一个更好的图书馆:starkbank-ecdsa

如何安装:

pip install starkbank-ecdsa

如何使用它:

# Generate Keys
privateKey = PrivateKey()
publicKey = privateKey.publicKey()

message = "My test message"

# Generate Signature
signature = Ecdsa.sign(message, privateKey)

# Verify if signature is valid
print Ecdsa.verify(message, signature, publicKey)

完整参考:https://github.com/starkbank/ecdsa-python

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