零知识证明库中更合理的默认设置,或如何获取证明者的私钥

许多零知识证明(ZKP)库为了追求性能,忽略了椭圆曲线的基本检查,可能导致安全漏洞。文章讨论了不验证椭圆曲线点和子群成员关系的风险,回顾了相关的攻击历史,并强调了在密码学库中默认启用所有检查的重要性,以确保程序的安全性。

介绍

许多 ZK 库允许创建点对 $(x,y)$,这些点对在构建电路时不属于它们正在使用的椭圆曲线。有些库也不检查这些点是否属于适当的子群,这可能会导致漏洞。

有人认为,无效点不应到达证明者。更令人惊讶的是,我们期望示例代码或应用程序解决这个问题,但它们并没有。它们甚至没有考虑到是否需要这些额外的检查。当然,许多人担心基准测试,因为添加约束会使事情变慢,但是移除安全网并忽略多年前发布的一些攻击并不是一个好的长期策略。即使这些检查不是证明者的一部分,它们也必须存在于某个地方,但在很多情况下它们并不存在!如果构建者从不受信任的用户那里获取点(如公钥),他们的系统可能会受到损害,并且密钥可能会被盗。

密钥可能会泄露服务器可能需要运行的加密数据或持有对资金的访问权限。

回到检查,正如我们之前所说,如果应用程序在输入到达证明者之前验证输入,或者如果对协议进行了周密的分析,那么它们可能是不需要的。

但是,第一个解决方案虽然简单,但可能会导致审查。为什么证明者应该拒绝生成证明,说输入无效,而没有证明它是无效的?

如果代码中存在另一个错误,可能会有更多的问题,因为恶意用户可能有更多方法来扰乱程序。

在一个实际的例子中,几周前,我们发现了一个漏洞,允许我们让证明者相信两个点相等,而实际上它们不相等。基本上,他们没有检查,给定 $A=(x_A,y_A)$ 和 $B=(x_B,y_B)$,$y_A=y_B$。如果他们检查这些点是否在椭圆曲线中,那么对于相同的 $x=x_A=x_B$,必然只有两种可能性,要么 $y_A=y_B$,要么 $y_A=-y_B$,因为它们必须满足曲线方程。如果没有这样的检查(因为开发者认为没有必要),那么 $y$ 坐标的值就和素数域的阶一样多。

因此,即使协议没有漏洞,保持一些额外的检查作为“深度防御”也是一个好主意和工程实践,以使程序更加健壮,以防出现任何其他漏洞,这些漏洞可以与缺乏验证相结合来创建漏洞利用。

攻击和漏洞的历史。

未检查点是否属于子组的问题最早由 Chae Hoon Lira 和 Pil Joong Lee 在 1997 年的 "使用素数阶子群对基于离散对数的方案进行密钥恢复攻击" 中报告。

同时,未检查坏曲线的问题最早由 Bhiel 在 2000 年的 "椭圆曲线密码系统的差分故障攻击" 中报告。这篇文章 还展示了当代码不验证是否属于椭圆曲线时出现的一些问题。

让我们通过一个例子来看看这个漏洞是如何工作的。我们可以用 Weierstrass 形式写椭圆曲线,

$y^2=x^3+ax+b$

一个关键的事实是,加法和倍乘公式不依赖于值 $b$。这意味着如果两条曲线 $E$ 和 $E'$ 仅在 $b$ 上不同,则它们具有相同的运算。曲线 $E'$ 被称为相对于 $E$ 的无效曲线,攻击者可以选择一个安全性弱得多的 $E'$。

假设攻击者发送一些低阶 $k$ 的点 $Q$(最简单的情况是 $k=2$,这意味着 $2Q=O$)。如果攻击者与用户 $A$ 执行密钥交换以导出共享密钥 $K=KDF(sk_AQ)$ 并且 $A$ 向攻击者发送一些消息 $m$,那么他可以学习 $sk \equiv \frac{sk}{k} \pmod{k}$

如果攻击者重复此过程多次(使用不同阶的点,所有点互质),可能使用不同的无效曲线,他会得到一个同余方程组。

$sk \equiv sk_1 \pmod{k_1}$

$sk \equiv sk_2 \pmod{k_2}$

$sk \equiv sk_3 \pmod{k_3}$

$sk \equiv sk_4 \pmod{k_4}$

然后,他可以使用中国剩余定理来重建 $sk$,或者至少重建候选列表,并使用暴力搜索解决剩下的问题。这导致攻击者学习密钥并冒充服务器或用户,甚至代表用户签署交易(例如,导致资金被盗)

我们可以扩展这种攻击,用于那些与直接原始示例开始不同的密钥交换协议。有关另一个示例,请参见 TLS-ECDH 上的实际无效曲线攻击

总结

许多用于零知识证明应用程序的密码学库删除了或忽略了对椭圆曲线的一些基本检查,这可能会导致漏洞。我们正在与这些库的贡献者讨论以解决这些问题并公开它们。

即使这些问题已经被人们知道超过 20 年了,但对性能的渴望导致忽略了这些问题,为在这些库之上进行开发的开发人员带来了潜在的问题。剩下的问题是,我们的应用程序距离这些类型的漏洞有多远,以及程序员在处理可能被污染的数据时会有多小心。

良好的默认设置非常重要。从我们的角度来看,所有检查都应该默认在库中完成,如果没有完成,则应该更加明确。包含合理默认设置的良好示例应该是库的一部分。将代码优化留给高度审核的代码,在这种代码中,跳过这些检查可以为实际用户带来真正的改进。

感谢 LambdaClass 的 Diego Kingston 和 Mauro Toscano 帮助撰写本文。

  • 原文链接: blog.lambdaclass.com/bet...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
lambdaclass
lambdaclass
LambdaClass是一家风险投资工作室,致力于解决与分布式系统、机器学习、编译器和密码学相关的难题。