每天进步一点点:"Canonical" 交易签名

每天进步一点点:"Canonical" 交易签名

在之前学习用私钥签名的文章中,虽然我们完成了用私钥进行签名,但是我还留下一下问题,就是生成的签名尽管可以通过验证,但是是否适用于STEEM/HIVE区块链呢?这里涉及到一个知识点就是canonical signature


(图源 :pixabay)

canonical signature

说到canonical signature,就要提到一个Signature Malleability,简单来讲就是对于同一个HASH,signature (r,s)以及signature (r, -s (mod N))都是合法的签名:

In addition for every ECDSA signature (r,s), thesignature (r, -s (mod N)) is a valid signature of the same message.

对于恶意攻击者而言,就可以利用这点来进行重播攻击,将一个交易用不同的签名提交两次(说的是啥?一头雾水ing)。

而杜绝这个问题的一个方法就是对签名的r、s进行一些约束,只有符合约束的才能算做合法的签名。

steemd中相关代码

在steemd中对应的检查代码如下:

image.png

其中两个检查代码分别如下:

image.png

如下代码会作为参数传递给签名/验证的相关函数:

has_hardfork( STEEM_HARDFORK_0_20__1944 ) ? fc::ecc::bip_0062 : fc::ecc::fc_canonical );

也就是说HF20之前用fc_canonical来检查,HF20之后用bip_0062来检查。话说,这个两个检查哪个更严格一些呢?另外bip_0062中为啥不检查

steem-python 中的相应检查

steem-python中针对用使用SECP256K1生成的签名使用如下代码检查:

1
2
3
4
5
def _is_canonical(self, sig):
return (not (sig[0] & 0x80)
and not (sig[0] == 0 and not (sig[1] & 0x80))
and not (sig[32] & 0x80)
and not (sig[32] == 0 and not (sig[33] & 0x80)))

而针对使用ecdsa生成的签名则使用如下代码来检查:

1
2
3
4
5
6
# Make sure signature is canonical!
#
lenR = sigder[3]
lenS = sigder[5 + lenR]
if lenR is 32 and lenS is 32:
其它代码

可见都不是遵循新的bip_0062标准。

不过这两组代码现在也都是工作的,我猜测是因为按着bip_0062标准,上述代码检查后的签名不符合标准的概率微乎其微,所以很难触发吧?😳

相关链接


This page is synchronized from the post: ‘每天进步一点点:”Canonical” 交易签名’

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×