生成一个公钥
以一个随机生成的数字_k_的私钥开始,我们通过将它乘以称为_generator point_ G_的曲线上的预定点,在曲线上的其他位置产生另一个点,这是相应的公钥_K。生成点被指定为+secp256k1+标准的一部分,对于+secp256k1+的所有实现始终相同,并且从该曲线派生的所有密钥都使用相同的点_G_:
\[\begin{equation} {K = k * G} \end{equation}\]
其中_k_是私钥,G_是生成点,_K_是生成的公钥,即曲线上的一个点。因为所有以太坊用户的生成点始终相同,所以_G_乘以_G_的私钥总是会导致相同的公钥_K。k_和_K_之间的关系是固定的,但只能从_k_到_K_的一个方向进行计算。这就是为什么以太坊地址(来自_K)可以与任何人共享,并且不会泄露用户的私钥(k)。
正如我们在 椭圆曲线算术运算中所描述的那样,k * G的乘法相当于重复加,G + G + G + … + G ,重复k次。总而言之,为了从私钥_k_生成公钥_K_,我们将生成点_G_添加到自己_k_次。
Tip | 私钥可以转换为公钥,但公钥不能转换回私钥,因为数学只能单向工作。 |
让我们应用这个计算来找到我们在 私钥 中给出的特定私钥的公钥:
Example private key to public key calculation
K = f8f8a2f43c8376ccb0871305060d7b27b0554d2cc72bccf41b2705608452f315 * G
密码库可以帮助我们使用椭圆曲线乘法计算K值。得到的公钥_K_被定义为一个点 K = (x,y) :
Example public key calculated from the example private key
K = (x, y)
where,
x = 6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b
y = 83b5c38e5e2b0c8529d7fa3f64d46daa1ece2d9ac14cab9477d042c84c32ccd0
在以太坊中,你可以看到公钥以66个十六进制字符(33字节)的十六进制序列表示。这是从行业联盟标准高效密码组(SECG)提出的标准序列化格式采用的,在[http://www.secg.org/sec1-v2.pdf\[Standards](http://www.secg.org/sec1-v2.pdf[Standards) for Efficient Cryptography(SEC1)]中有记载。该标准定义了四个可用于识别椭圆曲线上点的可能前缀:
Prefix | Meaning | Length (bytes counting prefix) | |
0x00 | Point at Infinity | 1 | |
0x04 | Uncompressed Point | 65 | |
0x02 | Compressed Point with even Y | 33 | |
0x03 | Compressed Point with odd Y | 33 |
以太坊只使用未压缩的公钥,因此唯一相关的前缀是(十六进制)04。顺序连接公钥的X和Y坐标:
04 + X-coordinate (32 bytes/64 hex) + Y coordinate (32 bytes/64 hex)
因此,我们在 Example public key calculated from the example private key 中计算的公钥被序列化为:
046e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b83b5c38e5e2b0c8529d7fa3f64d46daa1ece2d9ac14cab9477d042c84c32ccd0