生成一个公钥

以一个随机生成的数字_k_的私钥开始,我们通过将它乘以称为_generator point_ G_的曲线上的预定点,在曲线上的其他位置产生另一个点,这是相应的公钥_K。生成点被指定为+secp256k1+标准的一部分,对于+secp256k1+的所有实现始终相同,并且从该曲线派生的所有密钥都使用相同的点_G_:

\[\begin{equation} {K = k * G} \end{equation}\]

其中_k_是私钥,G_是生成点,_K_是生成的公钥,即曲线上的一个点。因为所有以太坊用户的生成点始终相同,所以_G_乘以_G_的私钥总是会导致相同的公钥_Kk_和_K_之间的关系是固定的,但只能从_k_到_K_的一个方向进行计算。这就是为什么以太坊地址(来自_K)可以与任何人共享,并且不会泄露用户的私钥(k)。

正如我们在 椭圆曲线算术运算中所描述的那样,k * G的乘法相当于重复加,G + G + G + …​ + G ,重复k次。总而言之,为了从私钥_k_生成公钥_K_,我们将生成点_G_添加到自己_k_次。

Tip

私钥可以转换为公钥,但公钥不能转换回私钥,因为数学只能单向工作。

让我们应用这个计算来找到我们在 私钥 中给出的特定私钥的公钥:

Example private key to public key calculation

  1. K = f8f8a2f43c8376ccb0871305060d7b27b0554d2cc72bccf41b2705608452f315 * G

密码库可以帮助我们使用椭圆曲线乘法计算K值。得到的公钥_K_被定义为一个点 K = (x,y) :

Example public key calculated from the example private key

  1. K = (x, y)
  2. where,
  3. x = 6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b
  4. 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坐标:

  1. 04 + X-coordinate (32 bytes/64 hex) + Y coordinate (32 bytes/64 hex)

因此,我们在 Example public key calculated from the example private key 中计算的公钥被序列化为:

  1. 046e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b83b5c38e5e2b0c8529d7fa3f64d46daa1ece2d9ac14cab9477d042c84c32ccd0