cover_image

Schnorr 签名基础

Kurt Pan XPTY
2022年01月08日 19:41

https://popeller.io/schnorr-basics

如果你在思考 Schnorr 签名时遇到困难,那么你并不孤单。在这篇文章中,我尝试在我自己能理解的水平上解释 Schnorr 签名,希望你也会发现它的价值。

1什么是Schnorr?

Schnorr 是比特币中的一种新签名方案,它在Taproot升级中被激活。BIP340 中列出了Schnorr 一些不错的性质 ,我不在这里赘述。

  • https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#motivation

2签名和验证

签名方案由两个操作组成,签名和验证,如下图所示:

左侧:使用消息和私钥进行签名。右侧:验证消息(猫)是否确实是使用正确的私钥进行签名的。

签名者拥有私钥和要签名的消息(例如,比特币交易或猫图),并生成签名。验证者拥有与签名者使用的私钥相对应的公钥、消息和签名。验证过程在不知道私钥的情况下确保签名是使用正确的私钥创建的。

如果你想要更深入的解释,请访问Grokking Bitcoin 第 2 章的后半部分

  • https://rosenbaum.se/book/grokking-bitcoin-2.html#_digital_signatures

签名者

我们现在来看 Schnorr 签名是如何创建的,即上图的左侧。我假设你熟悉如何使用随机数生成器和椭圆曲线创建密钥对。如果没有,我建议你阅读 Grokking Bitcoin 的第 4.8 节。

  • https://rosenbaum.se/book/grokking-bitcoin-4.html#public-key-math

假设你要给一张猫图签名,猫图就是要签名的消息,你的属于你的公钥的私钥是

你要做的第一件事是抽取一个随机数,我们将称之为nonce(“只用一次的数字”的意思)。接着你就把当作是一个私钥,这意味着你可以通过乘以来生成相应的公钥(生成元点)。在此阶段,你有的东西如下:

nonce的承诺,它将成为最终签名的第一部分。则必须保密并且永远不会被重复使用。你已准备好签名所需的一切。签名将分两步完成。第一步是计算一个所谓的挑战哈希

挑战哈希是对挑战进行哈希,其中挑战是的串联。这几个部分都将供验证者使用。使用挑战哈希,你现在可以进行第 2 步:计算挑战应答,这是签名的第二部分:

最终你生成的签名是:

你把猫图,还有你的签名 一起发给你的朋友Fred。

验证者

Fred 想确保猫图片在传输过程中没有受到损坏,以及确保它确实是来自与你,即唯一可以访问你的私钥的人。他可以访问,当然也可以访问这个广为人知的常数。根据这些信息可以计算挑战哈希并验证验证方程是否成立:

如果这个等式成立,Fred 可以确定签名是用生成的. 可以看到如果给上述应答方程两边同乘以,我们就可以得到验证方程

如你所见:如果应答方程成立,则验证方程成立。同样,如果验证方程成立,则响应方程也成立。因此,当 Fred 基于椭圆曲线上的点验证验证方程成立时,他也隐含地验证了基于标量的应答方程成立。

当 Fred 验证了签名后,他就可以欣赏这张猫的照片了,并完全相信这张图实际上与你发送给他的照片是相同的。

3为什么要是秘密的?

你可能想知道为什么 nonce 必须保密。你甚至可能想知道为什么会需要这个 ?我们从后者开始,如果从签名过程中删除,看看会发生什么。

你将按如下方式创建签名:

签名将只包括 .  Fred 将验证你的签名通过验证如下等式成立:

这个等式是成立的。但是,因为Fred知道,他可以通过应答方程提取出私钥:

好吧,我们确实需要 nonce 来防止 Fred 得到你的私钥。但是为什么我们必须对 nonce 保密呢?为什么要很麻烦地去使用 nonce 承诺而不是 nonce 本身呢?

这是出于同样的原因。假设Fred得到了nonce ,那么他可以弄通过如下方式得到

所以Fred可以通过从里减掉再除以的方式来计算出

通过只给Fred展现 nonce 承诺,我们确保 Fred 无法计算出 , 同时允许他验证确实被用于签名的生成。

4不要重用Nonce

即使对 nonce 保密,如果你对同一个私钥使用两次 nonce,仍然可能会泄露你的私钥。假设你使用相同的nonce和私钥进行两个签名,如下所示:

你把签名 给验证者。验证者就可以使用简单算术来计算出你的私钥了!他可以建立一个有两个方程和两个未知数的方程组如下:

两个方程相减是可以得到的:

如你所见,验证者将能够提取私钥。学到的经验教训:不要重复使用nonce

如果 nonce 被重用,但是对于不同的私钥的,上述的方程组将不可解,因为你有三个未知数,  和 ,但只有两个方程。

5挑战里包括什么?

挑战哈希 是挑战的哈希. 为什么要使用这个特殊的挑战呢?我们分别看一下这三个部分。

要签名的消息是 ,所以以某种方式由签名得到承诺当然是重要的。如果从挑战中去掉,“签名”将对任何消息都有效。

为了确保除了私钥的所有者之外没有人可以创建签名,挑战必须包含 nonce 承诺 。假设挑战不包括 nonce 承诺,那么任何有权访问公钥的人都可以轻松伪造签名。他们可以使用任意的并做如下操作:

最后一个方程是为了解的所谓“验证方程”。注意到方程右侧只包含已知量,因此签名是有效的。

如果把包含在挑战中,使得 是挑战的一部分,就不可能解关于的验证方程了,因为很难找到一个 使得  

我们最后来看看在挑战中做些什么。假设在挑战中没有是对公钥和消息的有效签名。那么对于任意数,签名将是对于公钥和消息的有效签名。我们看看为什么:

这称为相关密钥攻击。如果你熟悉BIP32 中的扩展公钥派生的工作原理,你可能会看到潜在的危险。这里是一般的想法:

从父扩展公钥派生子扩展公钥,橙色纸条被称为chain code,在 Grokking Bitcoin 中有详细描述,你只需要知道它们是 256 位的数字。

这意味着,如果攻击者知道父扩展公钥 (xpub) 和子密钥的有效签名,则攻击者可以使用此技巧来为父 xpub 以及可以派生的任何子xpub 伪造签名。这不仅仅是 BIP32 的问题,也是许多以某种方式使用公钥添加的方案的问题,例如 Taproot(BIP341)。更多详细信息请查看 BIP340 的设计部分。

  • https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
  • https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs
  • https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#Design

6下一步

在下一篇文章中,我将展示如何在多重签名场景中使用 Schnorr 签名来生成看起来像普通单个签名的签名。这在比特币中非常实用,因为它减少了验证区块链的资源需求。

最后加一个Google翻译的梗来作为这篇关于签名文章的meta-签名:

电子 = H(电阻|磷|米) ;秒 = 电阻 + 电子磷