我们继续关于门罗币区块链的系列文章,今天的文章将重点介绍 RingCT(环机密交易)协议,该协议介绍了机密交易和新的环签名。 不幸的是,互联网上关于它如何工作的信息很少,我们试图填补这个空白。
我们将讨论网络如何使用该协议隐藏传输金额,为什么他们放弃经典的加密货币环签名,以及该技术将如何进一步发展。
由于该协议是门罗币中最复杂的技术之一,因此读者需要了解该区块链的设计基础知识以及椭圆曲线密码学的基本知识(要温习这些知识,您可以阅读我们的上一篇文章关于
RingCT协议
对加密货币的可能攻击之一是基于对发送交易的金额和时间的了解的区块链分析。 这允许
值得注意的是,隐藏金额的想法并不新鲜。 比特币核心开发者格雷格·麦克斯韦(Greg Maxwell)是第一个在他的著作中描述它的人之一。
除其他外,该协议有助于消除混合灰尘输出的问题 - 少量输出(通常以交易找零的形式收到),这会产生比其价值更多的问题。
2017 年 6 月,门罗币网络发生了硬分叉,允许选择性使用机密交易。 同年 XNUMX 月,随着版本 XNUMX 硬分叉,此类交易成为网络上唯一允许的交易。
RingCT同时使用多种机制:多层链接自发匿名群签名(Multilayered Linkable Spontaneous Anonymous Group Signature,以下简称MLSAG)、承诺方案(Pedersen Commitments)和范围证明(该术语没有既定的俄语翻译) 。
RingCT协议引入了两种类型的匿名交易:简单和完整。 当交易使用多个输入时,钱包会生成第一个,而在相反的情况下,钱包会生成第二个。 它们的不同之处在于交易金额的验证和使用 MLSAG 签名签署的数据(我们将在下面详细讨论这一点)。 而且,full类型的交易可以用任意数量的输入生成,没有根本的区别。 在书里
MLSAG签名
让我们记住什么是签名的交易输入。 每笔交易都会花费并产生一些资金。 资金的产生是通过创建交易输出(直接类比钞票)而发生的,交易花费的输出(毕竟现实生活中我们花的是纸币)成为输入(小心,很容易混淆)这里)。
一个输入引用多个输出,但只花费一个输出,从而创建了一个“烟幕”,使分析翻译历史变得困难。 如果一笔交易有多个输入,那么这样的结构可以表示为矩阵,其中行是输入,列是混合输出。 为了向网络证明交易准确地花费了其输出(知道其密钥),输入使用环签名进行签名。 这样的签名保证签名者知道任何列的所有元素的密钥。
保密交易不再使用经典交易
它们被称为多层,因为它们一次对多个输入进行签名,每个输入都与其他几个输入混合,即对一个矩阵进行签名,而不是对一行进行签名。 正如我们稍后将看到的,这有助于节省签名大小。
让我们看看环签名是如何形成的,以一个交易为例,该交易花费 2 个实际输出并使用区块链中的 m - 1 个随机输出进行混合。 让我们将我们花费的输出的公钥表示为
,以及相应的关键图像: 这样我们就得到了一个大小为 2×米。 首先,我们需要计算每对输出的所谓挑战:
我们从输出开始计算,并使用它们的公钥进行计算:和随机数结果,我们得到以下值:
,我们用它来计算挑战
下一对输出(为了更容易理解我们在哪里替换什么,我们用不同的颜色突出显示了这些值)。 以下所有值均使用第一个插图中给出的公式在一个圆圈中计算。 最后要计算的是一对实际输出的挑战。
正如我们所看到的,除了包含实际输出的一列之外,所有列都使用随机生成的数字。 为 π- 专栏我们也需要它们。 让我们转型吧在 s 中:
签名本身是所有这些值的元组:
然后该数据被写入事务中。
正如我们所看到的,MLSAG 仅包含一项挑战 c0,这可以让您节省签名大小(这已经需要大量空间)。 此外,任何检查员使用这些数据,恢复值 c1,…, cm 并检查。 因此,我们的环已关闭并且签名已得到验证。
对于完整类型的 RingCT 交易,在混合输出的矩阵中又添加了一行,但我们将在下面讨论这一点。
彼德森承诺
门罗币承诺用于隐藏转账金额并使用最常见的选项 - Pedersen 承诺。 顺便说一句,一个有趣的事实 - 最初开发人员建议通过普通混合来隐藏金额,即添加任意金额的输出以引入不确定性,但后来他们转向承诺(这并不是他们节省的事实)交易规模,我们将在下面看到)。
一般来说,承诺是这样的:
哪里 C ——承诺本身的意义, a - 隐藏金额, H 是椭圆曲线上的一个固定点(附加生成器),并且 x - 某种任意掩码,随机生成的隐藏因子。 这里需要掩码,以便第三方不能简单地猜测承诺的价值。
当生成新的输出时,钱包会计算其承诺,并且在花费时,它会根据交易的类型,采用生成过程中计算的值或重新计算它。
环CT简单
在简单的RingCT交易的情况下,为了保证交易创建的输出等于输入的数量(不是凭空产生钱),需要第一个和第二个的承诺之和为相同,即:
承诺委员会的看法略有不同——没有面具:
哪里 a — 佣金数额,是公开的。
这种方法使我们能够向依赖方证明我们正在使用相同的金额,而无需披露它们。
为了让事情更清楚,让我们看一个例子。 假设一笔交易花费了 10 和 5 XMR 的两个输出(意味着它们成为输入),并生成了三个价值 12 XMR 的输出:3、4 和 5 XMR。 同时,他支付了3 XMR的佣金。 因此,花费的金额加上生成的金额和佣金等于 15 XMR。 让我们尝试计算承诺并查看其金额的差异(记住数学):
在这里我们看到,为了使方程收敛,我们需要输入和输出掩码的总和相同。 为此,钱包随机生成 x1、y1、y2 和 y3,以及剩余的 x2 计算如下:
使用这些掩码,我们可以向任何验证者证明我们产生的资金不会多于我们支出的资金,而无需透露金额。 原创吧?
环CT全
在完整的 RingCT 交易中,检查转账金额稍微复杂一些。 在这些交易中,钱包不会重新计算输入的承诺,而是使用生成时计算的承诺。 在这种情况下,我们必须假设总和之差不再为零,而是:
这是 z — 输入和输出掩码之间的差异。 如果我们考虑 zG 作为公钥(事实上是),那么 z 是私钥。 这样,我们就知道了公钥和相应的私钥。 有了这些数据,我们就可以在 MLSAG 环签名中使用它以及混合输出的公钥:
因此,有效的环签名将确保我们知道其中一列的所有私钥,并且只有在交易产生的资金不超过其支出的资金时,我们才能知道最后一行的私钥。 顺便说一句,这是“为什么承诺金额的差异不会导致零”问题的答案 - 如果 zG = 0,然后我们将用实际输出扩展该列。
资金接收者如何知道向他发送了多少钱? 这里一切都很简单 - 交易的发送者和接收者使用 Diffie-Hellman 协议交换密钥,使用交易密钥和接收者的查看密钥并计算共享秘密。 发送者将有关输出金额的数据写入交易的特殊字段中,并使用此共享密钥加密。
范围证明
如果您使用负数作为承诺金额会发生什么? 这可能会导致额外硬币的产生! 这个结果是不可接受的,所以我们需要保证我们使用的金额不是负数(当然不能透露这些金额,否则这么多工作都是白费)。 换句话说,我们必须证明总和在区间内 [0, 2n - 1].
为此,每个输出的总和被分成二进制数字,并分别计算每个数字的承诺。 最好通过一个例子来了解这是如何发生的。
假设我们的金额很小并且适合 4 位(实际上是 64 位),并且我们创建一个价值 5 XMR 的输出。 我们计算每个类别的承诺以及整个金额的总承诺:
接下来,每个承诺都与代理混合 (Ci-2iH) 并与 Borromeo 环签名(另一个环签名)成对签名,由 Greg Maxwell 在 2015 年提出(您可以阅读更多相关信息)
总而言之,这称为范围证明,并允许您确保承诺使用范围内的金额 [0, 2n - 1].
接下来是什么?
在当前的实现中,范围证明占用大量空间 - 每个输出 6176 字节。 这导致交易量更大,因此费用更高。 为了减少门罗币交易的规模,开发人员正在引入防弹技术而不是 Borromeo 签名——一种没有按位承诺的范围证明机制。
提出您的问题,为有关加密货币领域技术的新文章提出主题,并订阅我们的小组
来源: habr.com