每天进步一点点: 学习比特币的公钥

in cn •  3 years ago 

在之前的文章中,学习了这些东西:

尤其是通过最后一篇文章的学习,已经可以生成比特币的私钥,并可以将生成的私钥导入到 blockchain.info 在线钱包,并由此得到比特币地址。通过从blockchain.info 钱包导出私钥与我们获得的私钥对比,我们得知并基本掌握了私钥的几种表示方法。

  • HEX
  • Base58
  • WIF
  • WIF-Compressed

椭圆曲线与公钥

提到私钥我们常常提到公钥,他们是成对出现的。
公钥是从私钥通过椭圆曲线运算计算得来的,这个过程是不可逆的。亦即通过私钥可以算出公钥,反之则不行。


( Source: 《Mastering Bitcoin》)
别问我啥意思,不懂,就是看着挺好看是不?

比特币使用NIST(National Institute of Standards and Technology)确定的secp256k1标准中定义的椭圆曲线以及一组数学常量。


( Source: 《Mastering Bitcoin》)

看了一下椭圆曲线的讲解,一头雾水,看来凭我的智商是学不明白了,交给数学家们去研究好了!
我关心的是,如何从私钥到公钥,研究了半天,原来很简单,就是一个公式:
K=k∗G
其中小k是我们的私钥,G是生成点,K是结果亦即公钥是曲线上的另外一个点。

因为生成点对所有的比特币用户都是相同的,所以同一个私钥k乘以生成点G,总会得到相同的公钥K。所以从k到K是确定的,并且只能单向运算。这就是为何比特币地址(由公钥生成)可以告诉任何人不用担心泄露私钥。

Steem 官方Python 库中的实现

        secret = unhexlify(repr(self._wif))
        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')

其中repr(self._wif)得到的是HEX形式表示的私钥

导入我们之前生成的私钥试试看:
a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e


我们也会生成公钥了!!!

神马椭圆曲线,神马方程之类的,统统丢一边去吧
作为常年CTRL+C, CTRL+V变成的猿类,不需要了解太高深的数学姿势!
(PS: 数学家们是最值得尊重的了,没有他们的辛苦耕耘,我们就没有这么多好用的数学工具)


《Mastering Bitcoin》中有一个例子,验证点P在secp256k1定义的椭圆曲线上。

我们也来验证一下我们的生成的点P符不符合要求。

完美

示例代码

本文中所使用的代码如下:
感兴趣的朋友可以使用自己的私钥试试来生成公钥玩。

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')
p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
x = int(hexlify(x_str).decode('ascii'), 16)
y = int(hexlify(y_str).decode('ascii'), 16)
(x ** 3 + 7 - y**2) % p

总结

  • 公钥(K)可以通过椭圆曲线运算由私钥(k)计算得出
  • 私钥(k)到公钥(K)计算公式: K=k∗G
  • 生成过程使用secp256k1标准中定义的椭圆曲线以及一组数学常量
  • 从私钥(k)到公钥(K)结果是确定的,并且只能单向运算
  • 使用Python的ecdsa库,可以轻松实现私钥(k)到公钥(K)的计算

今天就探索到这里。
免责声明,本文为个人理解,示例仅供参考
因使用文中代码造成的损失,概不负责!

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

你太牛了, 我看不懂

sounds good
I wish this post translate to English @oflyhigh

這篇有一點點懂!>v<

威武霸气外加美丽动人!

嘿嘿!!>v<

哥 steemit也有wif登陆 一不知道是啥 这个这么用呢

Steemit的wif就是私钥,不过是好几个不同权限级别的私钥
比如posting 私钥就是用来发帖和点赞的

对应的公私钥算法几乎和bitcoin的一样

就像chainbb要的postkey。就是wif吗 了解了

posting key, active key, owner key, memo key 都是私钥

DWD: Good really

有意思,比以前自己的了解更深入了,跟着学习了。

我以前除了知道名,就啥也不知道了😢

我早前也有看過橢圓曲線在加密學中的應用,真是太難明了,甚麼G點我都是一知半解,直接跳過便算了😂

😄 为啥看你的回复,我觉得这么邪恶呢

我只看到 “G点” 😄,这个我懂。

大家思想太污穢了😄 point G 不就是 G點啦,你們都想起甚麼了?

我只是看看而已。其实什么也看不懂。

我只是过来点个赞,其实什么也看不懂。

有意思。

總結看得懂,上面的看不懂,我當我算是懂了哈哈 :D

恭喜你 😄

your post looks interesting
wish there was an english translation
anyway thanks for sharing

Mastering Bitcoin 这本书不错,我在读transaction的部分,有些代码不是很好懂

你已经遥遥领先了:)
前辈你好

O哥真是勤奋好学,是我们学习的榜样。

过奖了
恰巧用到,学完还怕忘了,年纪大记性不好

Looks like some thing really necessary to know! Wish the post was in English! Anyways, hey if anyone interested to know about India here you go, a place nicknamed as The Scotland of India !https://steemit.com/travel/@alexkoshy/the-scotland-of-india-coorg-why-should-you-tour-india-vii

感谢您对这个职位感兴趣

In english would be great . I have a feeling this post contains valuable information.

The principal! He will give me TP! I would hate for my bungholio to get polio....Where I come from, we have no bunghole.

would love to learn this language..looks great

Upvoted & RESTEEMED!

Congratulations @oflyhigh!
Your post was mentioned in the hit parade in the following category:

  • Pending payout - Ranked 6 with $ 255,74