协议演进 / BIP/比特币改进提案 / BIP-373
BIP-373
为 PSBT 新增 MuSig2 字段,携带参与方公钥、公开随机数与部分签名,让多方能用 PSBT 流程协作完成一次 MuSig2 聚合签名。本 BIP 目前处于已完成状态。
一、档案卡
| 编号 | BIP-373 |
|---|---|
| 标题 | MuSig2 PSBT Fields |
| 作者 | Ava Chow <[email protected]> |
| 指定日期 | 2024-06-04 |
| 层级 | Applications(应用) |
| 类型 | Specification(规范类) |
| 状态 | Complete(已完成) |
| 依赖 | BIP-32、BIP-174、BIP-327、BIP-328、BIP-370 |
| 阅读版 | https://bips.dev/373 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0373.mediawiki |
二、放在哪一族
PSBT 扩展族,专为 MuSig2 多方聚合签名服务,是 BIP-371(PSBT 的 Taproot 字段)的姊妹篇。
上游依赖一串:MuSig2 算法本体在 BIP-327,它产出与 BIP-340 兼容的公钥与签名;从聚合公钥作 BIP32 派生的规则在 BIP-328;PSBT 容器本体是 BIP-174(PSBTv0)与 BIP-370(PSBTv2)。
理解顺序建议是:先懂 MuSig2 为什么需要多轮交互(BIP-327),再看 BIP-373 如何把每一轮要交换的东西装进 PSBT 在各方之间传递。
三、它要解决什么
MuSig2 让多位参与方共同持有一把聚合公钥,最终只产出一个与普通 Schnorr 签名无异的签名。但它的过程比单方签名多出新的概念与额外的通信轮次:
- 各方先要交换公开随机数(public nonce);
- 聚合随机数之后,各方才能各自算出部分签名(partial signature);
- 最后把部分签名聚合,才得到完整的 BIP-340 签名。
现有 PSBT 字段表达不了这套流程:没有地方放“某个聚合公钥由哪几把参与方公钥组成”,没有地方放各方的公开随机数,也没有地方放部分签名。没有标准字段,多方钱包之间就无法用 PSBT 互通地协作完成一次 MuSig2 签名。BIP-373 定义的正是这组字段与配套的角色职责。
四、规则本身
4.1 每输入字段(三个)
PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS(0x1a):键是 33 字节压缩形式的聚合公钥;值是各参与方压缩公钥按聚合所需顺序(若作过排序则按排序后顺序)组成的列表。原文特意说明为何聚合公钥用带奇偶字节的压缩形式而不是 x-only:聚合公钥要能按 BIP-328 作 BIP32 派生,且指纹计算需要完整的 y 坐标信息,x-only 序列化不够用。PSBT_IN_MUSIG2_PUB_NONCE(0x1b):键依次是参与方公钥、聚合公钥,以及可选的 Tapleaf 哈希(聚合公钥就是 Taproot 内部密钥或输出密钥时省略该哈希);值是 66 字节公开随机数,由 BIP-327 的 NonceGen 算法生成。PSBT_IN_MUSIG2_PARTIAL_SIG(0x1c):键的构成与公开随机数字段相同;值是 32 字节部分签名。
另有每输出字段 PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS(0x08),供更新者为输出记录参与方公钥,辅助找零检测。以上字段允许纳入的 PSBT 版本为 0 与 2。
4.2 更新者(Updater)
当更新者发现某个 Taproot 输出涉及自己知道的 MuSig2 聚合公钥时,可添加参与方公钥字段;聚合公钥可能直接出现在脚本、内部密钥或输出密钥中,也可能是脚本中公钥的父公钥。若聚合结果经子公钥派生而来,还应补上 PSBT_IN_TAP_BIP32_DERIVATION(见 BIP-371),并默认按 BIP-328 理解这种派生,除非 PSBT 全局扩展公钥另有说明。
4.3 签名者(Signer)
签名者先判断自己是不是某个聚合公钥的参与方:查参与方公钥字段里有没有自己掌握私钥的公钥,也查 Taproot 派生字段中的公钥与参与方名单的交集。
是参与方且尚无自己的公开随机数时,用 NonceGen 生成并填入。原文特别警告:随机数使用不当会泄露私钥,务必遵循 BIP-327 的随机数生成与使用最佳实践。
待各方公开随机数到齐,每个签名者依次执行 NonceAgg 与 Sign,算出部分签名填入对应字段,并注意施加相关微调(例如以聚合公钥为父公钥作 BIP32 非硬化派生带来的微调)。最后一个签名者在集齐全部部分签名后,可执行 PartialSigAgg,得到完整的 BIP-340 签名,放入 BIP-371 的 PSBT_IN_TAP_KEY_SIG 或 PSBT_IN_TAP_SCRIPT_SIG。
4.4 终结者(Finalizer)
若最后一步聚合尚未完成,终结者可代为执行 PartialSigAgg;聚合完成后,所得签名就是普通的 BIP-340 兼容签名,终结者按常规 Taproot 签名处理即可。
五、谁必须动
普通持币人:无直接动作。使用支持 MuSig2 的多方钱包时,体验上仍是多方依次参与签名,只是底层多走了随机数交换这一轮。
钱包开发者:要实现参与方公钥、公开随机数、部分签名三个字段的读写,并按更新者/签名者/终结者的职责编排多轮传递;随机数处理必须严格照 BIP-327。
硬件钱包与离线签名者:作为参与方时要能生成公开随机数、保存会话状态、再在第二轮产出部分签名,不能再假设“拿到 PSBT 一次签完”。
全节点与矿工:无需动作。链上最终只看到一个普通 Taproot 签名,本 BIP 不改共识规则。
六、现在算不算数,以及一个常见误读
状态为 Complete(已完成):规范本身已经定稿,并附有测试向量。它只是新字段的增加,PSBT 可扩展,旧软件会忽略新字段。原文还专门讨论了一个兼容细节:复用 PSBT_IN_TAP_BIP32_DERIVATION 给参与方公钥提供派生路径,可能让不懂 MuSig2 的软件为该公钥产出签名,但原文论证这在两种情形下都不会造成资金损失。
常见误读:“用了 MuSig2,链上就能看出这是多方签名,或需要节点升级支持。”不对。MuSig2 聚合出的就是一个 BIP-340 兼容签名,链上与单方 Taproot 密钥路径花费无法区分;多方协作的全部复杂度都在链下的 PSBT 传递中,BIP-373 管的正是这一段。
七、延伸
- 阅读版:https://bips.dev/373
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0373.mediawiki
- 相关:BIP-327 MuSig2、BIP-328 聚合公钥派生、BIP-371 PSBT 的 Taproot 字段、BIP-174 PSBTv0、BIP-370 PSBTv2
- 仓库总目录:https://github.com/bitcoin/bips
