在比特币wiki上,我发现比特币使用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)的东西。在
我认为发生了以下情况之一:
前两个是更有可能的。在
有谁能解释一下为什么我的期望值和实际值不匹配?在
ECDSA签名由两个数字组成,r和s是在[1..n-1]范围内的数字,其中n是曲线的顺序。n是[2^(k-1)…2^k-1]范围内的(已知)数字,其中k是密钥大小。因此r和s的大小通常是相同的,有时会比密钥大小(字节)小一些。在
现在r和s可以用多种方式编码,其中有两种是常见的:
所以大小的不同仅仅是因为r和s的编码方式不同。当然,在验证签名之前,您需要知道编码的类型。在
由于r和s完全独立于编码,所以在两个版本之间转换相对简单(如果您可以将任何需要生成或解析DER编码的ASN.1结构称为“simple”)。在
类型1在ansix9.62中已经被标准化,而类型2,通常称为平面编码,通常用于嵌入式平台或智能卡。在
r和s很可能与n/密钥大小相同,但原则上,它们可以是数字3。这种情况发生的可能性微乎其微。但是,您应该对r和s的大小执行任何测试。如果其中任何一个小于8字节,那么您可能会开始挠头,因为发生这种情况的可能性在1/2^63和1/2^64之间,即极不可能。在
所以:
不,wiki文章假设标准化编码是ansix9.62。在
不,python ecdsa包只是使用了不同的编码,您会感到惊讶。在
不,比特币wiki假设他们的协议选择了一种特定的编码方式。在
绝对没有;至少在签名的大小上没有。在
现在了解实施细节;文档中包含以下内容:
所以尝试使用} 源具有您可能需要的所有转换。它使用
sigencode=sigencode_der
来获得wiki文章所期望的格式。^{number_to_string
来创建静态大小的数字。此函数在PKCS#1(RSA)中也称为I2OSP或整数到八位字节字符串原语。请注意,代码中的“字符串”指的是八位字节字符串,也称为字节数组,而不是文本字符串。在python ecdsa的唯一问题是性能,因为它太慢了。在
更好的图书馆:starkbank ecdsa
安装方法:
pip install starkbank-ecdsa
使用方法:
完整引用:https://github.com/starkbank/ecdsa-python
相关问题 更多 >
编程相关推荐