密码学--公私钥和比特币地址

私钥

任意一个256位的二进制的随机数都能作为公钥,转换为十六进制是64位数字。

公钥

通过椭圆曲线加密算法可以从私钥计算得到公钥,且该过程不可逆。

比特币使用了secp256k1标准所定义的一条特殊的椭圆曲线,该标准由美国国家标准与技术研究院(NIST)设立。

比特币地址

一般为一个由数字和字母组成的字符串,由公钥生成的比特币地址以数字“1”开头。

以公钥K为输入,计算其SHA256哈希值,并以此结果计算RIPEMD160哈希值,得到一个长度为160位(160比特,20字节)的数字,即为比特币地址。但通常用户所见到的比特币地址是经“Base58Check”编码的地址。


Base58和Base58Check编码

为了简洁的表示长串数字,计算机会使用数字和字母组合的方式表示数字的表示法。

  • Base64

使用了26个大小写字母、10个数字以及两个符号(“+ /“)对数字进行编码,通常用于编码邮件中的二进制附件。

  • Base58

用于比特币和其他的加密货币中,Base58是Base64编码格式的子集,同样使用了大小写字母和10个数字,但舍弃了容易错读和容易混淆的字符,舍弃了Base64中的0(数字零)、O(大写字母O)、l(小写字母L)、I(大写字母i)和“+ /”两个字符。

  • Base58Check

比Base58增加了错误校验码来检查数据在转录中出现的错误。

image

比特币中,大多数要向用户展示的数据都是使用Base58Check编码的,可以实现数据压缩,易读且有错误检验,其版本前缀使数据的格式易于辨别,如:Base58Check编码的比特币地址是以1开头的,而Base58Check编码的私钥WIF是以5开头的。

  • Base58Check版本前缀和编码后的结果
种类 版本前缀(hex) Base58格式
Bitcoin Address 0x00 1
Pay-to-Script-Hash Address 0x05 3
Private Key WIF 0x80 5,K or L

密钥的格式

公钥和私钥都可以有多种编码格式。一个密钥被不同的格式编码后,虽然结果看起来不同,但密钥所编码的数字没有改变。这些不同的编码格式主要是用来方便人们无误的使用和识别密钥。

  • 私钥的格式

私钥可以有多种不同的格式表示,所有这些都对应相同的256位数字。以下为私钥常见三种编码格式:

种类 版本 描述
Hex None 64位的十六进制表示
WIF(钱包导入格式) 5 Base58Check encoding: Base58 with version prefix of 128 and 32-bit checksum
WIF-compressed K or L As above, with added suffix 0x01 before encoding

示例:同样的私钥,不同的格式,WIF为Base58Check编码

格式 私钥
Hex 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD
WIF 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
WIF-compressed KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ
  • 公钥的格式

主要分为非压缩格式和压缩格式。

因为公钥是从私钥通过椭圆曲线算法计算得到的,即公钥是再椭圆曲线上的一个点,由一对坐标(x,y)组成。非压缩公钥通常为前缀04紧接着两个256比特的x,y(共520位比特/130个十六进制数字)。压缩格式的公钥是以02或者03开头。

椭圆曲线实际上是一个数学方程,曲线上的点实际是该方程的一个解,因此知道了x,通过方程y^2 mod p = (x^3 + 7) mod p 可以解出y.只需存储x坐标,从而压缩节省了256比特。因为方程左边上y的平方,所以y的值可能是正或负,为了区分,y为偶数以02做前缀,y为奇数以03做前缀。

  • “压缩格式的私钥”

实际上压缩格式私钥是一种误导,因为一个私钥被使用WIF-compressed格式导出时,不但没有压缩,而且比WIF多出一个字节,即加了后缀01,用以表明该私钥是来自一个较新的钱包,只能被用来生成压缩的公钥。

私钥是非压缩的,也不能被压缩。“压缩的私钥”实际上用来表示“用于生成压缩格式公钥的私钥”, 而“非压缩格式私钥”用来表明“用于生成非压缩格式公钥的私钥”。为了避免误解,我们应该只说导出格式是WIF压缩格式或WIF,而不能说这个私钥是“压缩的”。