在前文secp256k1-py 安装以及命令行操作中,我们介绍了secp256k1-py这个Python 库。
我们可以使用这个库用简单的命令行进行公钥私钥对的生成,以及对消息进行签名、校验等操作。
(图源 :pixabay)
而在以前的学习中,我们曾经用ecdsa这个Python库来从私钥生成公钥,这节我们回顾一下这些知识,并对比一下ecdsa与secp256k1-py从私钥生成公钥的异同。
生成私钥
在之前的文章中,我们曾经说过,私钥就一串随机数,可以用抛硬币256次来生成。不过估计没谁会无聊到这种程度,所以在之前的文章中,我们用hashlib来生成私钥。
import hashlib
from binascii import hexlify, unhexlify
s = hashlib.sha256(bytes('Hello World', 'utf-8')).digest()
print(hexlify(s).decode('ascii'))
上述代码生成如下私钥:
a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
我们也可以使用
python -m secp256k1 privkey
来生成私钥,但是程序员嘛,对Hello World
情有独钟,所以就用我们上边用Hello World
生成的私钥好了。
生成公钥
在之前的文章中,我们得出过结论,公钥可以通过K=k∗G
计算得出,
其中小k
是我们的私钥
,G
是生成点
,K
是结果亦即公钥
是曲线上的另外一个点
。
另外,由于对于点P(x, y),根据椭圆曲线的方程,我们是可以通过x求得y的,所以公钥可以压缩表示。
ecdsa由私钥生成公钥
在之前的文章中,我们最终得出如下代码:
import ecdsa
from binascii import hexlify, unhexlify
secret = unhexlify('a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e')
order = ecdsa.SigningKey.from_string(secret, curve=ecdsa.SECP256k1).curve.generator.order()
p = ecdsa.SigningKey.from_string(secret, curve=ecdsa.SECP256k1).verifying_key.pubkey.point
x_str = ecdsa.util.number_to_string(p.x(), order)
y_str = ecdsa.util.number_to_string(p.y(), order)
compressed = hexlify(bytes(chr(2 + (p.y() & 1)), 'ascii') + x_str).decode('ascii')
uncompressed = hexlify(bytes(chr(4), 'ascii') + x_str + y_str).decode('ascii')
print(compressed)
print(uncompressed)
输出如下:
secp256k1-py 命令行生成公钥
我们可以通过以下指令从私钥生成公钥:
python -m secp256k1 privkey -p -k a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
生成的压缩公钥和上边我们用ecdsa生成的完全一致。
secp256k1-py 代码生成公钥
from secp256k1 import PrivateKey
from binascii import hexlify, unhexlify
privkey = PrivateKey(unhexlify('a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e'))
compressed = hexlify(privkey.pubkey.serialize()).decode('ascii')
uncompressed = hexlify(privkey.pubkey.serialize(compressed=False)).decode('ascii')
print(compressed)
print(uncompressed)
输出如下:
可见和ecdsa生成的公钥完全一致。
结论
在程序中使用secp256k1-py可以更快捷地从私钥生成公钥,代码也更易于阅读和理解。
但是同样因为secp256k1-py的公钥生成逻辑和细节对用户完全透明,要学习相关知识的话,还是用ecdsa更好一些。