在传统密码系统中,一把私钥由单个实体保管——无论是用于签名的 ECDSA 私钥,还是用于解密的 RSA 私钥,都集中存储在一台设备或一份文件之中。这种设计简洁高效,却存在一个致命弱点:一旦该设备被入侵、该文件被窃取,整条安全链便彻底断裂。门限密码学(threshold cryptography)正是为消除这一”单点失败”(single point of failure)而生的理论与技术体系。它将一把私钥拆分为若干份额(share),分散交由多个参与方持有;只有当足够数量的参与方协同运作时,才能完成签名或解密操作,而任何少于门限值的子集既无法还原私钥、也无法伪造有效输出。本文将从动机与模型出发,系统讲解分布式密钥生成(distributed key generation, DKG)、门限 Schnorr 签名、门限 ECDSA、门限 BLS 签名、门限解密、主动安全与份额刷新,并结合实际部署案例和未来展望,为读者呈现门限密码学的全景。
一、门限密码学的动机与模型
1.1 消除单点失败
现代数字资产托管场景最能说明问题。一家交易所持有价值数十亿美元的加密货币,其热钱包的签名私钥若被单一管理员掌控,则该管理员的笔记本电脑就是整个系统的”阿喀琉斯之踵”。传统的多签方案(multisignature)——例如比特币的 OP_CHECKMULTISIG——能够要求 m-of-n 个签名才能转账,但它在链上暴露了参与者数量与门限结构,且每条区块链的多签实现各不相同,缺乏通用性。门限签名(threshold signature)提供了一种更优雅的替代:对外界而言,它生成的签名与普通单人签名在格式上完全一致,验证算法不需要任何修改;而签名的生成过程实际上是多个参与方在链下通过交互协议共同完成的。
1.2 (t, n)-门限模型
门限密码学的核心抽象是 (t, n)-门限模型:系统有 n 个参与方(party),其中任意 t 个或更多参与方可以联合执行密码操作(签名、解密等),而任意少于 t 个参与方的联盟无法获得关于私钥的任何有用信息。这里的 t 称为门限值(threshold),通常取 t = n/2 + 1(诚实多数假设)或更一般的值。
更精确地说,(t, n)-门限方案需要满足两个性质:
- 正确性(correctness):任意 t 个诚实参与方协同执行协议后,可以生成合法的签名或解密结果。
- 安全性(security):即使攻击者腐化(corrupt)了至多 t - 1 个参与方,也无法伪造签名或解密密文。在更强的安全模型中,还要求腐化方无法获得关于诚实方份额的任何信息。
1.3 访问结构
(t, n)-门限模型是一般访问结构(access structure)的特例。一般访问结构用一个集合族来描述哪些参与方子集”被授权”。例如,“CEO 单独可以签名,或者 CFO 与 CTO 联合可以签名”就是一种非门限的访问结构。在实践中,门限模型因其简洁性和与 Shamir 秘密共享(Shamir’s Secret Sharing, SSS)的自然结合而最为常用。更复杂的访问结构可以通过将多层门限方案组合来近似实现。
1.4 安全模型与敌手类型
门限协议的安全分析需要指定敌手模型。按行为分类,敌手可以是半诚实的(semi-honest / passive)——遵循协议但试图从观察到的消息中提取额外信息;也可以是恶意的(malicious / active)——可以任意偏离协议。按腐化时机分类,敌手可以是静态的(static)——在协议开始前选定要腐化的参与方;也可以是自适应的(adaptive)——在协议执行过程中根据观察到的信息动态决定腐化对象。最强的模型还考虑移动敌手(mobile adversary),它可以在不同时间段腐化不同的参与方,只要在每个时间段内被腐化的参与方数量不超过门限。主动安全(proactive security)正是应对移动敌手的核心技术,将在第七节详述。
二、分布式密钥生成
门限密码学的第一步,也是最关键的基础设施环节,是分布式密钥生成(distributed key generation, DKG)。DKG 协议使得 n 个参与方能够共同生成一对公钥/私钥,其中私钥以秘密份额的形式分布在各方手中,而从未在任何时刻以完整形式存在于任何单一位置。
2.1 Feldman 可验证秘密共享
Feldman 可验证秘密共享(Feldman’s Verifiable Secret Sharing, Feldman VSS)是理解 DKG 的基础构件。在标准的 Shamir 秘密共享中,分发者(dealer)选择一个 t-1 次多项式 f(x),令 f(0) = s 为秘密,然后向第 i 个参与方发送 f(i) 作为份额。问题在于:参与方无法验证分发者是否诚实地使用了一个合法的多项式。Feldman VSS 通过在群上发布承诺来解决这一问题。
设 g 是一个素数阶 q 的循环群 G 的生成元。分发者选择多项式 f(x) = a_0 + a_1 x + … + a_{t-1} x^{t-1},其中 a_0 = s。分发者公开发布承诺 C_k = g^{a_k} (k = 0, 1, …, t-1)。第 i 个参与方收到份额 s_i = f(i) 后,可以验证:
g^{s_i} = C_0 * C_1^i * C_2{i2} * … * C_{t-1}{i{t-1}}
如果等式成立,说明份额与公开的承诺一致。由于离散对数问题的困难性,承诺不会泄露多项式系数的具体值。
2.2 Pedersen DKG
Pedersen DKG 是最早被提出的完整 DKG 协议之一。其核心思想是让每个参与方都充当一次”分发者”,各自运行 Feldman VSS,然后将所有份额叠加。具体来说:
- 每个参与方 P_i 选择随机多项式 f_i(x),令 f_i(0) = s_i 为自己选择的秘密贡献。
- P_i 向每个 P_j 秘密发送 f_i(j),并公开发布 Feldman 承诺。
- 每个 P_j 验证收到的所有份额,对不一致的份额提出投诉。
- 最终,联合私钥为 s = s_1 + s_2 + … + s_n(模 q),联合公钥为 Y = g^s = g^{s_1} * g^{s_2} * … * g^{s_n}。
- 参与方 P_j 的最终份额为 x_j = f_1(j) + f_2(j) + … + f_n(j)。
由于每个 s_i 都由 P_i 独立选择,只要至少一个参与方诚实,联合私钥 s 就是均匀随机的——没有任何单一参与方能够控制或预测最终的私钥。
2.3 Feldman DKG 与 GJKR 协议
Pedersen DKG 有一个微妙的安全缺陷:恶意参与方可以在看到其他人的承诺后选择自己的贡献,从而对公钥的分布施加偏差。虽然这不影响私钥的保密性,但在某些应用中公钥的均匀随机性是必要的。Gennaro、Jarecki、Krawczyk 和 Rabin 在 1999 年提出的 GJKR 协议通过两层秘密共享——先用 Pedersen 承诺方案(使用两个生成元 g 和 h)进行第一轮分享,再在第二轮揭示实际的 Feldman 承诺——解决了这一问题。GJKR 协议在离散对数设置下被证明是安全的 DKG 方案。
2.4 DKG 的通信复杂度
DKG 协议的通信复杂度是实际部署中的重要考量。在 n 个参与方的 Pedersen DKG 中,每个参与方需要向其他 n-1 个参与方发送份额(点对点通道),并广播 t 个承诺值。总的通信量为 O(n^2) 点对点消息加 O(nt) 广播消息。对于数十个参与方的场景,这完全可以接受;但当 n 增长到数百甚至数千时,就需要考虑基于聚合(aggregation)的优化技术。
一个值得深思的现象是:DKG 恰好处于门限密码学与分布式系统两大研究社区的交叉地带,而这两个社区对「失败」的理解截然不同。密码学研究者关心的是对抗性行为——恶意参与方发送伪造的份额、故意提交错误的承诺——因此 DKG 协议需要可验证性(如 Feldman/Pedersen 的承诺验证)和可追责性(如可识别中止)。分布式系统研究者关心的是崩溃故障——节点宕机、网络分区、消息丢失——因此系统需要容错、重试和状态恢复机制。但现实世界的 DKG 部署必须同时应对两种故障模式。笔者认为,这正是为什么在实验室中运行完美的 DKG 协议、在生产环境中部署它却困难重重的根本原因——不是密码学不够好,而是密码学的安全模型假设了可靠的通信层,分布式系统的容错模型假设了诚实的参与方,而真实世界两种假设都不成立。GJKR 到 FROST 再到 ROAST 的演进,本质上就是在弥合这两种世界观之间的鸿沟。
三、门限 Schnorr 签名
Schnorr 签名方案因其代数结构的线性性质,天然适合门限化。一个标准 Schnorr 签名的生成过程为:选择随机数 k,计算承诺 R = g^k,计算挑战 c = H(R || m),计算响应 z = k + c * s(其中 s 是私钥)。由于 z 是 k 和 s 的线性组合,若每个参与方持有 s 的 Shamir 份额 s_i,并各自贡献随机数 k_i,则可以通过拉格朗日插值在”指数上”重组出合法签名,而无需在任何时刻重建完整的 s 或 k。
3.1 FROST 协议
FROST(Flexible Round-Optimized Schnorr Threshold signatures)是由 Komlo 和 Goldberg 在 2020 年提出的高效门限 Schnorr 签名协议,目前正作为 IETF 草案(draft-irtf-cfrg-frost)推进标准化。FROST 的核心创新在于将签名过程压缩到仅需两轮通信。
预处理阶段:每个参与方 P_i 预先生成若干对随机数承诺 (D_i = g^{d_i}, E_i = g^{e_i}),并将这些承诺公开发布。这一步可以在实际签名请求到来之前离线完成。
签名阶段(两轮):
第一轮:协调者(coordinator)收集签名请求,确定参与方集合 S(|S| >= t),并向各方发送消息 m 以及从预处理池中选取的承诺对标识符。每个参与方 P_i 使用绑定因子 rho_i = H(i, m, B) (其中 B 是所有参与方承诺的列表)来计算有效随机数 k_i = d_i + rho_i * e_i,以及对应的承诺 R_i = D_i * E_i^{rho_i}。群承诺为 R = 各 R_i 之积。
第二轮:每个参与方计算部分签名 z_i = d_i + rho_i * e_i + lambda_i * c * s_i(其中 lambda_i 是拉格朗日系数,c = H(R, Y, m) 是挑战值)。协调者收集所有 z_i,验证每个部分签名的正确性,然后将它们相加得到最终签名 z = sum(z_i)。最终签名 (R, z) 与标准 Schnorr 签名格式完全一致。
3.2 FROST 的安全性与鲁棒性
FROST 在随机预言模型(random oracle model)下被证明对恶意敌手是安全的,假设离散对数问题是困难的。绑定因子 rho_i 的引入是关键:它确保每个参与方的有效随机数与消息 m 和整个参与方集合绑定,防止了所谓的”伪造攻击”(forgery attack),即敌手通过操纵其他参与方的承诺来控制群随机数 R。
关于鲁棒性(robustness),FROST 的基础版本并不具备:如果某个参与方提交了无效的部分签名,协议将失败。但由于协调者可以验证每个部分签名(利用公开的份额验证密钥),它可以识别并排除恶意参与方,然后用剩余的诚实参与方重新执行协议。FROST 的后续变体 FROST2 和 ROAST(Robust Asynchronous Schnorr Threshold signatures)进一步增强了鲁棒性,即使在异步网络环境中也能保证终止(termination)。
3.3 IETF 标准化进展
截至本文写作时,FROST 的 IETF 草案已经定义了多个密码套件(ciphersuite),包括基于 Ed25519、Ed448、Ristretto255 和 P-256 的实例化。标准化的推进意味着门限 Schnorr 签名正在从学术研究走向工业级部署。对于支持 Schnorr 签名的区块链(如比特币的 Taproot 升级所使用的 BIP-340 Schnorr),FROST 提供了理想的门限化方案。
四、门限 ECDSA
与 Schnorr 签名的线性结构不同,ECDSA 签名包含一个关键的非线性步骤:最终签名的 s 分量计算为 s = k^{-1} * (H(m) + r * x),其中 k 是随机数,x 是私钥,r 是随机点 R 的横坐标。k^{-1} 与 x 的乘积意味着,即使各参与方持有 k 和 x 的加法份额,也不能简单地通过本地计算和线性组合来得到 s 的份额——这需要安全的乘法协议。这一结构性差异使得门限 ECDSA 比门限 Schnorr 复杂得多。
4.1 GG18 与 GG20
Gennaro 和 Goldfeder 在 2018 年提出的 GG18 协议是首个实用的门限 ECDSA 方案,随后在 2020 年的 GG20 中进行了优化。GG18 的核心技术是利用 Paillier 同态加密来实现安全的乘法。
简要来说,GG18 的签名过程如下:
- 密钥生成:通过 DKG 生成联合 ECDSA 密钥对,各方持有私钥份额 x_i。
- 随机数生成:各方通过一轮类似 DKG 的协议生成随机数 k 的份额 k_i,以及辅助随机数 gamma_i,使得 k * gamma = sum(k_i) * sum(gamma_i)。
- 乘法到加法转换(Multiplicative-to-Additive, MtA):利用 Paillier 加密的同态性质,两两参与方之间执行 MtA 子协议,将 k_i * gamma_j 的乘法关系转换为加法份额。这一步使得各方能够获得 k * gamma 的加法份额 delta_i。
- 计算 R:各方公开 delta_i 并求和得到 delta = k * gamma,然后计算 R = (sum(g{gamma_i})){delta^{-1}},从中提取 r。
- 部分签名:各方计算部分签名 sigma_i = k_i * H(m) + k_i * r * x_i(通过另一轮 MtA),最终汇总为 s = sum(sigma_i)。
4.2 CGGMP 协议
Canetti、Gennaro、Goldfeder、Makriyannis 和 Peled 在 2020 年提出的 CGGMP 协议对 GG20 进行了重要改进。CGGMP 引入了更强的可识别中止(identifiable abort)性质:如果协议失败,诚实方可以确定哪个参与方行为不当。这对实际部署至关重要,因为在商业环境中,需要能够追究恶意参与方的责任。
CGGMP 还改进了零知识证明的效率,使用了 Schnorr 风格的证明而非更昂贵的范围证明(range proof),从而显著降低了通信和计算开销。
4.3 Paillier 加密在门限 ECDSA 中的角色
Paillier 加密系统是一种加法同态加密方案:给定密文 Enc(a) 和 Enc(b),任何人都可以计算 Enc(a + b),而无需解密。此外,给定 Enc(a) 和明文 b,可以计算 Enc(a * b)。这些性质使 Paillier 成为门限 ECDSA 中 MtA 子协议的理想工具。
具体地,在 MtA 中,P_i 持有 a_i,P_j 持有 b_j。P_i 发送 Enc(a_i) 给 P_j。P_j 计算 Enc(a_i * b_j) = Enc(a_i)^{b_j},然后加上一个随机掩码 beta_j,得到 Enc(a_i * b_j + beta_j),发回给 P_i。P_i 解密得到 alpha_i = a_i * b_j + beta_j。此时 alpha_i + (-beta_j) = a_i * b_j,即两方分别持有乘积的加法份额。
需要注意的是,Paillier 密钥的模数通常为 2048 位,这使得 MtA 中的密文运算成为门限 ECDSA 协议的性能瓶颈。近年的研究致力于用椭圆曲线上的同态承诺(如 CL 加密)替换 Paillier,以提高效率。
五、门限 BLS 签名
BLS(Boneh-Lynn-Shacham)签名方案基于双线性配对(bilinear pairing),其门限化过程比 Schnorr 和 ECDSA 都简单得多——这得益于 BLS 签名的确定性和线性代数结构。
5.1 BLS 签名回顾
在 BLS 方案中,私钥为标量 sk,公钥为 pk = g_2^{sk}(g_2 是 G_2 群的生成元),对消息 m 的签名为 sigma = H(m)^{sk}(H 将消息映射到 G_1 群上的点)。验证通过检查配对等式 e(sigma, g_2) = e(H(m), pk) 来完成。
5.2 门限 BLS 的简洁性
将 BLS 门限化几乎是直接的。通过 DKG,各参与方获得 sk 的 Shamir 份额 sk_i。签名时,第 i 个参与方计算部分签名 sigma_i = H(m)^{sk_i}。协调者收集至少 t 个部分签名后,利用拉格朗日系数在椭圆曲线点上执行插值:sigma = prod(sigma_i^{lambda_i})。由于这一过程完全在群上完成,没有涉及秘密标量的交互或同态加密,因此门限 BLS 签名的通信开销极低——每个参与方只需发送一个群元素(部分签名),且整个过程只需一轮通信。
更进一步,部分签名可以被独立验证:e(sigma_i, g_2) = e(H(m), pk_i)(其中 pk_i = g_2^{sk_i} 是公开的份额验证密钥)。这使得协调者可以在聚合之前过滤掉无效的部分签名,天然具备鲁棒性。
5.3 以太坊验证器中的应用
以太坊信标链(Beacon Chain)的共识机制大量使用 BLS 签名。每个验证器(validator)在每个时隙(slot)发送证明(attestation),这些证明是 BLS 签名。为了降低链上的验证负担,同一委员会(committee)中所有验证器的签名通过 BLS 聚合(aggregation)压缩为一个签名。虽然这里的聚合与门限签名在概念上有所不同(聚合是将多个独立签名合并,门限是从份额重构单个签名),但许多以太坊质押池(staking pool)——如 SSV Network——使用门限 BLS 来让多个运营商共同管理一个验证器密钥,从而避免单点失败。在典型的 3-of-4 或 4-of-7 配置中,即使部分运营商离线,剩余的诚实运营商仍能及时提交证明,避免罚没(slashing)。
至此,三种主要签名方案的门限化方案均已介绍完毕。下表从工程实现的角度对比了它们的关键特性:
| 特性 | Schnorr(FROST) | ECDSA(GG18/GG20/CGGMP) | BLS(原生门限) |
|---|---|---|---|
| 签名轮次 | 2 轮 | 4-8 轮(视协议版本) | 1 轮 |
| 通信复杂度 | O(n) 群元素 | O(n^2)(含 MtA 交互) | O(n) 群元素 |
| DKG 复杂度 | 标准 Pedersen DKG | 标准 DKG + Paillier 密钥 | 标准 Pedersen DKG |
| 确定性签名 | 否(需要分布式随机数) | 否(需要分布式随机数) | 是(H(m)^sk 确定) |
| 签名可聚合 | 否 | 否 | 是(天然支持) |
| 工程成熟度 | 高(IETF 标准化中) | 中高(多个生产实现) | 高(以太坊大规模部署) |
个人观察: 从这张对比表可以清晰地看出,BLS 是最「干净」的门限签名方案——一轮通信、确定性签名、天然可聚合、DKG 直接复用标准构造。这种简洁性不是偶然的,而是源于 BLS 签名的数学结构:签名 sigma = H(m)^sk 本身就是私钥 sk 的线性函数(在指数位置上),因此 Shamir 份额的拉格朗日插值可以直接在椭圆曲线点上完成,不需要任何额外的密码学工具。相比之下,ECDSA 的门限化堪称工程噩梦——签名公式 s = k^{-1}(H(m) + r·sk) 中的 k^{-1} 引入了非线性,迫使协议引入 Paillier 同态加密或 OT 来实现 multiplicative-to-additive(MtA)转换,使得通信复杂度从 O(n) 膨胀到 O(n^2)。GG18 到 GG20 再到 CGGMP 的演进,本质上就是在与这个非线性结构做斗争。讽刺的是,ECDSA 之所以仍然是门限签名领域投入最多工程资源的方向,完全是因为比特币和以太坊的历史选型——如果这两条链当初选择了 Schnorr 或 BLS,门限签名的整个工程版图将会简单得多。
六、门限解密
门限密码学不仅适用于签名,也适用于解密。门限解密方案使得密文只有在至少 t 个参与方协同工作时才能被解密。
6.1 门限 ElGamal
ElGamal 加密方案天然支持门限化。回顾标准 ElGamal:公钥 Y = g^s,加密消息 m 得到密文 (C_1, C_2) = (g^r, m * Y^r)。解密时计算 m = C_2 / C_1^s。
在门限 ElGamal 中,私钥 s 以 Shamir 份额 s_i 分布在各参与方手中。解密时,每个参与方 P_i 计算部分解密 D_i = C_1^{s_i},并公开 D_i。协调者使用拉格朗日插值重组 C_1^s = prod(D_i^{lambda_i}),然后计算 m = C_2 / C_1^s。由于 ElGamal 的解密运算也是线性的(在指数上),门限 ElGamal 的效率与门限 BLS 签名类似。
每个参与方还可以附加一个零知识证明(例如 Chaum-Pedersen 证明),证明 D_i 是正确计算的——即 D_i = C_1^{s_i} 且 pk_i = g^{s_i},两者使用相同的 s_i。这保证了恶意参与方无法通过提交错误的部分解密来破坏协议。
6.2 门限 RSA
RSA 的门限化要复杂得多。RSA 解密涉及模幂运算 m = c^d mod N,其中 d 是私钥,N = p * q。关键困难在于 RSA 的模运算是在 Z_N 上进行的,而 Shamir 秘密共享需要在一个已知阶的域上操作——但 phi(N) = (p-1)(q-1) 本身就是需要保密的信息。Shoup 在 2000 年提出了一种实用的门限 RSA 方案,通过将份额定义在一个特殊结构上并使用 Delta = n! 的技巧来绕过这一难题。各参与方计算部分签名 sigma_i = c^{2 * Delta * d_i},然后通过组合和提取平方根(利用扩展欧几里得算法)得到最终结果。
6.3 应用:电子投票与密封拍卖
门限解密在电子投票(e-voting)中有重要应用。选民使用公钥加密自己的选票,投票结束后,至少 t 个选举委员(election authority)必须联合才能解密计票。这确保了:投票过程中没有任何单一委员能够窥探中间结果,只有在投票截止后所有委员协同操作时才能公开结果。
类似地,在密封拍卖(sealed-bid auction)中,竞拍者的出价用门限加密公钥加密,拍卖结束后由多个公证方联合解密。这不仅防止了提前泄露,还允许在解密前通过同态运算对密文进行处理——例如使用加法同态性来计算总出价,或使用混洗网络(mix-net)打乱密文顺序以保护竞拍者身份。
七、主动安全与份额刷新
7.1 移动敌手与长期安全
在前述的静态安全模型中,我们假设敌手在协议生命周期开始时选定了要腐化的参与方。但在现实世界中,攻击者可能在不同时间段入侵不同的服务器。例如,在一个长期运行的门限签名系统中,攻击者可能在一月份入侵了服务器 A,获取了 A 的份额;然后在三月份入侵了服务器 B,获取了 B 的份额。虽然在任何单一时间点被腐化的服务器数量未超过门限 t,但攻击者最终积累的份额总数却可能超过 t。这就是移动敌手(mobile adversary)模型所捕捉的威胁。
7.2 份额刷新协议
主动安全(proactive security)通过定期执行份额刷新(share refresh)来应对移动敌手。份额刷新协议的目标是:在不改变公钥的前提下,将所有参与方的旧份额替换为新的、与旧份额不相关的份额。
份额刷新的基本思想出人意料地简单:各参与方联合生成一个”零秘密”的秘密共享——即共享一个值为 0 的秘密,使得每方得到一个”刷新增量” delta_i。然后每方将自己的旧份额 x_i 更新为 x_i’ = x_i + delta_i。由于零秘密共享的性质,新份额 x_i’ 仍然是原始秘密 s 的有效 (t, n) Shamir 份额。但是,旧份额 x_i 与新份额 x_i’ 之间不存在可利用的关联——知道旧份额不能帮助推断新份额。因此,只要每个刷新周期(epoch)内被腐化的参与方数量不超过 t-1,系统就是安全的,即使攻击者在整个生命周期中腐化了超过 t 个不同的参与方。
7.3 实现考量
份额刷新在实践中需要注意以下几点:
- 同步性:所有参与方必须在同一个时间窗口内完成刷新,否则持有旧份额和新份额的参与方将无法兼容。
- 旧份额的安全擦除:刷新完成后,旧份额必须被安全删除。如果旧份额泄露,攻击者可以结合旧份额和当前份额来攻击系统。
- 与 DKG 的结合:份额刷新协议本质上是一个简化的 DKG——共享”零秘密”等价于运行一个贡献为零的 DKG。因此,其安全性分析可以复用 DKG 的安全证明框架。
八、实际部署案例
8.1 Fireblocks
Fireblocks 是数字资产托管领域的领先平台,其 MPC 钱包技术核心基于门限 ECDSA(具体采用 GG18/GG20 和 CGGMP 协议)。Fireblocks 的架构将密钥份额分布在客户本地的服务器、Fireblocks 的云基础设施以及可选的第三方灾备节点之间,形成 2-of-3 或更高的门限结构。当需要签署交易时,至少两个份额持有方通过安全通道协同执行门限签名协议,生成一个标准的 ECDSA 签名提交到链上。Fireblocks 还实现了主动份额刷新,以应对长期安全威胁。
8.2 Coinbase
Coinbase 在其机构托管服务中同样采用了门限签名技术。与传统的硬件安全模块(HSM)方案相比,门限签名消除了单一 HSM 被攻破导致全部资产丢失的风险。Coinbase 的方案结合了门限 ECDSA 和策略引擎(policy engine),后者在签名协议开始前验证交易是否符合预设的安全策略(如金额限制、白名单地址等)。
8.3 Lit Protocol
Lit Protocol 是一个去中心化的门限密码学网络,提供门限签名和门限解密作为基础服务。与 Fireblocks 等中心化托管方案不同,Lit 的节点网络由独立的运营商组成,通过质押机制和链上治理来保证行为诚实。用户可以通过链上条件(如持有特定 NFT 或满足某个智能合约逻辑)来控制门限签名和解密的授权——这实现了一种”可编程密码学”(programmable cryptography)。Lit 的底层协议基于门限 BLS 和门限 ECDSA。
8.4 Entropy
Entropy 是一个专注于链上签名服务的去中心化协议。其设计目标是为任何区块链提供门限签名能力,使得用户可以创建由去中心化网络管理的账户,而无需自行保管私钥。Entropy 的架构包含一个验证网络(validation network),节点通过阈值签名协议来批准和执行交易。
笔者认为,加密货币托管领域正在发生的事情具有超越区块链本身的深远意义——它是「高级密码学原语」第一次大规模商业部署的活生生案例。在此之前,门限签名、DKG、份额刷新等概念基本停留在学术论文和小规模实验中。是数十亿美元数字资产的安全需求——而非任何理论上的突破——将这些原语推入了生产环境。而在这个过程中积累的工程经验——如何处理份额刷新期间的网络分区?如何在参与方集合动态变化时执行 resharing?如何在审计合规与密码学隐私之间取得平衡?——正在建立一套实践模式(patterns),这些模式将定义所有未来门限系统的部署方式。从这个角度看,Fireblocks、Coinbase 等公司不仅是门限密码学的用户,更是这个领域事实上的标准制定者。
8.5 Web3Auth
Web3Auth 面向终端用户体验,将门限密码学应用于钱包密钥管理。当用户通过社交登录(如 Google OAuth)创建钱包时,Web3Auth 将用户的私钥拆分为多个份额:一份存储在用户设备上,一份由 Web3Auth 网络的门限节点持有,一份可选地存储在云备份中。日常使用时,用户设备上的份额与门限网络的份额联合生成签名;设备丢失时,可以通过社交恢复和云备份重建份额。
九、门限密码学的未来
9.1 门限全同态加密
全同态加密(FHE)允许在密文上执行任意计算。门限全同态加密(threshold FHE)将 FHE 的解密过程门限化:密文可以由任何人加密和计算,但最终的解密需要至少 t 个参与方的协同。这在多方计算中有巨大价值——各方将输入加密后交给一个不可信的计算服务器,服务器在密文上执行计算,最终结果由各方门限解密。门限 FHE 结合了 FHE 的计算灵活性和门限密码学的信任分散特性。
9.2 后量子门限密码学
随着量子计算的发展,基于离散对数和椭圆曲线的门限方案将面临威胁。研究者正在探索基于格(lattice)的门限签名和门限解密方案。例如,基于 LWE(Learning with Errors)的门限解密相对直接,因为 LWE 解密本身具有线性结构。门限签名则更具挑战性——NIST 后量子标准中的 Dilithium 签名方案的门限化正在积极研究中,但其拒绝采样(rejection sampling)步骤使得门限化变得复杂。
9.3 基于身份的门限密码学
基于身份的加密(Identity-Based Encryption, IBE)允许使用任意字符串(如电子邮件地址)作为公钥。将 IBE 与门限密码学结合,可以构建门限密钥生成中心(threshold KGC)——用户的私钥由多个 KGC 节点联合生成,任何单一节点无法独立生成用户私钥,从而缓解了 IBE 固有的密钥托管(key escrow)问题。
9.4 标准化工作
门限密码学的标准化正在多个组织中推进。IETF 的 FROST 草案前已提及。NIST 也在 2023 年发布了门限密码学的标准化路线图(NIST IR 8214C),涵盖门限签名(EdDSA、ECDSA、RSA)和门限解密。这些标准化努力将为门限密码学的工业级部署铺平道路,使得门限方案从”定制开发”走向”标准组件”。
此外,学术界也在探索更高效的协议——例如将轮次数降至一轮的门限签名(one-round threshold signatures),以及支持动态参与方变更(dynamic committee)的门限方案。后者允许参与方集合随时间演化,而无需完全重新执行 DKG。
Python 代码演示
以下代码基于有限域运算,演示了简化版 Feldman VSS 以及门限 Schnorr 签名的核心流程。为聚焦于协议逻辑,此处在素数阶乘法群上模拟椭圆曲线上的离散对数运算。
"""
简化版 Feldman VSS + 门限 Schnorr 签名演示
仅用于教学目的——生产环境请使用经过审计的密码库
"""
import hashlib
import secrets
from functools import reduce
# ---------- 参数:安全素数群(教学用途) ----------
# p 为安全素数(p = 2q + 1,p 和 q 均为素数)
# g 为 q 阶子群的生成元;实际应用中应使用椭圆曲线群
q = 0xD5F46C882209A7EA620A427397E1EF29F108AD3F5B728F97DCF2E95209DA8983
p = 2 * q + 1
g = 4 # g = 2^2 mod p,是 q 阶子群的生成元
assert pow(g, q, p) == 1 and pow(g, 1, p) != 1
def mod_inv(a: int, m: int) -> int:
"""模逆元(扩展欧几里得)"""
return pow(a, -1, m)
def hash_to_scalar(*args: bytes) -> int:
"""将多个字节串哈希为域元素"""
h = hashlib.sha256()
for a in args:
h.update(a)
return int.from_bytes(h.digest(), "big") % q
# ============================================================
# 第一部分:Feldman VSS
# ============================================================
def feldman_vss_share(secret: int, t: int, n: int):
"""
分发者执行 Feldman VSS
返回: (shares, commitments)
shares[i] = (i+1, f(i+1)),共 n 份
commitments = [g^a_0, g^a_1, ..., g^a_{t-1}] mod p
"""
# 随机多项式 f(x) = a_0 + a_1*x + ... + a_{t-1}*x^{t-1},a_0 = secret
coeffs = [secret] + [secrets.randbelow(q) for _ in range(t - 1)]
# Feldman 承诺
commitments = [pow(g, c, p) for c in coeffs]
# 生成份额
shares = []
for i in range(1, n + 1):
val = sum(c * pow(i, k, q) % q for k, c in enumerate(coeffs)) % q
shares.append((i, val))
return shares, commitments
def feldman_vss_verify(share: tuple, commitments: list) -> bool:
"""验证份额是否与 Feldman 承诺一致"""
i, s_i = share
t = len(commitments)
# 计算 g^{s_i} mod p
lhs = pow(g, s_i, p)
# 计算 prod(C_k^{i^k}) mod p
rhs = 1
for k in range(t):
rhs = rhs * pow(commitments[k], pow(i, k, q), p) % p
return lhs == rhs
# ============================================================
# 第二部分:门限 Schnorr 签名(简化版 FROST 流程)
# ============================================================
def lagrange_coeff(participants: list, i: int) -> int:
"""计算参与方 i 在参与方集合中的拉格朗日系数"""
num, den = 1, 1
for j in participants:
if j != i:
num = num * (0 - j) % q
den = den * (i - j) % q
return num * mod_inv(den, q) % q
def threshold_schnorr_keygen(t: int, n: int):
"""
模拟 DKG:每个参与方贡献一个随机秘密,然后叠加
返回: (public_key, shares, share_verification_keys)
"""
all_shares = [[] for _ in range(n)]
all_commitments = []
for dealer in range(n):
secret_i = secrets.randbelow(q)
shares_i, comms_i = feldman_vss_share(secret_i, t, n)
all_commitments.append(comms_i)
for idx in range(n):
all_shares[idx].append(shares_i[idx])
# 各参与方汇总份额
final_shares = []
for idx in range(n):
party_id = idx + 1
total = sum(s for (_, s) in all_shares[idx]) % q
final_shares.append((party_id, total))
# 联合公钥 = 各分发者首项承诺之积
pk = 1
for comms in all_commitments:
pk = pk * comms[0] % p
# pk = g^{s_1 + s_2 + ... + s_n} = g^s
# 份额验证密钥
svk = [pow(g, s, p) for (_, s) in final_shares]
return pk, final_shares, svk
def threshold_schnorr_sign(message: bytes, t: int,
signers: list, pk: int):
"""
简化门限 Schnorr 签名(两轮)
signers: [(party_id, share)] 列表,长度 >= t
"""
assert len(signers) >= t
participant_ids = [pid for pid, _ in signers]
# 第一轮:各方生成随机数并公开承诺
nonces = {}
commitments_R = {}
for pid, _ in signers:
k_i = secrets.randbelow(q)
R_i = pow(g, k_i, p)
nonces[pid] = k_i
commitments_R[pid] = R_i
# 群承诺 R = prod(R_i)
R = reduce(lambda a, b: a * b % p, commitments_R.values())
# 挑战 c = H(R || pk || m)
c = hash_to_scalar(
R.to_bytes(256, "big"),
pk.to_bytes(256, "big"),
message
)
# 第二轮:各方计算部分签名
partial_sigs = {}
for pid, share in signers:
lam = lagrange_coeff(participant_ids, pid)
z_i = (nonces[pid] + c * lam * share) % q
partial_sigs[pid] = z_i
# 汇总
z = sum(partial_sigs.values()) % q
return R, z
def schnorr_verify(message: bytes, pk: int, sig: tuple) -> bool:
"""验证 Schnorr 签名"""
R, z = sig
c = hash_to_scalar(
R.to_bytes(256, "big"),
pk.to_bytes(256, "big"),
message
)
# 检查 g^z == R * pk^c
lhs = pow(g, z, p)
rhs = R * pow(pk, c, p) % p
return lhs == rhs
# ============================================================
# 演示
# ============================================================
if __name__ == "__main__":
T, N = 3, 5 # 3-of-5 门限
print(f"=== Feldman VSS 演示 ===")
secret = secrets.randbelow(q)
shares, comms = feldman_vss_share(secret, T, N)
for sh in shares:
ok = feldman_vss_verify(sh, comms)
print(f" 份额 #{sh[0]} 验证: {'通过' if ok else '失败'}")
print(f"\n=== 门限 Schnorr 签名演示 ({T}-of-{N}) ===")
pk, all_shares, svk = threshold_schnorr_keygen(T, N)
print(f" 联合公钥: {hex(pk)[:32]}...")
# 任选 t 个参与方签名
selected = all_shares[:T]
msg = "门限密码学示范消息".encode("utf-8")
sig = threshold_schnorr_sign(msg, T, selected, pk)
valid = schnorr_verify(msg, pk, sig)
print(f" 消息: {msg.decode()}")
print(f" 签名验证: {'通过' if valid else '失败'}")
# 换一组参与方
selected2 = all_shares[2:] # 参与方 3,4,5
sig2 = threshold_schnorr_sign(msg, T, selected2, pk)
valid2 = schnorr_verify(msg, pk, sig2)
print(f" 另一组参与方签名验证: {'通过' if valid2 else '失败'}")上面的代码分为两部分。第一部分实现了 Feldman
VSS:feldman_vss_share
函数生成多项式系数、计算份额和承诺;feldman_vss_verify
函数让每个参与方验证其份额是否与公开承诺一致。第二部分实现了简化版的门限
Schnorr 签名:threshold_schnorr_keygen 模拟 DKG
过程,每个参与方分别运行 Feldman VSS
并叠加份额;threshold_schnorr_sign
执行两轮签名协议——第一轮生成随机数承诺,第二轮计算部分签名并汇总;schnorr_verify
使用标准 Schnorr 验证算法检查签名。主程序演示了 3-of-5
门限配置下的完整流程:密钥生成、两组不同参与方分别签名、验证签名均有效。这验证了门限方案的核心性质——任意
t 个参与方的子集都能产生合法签名。
小结
门限密码学从理论到实践已经走过了近四十年的发展历程。从 Desmedt 和 Frankel 在 1989 年首次提出门限签名概念,到如今 FROST 和 CGGMP 等协议在数字资产托管和去中心化基础设施中的大规模部署,门限密码学已经证明了其在消除单点失败、实现分布式信任方面的不可替代性。
核心要点回顾:Shamir 秘密共享与可验证秘密共享(Feldman VSS、Pedersen 承诺)构成了 DKG 和门限方案的基础构件;Schnorr 签名的线性结构使其门限化最为自然,FROST 协议将轮次压缩到两轮并正在走向 IETF 标准;ECDSA 的非线性结构迫使门限化方案引入同态加密(Paillier)或不经意传输,GG18/GG20/CGGMP 逐步解决了效率和可识别中止的问题;BLS 签名的确定性和配对结构使其门限化极其简洁,在以太坊验证器管理中广泛使用;门限解密在电子投票和密封拍卖中有天然应用场景;主动安全与份额刷新是应对长期安全威胁的关键机制。
展望未来,门限全同态加密、后量子门限方案和基于身份的门限密码学将进一步扩展门限密码学的应用边界。随着 NIST 和 IETF 标准化工作的推进,门限密码学有望从专业领域的高级工具演变为通用密码基础设施的标准组成部分。
密码学百科系列 · 第 46 篇
← 上一篇:不经意传输与 PIR | 系列目录 | 下一篇:国密算法体系 →