区块链的数学基础与密码学原语
区块链的数学基础与密码学原语
在不依赖可信第三方的前提下,如何让一组互不信任的节点对同一份账本达成一致,并保证账本条目不可篡改、可追溯、可验证?这一问题的回答必须首先落到数学与密码学层面。区块链系统中所有的"信任",本质上都是从一组精心设计的密码学原语中"蒸馏"出来的:哈希函数提供了数据完整性的最小证明单位,公钥密码体制提供了身份与签名的代数结构,而承诺方案与零知识证明则在不泄露隐私的前提下扩展了可验证性的边界。本章不讨论任何链上治理或经济激励层面的内容,只回答一个前置问题:区块链赖以构建安全性的密码学原语究竟是什么?它们的形式化定义如何?在主流公链中如何被工程化选型与组合?
1.1 哈希函数的形式化安全模型与算法选型对比
1.1.1 从群论与有限域出发
哈希函数 $H: \{0,1\}^* \to \{0,1\}^n$ 是区块链体系中最基础、调用最频繁的组件。要理解其安全性为何可被形式化定义,需要先理解它所处的数学结构。哈希函数将任意长度的二进制串压缩为固定长度(典型为 256 比特)的"指纹",这一过程既不是随机的,也不是一一对应的,因此必然存在碰撞——只是我们要求"找到碰撞"在计算上不可行。
形式化地,设安全参数为 $\lambda$,哈希函数族 $\mathcal{H}_\lambda$ 中的 $H$ 必须满足三类性质,其难度按从弱到强排列:
- **抗原像性(Pre-image Resistance)**:给定目标值 $y$,任意概率多项式时间(PPT)敌手 $\mathcal{A}$ 找到 $x$ 使 $H(x) = y$ 的概率可忽略,即 $\Pr_{x \leftarrow \mathcal{A}} [H(x) = y] \le \mathsf{negl}(\lambda)$。
- **抗第二原像性(Second Pre-image Resistance)**:给定 $x$,PPT 敌手找到 $x' \neq x$ 使 $H(x') = H(x)$ 的概率可忽略。
- **抗碰撞性(Collision Resistance)**:PPT 敌手找到任意 $(x, x')$ 满足 $x \neq x' \land H(x) = H(x')$ 的概率可忽略。
三者并非等价关系。抗原像性最弱(生日攻击在 $O(2^{n/2})$ 次询问后可找到一个碰撞,但不能立刻求出原像),抗碰撞性最强。值得注意的是,Merkle-Damgård 构造(如 SHA-256)可以证明其抗碰撞性归约到底层压缩函数的抗碰撞性,但无法保证抗原像性——攻击者若拥有"原像预言机"则可轻易扩展到任意长度的原像。这就是著名的"长度扩展攻击"(Length Extension Attack)的根源,意味着在使用 SHA-256 这类构造时,不能简单地 $H(\text{secret} \| m)$ 来构造 MAC,必须改用 HMAC 或 SHA-3 类的海绵构造。
1.1.2 三类主流构造的工程权衡
从工程视角看,主流哈希函数可根据内部结构划分为三个家族,其性能-安全-适用性权衡显著不同。
SHA-256(Secure Hash Algorithm 256) 由 NSA 于 2001 年标准化,采用 Davies-Meyer 迭代式压缩函数 + Merkle-Damgård 强化结构。其内部状态为 256 比特,经 64 轮非线性变换生成摘要。比特币的双 SHA-256 设计(对消息先做一次 SHA-256,再对结果做一次 SHA-256,记为 HASH256)是为了在长度扩展攻击面前提供额外防御,同时利用了 ASIC 流水线并行性——SHA-256 已成为矿机产业的事实标准,矿机算力由此演化为对 SHA-256 的极致优化。
Keccak-256(SHA-3 的原始版本)采用完全不同的海绵(Sponge)构造:1600 比特状态被分为 rate 与 capacity 两部分,经多轮 $\chi$、$\theta$、$\pi$、$\rho$、$\iota$ 置换实现吸收与挤压阶段。海绵构造在理论上免疫长度扩展攻击,且具备可证明的安全性归约。Ethereum 选择 Keccak-256(注意:这是 SHA-3 竞赛获胜方案的原始版本,与 NIST 后续调整了 padding 的 SHA3-256 字节序不同,二者输出哈希值不兼容)而非 SHA-256,核心考量包括:避免与比特币挖矿生态重叠、获得更简洁的 Solidity 合约调用接口(`keccak256` 为内建函数)、以及利用海绵构造的灵活性。
BLAKE3 是 BLAKE2 的继任者,基于 ChaCha 置换与树形(Merkle tree)结构,支持任意大小的并行分片并在叶节点并行哈希。在软件实现中,BLAKE3 在 x86-64 与 ARM NEON 上的吞吐量可达 SHA-256 的 5–10 倍。其树形结构天然支持验证流式更新(incremental verification),这一点对 Layer 2 的状态同步尤为友好——Zcash(早期版本)、Polkadot 的 Runtime 哈希、Solana 的状态哈希均选用 BLAKE 家族。
| 算法 | 内部结构 | 输出长度 | 抗长度扩展 | 软件吞吐(参考量级) | 主流公链应用 | |---|---|---|---|---|---| | SHA-256 | Merkle-Damgård | 256 bit | 否(需 HMAC) | 1× | Bitcoin、BCH | | Keccak-256 | 海绵构造 | 256 bit | 是 | 0.4–0.8× | Ethereum、EVM 系链 | | BLAKE2b | HAIFA 树 | 可变 ≤ 512 bit | 是 | 3–5× | Zcash、Polkadot | | BLAKE3 | 树+并行 | 可变 ≤ 256 bit | 是 | 5–10× | Solana 部分场景 |
选型的核心判断依据并非"谁更新就用谁",而是三层对齐:计算环境的算力结构(CPU/GPU/ASIC 友好性)、抗量子迁移路径(SHA-256 与 Keccak 均非后量子安全,Blake3 同样需要后量子替换)、与既有生态的兼容性(切换哈希函数意味着硬分叉与历史回填,代价极高)。这也是为何 SHA-256 在比特币中始终未被动摇的工程原因。
1.1.3 随机预言机模型与现实差距
形式化安全证明中,哈希函数常被建模为随机预言机(Random Oracle):对任意输入独立、均匀地输出随机值,且同一输入必得同一输出。然而现实中的哈希函数是确定性的公开函数,严格意义上不是随机预言机。Canetti 等人的研究表明,某些协议在随机预言机模型下可证安全,但在标准模型(以具体哈希函数实例替换)下存在具体攻击——即所谓"随机预言模型不可实例化"。
工程实践中,这一理论差距通常以保守设计来弥合:在协议关键路径上,对同一消息使用双独立哈希或域分离(domain separation,即在哈希输入前拼接上下文标签,如 $H(\text{"BitcoinSig"} \| m)$),以降低单一哈希函数被攻破时的爆炸半径。本节关于"哈希函数安全"的论述因此必须加上一条注脚:它只对当前已知的密码分析攻击成立,不构成对未来攻击的绝对防御。这一点对后续讨论可组合性时尤为关键。
1.2 公钥密码体制与椭圆曲线密码学
1.2.1 从整数群到椭圆曲线群
公钥密码体制的本质是构造一个单向陷门函数:正向计算容易,反向求逆在没有陷门信息时计算上不可行。1976 年 Diffie 与 Hellman 提出的 DH 密钥交换建立在离散对数问题(Discrete Logarithm Problem, DLP)的难解性之上:在阶为大素数 $q$ 的循环群 $\mathbb{Z}_q^*$ 中,已知 $g, g^a, g^b$,计算 $g^{ab}$ 在 DLP 假设下是困难的。
椭圆曲线密码学(Elliptic Curve Cryptography, ECC)将上述困难性平移到了椭圆曲线上的有理点群,后者在精心选择的参数下没有已知的亚指数时间算法(而整数群上的 DLP 存在指数/亚指数时间的 index calculus 方法)。其代数定义如下:
设 $\mathbb{F}_p$ 为素数域($p > 3$),曲线 $E/\mathbb{F}_p$ 由 Weierstrass 方程描述:
$$y^2 \equiv x^3 + ax + b \pmod{p}, \quad 4a^3 + 27b^2 \not\equiv 0 \pmod{p}$$
$E(\mathbb{F}_p)$ 上的点(包括无穷远点 $\mathcal{O}$)在"弦切法"定义的加法下构成阿贝尔群。给定基点 $G$ 与标量 $d$,计算 $P = dG$ 通过倍加-加法链(double-and-add)只需 $O(\log d)$ 次点加/点倍,时间复杂度对数级别;但反过来,已知 $P$ 与 $G$ 求 $d$,即椭圆曲线离散对数问题(ECDLP),目前已知最优算法是 Pollard rho,复杂度 $O(\sqrt{n})$(其中 $n$ 为群阶)。换言之,256 比特阶的椭圆曲线群提供约 128 比特的安全强度,与 3072 比特 RSA 等价但参数更小、运算更快。
1.2.2 secp256k1 的选型逻辑
Bitcoin 与 Ethereum(以及绝大多数 EVM 兼容链)选择的曲线是 secp256k1,由 Standards for Efficient Cryptography Group(SECG)在 SEC2 标准中定义,其关键参数为:
- 素数 $p = 2^{256} - 2^{32} - 977$
- 曲线方程 $y^2 \equiv x^3 + 7 \pmod p$($a = 0$,$b = 7$)
- 群阶 $n$ 为接近 $p$ 的大素数,确保无小因子子群
- 基点 $G$ 的阶为 $n$,坐标为确定常数
为何中本聪在十余个标准曲线中独选 secp256k1?这是一段融合了工程效率、密码学保守主义与"无可信第三方"哲学的选型史:
第一,Koblitz 曲线的代数优势。$a = 0$ 的形式使 secp256k1 属于 Koblitz 曲线族,其 Frobenius 自同态可加速标量乘法(在 libsecp256k1 中通过 GLV 端射将单次点乘时间减半)。这对每秒需验证数千笔交易的节点至关重要。
第二,无可信种子。与 NIST P-256 等曲线不同,secp256k1 的参数 $a, b$ 是显式确定的($a = 0, b = 7$),不存在"种子生成器是否包含 NSA 后门"的争议。这是密码学社区对 NIST 曲线长期质疑的背景下,Satoshi 做出的"nothing-up-my-sleeve"选择。
第三,共生态构建。Bitcoin 与 Ethereum 共享同一曲线,使跨链桥、签名验证互操作(如 BTC Relay、EIP-665 等提案)在工程上无需引入额外的曲线适配层。
第四,成熟实现库。libsecp256k1(Bitcoin Core 维护)是经过形式化验证(通过 Project Wycheproof 测试套件)、常数时间实现、广泛审计的工业级库;Ethereum 的 go-ethereum 与 rust-bitcoin 均直接绑定该库。这种"单一可信实现"避免了"各自实现带来的潜在不一致"。
需要注意,secp256k1 也存在局限性:其配对友好性较差(BLS12-381 等配对友好曲线更适合聚合签名),且没有原生抗量子变体。后量子迁移是当前研究热点,例如 NIST 后量子标准中的 ML-DSA(基于模块格)与 SLH-DSA(基于哈希签名)预计将在未来十年内逐步替代 ECDSA。
1.2.3 密钥对的代数结构
私钥是 32 字节(256 比特)的随机整数 $d \in [1, n-1]$,生成方式应为密码学安全伪随机数(CSPRNG),如 `/dev/urandom` 或符合 NIST SP 800-90A 的 DRBG。公钥是点 $P = dG \in E(\mathbb{F}_p)$,通常以压缩形式存储:33 字节,首字节为 $0x02$(若 $P_y$ 为偶数)或 $0x03$(若为奇数),后 32 字节为 $P_x$。解压缩时,通过 $y = \sqrt{x^3 + 7} \bmod p$ 还原 $y$,这一步需常数时间实现以避免侧信道泄露。
```python
基于 coincurve 库(libsecp256k1 的 Python 绑定)的密钥对生成示例
from coincurve import PrivateKey, PublicKey import os
1. 从 CSPRNG 生成 32 字节熵
priv_bytes = os.urandom(32) sk = PrivateKey(priv_bytes)
2. 派生压缩公钥
pk_compressed = sk.public_key.format(compressed=True) # 33 字节 pk_uncompressed = sk.public_key.format(compressed=False) # 65 字节
print(f"私钥(hex): {sk.to_hex()}") print(f"压缩公钥(hex): {pk_compressed.hex()}") ```
1.3 签名方案的演进与工程权衡
1.3.1 ECDSA 及其可塑性缺陷
椭圆曲线数字签名算法(ECDSA)是当前公链生态使用最广泛的签名方案。其签名生成流程如下:对消息 $m$ 先哈希得 $z = H(m)$,选取随机数 $k \in [1, n-1]$,计算 $(r, s)$:
$$R = kG, \quad r = R_x \bmod n, \quad s = k^{-1}(z + r \cdot d_A) \bmod n$$
验证时,计算 $u_1 = z s^{-1}, u_2 = r s^{-1}$,检查 $R' = u_1 G + u_2 P_A$ 是否满足 $R'_x \equiv r \pmod n$。
ECDSA 的安全性在随机预言机模型 + 椭圆曲线离散对数假设下可证明,但其代数结构存在两个工程层面的重大隐患。
可塑性(Malleability)。给定一个合法签名 $(r, s)$,计算 $s' = -s \bmod n$ 即可得到另一个合法签名 $(r, s')$,因为验证方程对 $s$ 与 $-s$ 都成立。在 Bitcoin 早期版本中,这直接导致了 transaction malleability 问题(CVE-2012-2459 涉及 multisig 路径下的可塑性):攻击者可在不修改交易输出的前提下修改签名,使交易 TXID 变化,破坏依赖于 TXID 稳定性的上层协议(如闪电网络的 commitment transaction 链)。Bitcoin SegWit(BIP 141)与 Ethereum 的 EIP-2 均通过将签名从交易可哈希部分中隔离来修复这一问题。Ethereum 的解决方案更激进:在 EIP-2 中规定 $s$ 必须位于下半个区间 $[1, (n-1)/2]$,从而强制唯一性。
Nonce 复用即密钥泄露。若两次签名使用了相同的 $k$,则可由两个签名 $(r, s_1, s_2)$ 解出私钥 $d_A$。历史上 Sony PS3 代码签名密钥泄露(2010 年)正是源于固定的 $k$。这一隐患推动了确定性 nonce 方案 RFC 6979 的广泛采用:用 HMAC-DRBG 以私钥与消息为种子派生 $k$,既消除随机源失败风险,又保证可重现性(对硬件钱包的"无状态"实现尤为关键)。
1.3.2 Schnorr 签名的线性之美
Schnorr 签名方案在结构上与 ECDSA 类似,但通过巧妙构造获得了线性可加性(linearity),这是其聚合能力的基础。Schnorr 签名生成:
$$R = kG, \quad s = k + H(R \| P \| m) \cdot d_A \bmod n$$
验证时检查 $sG = R + H(R \| P \| m) \cdot P_A$。注意签名 $(R, s)$ 是两个群元素的组合,关键性质在于:验证方程是线性的。
线性带来的聚合。对于 $n$ 个签名者各自的 $(R_i, s_i)$ 与公钥 $P_i$,可以将所有 $R_i$ 聚合为 $R_{\text{agg}} = \sum R_i$,所有 $s_i$ 聚合为 $s_{\text{agg}} = \sum s_i$,且验证方程仍然成立——前提是挑战的哈希输入中包含了所有公钥的承诺(否则存在 rogue key 攻击)。这就是 MuSig 协议(Maxwell 等, 2018)的核心思想,Bitcoin Taproot(BIP 341)采用的 MuSig2 进一步支持三轮交互下的安全聚合,使多签交易在链上呈现为单一公钥 + 单一签名,显著降低手续费与隐私泄露面。
Schnorr 与 ECDSA 的工程差异可用以下对比概括:
| 维度 | ECDSA | Schnorr | |---|---|---| | 签名大小 | 64 字节(两个 32 字节整数) | 64 字节(一个点 + 一个标量) | | 验证速度 | 较慢(需两次点乘 + 一次反演) | 较快(一次点乘 + 一次点加) | | 可塑性 | 存在 $(r, -s)$ 形式 | 不存在(签名天然唯一) | | 多签聚合 | 需要复杂脚本(如 P2SH) | 原生支持 MuSig/MuSig2 | | 标准化程度 | 高度成熟 | BIP 340(Bitcoin)、EIP-7602(草案) | | 抗量子 | 不抗 | 不抗 |
1.3.3 BLS 签名与配对的魔法
Boneh-Lynn-Shacham(BLS)签名建立在双线性配对(bilinear pairing)之上,这是与 ECDSA、Schnorr 完全不同的一类代数工具。设 $\mathbb{G}_1, \mathbb{G}_2, \mathbb{G}_T$ 为三个阶为 $n$ 的循环群,配对 $e: \mathbb{G}_1 \times \mathbb{G}_2 \to \mathbb{G}_T$