《精通门罗币》第5章-深入探究门罗币与密码学 下篇

WooKey
14 min readMay 20, 2019

--

​​作者 | SerHack 翻译 | WooKey-极光

5.4 隐私技术

5.4.1 混淆地址

第 3 章从概念上描述了一次性地址(也称为混淆地址)如何允许交易在不暴露接收人真实地址的情况下发布到网络上。本节将更深入地解释一次性公钥背后的加密技术。

5.4.1.1 发送

CryptoNote 协议根据公式 X=Hs(r*PV|i)G+PS 计算接收一次性地址。让我们逐步了解这些符号的含义,以及 Maria 向 George 付钱时会如何生成一个一次性地址。

变量 r 是交易私钥,这是一个 256 位的伪随机标量。Maria(发送人)是唯一知道该密钥的人;甚至 George(接收人)也从来不知 Maria 钱包里选的 r 的随机数。

Maria 然后将 George 的查看公钥 PV 乘以 r,然后附加输出索引 i。该量 (r*PV|i) 随后通过 hash_to_scalar 函数 Hs() 运行。该函数使用 Keccak-256 算法对其输入进行散列,然后将得到的散列结果对质数进行取模

2²⁵⁵+27742317777372353535851937790883648493。

将上段中计得的 Hs(r*PV|i) 项乘以 ed25519 基点 G。最后,Maria 将该量加到 George 的支付公钥 PS 中,以产生最终输出 X,即混淆地址。

这一错综复杂的过程使得 Maria 能够使用一个随机生成的一次性地址向区块链的 George 进行隐秘交易,但无人能够与他联系。

5.4.1.2 接收

鉴于 Maria 将发送给 George 的门罗币隐藏得那么好(受 George 不知的交易私钥所掩蔽),你可能想了解 George 如何能在区块链找到它!

如第 3 章所述,George 必须扫描区块链,寻找属于他的输出。这个过程与 Maria 用来生成地址的方法非常相似。

George 从区块链获得交易公钥 R,并将 R 乘以他的查看私钥 pV。按照与 Maria 相似的步骤,George 附加输出索引 i,然后将 hash_to_scalar 函数应用于 (pV*R|i)。然后,他将结果乘以 G,并加上自己的支付公钥 PS。如果该值与输出匹配,则其属于他。

换言之,George 的钱包扫描了区块链的每一笔交易,以确定 X=Hs(pV*R|i)G+PS 的输出。

5.4.2 环机密交易

环机密交易(RingCT)模糊了交易中发送的门罗币的数量。RingCT 于 2017 年 1 月实施,并于 2017 年 9 月之后成为所有交易的强制性规定。

只有创造新门罗币作为 coinbase 奖励的交易才具有可见的数量,且不会受 RingCT 所掩蔽。这是一个审计功能,允许任何网络参与者计数并验证已生成多少门罗币。在币公开释放之后,这些交易在进一步使用之前被转换成 RingCT。

所有非 coinbase 交易均使用 RingCT 加密交易金额。每笔交易的金额以两种不同的方式加密,这两种方式均包含在消息中。

首先,该金额由从接收人地址中的公共信息导出的密钥加密。该版本记录在 ecdhInfo 字段中,只能由接收人使用交易共享秘密解密和读取。

其次,该金额被纳入佩德森承诺,如此可允许其他门罗币用户自己验证交易的有效性。无人可从佩德森承诺中检索交易金额,但是任何人均可检查结果,以数学方式验证输出与输入是否平衡。如此防止任何试图伪造门罗币的交易。

RingCT 的验证有两个关键方面:

发送人使用范围证明,可验证性证明所有输出均包含正数。范围证明表明,掩蔽数可被生成为 2 的正幂之和,而不会揭示这些幂是什么。如果没有范围证明,则一个拥有 5 XMR 的恶意的用户可用一对包含 +13 XMR 和 -8 XMR 的输出创建一个交易。

发送人还能证明输入与输出平衡,这是十分厉害的技能,因为环签名包含诱饵,以防止验证方知悉输入资金的真正来源!同态的佩德森承诺使发送人能够证明其中一个潜在的输入与输出之间的差异为零,而不会揭示过程中的数量。

为进行简单的类比,请考虑以下等式示例。类似掩蔽交易金额,你可验证每个等式是否有效,而无需知道 A 值。

A=我们的输出,无人知晓

5A+1A+4A=10A 真!已验证,不知晓A

6A+4A+2A=14A 假!未通过验证,拒绝!

5.4.3 环签名

门罗币利用环签名技术来保护每个交易发送人的隐私。环签名是一种加密签名,允许一个有效参与者代表一个组对消息进行签名。有效签名者拥有的私钥与来自其他成员的公钥信息混合,以产生单个签名。任何人均可对照公钥验证签名的消息,以验证某个环成员发起了签名,但是无法确定哪个成员贡献了私钥。

在门罗币背景下,消息是由环签名授权的交易。实际支出的输出是真正的签名者,来自其他输出(来自过去的交易)的公钥受混合作为诱饵签名者。实际签名者和诱饵签名者在数学上同等有效;不可用密码检查得到的环签名来确定哪个成员主动发起了签名。因此,任何外部方(包括接收人)均无法确定交易中引用的输出中的哪一项被实际支出了。

每个环签名产生一个单一密钥镜像,该图像是从实际支出的输出中派生而来。这是一个加密安全的过程:每个输出对应一个密钥镜像,且生成密钥镜像并不能揭示环中真正的签名者。

当输出的所有者在新的交易中支出该输出时,网络将存储由环签名产生的密钥镜像。由于网络无法识别哪些输出被支出了,反而会跟踪那些被支出的密钥镜像!如果所有者试图欺诈性地再次支出该输出(双花),则将会产生相同的密钥镜像,因此网络会拒绝交易。

让我们深入研究生成环签名的实际数学运算。在本示例中,假设 HS 是返回标量(在适当的字段中)的散列函数,HP 是返回点(在适当的曲线组中)的散列函数。我们有意避免正式定义这些域和上域,以避免复杂化。让 G 成为各方均知晓的固定点。

你将使用环签名在交易消息M上签名。门罗币目前要求每个签名有 11 个环成员,但是应考虑一个有 3 个环成员的简化示例。你拥有所支出的输出的密钥对(公开和私有),并选择另外两个输出(及其公钥)作为诱饵。自然而然,环成员的索引应为随机性,因为如果真正的签名者总是在 1 号币口中,则密码匿名将被规避。对于有 3 个环成员的简化示例,假设你的钱包已随机选择将资金的真正来源放在 2 号币口中。

你从区块链检索诱饵(P₁和P₃)的公开输出密钥,且你拥有所支出的输出的私钥(p₂)和公钥(P₂=p₂G)。你先选择一个稍后会丢弃的随机数 u。首先你构建以下承诺,从你为密钥选择的一个索引开始:

c₃=Hs(M,uG,uHp(P₂))

为构建其余的承诺,你还可选择稍后需要的随机数 s₃ 和 s₁:

c₁=Hs(M,s₃G+c₃P₃ , s₃Hp(P₃)+c₃p₂Hp(p₂))

请注意,此处包含了几条信息:你从区块链提取的公钥 P₃、你想出的随机数 s_3、之前的承诺 c₃ 以及由你自己的密钥形成的值 p₂Hp(P₂)。继续:

c₂=Hs(M, s₁G+c₁P₁, s₁Hp(P₁)+c₁p₂Hp(P₂))

但是你还未完成!为隐藏实际密钥,你巧妙地定义 s₂= u-c₂p₂。你发送到区块链和世界的签名包含几个数量:(c₁ , s₁ , s₂ , s₂ , J),其中 J=p₂Hp(P₂) 是每个承诺中使用的关键图像。我们在此将其重新命名,以强调一个事实:公众对构建承诺的碎片不了解。

这便是高明之处:通过设置 s₂=u-c₂p₂,你可重新排列来得出 u=s₂+c₂p₂。这意味着公众认为你构建的第一个承诺 c₃ 如下:

c₃=Hs(M, s₂G+c₂P₂, s₂Hp(P₂)+c₂p₂Hp(P₂))

这看起来和其他承诺完全一样!尽管你从未广播 u,但你用它巧妙地让每个承诺在观察者眼中看起来都一样。这便是环签名的力量。无人能确定哪个承诺隐藏了你真正的密钥,但是每个人均可采用数学方法来证明:

1. 发送人知晓由公钥表示的一个私钥

2. 密钥镜像计算正确

观察到密钥镜像 J=p₂Hp(P₂) 是从真实输出的密钥对中唯一计算出的、无任何随机数或诱饵的公钥。因此,任何试图欺诈性地第二次支出这笔输出(双花)的情况都将生成相同的密钥镜像。由于网络可跟踪使用的密钥镜像,因此任何重用输出的尝试均会被轻易地检测到并被拒绝。

请注意,上述 Back 类型 LSAG 环签名示例是出于培训目的而纳入,不应用作产品实现的参考文档。

5.4.4 更多资源

如果想更深入地研究这些技术背后的计算,可以看看《Zero to Monero》,这将是一段高技术性地数学旅程,也是一个社区资助的免费 PDF。

5.5 门罗币区块链

现在你已熟悉区块链作为分布式公开账本的重要性和实用性。这些区块被结构化并排序到不可变的只加数据库中,由防止任何篡改或欺骗的加密工具进行保护。对于该独一无二的门罗币区块链,我们将会在本节中讨论其技术和规格。

5.5.1 闪电记忆映射数据库

门罗币使用闪电记忆映射数据库(LMDB)系统来存储其区块链。LMDB 是一个软件库,可以密钥值存储形式提供高性能嵌入式交易数据库。这意味着其非常高效,且易于搜索。

LMDB 是由 C++ 编写的,具有多种编程语言的 API 绑定。由 Symas 公司开发。以下是 LMDB 的一些特征:

• 任意密钥/数据对存储为字节数组

• 基于范围的搜索能力

• 支持具有多个数据项的单个密钥

• 在数据库末尾添加记录的高级方法,与其他类似存储相比,该方法大大提高了写入性能

5.5.2 区块结构

CryptoNote 标准定义了在区块内和区块链上存储和描绘数据的规范。区块结构包含三个主要部分:

• 区块头

• 基础交易(一种产生新币的交易)

  • 交易标识符列表(在区块中挖掘出的交易散列)

5.5.2.1 区块头

每个区块均以包含密钥元数据的区块头开始。字段“major_version”定义了区块头解析规则,因此其可获得正确解释。字段“minor_version”定义了与主区块头解析无关的解释细节。

即使“minor_version”未知,用特定“major_version”解析区块头也始终安全。用未知的“major_version”解析区块头有风险,因为区块头内容可能会受到误解。

5.5.2.2 基础交易

每个有效区块包含一个单一的基础交易,该交易将其 coinbase 奖励发送给矿工。基础交易必须遵循发币规则,并包含区块高度字段。

5.5.2.3 交易标识符列表

基础交易之后是交易标识符列表。这些标识符是通过获取交易本身的 Keccak 散列来计算。列表开头为标识符数量,后面为标识符本身(如果区块不为空)。

5.5.2.4 区块标识符的计算

区块标识符通过用 Keccak-256 散列下列数据产生:

• 区块头的尺寸

• 区块头

• Merkle 根哈希

• 交易数量(变量)

Merkle 根哈希将区块主体中引用的交易“添加”到区块头:一旦 Merkle 根哈希固定后,交易便不能被修改。该安全特性使区块链免受篡改或任何形式的追溯性修改。

5.5.3 挖矿经济

第 2 章和第 4 章从概念上提及区块奖励和费用。现在,你将真正了解区块大小、奖励以及与费用关系的复杂性。

5.5.3.1 挖矿 coinbase 奖励

正如第 4 章所讨论那样,所有门罗币均是作为对矿工成功完成区块奖励而产生。该 coinbase 奖励支付的规模取决于当前供应量(A)和原子单位的初始数量(S=²⁶⁴-1)。原子单位是门罗币目前可由网络(1x10⁻¹² XMR)识别的最小单位

基础奖励 =2*((S-A)*2⁻²⁰*10⁻¹²)

门罗币有一个“尾部发行”,这是一个小的固定基础奖励,将在大部分供应开采后继续进行。门罗币的最低基础奖励是每区块 0.6 XMR,因此矿工们将永远不必仅依靠交易手续费维生。

5.5.3.2 动态区块大小

与许多使用静态(固定)区块大小的加密货币相比,门罗币动态区块大小可随着网络的增长而不断调整。例如,比特币最初的 1 MB 固定区块大小会通过限制每个区块中可包含的交易数量(从而限制网络的总交易量)进行缩放。2017 年,该瓶颈导致了极高的费用和交易处理的延迟。因此针对该问题提出了各种拟议的解决办法,导致在一段时间内出现了有争议的辩论。

为避免这些问题,门罗币采用了动态区块大小机制,允许矿工使用更大的区块来容纳增加的流量。但是,如果区块大小完全不受限,则门罗币网络可能容易受到垃圾交易攻击,即,会有许多小额交易通过使区块链扩张过快来耗尽网络和存储资源。

为防止区块大小过度增长,门罗币挖矿协议包括一个惩罚函数,以降低对超大区块的 coinbase 奖励。最初的 CryptoNote 作者纳入了该共识规则,以限制区块大小扩展的速率,避免快速的区块链膨胀。

如果所开采区块的大小(B)大于最后 100 个区块(Mɴ)的中值大小,将会根据以下条件扣留部分基础奖励:

惩罚 = 基础奖励*((B/Mɴ)-1)²

矿工可获得全部奖励只要区块尺寸在 300 kB 以内;对于任何更大的区块,惩罚函数“开始生效”。最大区块大小为 2*Mɴ,此时所有 coinbase 奖励都会被扣缴。

5.5.3.3 费用

当交易量较低、区块较小时,矿工会以最低的费用获得全部 coinbase 奖励。

但是,想象一个不同的场景:当最后 100 个区块的中值大小变得大于无惩罚区块尺寸(300 kB)时,将会发生什么?此时,动态费用算法开始发挥作用!

费用根据交易的权重(kB)计算。较大(“较重”)的交易会产生较高的费用。考虑到门罗币生态系统的几个因素和交易的优先级,动态费用的计算较复杂(发送人可通过追加更高的费用来激励矿工快速纳入紧急交易)。为在即将到来的区块中具有竞争力所需的费用根据以下公式计算:

每 kB 费用=(R/R₀)*(M₀/M)*F₀*(60/300)*4

• R 为基础奖励

• R₀ 为参考基础奖励(10 XMR)

• M 为区块大小限制

• M₀ 为最小区块尺寸限制(300 kB)

• F₀ 为 0.002 XMR

• 60/300 是一个调整系数说明无惩罚区块尺寸限制的提高(2017 年从 60 kB 调整到 300 kB)

• 4是一个调整系数说明默认费用乘数(最低费用水平使用 x1 的乘数,正常优先级交易使用 x4)

因此,费用考虑了相对于最小区块大小的中间区块大小的增加。例如,600 kB 区块大小(最小区块的两倍)可将费用降低一半。

理想情况下,提高门罗币的汇率和使用率会导致绝对费用(即,依据 XMR)减少。这种费用减免机制在价格大幅上涨时效率较低,价格涨幅远远大于交易量的涨幅(因此也大于区块大小的涨幅)。

动态费用算法设计为在中值区块大小始终高于 300 kB 时起作用。尽管该系统旨在解决价格上涨的问题,但使用率与价格并不完全相关,因此这并非一个完美的指标。

5.5.4 防弹协议

防弹协议是一种新技术,其极大地减小了交易尺寸,进而降低了每笔交易的总费用!门罗币交易尺寸曾经相当大(通常大于 12 kB),因此防弹协议曾是一个备受期待的增强功能。

为防止滥用和垃圾交易,门罗币的隐私特性需要在交易验证期间进行几项复杂的“测试”。这包括核实隐蔽金额、查询费用以及确保没有发生双花。

大多数开发人员都遇到过“溢出”错误,即操作创建值超出了可表示范围。不幸的是,“无限”对于电子产品而言是一个抽象的概念,其会遇到许多巨大的障碍。

由于 RingCT 隐藏了交易金额,因此需要复杂的计算来验证输入和输出是否正确地平衡。承诺的有用代数性质对于实现任何参与者均可确认其有效性的屏蔽交易而言具有价值性。

但是,确保每个金额均为正值,而不会导致溢出,这也是至关重要的因素。这便是范围证明的作用,即通过允许任何人验证一个承诺,此承诺代表一个特定范围内的金额,验证不会透露这个值的任何其他信息。每个范围证明过去需要大约7 kB,因此它们构成了交易的大部分。大多数交易有两个输出(目的地和更改地址),需要至少约 12 kB。

防弹协议采用一些巧妙的数学技巧,以更高效的机制构建范围证明。这可将单个范围证明大小减少到 2 kB 左右!

在防弹协议之前,具有多个输出的交易需要有多个独立的范围证明。因此,交易尺寸与输出数量成线性比例(例如,1 个输出=7 kB,2 个输出=14 kB)。凭借防弹协议,交易尺寸反而会随着输出增加(例如,1 个输出=2 kB,2 个输出=2.5 kB)以对数形式缩放。

通过减小每个范围证明的大小,并允许其以更有效的方式组合,防弹协议极大地减小了交易规模,从而降低了交易费用。2018 年 10 月,门罗币 v0.13.0 网络升级启用了防弹协议,作为一个可选的功能,在后继的升级中将会强制实行。

本章完…​​​​

--

--