type
Post
status
Published
date
Dec 22, 2025
slug
summary
tags
category
icon
password
remark
类别
状态
发布时间
更新时间
DKG(Distributed Key Generation,分布式密钥生成)是一个通用密码学协议,
让 n 个节点在不信任彼此的情况下,共同生成一个共享私钥 x,使得:
- 没有任何一个节点知道完整的 x;
- 但所有节点可以协作使用 x(比如签名);
- 即使部分节点作恶或离线,只要诚实节点 ≥ t,系统仍安全可用。
这解决了 Shamir SSS 的最大痛点:不需要可信第三方分发私钥分片!
🌟 第一步:先问一个问题
怎么让 5 个人共同“拥有”一把私钥,但谁都不知道完整私钥?
- 如果一个人生成私钥再分给大家 → 他一开始就知道全部(不安全)。
- 如果每人随便写一个数字,加起来当私钥 → 没人验证,可能被作弊。
✅ DKG 要解决的就是:
在没人可信的前提下,大家协作生成一个“共享私钥”,且私钥从未完整出现过!
🧩 第二步:用“拼图”比喻理解 DKG
想象你们 5 个人要共同画一幅秘密图案(私钥),规则是:
- 每人画一部分(比如一块拼图)。
- 不能提前看到别人的拼图。
- 最后把所有拼图合起来,才能看到完整图案。
- 但如果有人画假拼图,其他人能发现并踢掉他。
👉 这就是 DKG 的核心思想!
📐 第三步:用初中数学解释原理(关键!)
回顾 Shamir 秘密共享(SSS)
- 有一个中心人,知道密钥 S。
- 他构造多项式:
f(x) = S + a₁x + a₂x²
- 给每人一个点:(1, f(1)), (2, f(2))...
- 凑够 3 个点 → 插值得到 S。
⚠️ 问题:这个中心人一开始就知道 S!
DKG 的改进:没有中心人!
步骤 1:每个人都“贡献”一部分秘密
- 5 个人:Alice、Bob、Carol、Dave、Eve
- 每个人自己偷偷选一个“小秘密”:
- Alice 选
s_A - Bob 选
s_B - ...
- 最终私钥 = s_A + s_B + s_C + s_D + s_E
✅ 这样,没人知道完整私钥,因为每个人只知道自己那一部分!
步骤 2:但怎么保证别人没作弊?
问题来了:
- 如果 Bob 声称他贡献了
s_B = 10,但实际上偷偷改成了20,怎么办?
👉 DKG 的聪明之处:用“承诺 + 验证”防止作弊!
🔐 第四步:DKG 四步走(简化版)
我们以 3/5 门限为例(任意 3 人可签名)。
✅ 第 1 步:每人构造自己的“密钥多项式” (根据门限值t-1项式)
- Alice 构造:
f_A(x) = a₀ + a₁x + a₂x²,其中a₀ = s_A(她的秘密)
- Bob 构造:
f_B(x) = b₀ + b₁x + b₂x²,其中b₀ = s_B
- 其他人类似...
🎯 最终共享多项式是:F(x) = f_A(x) + f_B(x) + f_C(x) + f_D(x) + f_E(x)所以 私钥 = F(0) = s_A + s_B + ... + s_E
✅ 第 2 步:广播“承诺”(防作弊的关键!类似公钥的方式)
为了不让别人撒谎,每个人要公开承诺自己的多项式。
怎么做?用指数承诺(别怕,很简单):
- 在椭圆曲线上,有一个公开基点
G。
- Alice 计算并广播:
C_A0 = a₀·G(这是她密钥的公钥形式)C_A1 = a₁·GC_A2 = a₂·G
💡 这些 C 值就像“指纹”——别人看不到 a₀,但能验证它是否一致。(公钥的生成方式也是这样的),每个节点都会收到Alice的C_A0, C_A1, C_A2的三个(门限的个数t个,本文3/5 门限所以是3个)椭圆曲线的点
✅ 第 3 步:分发“分片”给其他人
- Alice 计算:
- 给 Bob:
f_A(2) - 给 Carol:
f_A(3) - 给 Dave:
f_A(4) - 给 Eve:
f_A(5)
- 通过加密消息发送(比如 TLS)。
其他人也做同样的事。相当于每个节点都把自己的多项式 中的x点发给其他节点
✅ 第 4 步:验证 + 投诉
Bob 收到 Alice 发的
f_A(2) 后,用承诺验证:检查(点加和标量乘法):f_A(2)·G == C_A0 + 2·C_A1 + 4·C_A2
- 左边:
f_A(2)·G(用收到的值计算)
- 右边:用 Alice 广播的承诺计算
✅ 如果相等 → Alice 没作弊
❌ 如果不等 → Bob 举报 Alice,大家剔除她
✅ 第 5 步:计算自己的总份额
如果所有人都诚实,Bob 现在有:
f_A(2)(来自 Alice)
f_B(2)(自己的)
f_C(2)(来自 Carol)
- ...
他把它们加起来:
🎯 所以 Bob 拥有 F(2),而完整私钥是 F(0) —— 但他不知道 F(0)!
同理:
- Alice 拥有
F(1)
- Carol 拥有
F(3)
- ...
🔑 第五步:如何用这个私钥签名?
当需要签名时:
- 任意 3 人(比如 Alice、Bob、Carol)合作。
- 他们各自用
F(1), F(2), F(3)参与 MPC 签名协议(如 GG18)。
- 最终生成一个合法 ECDSA 签名,全程没人知道 F(0)!
✨ 这就是 DKG + MPC 的魔力!
🧪 举个超简单数字例子(非有限域,仅演示逻辑)
假设 2/2 DKG(2人,需2人签名):
- Alice 选
f_A(x) = 3 + 2x
- Bob 选
f_B(x) = 5 + 1x
→ 共享私钥 =
F(0) = 3 + 5 = 8Alice 给 Bob:
f_A(2) = 3 + 4 = 7Bob 给 Alice:
f_B(1) = 5 + 1 = 6验证(略去承诺步骤)后:
- Alice 的份额:
F(1) = f_A(1) + f_B(1) = (3+2) + 6 = 11
- Bob 的份额:
F(2) = 7 + (5+2) = 14
当签名时,他们用 MPC 协议,用 11 和 14 协作生成对私钥 8 的签名 —— 但没人说出 8!
✅ 最后总结(一句话记住)
DKG = 每人贡献一部分秘密 + 用密码学承诺防作弊 + 最终每人拿到一个“分片”,但完整私钥从未存在过!
📌 对比 Shamir SSS vs DKG
特性 | Shamir SSS | DKG |
是否需要可信中心? | ✅ 需要 | ❌ 不需要 |
私钥是否曾完整存在? | ✅ 是 | ❌ 否 |
安全性依赖 | 信任分发者 | 信任多数诚实节点 |
适合场景 | 内部备份 | 去中心化系统(如 MPC 钱包) |
总结就是:
TSS-Manager 是“流程编排 + 消息路由 + 状态机”
MPC Node 是“持密钥 + 做密码学计算”的执行者。
- KeyGen(分布式密钥生成)
- Presign / Nonce(签名前准备)
- Sign(签名)
- Reshare / Refresh(可选,密钥轮换)
summary:
0, 首先TSS-Manager下发 session-ID,参与节点的列表,以及阈值参数(t, n)广播到节点进行签名
StartKeyGen(sessionId, participants, threshold)1,然后每个节点生成t-1项式,然后找出不同的n个(x,y)的点(x非0) (这几个点通常是x为1,2,3~n (0为实际的该节点私钥),这个其实就是相当于多项式中类似代数的点)
2, 节点对曲线的n个点分别 对G做 向量运算(类似拿私钥推算公钥运算), 算出来的这个值用WebSocket的方式传给TssManager进行广播 (这一步被称为广播承诺commitment)
SubmitKeyGenShare(sessionId, Pi, commitment, proof)3, 每个节点生成1个随机数k, 然后k对生成元点G做点乘运算到Ri,发给Tss-manager的到聚合的R (这一步的作用类似ECDSA的 R = k · G / r = x(R) mod n 只不过是分片)
4, TSS-Manager已知聚合R预签名使用签名公式 x(R)mod n 的到签名r,s里面的r
5,TSS-Manager 对 MPC-Nodes的每个节点下发message hash和
6,每个节点用公式 si = k⁻¹_share · (hash + r · di) mod n 独立计算s的分片si,计算之后给到Tss-Manager, TssManager收集大于等于t个s分片,进行聚合对n取模之后,执行low-s的规范输出最终签名(r,s)
- 作者:Oxygen
- 链接:https://blog.yanggc.fun/article/2d15b1a9-f9d4-80ca-9ecf-c905193d0e9d
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
