搜索
NFT元宇宙Web3
近期热门

V神:使用 ZK-SNARK 保护隐私的一些方法

波动

ZK-SNARK 是一种强大的加密工具,也是人们在区块链空间内外构建的应用程序中越来越重要的一部分。但是它们很复杂,无论是就它们的工作方式而言,还是就您如何使用它们而言。

我之前解释 ZK-SNARKs 的帖子集中在第一个问题上,试图以一种可以合理理解但理论上仍然完整的方式来解释 ZK-SNARKs 背后的数学。这篇文章将关注第二个问题:ZK-SNARKs 如何适应现有的应用程序,它们可以做什么,不能做什么的一些例子,以及确定 ZK-SNARKs 是否SNARKing 一些特定的应用程序是可能的?

特别是,这篇文章重点介绍了 ZK-SNARK 在保护隐私方面的应用

ZK-SNARK 有什么作用?

假设您有一个公共输入X, 私人输入w, 使用 ZK-SNARK,验证者可以更快地验证证明。

这赋予了 ZK-SNARK 两个属性:隐私可扩展性。如上所述,在这篇文章中,我们的示例将关注隐私。

会员证明

假设你有一个以太坊钱包,并且你想证明这个钱包有一个人类证明注册,而不是透露你是哪个注册的人。我们可以用数学方法描述函数如下:

  • 私人输入(w): 你的地址一个, 和私钥ķ到你的地址
  • 公众意见(X):具有经过验证的人性证明配置文件的所有地址的集合{H1…Hn}
  • 验证功能 F(X,w):
    • 解释w作为对(一个,ķ), 和X作为有效配置文件的列表{H1…Hn}
    • 验证一个是地址之一{H1…Hn}
    • 验证privtoaddr(k) = A
    • 返回True如果两个验证都通过,False如果任一验证失败

证明者生成他们的地址一个和相关的密钥ķ, 并提供w = (A, k)作为私人输入F. 他们接受公众的意见,即当前一组经过验证的人性证明配置文件{H1…Hn}。他们运行 ZK-SNARK 证明算法,该算法(假设输入正确)生成证明。证明者将证明发送给验证者,他们提供他们获得已验证配置文件列表的块高度。

验证者也读取链,获取列表{H1…Hn}在证明者指定的高度,并检查证明。如果检查通过,则验证者确信证明者具有一些经过验证的人类证明档案。

在我们继续讨论更复杂的示例之前,我强烈建议仔细阅读上面的示例,直到了解所发生的每一点。

提高会员证明的效率

上述证明系统的一个弱点是验证者需要知道整套配置文件{H1…Hn},他们需要花费O(n)将这个集合“输入”到 ZK-SNARK 机制的时间。

我们可以通过将包含所有配置文件的链上 Merkle 根(这可能只是状态根)作为公共输入作为公共输入来解决这个问题。我们添加另一个私有输入,一个 Merkle 证明M证明证明者的帐户A位于树的相关部分。

高级读者:用于 ZK 证明成员资格的 Merkle 证明的一个非常新且更有效的替代方案是Caulk。将来,其中一些用例可能会迁移到类似于填缝的方案。

coins的 ZK-SNARK

Zcash和Tornado.cash等项目允许您拥有保护隐私的货币。现在,您可能认为您可以采用上面的“ZK 人性证明”,但不是证明对人性证明配置文件的访问,而是使用它来证明对硬币的访问。但是我们有一个问题:我们必须同时解决隐私和双花问题。也就是说,应该不可能将硬币花两次。

以下是我们如何解决这个问题。任何拥有硬币的人都有一个私人秘密s. 他们在本地计算“叶子”L = hash(s, 1),它在链上发布并成为状态的一部分,并且N = hash(s, 2),我们称之为无效符。状态存储在 Merkle 树中。

要花费coins,发件人必须制作 ZK-SNARK,其中:

  • 公共输入包含一个无效符N, 当前或最近的 Merkle 根R,和一片新的叶子L’(目的是收件人有一个秘密s’, 并传递给发件人L’ = hash(s’, 1)
  • 私有输入包含一个秘密s, 一片树叶L和一个 Merkle 分支M
  • 验证功能检查 :
    • M是一个有效的 Merkle 分支,证明L是有根的树上的叶子L, R是当前状态的Merkle 根。
    • hash(s, 1) = L
    • hash(s, 2) = N

交易包含无效符N和新叶L’. 我们实际上并没有证明任何关于L’,但我们将其“混入”到证明中以防止L’交易进行中时不会被第三方修改。

为了验证交易,链检查 ZK-SNARK,并额外检查N未在之前的支出交易中使用。如果交易成功,N被添加到已花费的无效符集中,因此无法再次花费。L’被添加到 Merkle 树中。

这里发生了什么?我们使用 zk-SNARK 来关联两个值,L’(在创建硬币时上链)和N(当一个硬币被花费时,它会在链上),但没有透露是哪个 L’连接到哪个 N.

这也是一个需要理解的重要原语。我们在下面描述的许多机制将基于一个非常相似的“私人只消费一次”小工具,尽管目的不同。

具有任意余额的coins

以上可以很容易地扩展到任意余额的coin。我们保留“coin”的概念,除了每个coin都有一个(私人)余额。一种简单的方法是为每枚硬币开设连锁店,而不仅仅是L’还有一个加密的余额。

每笔交易将消耗两个coins并创建两个新coins。ZK-SNARK 还会检查输入余额的总和是否等于输出余额的总和,并且两个输出余额都是非负的。

ZK 反拒绝服务

一个有趣的反拒绝服务小工具。假设您有一些创建起来并不简单的链上身份:它可能是一个人类证明配置文件,它可能是一个拥有 32 ETH 的验证者,或者它可能只是一个拥有非零 ETH 余额的账户. 我们可以创建一个更具 DoS 抵抗力的点对点网络,方法是只接受带有证明消息的发件人具有这样一个配置文件的消息。每个配置文件每小时最多可以发送 1000 条消息,如果发件人作弊,发件人的配置文件将从列表中删除。但是我们如何保护隐私呢?

首先,设置。让k是用户的私钥;A = privtoaddr(k) 是对应的地址。有效地址列表是公开的(例如,它是链上的注册表)。到目前为止,这类似于人类证明的例子:你必须证明你拥有一个地址的私钥,而不能透露是哪一个。但是在这里,我们不只是想要证明您在列表中。我们想要一个协议,可以让您证明您在列表中,但可以防止您制作太多证明。所以我们需要做更多的工作。

我们将时间划分为时期;每个时期持续 3.6 秒(因此,每小时 1000 个时期)。我们的目标是允许每个用户每个 epoch 只发送一条消息;如果用户在同一时期发送两条消息,他们将被捕获。为了允许用户偶尔发送突发消息,他们可以使用最近的 epoch,因此如果某些用户有 500 个未使用的 epoch,他们可以使用这些 epoch 一次性发送 500 条消息。

协议

我们将从一个简单的版本开始:我们使用无效符。用户生成一个无效符N = hash(k, e), ķ是他们的钥匙和,e是纪元号,并与消息一起发布m. ZK-SNARK 再次混入hash(m)没有验证任何m,因此证明绑定到单个消息。如果用户使用相同的无效符将两个证明绑定到两条不同的消息,他们可能会被捕获。

现在,我们将继续讨论更复杂的版本。下一个协议不仅可以轻松证明某人是否两次使用了相同的时期,而且在这种情况下实际上会显示他们的私钥。我们的核心技术将依赖于“两点成一条线”的技巧:如果你在一条线上显示一个点,你就显示的很少,但是如果你在一条线上显示两个点,你就显示了整条线。

对于每个e,我们L_e(x) = hash(k, e) * x + k. 线的斜率为hash(k, e), y 截距为ķ; 两者都不为公众所知。为消息制作证书m,发件人提供y = L_e(hash(m)) =hash(k, e) * hash(m) + k,以及一个 ZK-SNARK 证明是的被正确计算。

回顾一下,这里的 ZK-SNARK 如下:

  • 公众意见
    • {A_1 … A_n\}, 有效账户列表
    • m,证书正在验证的消息
    • e, 用于证书的纪元号
    • y, 线函数评价
  • 私人输入
    • ķ, 你的私钥
  • 验证功能
    • 检查privtoaddr(k)在\{A_1 … A_n\}
    • 检查y = hash(k, e) * hash(m) + k

但是如果有人使用一个 epoch 两次呢?这意味着他们发布了两个值m1和m2和相应的证书值是的y_1 = hash(k, e) * hash(m_1) + k和 y_2 = hash(k, e) * hash(m_2) + k. 我们可以使用这两个点来恢复线,从而恢复 y 截距(这是私钥):

因此,如果有人重用一个 epoch,他们就会泄露他们的私钥供所有人查看。根据具体情况,这可能意味着资金被盗、验证者被削减,或者只是将私钥广播并包含在智能合约中,此时相应的地址将从集合中删除。

我们在这里完成了什么?一个可行的链下匿名反拒绝服务系统,可用于区块链对等网络、聊天应用程序等系统,无需任何工作证明。RLN(速率限制无效器)项目目前基本上正在构建这个想法,尽管有一些小的修改(即,他们同时使用无效器和两点在线技术,使用无效器更容易捕获双重- 使用一个时代)。

ZK 负面声誉

假设我们要建立0chan,一个像 4chan 一样提供完全匿名的互联网论坛(所以你甚至没有永久的名字),但有一个信誉系统来鼓励更多高质量的内容。这可能是一个系统,其中一些审核 DAO 可以将帖子标记为违反系统规则并建立三击即退机制,它可能是用户能够对帖子投赞成票和反对票;有很多配置。

信誉系统可以支持正面或负面的信誉;然而,支持负面声誉需要额外的基础设施来要求用户在他们的证明中考虑所有声誉消息,甚至是负面消息。我们将重点关注这个更难的用例,它类似于Unirep Social正在实施的用例。

链接帖子:基础知识

任何人都可以通过在链上发布包含帖子的消息和 ZK-SNARK 来发布帖子,以证明 (i) 你拥有一些稀缺的外部身份,例如。人性证明,使您有权创建一个帐户,或 (ii) 您之前发表了一些特定的帖子。具体来说,ZK-SNARK 如下:

  • 公共投入
    • 无效符N
    • 最近的区块链状态根R
    • 帖子内容(“混合”到证明中以将其绑定到帖子,但我们不对它进行任何计算)
  • 私人输入
    • 你的私钥ķ
    • 外部身份(带有地址一个),或无效符N_{prev}由上一篇文章使用
    • 默克尔证明M证明包含A或者链上N_{prev}
    • 号码i使用此帐户发布的帖子
  • 验证功能
    • 检查M是一个有效的 Merkle 分支证明(或者A或者N_{prev}, 以提供者为准) 是一棵有根的树中的叶子R
    • 检查N = enc(i, k), enc是一个加密函数(例如 AES)
    • 如果i = 0, 检查A = privtoaddr(k), 否则检查N_{prev} = enc(i-1, k)

除了验证证明之外,该链还检查 (i)R实际上是最近的状态根,并且(ii)无效符ñ尚未使用。到目前为止,这就像之前介绍的隐私保护coin,但我们添加了一个“铸造”新帐户的程序,并且我们删除了将你的帐户“发送”到不同密钥的能力 – 相反,所有无效符都是使用你原来的钥匙生成的。

我们用enC代替H一个sH在这里使无效符可逆:如果你有ķ,您可以解密您在链上看到的任何特定无效符,并且如果结果是有效索引而不是随机垃圾(例如,我们可以检查dec(N) < 2^{64}),那么你知道 nullifier 是使用生成的ķ.

添加声誉

该方案中的声誉是链上明确的:一些智能合约有一个方法addReputation,该方法将 (i) 与帖子一起发布的无效值作为输入,以及 (ii) 要添加和减去的声誉单元的数量。

我们扩展了每个帖子存储的链上数据:而不是仅仅存储 nullifierñ:

  • bar{h} = hash(h, r) H是证明中引用的状态根的块高度
  • bar{u} = hash(u, r) U是帐户的信誉分数(新​​帐户为 0)

r这里只是一个随机值,添加以防止H和U从被蛮力搜索发现(在密码学术语中,添加r使哈希成为隐藏承诺)。

如果我们想要“三击出局”规则,ZK-SNARK 也会检查U>-3. 如果我们想要一个规则,一个帖子可以得到一个特殊的“高声誉海报”标志,如果海报有≥100,我们可以通过添加“U≥100?”作为公共输入。可以容纳多种这样的规则。

为了增加该方案的可扩展性,我们可以将其拆分为两种消息:帖子信誉更新确认(RCA)。一个帖子将是链下的,尽管它需要指向过去一周制作的 RCA。RCA 将在链上,并且 RCA 将遍历自该发布者之前的 RCA 以来的所有声誉更新。这样,链上负载减少到每周每张贴者一笔交易加上每条声誉消息一笔交易。

追究中心化各方的责任

有时,需要构建一个具有某种中央“操作员”的方案。这可能有很多原因:有时是为了可扩展性,有时是为了隐私——特别是运营商持有的数据的隐私。

例如, MACI抗强制投票系统要求选民在链上提交他们的投票,并加密到中央运营商持有的密钥中。运营商将解密链上的所有选票,将它们计数,并显示最终结果,以及证明他们做的一切正确的 ZK-SNARK。这种额外的复杂性对于确保强大的隐私属性(称为强制抗性)是必要的:即使用户想要,用户也无法向其他人证明他们是如何投票的。

多亏了区块链和 ZK-SNARK,对运营商的信任度可以保持在非常低的水平。恶意运营商仍然可以打破强制抵抗,但由于投票是在区块链上发布的,运营商不能通过审查投票来作弊,并且由于运营商必须提供 ZK-SNARK,所以他们不能通过错误计算结果来作弊。

将 ZK-SNARK 与 MPC 相结合

ZK-SNARK 的更高级的使用涉及对计算进行证明,其中输入在两方或多方之间分配,我们不希望每一方都学习其他方的输入。可以在 2 方情况下通过乱码电路满足隐私要求,在 N 方情况下使用更复杂的多方计算协议来满足隐私要求。ZK-SNARKs 可以与这些协议结合起来进行可验证的多方计算。

这可以启用更高级的信誉系统,其中多个参与者可以对其私人输入执行联合计算,它可以启用隐私保护但经过身份验证的数据市场,以及许多其他应用程序。也就是说,请注意,有效执行此操作的数学运算仍处于起步阶段。

我们不能将什么设为私有?

ZK-SNARK 通常对于创建用户拥有私有状态的系统非常有效。但是 ZK-SNARKs 不能保持没有人知道的私有状态。要对一条信息进行证明,证明者必须以明文形式知道该信息。

Uniswap 是一个不能(轻易)私有化的简单例子。在 Uniswap 中,有一个逻辑中心的“事物”,即做市商账户,它不属于任何人,Uniswap 上的每一笔交易都与做市商账户进行交易。你无法隐藏做市商账户的状态,因为这样就必须有人以明文形式保存状态以进行证明,并且每笔交易都需要他们的积极参与。

可以使用 ZK-SNARKed 乱码电路制作一个中央操作但安全且私密的 Uniswap,但目前尚不清楚这样做的好处是否值得付出代价。甚至可能没有任何真正的好处:合约需要能够告诉用户资产的价格是多少,而价格的逐块变化可以很好地说明交易活动是什么。

区块链可以使状态信息全局化,ZK-SNARK 可以使状态信息私有化,但是我们真的没有任何好的方法可以同时使状态信息全局化和私有化

将primitives原语放在一起

在上面的部分中,我们看到了一些本身就是强大且有用的工具的示例,但它们也旨在用作其他应用程序的构建块。例如,无效符对货币很重要,但事实证明它们在各种用例中一次又一次地出现。

负面信誉部分中使用的“强制链接”技术非常适用。对于许多应用程序来说,它非常有效,因为用户拥有复杂的“配置文件”,这些配置文件会随着时间的推移以复杂的方式发生变化,并且你希望强制用户在保护隐私的同时遵守系统规则,这样就没有人看到哪个用户正在执行哪个操作。甚至可能要求用户拥有代表其内部“状态”的整个私有 Merkle 树。这篇文章中提出的“承诺池”小工具可以使用 ZK-SNARKs 构建。如果某些应用程序不能完全在链上并且必须有一个集中的运营商,那么完全相同的技术也可以用来保持运营商的诚实。

ZK-SNARK 是一个非常强大的工具,可以将责任和隐私的好处结合在一起。它们确实有其局限性,尽管在某些情况下,聪明的应用程序设计可以解决这些限制。我希望看到更多使用 ZK-SNARK 的应用程序,以及最终将 ZK-SNARK 与其他形式的密码学相结合的应用程序,这些应用程序将在未来几年内构建。

编辑于 2022-06-20 22:09
「 真诚赞赏,手留余香 」
赞赏

发表评论已发布0

手机APP 意见反馈 返回顶部 返回底部