libsecp256k1 与 openssl ecdsa

时间:2022-08-17 17:52:49

1. 历史

区块链节点在接收到的用户发送的交易时,首先会验证交易所涉及utxo的可用性。方法是验证用户签名的合法性,涉及的签名算法就是secp256k1,一种椭圆曲线加密算法。

长期以来,实现了该算法的第三方库只有openssl,因此btcoin core一直都引用了此库。

openssl是一个庞大的开源库,不仅仅实现了椭圆曲线加密算法,在椭圆曲线加密算法中也不仅仅实现了secp256k1这一种椭圆曲线。

不久大家就发现了openssl的一些问题,除了自身结构复杂庞大,文档也不全面,最重要的是,opensssl的算法一致性也有潜在的问题,这会导致区块链发生不可预料的分叉,造成难以估量的损失。

以下是来自BIP66中的说明:

--BIP66 --
"Bitcoin's reference implementation currently relies on OpenSSL for signature validation, which means it is implicitly defining Bitcoin's block validity rules. Unfortunately, OpenSSL is not designed for consensus-critical behaviour (it does not guarantee bug-for-bug compatibility between versions), and thus changes to it can - and have - affected Bitcoin software.

One specifically critical area is the encoding of signatures. Until recently, OpenSSL's releases would accept various deviations from the DER standard and accept signatures as valid. When this changed in OpenSSL 1.0.0p and 1.0.1k, it made some nodes reject the chain.

This document proposes to restrict valid signatures to exactly what is mandated by DER, to make the consensus rules not depend on OpenSSL's signature parsing. A change like this is required if implementations would want to remove all of OpenSSL from the consensus code."

所以自2016年2月13日起,在新发布的bitcoin core 0.12.0版本中,libsecp256k1库代替了openssl ecdsa。 libsecp256k1中只实现了一种椭圆曲线算法,代码简练,很快大部分社区就接收了这种改变。

2. 区别

  • 在基于椭圆曲线secp256k1的加解密算法的实现上,libsecp256k1 与 openssl ecdsa不一致,你若使用openssl ecdsa对交易签名,现在的区块链可能不会正确验证。
  • libsecp256k1已经成为bitcoin社区事实上的标准,成为开发者唯一能选择的官方库
  • libsecp256k1 与 openssl ecdsa的主要差别之一,在于bip62提出的"Low S values in signatures"规则。libsecp256k1中包含了对规则的自动应用,而openssl ecdsa需要开发者自己实现该规则。

3. 关于"Low S values in signatures"规则

在BIP中描述如下:

--BIP62--
"Low S values in signatures

The value S in signatures must be between 0x1 and 0x7FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 5D576E73 57A4501D DFE92F46 681B20A0 (inclusive). If S is too high, simply replace it by S' = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 - S."

关于"Low S values in signatures"的必要性,有一段解释如下:

"Absent this rule, any person is able to take a Bitcoin transaction, flip s in any of its signatures, and push the transaction out again with a different TXID. Being able to do this only changes the hash of the transaction, and does not alter its validity in any way. Being able to mutate transactions breaks a number of potentially interesting transaction types in Bitcoin like payment channels, where chains of transactions will suddenly be invalidated by a parent being mutated and an alternate form included in a block.

By forcing valid transactions to always have low s this ability is removed, though a person with the private key for a transaction is still able to mutate their own transactions by resigning them with a new nonce."

简言之,其目的是,防止恶意第三方通过修改transaction(按照以往ecdsa规则,修改后依然合法)影响区块链网络运行,同时依然保障私钥所有者生成多样transaction的能力。

相关实现可以参考早期的bitcoin代码

4. 引用