Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

导读与学习约定

这本手册要解决什么问题

门限签名常被简单描述为“把私钥切成几片,凑够几片就能签名”。这个说法适合建立第一印象,但不够准确:

  • 参与者持有的是满足代数关系的密钥份额,而不是把私钥字节切开后的碎片;
  • 签名过程通常不会先恢复完整私钥;
  • 签名 nonce 也需要门限化,并且其生命周期往往比长期密钥更容易出错;
  • 协议安全依赖参与者身份、消息认证、可靠广播、状态机和持久化等额外条件;
  • “最终签名可以验证”不代表密钥生成、签名份额或网络流程没有漏洞。

本手册以 Schnorr/FROST 为主线,因为 Schnorr 的线性结构能清晰展示 Shamir 份额如何进入签名方程。门限 ECDSA 被安排在最后,只用于理解复杂度来源,不作为第一个完整实现目标。

适合的读者

你需要具备:

  • 基础 Rust:结构体、枚举、trait、模块、Result、单元测试;
  • 高中代数水平,并愿意重新学习模运算;
  • 能使用 Git 和 Cargo;
  • 接受“先证明和测试,再扩展功能”的节奏。

不要求预先掌握椭圆曲线、零知识证明或多方安全计算。

两种实现层次

本工程始终区分两种代码:

toy:透明、可手算、故意不安全

用于理解有限域、多项式和攻击。可以使用很小的素数、确定性随机数和可打印的秘密。它的价值是教学透明度,绝不能承载真实秘密。

protocol:接近规范、仍非生产级

使用 Ristretto255、SHA-512、系统随机数、规范编码和严格状态机。它应当对照 RFC 9591 测试向量和成熟实现,但仍然只是学习工程。

不要让 toy 类型悄悄进入 protocol;最好使用独立模块和明显的类型名称。

威胁模型从简单到复杂

第一阶段的假设:

  • 所有参与者运行在同一个本地进程中;
  • 参与者名单固定;
  • 有一个可信 Dealer 生成并分发份额;
  • coordinator 可以看到公开消息并阻断协议,但不能伪造已认证参与者;
  • 暂不处理网络丢包、进程崩溃、磁盘泄露和侧信道。

后续逐项移除假设:

  • 用 VSS 检测 Dealer 发放错误份额;
  • 用 DKG 移除知道完整私钥的 Dealer;
  • 用显式状态机处理重复、乱序和跨会话消息;
  • 用持久化的 nonce 消耗记录处理崩溃恢复;
  • 用认证信道和可靠广播明确网络假设。

每次扩展前,都要写下“新增能力”和“仍未解决的问题”。

本手册的符号约定

符号含义
\(q\)素数阶群的阶,也是标量域模数
\(\mathbb{F}_q\)模 \(q\) 的有限域
\(G\)群生成元
\(x\)私钥标量
\(X=xG\)群公钥
\(i\)非零、唯一的参与者标识符
\(s_i\)参与者 \(i\) 的秘密份额
\(Y_i=s_iG\)参与者 \(i\) 的公开验证份额
\(t\)恢复或签名所需的最少参与者数
\(n\)总参与者数,满足 \(1\le t\le n\)
\(H\)带域分离、输出到标量域的哈希函数

标量使用小写字母,群元素使用大写字母。所有除法都表示乘以有限域中的逆元,不是普通浮点除法。

三条贯穿全书的规则

  1. 秘密 nonce 只能使用一次。 “同一消息可以复用”也是错误的。
  2. 密码 transcript 必须规范编码。 不要哈希 Debug、JSON 文本或未规定字段顺序的序列化结果。
  3. 先验证再聚合。 参与者 ID、点、标量、承诺和签名份额都可能来自敌手。

如何使用检查题

不要只在脑中回答。把答案写下来,最好附一段公式、一个反例或一个测试名称。如果不能解释某个结论,先回到推导,而不是继续堆代码。