本文深入探讨了零知识证明的理论基础、数学原理和加密技术,旨在帮助读者理解这一复杂的概念及其在Solana等网络上的应用。文章结构清晰,模块化设计,适合各个知识层次的读者,尤其是对加密技术有一定了解的人士。
非常感谢 Matt, Porter, Nick, Swen 和 bl0ckpain 在本系列文章中的评审。
零知识证明是密码学家设计的最强大工具之一。不幸的是,普通人并不理解它们。本文旨在通过提供零知识证明的全面概述来纠正这一点,从其基本原理出发。我们将涵盖零知识证明背后的理论、数学和密码学,以便任何人都能理解Solana上的最新发展,特别是ZK Compression以及互操作性的未来。
本文假设读者了解Solana的编程模型和区块链系统中固有的密码原语(即:哈希函数、哈希指针、Merkle树、并发Merkle树)。如果这些概念是新的,我建议首先阅读以下的历史博客文章:
请注意,本文设计时考虑了模块化。虽然建议对这些主题不熟悉的读者按顺序阅读每个部分和小节,但如果你对特定主题已有了解或想学习特定主题,直接跳到特定小节也不会有问题。
这也是关于零知识证明的两篇文章系列中的第一篇。强烈建议你首先阅读本文,然后再继续阅读 零知识证明:在Solana上的应用。
在1989年,麻省理工学院的研究人员Shafi Goldwasser、Silvio Micali(Algorand的创始人)和Charles Rackoff发布了交互式证明系统的知识复杂性。他们研究的系统中,一方(即,证明者)与第二方(即,验证者)交换消息,以说服后者某个数学语句为真。他们是第一个问这个问题的人:“如果证明者和验证者都不信任彼此,会怎样?”这里的担忧是,验证者在这些消息的过程中还将学习到多少信息,除了语句是真的。例如,证明者可能想要说服验证者,他们知道复杂谜题的解决方案而不透露具体解决方案。
图的三色性是计算机科学和图论中的经典问题。它涉及使用三种颜色来给图的顶点上色,以确保没有相邻的顶点共享相同的颜色。对于一个拥有三个顶点的图,这很简单。然而,随着顶点数量的增加,执行这一操作变得越来越困难。
一个实际应用例子是大学的课表安排。在一所大大学中,需要创建设定时间表,以确保没有学生的课程冲突。每堂课都可以表示为图中的一个顶点,边表示课程之间的共享学生。这保证了不会有两个共享相同学生的课程在同一时间安排。此外,约束条件包括教室容量、教授的偏好时间以及确保课程在一周中均匀分布。因此,时间段和教室应该被分配给课程,以确保没有两个相邻的课程共享相同的时间段。这可以通过图的三色性来完成。
现在,假设最终的课程表需要被外部审计公司验证。由于特定的隐私法规,大学无法与审计员共享详细的学生注册信息。相反,大学必须证明最终的时间表满足所需的约束,而不透露哪些学生注册了哪些课程的具体信息。
为此,大学必须创建一个图,其中每个顶点表示一门课。如果对应的课程至少有一名共同学生,则会在两个顶点之间绘制边。大学将为每门课指定时间段,以确保没有两个相邻的课程同时安排。大学将通过一种加密承诺方案,对其完成的时间表进行承诺。这涉及为每门课的分配时间段创建一个加密哈希,并在不透露时间段的情况下,与验证者分享这些哈希。外部审计公司然后随机选择相邻课程的对,以挑战已分配的时间段。大学会揭示选定的相邻课程的已承诺时间段,并提供原始承诺(即哈希),以便外部审计公司可以验证所揭示的值。挑战、揭示和验证的最后几个步骤会重复,直到外部审计公司确信没有课程重叠。我强烈推荐麻省理工学院的交互式零知识三色性演示,以查看这些步骤如何实时进行。
大学想向外部审计公司证明,他们知道一个正确的课程表。也就是说,他们想证明他们知道一些事情。这个问题的美在于,它是_ NP-完全 _的。
在计算复杂性理论中,当一个问题满足以下条件时,它被称为NP-完全:
NP-完全问题之所以重要,是因为它们代表了NP类中最难的问题(即,它们是一类非常困难的谜题,其中验证一个猜测的解决方案在多项式时间内是简单的,但找到解决方案是困难的)。这些问题以其通用可模拟性而著称。也就是说,如果我们能快速解决一个NP-完全问题,我们就可以将任何NP问题简化或转化为NP-完全问题,并在多项式时间内找到其解决方案。验证NP-完全问题的解决方案同样容易。
因此,我们有一个完整的问题类别,我们可以通过零知识证明高效证明。例如:
此外,Cook-Levin定理说明布尔可满足性问题是NP-完全的。也就是说,任何问题其变量可以被替换为真或假值,以使其最终计算结果为真,均能转化为NP-完全问题。这意味着,任何我们可以将其简化为一系列真和假问题的问题都可以使用零知识证明高效证明。
考虑到NP-完全问题的复杂性和重要性,有效且安全地证明这一类问题的解决方案变得至关重要。零知识证明提供了一种方法来进行证明,而不会侵犯相关信息的隐私。Goldwasser、Micali和Rackoff提出,所有的零知识证明必须满足以下性质:
通过利用零知识证明的强大特性,我们可以在各种上下文中证明某些信息的事实或知识,以隐私保护和精确无误的方式进行。在后续章节中,我们将探讨这对于需要高安全性和效率的应用(如区块链)为何是如此有价值。
零知识证明往往有相同的三步结构:
这个结构本质上是交互式的 — 证明者声明他们知道某些内容,验证者不断挑战他们,直到证明者欺骗他们的可能性微不足道。这对于大多数应用并不理想,因为证明者在生成完成的证明之前需要一个或多个响应。这个设置本质上存在以下挑战:
Fiat-Shamir启发式是一种将交互式知识证明转化为数字签名的技术。这种方式可以在不揭示底层信息的情况下公开证明某个事实。其想法是,证明者可以通过使用随机函数(例如_良好的_加密哈希函数)计算此数字签名,而不需要验证者向他们发送随机挑战值。因此,证明者不需要在500个不同的位置检查计算是否都正确,而是计算出计算的Merkle根,利用该Merkle根伪随机选择500个索引,并提供500个对应的Merkle数据分支。关键在于,证明者在数据被承诺之前并不知道哪些分支需要揭示。
机智的读者可能会注意到将随机抽样应用于抽查计算存在致命缺陷——计算本质上是脆弱的。恶意的证明者可以在计算中间翻转一个比特,而验证者将永远无法发现。验证者如何检查计算中的每个部分,而不逐个查看计算的每个部分呢?多项式。
然而,在谈论多项式之前,我们需要理解相当多的数学知识。
“不了解数学是理解世界的一个严重限制” — 理查德·P·费曼
这并不是对以下数学领域的全面介绍——这些部分本身可以是完整的文章。这是一个简短的介绍,希望你能开始理解零知识证明背后的数学基础以及它们在高层次运作的方式。
本文还将向你介绍适当的数学符号。例如,以下小节关于集合论,我们介绍了符号 ∈、 ∉ 和 ⊆。归根结底,这些符号都是某种东西的占位符。零知识证明并不是初学者的话题;因此,此主题的大多数文章都不适合初学者。它们不会深入解释这些符号的意义,并且假设读者理解这些符号。现在引入这些符号对于那些希望深入研究零知识证明的人来说至关重要。尽量不要在符号中迷失,努力克服,因为终有一天你会看到这些符号背后的概念,而不是某个希腊字母。
集合论是研究物体集合的数学分支。集合是一个包含不同对象的集合。这些不同的对象被称为元素或集合的成员。例如,考虑一个水果的集合:
$$ Fruit= { apple,orange,pear,banana } $$
大括号在集合符号中用于包裹元素的集合,以表示一个集合。这样,我们就知道苹果、橘子、梨和香蕉是这个集合的一部分,而类似“土豆”的物体则不在其中。符号 ∈ 用于指示集合的成员资格,读作“是某个元素”。同样,∉表示一个元素不是给定集合的成员。因此,我们可以说: $$ apple∈Fruit and potato∉Fruit $$
我们可以阅读为:“苹果是集合Fruit的元素,而土豆不是集合Fruit的元素。”
我们也可以有由其他集合组成的集合。子集是仅包含其他集合中元素的集合。例如,如果我们有:
$$ Citrus= {orange,lemon } $$
$$ AllFruits= {apple,orange,pear,banana,lemon,grapefruit } $$
我们可以说Citrus集合是较大集合AllFruits的一个子集。我们也可以使用之前的Fruit集,来说明Fruit是较大集合AllFruits的一个子集。我们可以在集合符号中写作:
$$ Citrus⊆AllFruits $$
$$ Fruit⊆AllFruits $$
集合论对于理解范围和约束的概念至关重要。在接下来的数论和模运算部分中,我们将探讨数字位于某个特定范围内的思想。例如,我们可能有一个密码密钥的可能值集合:
$$ K={k_1,k_2,k_3,…,k_n} $$
这里,K定义了所有可能密钥的范围。我们可以构造我们的零知识证明,使得某些约束应用于此集合,以便只有某些值是有效的。例如,我们可以说密钥必须是1到5之间的一个数字。
因此,集合论为在密码协议中定义和分析可能输入、输出和状态的集合提供了基础语言、工具和符号。在零知识证明中,我们往往需要证明一个元素属于特定的集合或范围,而不透露该元素本身。
我推荐你查看可汗学院的一些基础集合符号的优秀练习问题。
数论是研究整数和算术函数的数学分支。我们可以将整数定义为一组整体数字(即,不是分数),包括正数、负数和零。可以更正式地定义整数集合为:
$$ Z={…,−2,−1,0,1,2,…} $$
这里,ℤ用于表示整数集合,省略号表明整数从负无穷延续至正无穷。例如,数字12是一个整数,而-1978649832794275也是一个整数。
有理数是能够表示为分数的整数,该分数的分母(即,常见分数中线下的数字,除数)不是零。例如,(12),(23),(74)(\frac{1}{2}),(\frac{2}{3}),(\frac{3}{4})(|×2|,74,(\frac{3}{2}))都是有理数。我们可以更正式地将有理数定义为可以表达为分数pq的整数集合,其中p是分子,q是分母,且q不等于0。符号ℚ用于表示有理数。在集合符号中,我们可以写成:
$$ \mathbb{Q} = \left{ \frac{p}{q} \mid p, q \in \mathbb{Z}, q \ne 0 \right} $$
虽然这看起来最开始很吓人,但这正好与之前的句子描述一致。我们可以将这种奇怪的数学术语读作“Q是所有分数p和q的集合,其中p和q是整数,并且q不等于零。”
实数包括有理数和无理数。 无理数是指不能用简单分数表示的数,其十进制点非重复且非终止。例如,π(即,pi)和2\sqrt{2}(即,1.41421…)都是无理数。我们暂时跳过实数的集合符号,但需要注意,实数用符号ℝ表示。
数论与集合论密切相关,因为它涉及特定数字集合(例如,有理数)的研究。这些集合通常是定义数学和密码学问题范围和约束的基础。
我们还可以看到数论和集合论是如何相互关联的。例如,我们可以说所有整数的集合ℤ是有理数ℚ的一个子集。这从我们在集合符号中定义实数的高级例子来看,当我们说明分子和分母都是整数时,就能够清楚地看到这一点。
模运算,又称为钟表算数,是一套适用于整数的数值运算系统,其中数字在达到特定值时“环绕”,这个特定值称为模数。这里的思想是,我们不是处理无限集合的数字,而是处理前_n_个正数字。
考虑一个模拟时钟(在这个时代我很讨厌我必须说明它有指针,并且不是数字显示的)上有1到12的数字。如果是11点钟,我们想知道2小时后的时间,我们不会得到13点钟。相反,我们将环绕回1点钟。这可以表达为$11+2≡1 (mod12)$。此处的正确数学表达为1$3mod12=1$ 1 。程序员可能会熟悉以_模运算_的格式使用模数运算,如 $ 13%12=1$ 。
当我们写_n_模_k_时,这意味着我们希望_n_被_k_除后的余数。这称为模运算。例如:
在模运算中,余数总是非负的。
理解模运算至关重要,因为它提供了对在约束条件下数字行为的深入了解,这对于密码学非常重要。模运算是许多密码学算法的基础,并广泛应用于计算机科学、工程以及任何需要安全处理和加密数据的领域。
考虑计算x + y = z。如果我们在一个由质数p = 17定义的有限域中运作(我们很快会覆盖这一点)。此时,计算将成为_(x + y)_模p = z。假如 x = 12,y = 15,则计算将会是:
$ (12+15)mod17=z $ $27 \mod 17 = z $ $ 10 = z$
在这里使用模运算使我们能够在有限的可管理取值范围内进行计算,该范围由质数 p 定义。 这尤其重要,因为计算机和处理器的空间有限,因此我们通常使用u32或u64这样的固定大小整数进行操作。模运算确保我们的值保持在这些范围内。此外,使用质数增加了复杂性。这在密码学上至关重要,因为它增强了安全性并使某些数学属性更加可预测和可靠。
例如,模运算在zk-SNARKs中用于确保计算值保持在特定的、可管理的范围内。同时,它们也用于在给定数字集上创建算术电路。这是为了使我们能够表达计算,同时确保能够高效地进行验证。在这里,证明者必须证明他们执行了该计算,而不透露x、_y_和_z_的值。
我强烈推荐查看问题解决艺术学的练习问题集和Joseph Zoller的模运算实践以获得有关解决模运算问题的更多实践经验。
群论是研究被称为群的代数结构的一门数学分支。群是包含能够满足以下条件的元素集的操作,称为群公理:
正式来说,它们的定义是:
我们可以举个例子,把这些数学术语简化成更易理解的内容。考虑整数加法的集合。我们可以说这个集合形成了一个群,因为它满足四个群公理:
我们还可以将此扩展到更复杂的例子,例如非零有理数的集合 $ \mathbb{Q} = \left{ \frac{a}{b} \mid a, b \in \mathbb{Z}, b \ne 0 \right} $ ,其运算为乘法。这也形成了一个集合:
子群是群内的群。如果我们说子群_H_是群_G_的一个子集,我们需要满足以下群公理:
这里的经典例子是偶数整数集合在加法下是整数集合的一个子群:
我们可以应用这个于一个更难的例子。考虑所有非零有理数的集合(即,ℚ*)下的乘法。我们可以证明 ℚ* 是所有非零实数的集合(即,ℝ*)在乘法下的一个子群:
由于 ℚ* 满足所有的群公理,因此它形成一个群。此外,由于 ℚ* 是 ℝ* 的一个子集,继承了其特性,因此我们可以说 ℚ* 是 ℝ* 的一个子群。
群是多种数学和密码学概念与结构的基础。例如,加密系统如RSA和椭圆曲线密码学严重依赖群的性质及其操作。理解子群有助于通过检查其较小、易管理的子集来了解较大群的结构。群为理解对称性、操作和变换提供了基本框架,这在我们进入下一个关于域的部分时将至关重要。
域是一个元素的集合,满足加法和乘法的域公理,并且是可交换的除法代数(即,除以零以外的除法始终是可能的)。领域公理通常以加法和乘法的组合对写出:- 加法
有限域是具有有限元素集合的域。有限域也被称为伽罗瓦域。元素的数量称为域的阶或基数。元素的数量始终是一个素数的幂。有限域的优点在于,在域内执行的任何算术运算都将保持在该域内,因为所有运算都在域的阶的模下进行,导致值循环。
每个有限域都有一个生成元。生成元可以通过指数运算生成域内的所有元素。这意味着我们可以取生成元,并将其指数递增,直到我们拥有域内的所有元素。因此,生成元是域内的一个元素,通过其幂可以生成域内的每一个非零元素。
例如,设想我们取整数集合模 p = 7,得到了域 $\mathbb{Z}_7 = {0, 1, 2, 3, 4, 5, 6}$ 。如果我们想找到 $ \mathbb{Z}_7^*$ 的生成元 g(即 $\mathbb{Z}_7$的非零元素的乘法群),我们需要确保 g1, g2,g3 等能够生成域中的所有非零元素。
让我们检查 3 是否是一个生成元: $$ 3_1 \equiv 3 \pmod{7} \ 3_2 \equiv 2 \pmod{7} \ 3_3 \equiv 6 \pmod{7} \ 3_4 \equiv 4 \pmod{7} \ 3_5 \equiv 5 \pmod{7} \ 3_6 \equiv 1 \pmod{7} $$
3 的幂生成了 $\mathbb{Z}_7$中的所有非零元素。因此,3 是乘法群 $\mathbb{Z}_7^*$ 的生成元。
加密学是处理有限集合的科学。 它形成了理解离散对数问题、加密、Diffie-Hellman 交换和椭圆曲线等主题所需的基础知识。生成元允许在不解密的情况下对加密多项式进行算术运算(即 同态加密)。也就是说,我们可以在保持底层值隐私的同时计算加密数据。 理解这一部分对于零知识证明的零知识部分至关重要。
我建议访问 Bill 的安全网站,提供一个交互式示例,该示例生成具有特定参数和底层理论的有限域,并使用 Python 实现。
函数是定义两个变量之间关系的表达式、规则或法则——独立变量和依赖变量。这两个变量通常描述为原因和结果。这个关系通常表示为 y = f(x),可读作“ f of x。”对于每个 x 值,都有唯一的 y 值,这意味着 f(x) 对于同一个 x 不能有多个值。
函数可以是一对一或多对一的, 通常称为基数。这意味着一个 x 值可以映射到一个唯一的 y 值,或多个 x 值可以映射到相同的 y 值。
想象一个由 y=3x+4y = 3x + 4y=3x+4 定义的直线。这是一个线性函数,通过代入 x 值会返回一个对应的 y 值。这两个值结合在一起形成直线上的一个点。例如,我们可以重写方程为 f(x)=3x+4f(x) = 3x + 4f(x)=3x+4并在 x = 1 时进行评估,结果为 f(1)=7f(1) = 7f(1)=7。函数也可以有多个变量。例如,三角形面积的公式是: A=bh2A = \frac{bh}{2}A=2bh。这里, A(即面积)是 b(即底)和 h(即高)的函数。
函数的 定义域 是函数可以接受的所有可能输入值(即独立变量)的集合。函数的 范围 是函数可以产生的所有可能输出值(即依赖变量)的集合。
对于函数 $y=2x+2$:
函数对于理解 多项式至关重要。它们是涉及变量保持不同幂次及其系数的特殊函数。多项式是基础代数结构,为构建加密协议提供基础。在下一部分中,我们将详细探讨多项式,研究其属性及在零知识证明中的重要性。
我建议查看 Paul 的在线笔记,并解决他们的练习问题,以更好地理解函数。
多项式是一个包含多个变量和系数的函数,仅涉及加法、减法、乘法和非负整数的变量指数运算。多项式通常写成以下形式:
$$P(x) = an x^n + a{n-1} x^{n-1} + \ldots + a_1 x + a_0$$
其中 $an x^n + a{n-1} x^{n−1} + \ldots + a_1 x + a_0$ 为系数,x 是变量。具有非零系数的变量 x 的最高幂称为多项式的 度。
多项式可以被分类为单变量,涉及单个变量(以上面所书写的形式),或多变量,涉及多个变量(例如, $P(x, y) = anx^ny^n + a{n-1}x^{n-1}y^{n-1} + \cdots + a_1xy + a_0$。 Sum-Check 是一个使用多变量多项式的协议示例。然而,大多数情况下,零知识证明仅需要一个变量。
根据其度数,多项式通常有以下命名:
如果我们有两个不同的多项式,最高度数为 ddd,它们最多可以在 ddd个点相交(例如,如果我们将线性函数与三次函数相等,它们可以最多交点三次)。这个性质源于我们如何找到共享点。如果我们想找到两个多项式的交点,我们需要将它们相等。在接下来的子标题中,我们将练习查找多项式的根,即找出给定多项式与 x 轴交点的位置。代数基本定理 说明,度为 ddd的多项式最多可以有 ddd个解,也就是说最多可以有 ddd个交点。
多项式的根或零点是使多项式等于零的 x 值。换句话说,如果 P(x)P(x)P(x) 是多项式,根 rrr是方程 P(r)=0P(r) = 0P(r)=0 的解。要找到根,我们必须了解如何因式分解多项式。因式分解是解决我们将如何乘以得到给定数量。例如,关于 12 的因式分解有几种方式:
$$ 0.5 \times 24 \ 1 \times 12 \ 2 \times 6 \ (-2) \times (-6) \ 3 \times 4 \ 3 \times (-2) \times (-2) \ 2 \times 2 \times 3 $$
一种常见的因式分解方法是将数字完全因式化为正质因数。在因式分解时,最好首先从所有项的最大公因数 (GCF)开始。例如,
$$ 6x + 3 \to 3(2x + 1)$$
在上面的例子中,两个项(6x 和 3)都可被 3 整除,因此它们共享的 GCF 为 3。因此,因子是 3 和 2x+12x + 12x+1。我们反转分配率: $3 \times 2x$ 和 $3 \times 1$。找到根就是在 $P(x) = 0 $ 时求解 x。
对具有两个项的多项式,因式分解是直接的。而且当给定一个图形时,会更加直接,因为根就是多项式与 x 轴交点的位置。然而,添加三个或更多度数可能会使其更为复杂。我建议阅读如何因式分解多项式解释以获得更深入的说明。
深入了解不同多项式的因式分解的确切细微差别并不是阅读本文其余部分的关键。就我们来说,我们对一个多项式等于另一个值的时刻最感兴趣。在这种情况下,我们关注当多项式等于零时。后来,我们会关注一个多项式等于另一个多项式或两个多项式之间的差异为恒等零(即所有系数均为零)的情况,这涉及检查给定多项式是否具有某些根的情况。
Schwartz-Zippel 引理是一种用于检查多项式方程是否总为真的概率工具。它在随机点上评估多项式并检查结果是否为零。
设想涉及变量 $x_1, x_2, \ldots, x_n $ 的复杂方程。如果这个方程是一个多项式,而不仅仅是一些随机项的集合,Schwartz-Zippel 引理可以帮助我们验证它是否对这些变量的所有可能值成立。
其工作原理如下:
该引理声明,P 在这些随机选择的点上为零的概率最多为$ \frac{d}{S} $。这意味着如果多项式不是零,那么它在某种随机机会出现零的概率非常小。这个特性对零知识证明特别有用,我们需要有效地验证多项式恒等式。
拉格朗日插值是一种构造通过给定点集的多项式的方法。拉格朗日多项式是通过每个给定点的最小度数多项式。对于 n 个点,可以创建一个度数为 n-1 的多项式,能够通过所有的点。例如,如果你有平面上的两个点,我们可以定义一条直线穿过这两个点。如果我们在平面上有三个点,我们可以定义一个二次多项式(即 $y = ax^2 + bx + c$),使其通过所有点。这类推。
多项式是一个数学对象,可以包含无限量的信息——想象一下多项式作为一个整数列表,这一点显而易见。因此,一个多项式之间的单一方程可以表示无限数量的数字之间的方程。如果有人可以验证给定的多项式之间的方程,他们隐含地验证了所有可能的方程。同时,这就是我们如何保护非交互式证明,避免依赖于随机抽查给定计算的危险。
多项式还具备多种特性,使它们在创建证明时非常有用:
零知识证明用于证明特定的计算。多项式对这一业务是无价的,因为我们可以按特定特征构造它们。假设你有一个计算或一组数据点你想证实。最简单的方式是将其编码到多项式中,并利用其属性创建证明:
多项式的大小无所谓;由于我们使用多项式承诺,我们可以在短时间内验证多项式之间的方程。这是一种高效、简洁的方法来创建证明。任何错误都会被放大,并且利用如 Fiat-Shamir 启发法等技术,这些证明可以变为非交互式,任何人都可以验证而无需进一步的互动。
为了加深理解,我建议查看以下练习问题:
可汗学院还提供了一套关于多项式表达式、方程和函数的广泛课程。
现在,为了更好地理解多项式承诺,有必要深入探讨零知识证明背后的加密学。
让我们探索对称和非对称加密。
对称加密是一种加密技术,其中相同的密钥用于加密明文和解密密文。这个密钥通常称为秘密密钥或私密密钥,因为使用单个密钥需要确保其保密。然而,这也意味着在两方能够安全通信之前,必须先共享秘密密钥。因此,以安全的方式管理和分发秘密密钥可能具有挑战性,并且如果处理不当可能会泄露。尽管这一缺点,对称加密仍然是快速、高效,并且所需的计算能力和内存低于其他加密方案。
常见的对称加密算法包括:
高级加密标准 (AES) 是一种广泛应用于数据安全的 Rijndael分组密码。它支持 128、192 和 256 位的密钥长度。
ChaCha20 是一种现代、高效的流密码,由 Daniel J. Bernstein 开发。它是 Salsa20 流密码的一个变体,利用加法-旋转-XOR(ARX)操作。它将一个 256 位密钥、一个 64 位随机数和一个 64 位计数器映射到一个 512 位的密钥流,即用户可以在常数时间内高效寻址密钥流中的任意位置。
虽然对称加密是坚固有效的,但它需要一种安全的方法来交换密钥。其中一种方法是 Diffie-Hellman 密钥交换,该方法允许两方在不安全的渠道上安全共享秘密密钥。然而,这一方法是基于非对称加密原则,我们将在下一部分讨论。
非对称加密也称为公钥加密,是一种使用一对相关密钥(即公钥和私钥)来加密和解密信息的方法。公钥公开共享,而私钥保持机密。当发送方想要加密一条消息时,他们使用接收方的公钥。接收到消息后,接收方使用相应的私钥解密消息。使用公钥加密的数据只能用私钥解密。因此,非对称加密允许通过不安全的渠道进行安全通信,因为解密密钥绝不会被共享。
非对称加密的优点在于它提供了较高的安全等级,因为私钥从不被共享。它还简化了密钥分发,因为公钥可以公开共享并支持数字签名。然而,非对称加密的计算强度和速度则低于对称加密。特别是在用户数量庞大且密钥对不直观的情况下,管理密钥对可能变得复杂。
常见的非对称加密算法包括:
数字签名 是公钥密码学的一个关键方面,提供了一种方法来验证消息、软件或数字文档的真实性和完整性。数字签名是使用发送者的私钥创建的,并且可以被任何拥有相应公钥的人验证。这保证了消息是由合法发送者发送的,并且没有被篡改。
用于数字签名的常见算法包括:
离散对数问题 是在方程 gk≡h(modp)g^k \equiv h \pmod{p}gk≡h(modp)中查找指数 k 的任务,其中:
简而言之,如果你知道 g、h 和 p 的值,离散对数问题的目的就是找到 k。例如,给定方程 $2^k \equiv 9 \pmod{23}$,目标是找到 k。
离散对数问题被认为很难有效解决,特别是对于大数字。因此,它构成了诸多密码系统,包括 Solana、ElGamal 加密、数字签名算法(即DSA和ECDSA)及 Diffie-Hellman 密钥交换 的安全基础。
Diffie-Hellman 密钥交换 是一种通过公共通道安全交换密码钥的办法。最简单且最原始的实施(即有限域 Diffie-Hellman)如下:
Alice和Bob现在拥有相同的秘密值。这是因为两次计算的结果相同,皆为相同的秘密 s ,因为:
$$ s \equiv (g^b)^a \pmod{p} \equiv (g^a)^b \pmod{p} \equiv g^{ab} \pmod{p}$$
这个共享的秘密 s 随后可以作为对称加密的密钥使用,使Alice和Bob能够安全通讯。Diffie-Hellman 密钥交换的安全性依赖于离散对数问题的难度。不知道秘密值 a 和 b 的情况下,窃听者计算出共享密钥的可能性极低。这被称为单向函数——相对容易计算但极难反转。
尽管有限域的 Diffie-Hellman 密钥交换安全且广泛使用,但它需要较大的密钥长度来确保安全。例如,如果Alice和Bob都公开选择一个模数为 23,那么破解会容易得多,因为 n mod 23 仅有 23 种可能结果。因此,这可能会造成计算上的负担且不高效。为解决这些挑战,椭圆曲线密码学 (ECC) 提供了一种更有效的替代方案,因为它采用相同的安全级别,但使用显著更小的密钥和更快的计算。
椭圆曲线由方程 $ y^2 = x^3 + ax + b$ 定义,其中 a 和 b 为常数。椭圆曲线密码学就是利用给定椭圆曲线上的点进行计算。这些曲线具有许多独特属性,使其在加密中非常有用。例如:
凭借我们新掌握的群论知识,我们可以说某些椭圆曲线方程将满足群的公理:
我强烈建议阅读椭圆曲线密码学 by Georgie Bumpus以更深入探索这一群体结构。
椭圆曲线提供的安全级别与其他传统密码系统(如 RSA)相同,但密钥大小更小。例如,ECC 中的 256 位密钥相当于 RSA 中的 3072 位密钥。这具有以下优点:
Montgomery 曲线是一种椭圆曲线,其方程为 $By^2 = x^3 + Ax^2 + x$,其中 A 和 B 为常数,且 B 不为零,A 不等于 -2 或 2。这些曲线重要的原因在于,可以更有效地使用 Montgomery 梯形 实现椭圆曲线乘法。
Montgomery 梯形会采取曲线上的点 P 和标量 k,并从无穷大初始化两个点到 P,从最重要位到最不重要位更新标量 k 的每一位。关键想法是保持两个点,并无论 k 的位而以一个常定的操作序列更新它们。
这很重要的原因有几点:
Montgomery 曲线被广泛应用于密码协议中,例如 X25519 密钥交换算法,它使用 Montgomery 形式的曲线 Curve25519。这个算法是现代安全通信的基础,包括在流行协议如 TLS 中的实现。
Edwards 曲线是一种由方程 $x^2 + y^2 = 1 + d x^2 y^2$ 定义的椭圆曲线,其中 d 是一个非零常数不同于 1。
这些曲线的重要性在于:- 点运算的效率 — 在 Edwards 曲线上加法的两个点比其他形式的椭圆曲线更高效。点加法和点倍加的公式更简单,并且涉及的域运算较少,这意味着计算速度更快。
统一加法公式 — Edwards 曲线使用统一的加法公式,这意味着相同的公式可以用于点加法和点倍加。这减少了实现错误的可能性并增强了安全性。
完整性 — 对于某些值的 d,Edwards 曲线是完整的。这意味着加法法则涵盖所有可能的输入,没有任何例外。
对侧信道攻击的抵抗力 — 像 Montgomery 曲线一样,由于其统一和可预测的操作模式,Edwards 曲线对侧信道攻击具有抵抗力。
一个广泛使用的 Edwards 曲线是 Edwards25519,其定义为方程 $x^2 + y^2 = 1 - \frac{121665}{121666} x^2 y^2$。该曲线以其高效的算术运算和 256 位密钥大小而闻名。其签名方案被实现于包括 Solana、OpenSSH 和 Tor 在内的各种安全协议和系统中。Monero 使用 Edwards25519 作为其密钥对生成的基础。
椭圆曲线在零知识证明中至关重要,因为它们的效率和增强安全性的特性。注意:使用椭圆曲线可以创建更小更快的证明,这对任何实际实施至关重要。我们将在讨论与零知识相关的发展时进一步分析这一点,但在拥有多种账户和交易限制的高计算环境中,对小型和快速证明的需求是 关键的。这就是为什么零知识证明在构建汇总时具有吸引力,因为人们可以生成一个简洁的证明,证明在 L2 上的所有操作都是有效的,并在 L1 上进行验证。
在这一天结束时, 将椭圆曲线视为对模运算的替代。使用椭圆曲线后,获取特定点变得更加困难。如果我们使用传统的模运算,如 gamodng^a \bmod ngamodn,其中 g 是生成器,n 是大素数,a 是秘密钥。正如之前对离散对数问题的探讨一样,你需要一个非常大的素数来保护秘密钥。椭圆曲线提供了一种更高效的替代方案,具有更小的密钥大小,提供相同级别的安全性,同时显著提高性能。
如果没有 随机性,这篇文章中的其他内容都不重要,这是加密的一个基本方面。如果其值可预测且有偏,你怎么能期待系统是安全的呢?真正的随机性可能很难实现,但它至关重要,原因如下:
密钥生成— 加密密钥必须随机生成,以确保其不可预测和安全
随机数和盐— 随机数(即只使用一次的数字)和 盐(即添加到数据中的随机值,以便在哈希之前使用)防止 重放攻击 并保护 against 预计算攻击 各自。
安全协议— 随机性用于确保公平性和安全性,防止可预测性和攻击者可能利用的模式。
大多数随机数生成器无法产生可以加密验证的随机数。这使得其实收到操控,并限制了它们的使用场景。然而,可信随机函数解决了这个问题。
可验证随机函数 (VRF) 是一种加密原语,它生成一个随机输出和一个证明,证明该输出是由给定输入正确生成的。VRF 必须是不可预测的,这意味着它的输出对于任何不知道秘密输入的人来说与随机值无法区分。其安全性依赖于 RSA 假设,即计算 $y = h^d \bmod n$ 是困难的而不知秘密指数 d 和哈希函数 H 的安全性。
给定 VRF 的主要步骤如下:
密钥生成— 用户生成一对 RSA 密钥 ( e, n) 作为公钥,( d, n) 作为私钥。公钥 e 是指数,n 是模。私钥 d 是秘密指数。
计算— 给定一个输入 x,用户计算 VRF 输出 y 和证明 π。首先,计算 h = H(x) 的哈希,其中 H 是一个加密哈希函数。然后计算 $ y = h^d \bmod n$,这是哈希的 RSA 签名。最后,计算证明 π = (h, y)。
验证— 给定公钥 ( e, n),输入 x,输出 y 以及证明 π = (h, y),任何人都可以通过检查哈希 h 是否等于 $H(x)$ 和 $y^e \equiv h \pmod{n}$ 来验证 VRF 输出的正确性,以验证 RSA 方程。
VRF 通常用于共识协议,其中随机性需要是不确定但可验证的。各个 L1,包括 Algorand、Cardano、Internet Computer 和 Polkadot,在其共识机制中使用 VRF 来随机选择区块生产者。Chainlink 提供了 Chainlink VRF,作为用户与区块链之间的抽象层,以生成可能公平且可验证的值。Pyth Entropy 还提供了一个可靠和安全的随机性来源。
加密仪式是协议或事件,在安全、受控的环境中进行关键的加密计算。加密仪式有几种类型,即:
密钥生成仪式— 这些涉及到生成加密密钥,以确保没有单一实体控制密钥生成的过程。
参数生成仪式— 这些涉及到创建多个参与方将使用的加密参数。
多方计算(MPC)仪式— 这些涉及多个参与方共同执行加密计算,以确保没有单一方可以破坏过程。
可信设置仪式是专门设计的大型活动或过程,用以生成运行加密协议所需的加密参数。在我们关于交互式和非交互式零知识证明的章节中,我们指出证明的第一步是让证明者和验证者达成一致的某个值。在可信设置仪式中,多个参与者贡献随机性以确保没有单一参与者控制这个过程。每位参与者生成某个随机值,与其他参与者提供的值相结合。组合输出成为一个所有人都可以信任的一组参数。
这个过程至关重要,因为如果所有参与者合谋,他们可以通过为无效声明生成证明来破坏系统。然而,只有签名的参与者保证了参数的安全。
Zcash 著名地使用了一个可信仪式来启动链的隐私特性。以太坊也进行了 KZG 仪式,这是一个协调的公共仪式,为其扩展工作提供加密基础(例如, EIP-4844 / proto-danksharding)。
请注意,一些零知识证明系统,例如 zk-STARKs,并不要求存在可信设置。我们将在第二篇文章中深入探讨这些内容。
通过这篇文章,我们探讨了驱动零知识证明的基础理论、数学和加密技术。这是你开始回答“什么是零知识证明”的问题所需了解的全部内容。现在,我们可以开始将这些学习应用于 Solana 等网络,以促进零知识证明的整体讨论和发展。
我们在有关零知识证明的两部分系列的第二篇和最后一篇文章中继续分析, aptly titled 零知识证明:它在 Solana 上的应用。
如果你读到这里,谢谢你,匿名者!请务必在下面输入你的电子邮件地址,以便你永远不会错过有关 Solana 新动态的更新。准备深入探讨了吗?今天就在 Helius 博客 上探索最新文章,并继续你的 Solana 之旅。
- 原文链接: helius.dev/blog/zero-kno...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!