比特币用到的算法知识

椭圆曲线数字签名算法椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线对数字签名算法(DSA)的模拟,该算法是构成比特币系统的基石 。
私钥非公开,拥有者需安全保管 。通常是由随机算法生成的,说白了,就是一个巨大的随机整数,256位、32字节 。大小介于1 ~ 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141之间的数,都可以认为是一个合法的私钥 。于是,除了随机方法外,采用特定算法由固定的输入,得到32字节输出的算法就可以成为得到私钥的方法 。于是,便有了迷你私钥(Mini Privkey),原理很简单,例如,采用SHA256的一种实现:
private key = SHA256(<passphase>)迷你私钥存在安全问题,因为输入集合太小,易被构造常见组合的彩虹表暴力破解,所以通常还是使用系统随机生成的比较好,无安全隐患 。
公钥公钥与私钥是相对应的,一把私钥可以推出唯一的公钥,但公钥却无法推导出私钥 。公钥有两种形式:压缩与非压缩 。
早期比特币均使用非压缩公钥,现大部分客户端已默认使用压缩公钥 。这个貌似是比特币系统一个长得像feature的bug,早期人少活多代码写得不够精细,openssl库的文档又不足够好,导致Satoshi以为必须使用非压缩的完整公钥,后来大家发现其实公钥的左右两个32字节是有关联的,左侧(X)可以推出右侧(Y)的平方值,有左侧(X)就可以了 。
现在系统里两种方式共存,应该会一直共存下去 。两种公钥的首个字节为标识位,压缩为33字节,非压缩为65字节 。以0x04开头为非压缩,0x02/0x03开头为压缩公钥,0x02/0x03的选取由右侧Y开方后的奇偶决定 。
压缩形式可以减小Tx/Block的体积,每个Tx Input减少32字节 。
签名使用私钥对数据进行签署(Sign)会得到签名(Signature) 。通常会将数据先生成Hash值,然后对此Hash值进行签名 。签名(signature)有两部分组成: R + S 。由签名(signature)与Hash值,便可以推出一个公钥,验证此公钥,便可知道此签名是否由公钥对应的私钥签名 。
通常,每个签名会有三个长度:73、72、71,符合校验的概率为25%、50%、25% 。所以每次签署后,需要找出符合校验的签名长度,再提供给验证方 。
地址地址是为了人们交换方便而弄出来的一个方案,因为公钥太长了(130字符串或66字符串) 。地址长度为25字节,转为base58编码后,为34或35个字符 。base58是类似base64的编码,但去掉了易引起视觉混淆的字符,又在地址末尾添加了4个字节校验位,保障在人们交换个别字符错误时,也能够因地址校验失败而制止了误操作 。
由于存在公钥有两种形式,那么一个公钥便对应两个地址 。这两个地址都可由同一私钥签署交易 。
公钥生成地址的算法:
Version = 1 byte of 0 (zero); on the test network, this is 1 byte of 111Key hash = Version concatenated with RIPEMD-160(SHA-256(public key))Checksum = 1st 4 bytes of SHA-256(SHA-256(Key hash))Bitcoin Address = Base58Encode(Key hash concatenated with Checksum)下图是非压缩公钥生成地址的过程:

比特币用到的算法知识

文章插图
【比特币用到的算法知识】 
对于压缩公钥生成地址时,则只取公钥的X部分即可 。
推导关系三者推导关系:私钥 >> 公钥 >> 两个地址 。过程均不可逆 。拥有私钥便拥有一切,但通常为了方便,会把对应的公钥、地址也存储起来 。
交易比特币的交易(Transation,缩写Tx),并不是通常意义的交易,例如一手交钱一手交货,而是转账 。交易由N个输入和M个输出两部分组成 。交易的每个输入便是前向交易的某个输出,那么追踪到源头,必然出现一个没有输入的交易,此类交易称为CoinBase Tx 。CoinBase类交易是奖励挖矿者而产生的交易,该交易总是位于Block块的第一笔 。
比特币用到的算法知识

文章插图
 
拥有一个输入与输出的Tx数据:
Input:Previous tx: f5d8ee39a430901c91a5917b9f2dc19d6d1a0e9cea205b009ca73dd04470b9a6Index: 0scriptSig: 304502206e21798a42fae0e854281abd38bacd1aeed3ee3738d9e1446618c4571d1090db022100e2ac980643b0b82c0e88ffdfec6b64e3e6ba35e7ba5fdd7d5d6cc8d25c6b241501 Output:Value: 5000000000scriptPubKey: OP_DUP OP_HASH160 404371705fa9bd789a2fcd52d2c580b65d35549dOP_EQUALVERIFY OP_CHECKSIG一旦某个Tx的第N个输出成为另一个Tx的输入,那么该笔比特币即为已花费 。每个交易有唯一Hash字符串来标识,通过对交易数据做两次SHA256哈希运算而来:
Tx Hash ID = SHA256(SHA256(Tx Data))矿工费矿工费(Transaction Fee)是鼓励矿工将Tx打包进Block的激励报酬 。计算一笔交易的矿工费:


推荐阅读