
系列: Zcash from First Principles . 文章 2 . 椭圆曲线 读者对象: 新手。我们只假设你读过文章 1(有限域):即模一个素数后会“回绕”的算术。不需要其他背景知识。 你将收获: 对椭圆曲线的直观且准确的理解、让它有用的“活板门”,以及 Zcash 究竟如何用它来构造密钥和承诺。
文章 1给了我们一个进行算术运算的完美 playground:有限域。但域本身只有数字。要构造文章 0中的密钥和“密封信封”,Zcash 需要一种具有特殊单向难度的对象:正向计算容易,反向求解几乎不可能。这个对象就是椭圆曲线。本文将从零开始构建它,先讲直觉,再讲代数。
任何隐私系统都需要一条单行道:一种操作,正向走很简单,反向走实际上不可能。
原因如下。你的私钥是一个你必须保密的数字。你的公钥(以及地址)由它推导出来,并对全世界公开。整个系统的安全性都建立在一个事实上:给定公钥,任何人都无法反推出你的私钥。 如果能反推,他们就能花掉你的钱。
所以我们需要一种数学运算,使得:
普通的有限域乘法还不够好;除法会立刻把它还原(这正是文章 1 的重点)。我们需要某种没有简单“撤销”按钮的东西。椭圆曲线恰好提供了这一点,而且额外的好处是,它的点还能以非常适合构造承诺的方式组合起来。下面我们来看看它是怎么做到的。
先暂时忘掉密码学。椭圆曲线就是满足如下形式方程的一组点 (x, y):
y^2 = x^3 + ax + b
在普通实数范围内,它看起来像一条平滑起伏的曲线,通常有一个圆润的环和两条尾部:

真正令人惊讶的部分是:你可以把曲线上的两个点“相加”,得到同一条曲线上的第三个点。 这不是坐标的普通加法,而是一条几何规则,而且比起描述出来,更容易“看出来”。
要计算 P + Q:
P 和 Q 的直线。R*。R* 沿水平轴翻折。 翻折后的点就是答案,也就是 P + Q。
要计算 P + P(写作 2P),因为没有第二个点可供连线,所以改用 P 点处的切线,然后遵循同样的“找第三个交点,再翻折”的步骤。
这就是整个运算。两条几何规则。有了它们,椭圆曲线上的点就构成了数学家所说的一个群:一个带有良好定义“加法”的集合。它甚至还有一个“零”。
任何数系都需要一个 0,也就是加上它后什么都不变的那个对象。在椭圆曲线上,这个角色由一个特殊的额外点扮演,称为无穷远点,记作 O。你可以把它想成“无限远的上方”,也就是竖直线汇聚的地方。把 O 加到任何点上都不会改变那个点,就像给数字加上 0 一样。
上面那条平滑曲线只是直觉图像。但 Zcash 不使用实数(它们会有舍入,还会泄露大小信息,见文章 1)。它使用的是定义在有限域上的椭圆曲线:方程仍然是 y^2 = x^3 + ax + b,但所有运算都在模一个素数的意义下进行。
一旦这样做,那条漂亮的曲线就会碎裂成一堆彼此不连通的散点,每一个满足模 p 方程的 (x, y) 对应一个点。它看起来甚至不再像曲线了。但关键在于:
弦与切线规则的代数版本仍然完全成立。 先前通过几何方式找到
P + Q的同一套公式,现在可以用有限域算术来计算。那些散点依然构成一个群,而且有相同的0(无穷远点)。
下面用一个很小、完全验证过的例子把这件事具体化。
取有限域 F_17 上的曲线 y^2 = x^3 + 2x + 2。把所有合法点都算出来,恰好得到18 个点,再加上无穷远点,总计 = 19 个。 其中一些是:
(0,6) (0,11) (3,1) (3,16) (5,1) (5,16) (6,3) (6,14) (7,6) (7,11) ...
现在选取点 G = (5, 1),不断把它加到自己身上。看看会发生什么(下面每一行都是计算得出的,不是猜的):
| 步骤 | 点 | 步骤 | 点 |
|---|---|---|---|
1G | (5, 1) | 11G | (13, 10) |
2G | (6, 3) | 12G | (0, 11) |
3G | (10, 6) | 13G | (16, 4) |
4G | (3, 1) | 14G | (9, 1) |
5G | (9, 16) | 15G | (3, 16) |
6G | (16, 13) | 16G | (10, 11) |
7G | (0, 6) | 17G | (6, 14) |
这里有两点值得注意:
O 上,之后就会永远重复下去。起始点 G “生成”了整个群,因此我们称它为生成元。1G + 2G = (5,1) + (6,3) = (10,6),这正好就是 3G。加法在内部是一致的,完全符合群的要求。那张 1G, 2G, 3G, ... 的表就是一切的核心。不断把一个点加到自己身上,称为标量乘法:点 kG 的意思是“把 G 自己加给自己 k 次”。
现在,魔法来了。看这两个方向:
| 方向 | 问题 | 难度 |
|---|---|---|
| 正向 | 已知 k 和 G,计算 kG | 容易。 即使 k 大到天文级别,一个叫作 double-and-add 的技巧也只需几百步 |
| 反向 | 已知 G 和 kG,恢复 k | 在真实的密码学曲线上实际上不可能 |
这种不对称性,就是我们在第 1 节需要的单行道。反向问题(“到底是哪个 k 产生了这个点?”)称为椭圆曲线离散对数问题(ECDLP),而在 Zcash 所使用的曲线上,已知的任何方法都不可能在宇宙热寂之前把它解出来。

在我们的玩具
F_17曲线上,你确实可以直接从表里查出k,因为它总共只有 19 个点。真实曲线大约有2^(255)个点。那张表的行数会比宇宙中的原子还多,所以“直接查表”根本不可行。正因为它足够小,玩具曲线才适合教学;也正因为它太小,所以它不安全。
现在我们已经拥有解释真实密码学密钥所需的一切,而且它简单得惊人:
选一个秘密数字
k。公开点kG。就这么简单。k是你的私钥。kG是你的公钥。单行道(ECDLP)保证没有人能把kG反推出k。
这个单一思想——公钥就是某个固定生成元乘上一个秘密标量——正是 Zcash 的花费密钥、Viewing Key 和地址的源头。完整的密钥树在其上又叠加了更多结构,但每一条分支都从这个根长出来。
回想文章 0 中的“密封信封”(承诺),它必须既能隐藏内容,又无法伪造。椭圆曲线给了我们一种干净利落的构造方式。取两个固定、公开的生成元点 G 和 H,一个秘密值 v,以及一个随机盲化数 r,构造:
Commitment = v.G + r.H
这就是一个Pedersen commitment,它同时具备我们想要的两个性质:
r 会把结果涂抹到整条曲线上,因此这个点不会泄露 v 的任何信息。(v, r) 组合变得不可行,因此你无法事后改口,改变你承诺的内容。还有一个额外性质后来会变得极其宝贵:这些承诺可以相加。对 v_1 的承诺加上对 v_2 的承诺,仍然是对 v_1 + v_2 的一个有效承诺。这种“同态”行为使得 Zcash 以后能够证明:一笔交易中流入的钱等于流出的钱,而无需公开任何金额。我们会在大约文章 6 兑现这一点。
它的痕迹是具体且可核查的。
| Zcash 设计 | 使用的曲线 | 角色 |
|---|---|---|
| Sapling(较早) | BLS12-381 加上一条嵌入曲线 Jubjub | BLS12-381 承载证明系统;Jubjub 建立在 BLS12-381 的标量域之上,因此密钥和承诺运算可以在零知识证明内部低成本执行 |
| Orchard(当前) | Pallas 和 Vesta(“Pasta”循环) | Pallas 承载 Orchard 的密钥和承诺;Pallas/Vesta 配对经过特别设计,使高级证明更高效 |
为什么一条曲线会“嵌入”到另一条曲线的域中,以及为什么两条曲线形成一个循环会有用,这些都是真实且重要的问题,但它们属于证明系统相关文章的内容。现在你只需要牢牢记住这一点:每个 Zcash 密钥都是生成元乘以标量,而每个 Zcash 承诺都是曲线点之和,它们都落在这些具名曲线之一上。

为了保证可读性,我们做了一些简化。我们使用了短 Weierstrass 形式(y^2 = x^3 + ax + b);Zcash 使用的曲线通常会写成其他等价形式(Jubjub 是一条 twisted Edwards 曲线),这些形式是出于效率和安全性考虑而选择的,但群的思想完全相同。我们没有给出精确的点加法公式(它们就是“第三个交点,再翻折”的代数版本),也暂时略过了曲线阶、余因子以及 “pairings” 之类的细节,这些会在证明系统相关文章中变得重要。这些都不会改变核心直觉;它们只会让它更精确。
y^2 = x^3 + ax + b 的点集,这些点可以通过几何上的弦与切线规则进行相加,其中特殊的无穷远点充当零元。F_17 上的 y^2 = x^3 + 2x + 2 有 19 个点,而 G = (5,1) 能生成它们全部。)kG 易于计算,却难以逆向:这就是ECDLP。这就是那个活板门。k,公钥 kG。承诺: Pedersen 形式 v.G + r.H,它既隐藏、又绑定,而且还能方便地相加。| 术语 | 通俗含义 |
|---|---|
| Elliptic curve | 满足 y^2 = x^3 + ax + b 的点,并带有一种特殊的点“加法” |
| Point addition | 弦与切线规则:过两点作线,取第三个交点,再翻折 |
Point at infinity (O) | 曲线上的“零”;加上它不会改变任何东西 |
Generator (G) | 一个基点,它的倍点最终会覆盖整个群 |
Scalar multiplication (kG) | 把 G 自己加给自己 k 次;正向容易,逆向困难 |
| ECDLP | 从 kG 恢复 k 的困难问题;安全性的基础 |
| Pedersen commitment | v.G + r.H;一个既隐藏、又绑定、还能相加的密封信封 |
为什么用曲线,而不是只用模一个素数的大数? 两者都可以提供单行道,但椭圆曲线能用更小得多的密钥达到同等安全性,运算也更快,而且它的点运算非常适合做承诺。
ECDLP 被证明很难了吗? 它并没有被证明不可能,但几十年来的大量研究都没有在精心选择的曲线上找到高效攻击。安全性正建立在这个经受充分检验的假设之上。
量子计算机会破解它吗? 足够强大的量子计算机可以破解 ECDLP。这是整个行业已知的长期风险,也是一个活跃研究领域;今天的曲线对经典计算机仍然是安全的。
为什么 Zcash 要使用不止一条曲线? 因为它们承担不同任务。一条曲线承载零知识证明系统;另一条曲线(嵌入在前者的域中)让证明内部的密钥与承诺运算更高效。接下来的文章会解释为什么这种配对很重要。
利用第 3 节中已验证的表,我们这条玩具曲线上的 9G + 10G 是什么?这个答案又说明了 G 的什么性质?(答案见下。)
9 + 10 = 19,而我们已经看到 19G = O,也就是无穷远点。所以 9G + 10G = O。这意味着 10G 是 9G 的负元(加法逆元):两个点相加得到“零”点。在曲线上,一个点的负元就是它关于 x 轴的镜像;确实,9G = (7,6),10G = (7,11) 具有相同的 x,而它们的 y 值之和为 17 = 0 (mod 17)。这个结构完全一致,而这正是“它是一个群”所保证的。
文章 3 . 哈希与承诺: 我们将真正打开这个“神奇的密封信封”。你现在已经见过一种用曲线点构造承诺的方法;接下来我们要问的是,隐藏性和绑定性究竟意味着什么,认识哈希函数,并把这两者与支撑每一笔 Zcash 支付的 note commitments 连接起来。
这是面向 ZecHub 的 Zcash from First Principles 系列的一部分。采用 CC BY-SA 4.0 许可。
8G |
| (13, 7) |
18G |
| (5, 16) |
9G | (7, 6) | 19G | O(无穷远点) |
10G | (7, 11) |