oflyhigh avatar

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

oflyhigh

Published: 10 Apr 2020 › Updated: 10 Apr 2020每天进步一点点:"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生成的签名使用如下代码检查:

    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生成的签名则使用如下代码来检查:

# Make sure signature is canonical!
#
lenR = sigder[3]
 lenS = sigder[5 + lenR]
if lenR is 32 and lenS is 32:
               

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

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

相关链接

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

Written by

Programmer, Maker, Freelancer, Witness. Make friends, Make money, Make life better!

Read more #cn posts


Best Posts From oflyhigh

We have not curated any of oflyhigh's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.

More Posts From oflyhigh