基于Schnorr的无脚本多重签名
在“Schnorr签名”页上描述的单签名Schnorr协议中,Alice使用签名(kG,s)公开证明了她对私钥的知识,这种情况下我们将其称为y。想象一下,如果Bob也有一个私钥(z),并且他愿意与Alice合作,以证明他们共同知道x = y + z,而不是他们中的任何一个向对方或其他人透露他们的私钥。让我们再次通过BIP340 schnorr签名协议进行说明。
我们即将描述的简单协议是不安全的,原因我们将很快解释。我们只是使用它来演示Schnorr多签名的机制,然后再描述与之相关的被认为是安全的协议。
Alice和Bob需要推导出x的公钥,即xG。由于可以使用椭圆曲线运算将两个EC点相加,因此他们从Alice派生yG和Bob派生zG开始。然后他们将它们相加在一起,创建xG = yG + zG。
该协议中的点xG是它们的聚合公钥。为了创建签名,他们开始简单的多签名协议:
他们各自选择一个大的随机私有nonce,对于Alice是a,对于Bob是b。他们还各自派生相应的公共nonce aG 和 bG。他们一起生成聚合公共nonce kG = aG + bG。
他们就要签名的消息m达成一致(例如,一笔交易),每个人都生成一个挑战标量的副本:e = hash(kG || xG || m)。
Alice生成标量 q = a + ey。Bob生成标量 r = b + ez。他们将这些标量相加得到 s = q + r。他们的签名是两个值 kG 和 s。
验证者使用正常的方程检查他们的公钥和签名:sG == kG + hash(kG || xG || m) × xG。
Alice和Bob已经证明他们知道他们私钥的总和,而不让其中任何一方向另一方或其他任何人透露他们的私钥。该协议可以扩展到任意数量的参与者(例如,百万人可以证明他们知道他们百万个不同密钥的总和)。
前述的协议存在几个安全问题。最值得注意的是,一方可能在承诺自己的公钥之前学习到其他方的公钥。例如,Alice诚实地生成了她的公钥yG,并与Bob分享了它。Bob使用zG - yG生成了他的公钥。当他们的两个密钥结合在一起时(yG + zG - yG),正负yG项会相互抵消,因此公钥只代表z的私钥(即Bob的私钥)。现在Bob可以在没有任何帮助的情况下创建有效的签名。这称为密钥取消攻击。
有各种方法可以解决密钥取消攻击。最简单的方案是要求每个参与者在与其他所有参与者分享有关该密钥的任何内容之前,都要承诺其公钥的一部分。例如,Alice和Bob各自对其公钥进行哈希处理,并将其摘要与彼此分享。当他们都拥有对方的摘要时,他们可以分享他们的密钥。他们各自检查对方的密钥是否哈希为先前提供的摘要,然后正常进行协议。这可以防止他们中的任何一个选择会抵消其他参与者密钥的公钥。然而,要正确实施此方案是很容易失败的,例如,将其用于未硬化的BIP32公钥派生。此外,这增加了参与者之间的通信额外步骤,在许多情况下可能不理想。已经提出了更复杂的方案来解决这些缺陷。
除了密钥取消攻击之外,还存在许多可能针对随机数的攻击。请回忆一下,随机数的目的是防止任何人利用对签名验证方程中其他值的了解来解出您的私钥,从而确定其值。为了有效实现这一点,您必须每次签署不同消息或更改其他签名参数时都使用不同的随机数。这些不同的随机数不能以任何方式相关联。对于多重签名,每个参与者都必须遵循这些规则,否则可能会危及其他参与者的安全性。此外,还需要防止取消和其他攻击。实现这些目标的不同协议会做出不同的权衡,因此没有一种单一的多重签名协议适用于所有情况。相反,我们将注意到 MuSig 协议族中的三个协议:
MuSig
也称为 MuSig1,此协议在签署过程中需要三轮通信,类似于我们刚刚描述的过程。MuSig1 的最大优势在于其简单性。
MuSig2
此协议只需要两轮通信,有时可以将其中一轮与密钥交换合并。这可以显着加快某些协议的签名速度,例如计划在 LN 中使用无脚本多重签名。MuSig2 在 BIP327 中有规定(截至本文撰写时,这是唯一一个具有 BIP 的无脚本多重签名协议)。
MuSig-DN
DN 代表确定性随机数,消除了一个称为重复会话攻击的问题。它无法与密钥交换结合使用,且实现起来比 MuSig 或 MuSig2 要复杂得多。
对于大多数应用程序来说,MuSig2 是撰写本文时可用的最佳多重签名协议。
Last updated