- A+
数字签名是一种由两部分组成的数学方案:
第一部分是使用私钥(签名密钥)从消息(交易)创建签名的算法;
第二部分是允许任何人验证签名的算法,给定消息和公钥。
创建数字签名
在比特币的ECDSA算法的实现中,被签名的“消息”是交易,或更确切地说是交易中特定数据子集的哈希值。签名密钥是用户的私钥,结果是签名:((Sig = F{sig}(F{hash}(m), dA)))
这里的:
- dA 是签名私钥
- m 是交易(或其部分)
- F{hash} 是散列函数
- F{sig} 是签名算法
- Sig 是结果签名
函数F{sig} 产生由两个值组成的签名Sig,通常称为R和S:
Sig = (R, S)
现在已经计算了两个值R和S,它们就序列化为字节流,使用一种称为“分辨编码规则”(Distinguished Encoding Rules)或 DER的国际标准编码方案
签名序列化(DER)
交易输入中有一个解锁脚本,其中包含以下DER编码签名:
3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb0220
4b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e381301
该签名是钱包生成的R和S值的序列化字节流,证明拥有授权花费该输出的私钥。 序列化格式包含以下9个元素:
- 0x30表示DER序列的开始
- 0x45 - 序列的长度(69字节)
- 0x02 - 一个整数值
- 0x21 - 整数的长度(33字节)
- R-00884d142d86652a3f47ba4746ec719bbfbd040a570b 1deccbb6498c75c4ae24cb
- 0x02 - 接下来是一个整数
- 0x20 - 整数的长度(32字节)
- S-4b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813
- 后缀(0x01)指示使用的哈希的类型(SIGHASH_ALL)
重要的数字是R和S; 数据的其余部分是DER编码方案的一部分。
验证签名
要验证签名,必须有签名(R和S)、序列化交易和公钥(对应于用于创建签名的私钥)。本质上,签名的验证意味着“只有生成此公钥的私钥的所有者,才能在此交易上产生此签名。”
签名验证算法采用消息(交易或其部分的哈希值)、签名者的公钥和签名(R和S值),如果签名对该消息和公钥有效,则返回 TRUE 值。