概念之外:MuSig2 在 LND 里怎么被调用
MuSig2 聚合签名的密码学原理与它在 PSBT 里的字段接力,中文资料已有专篇;本文只讲一件事——在 LND 里,MuSig2 是以 lnrpc/signrpc/signer.proto(v0.19.0-beta)的一组 gRPC 接口交付的,共六个:MuSig2CreateSession、MuSig2RegisterNonces、MuSig2Sign、MuSig2CombineSig、MuSig2CombineKeys、MuSig2Cleanup。它们没有对应的 lncli 命令,目标用户是自建协作签名流程的开发者与机构钱包后端。

会话是内存里的状态
理解这组接口的关键,是明白签名会话是 LND 存在内存里的状态:会话 ID 是后续登记、签名、合并的门票。这个设计带来一个现实推论——若 nonce 还没收齐而持有会话的一方节点重启,会话作废,各方此前登记的 nonce 全部浪费,MuSig2 的一对 nonce 只属于一次签名。所以接入这套 RPC 的第一军规是:把 nonce 收集与签名收敛在尽可能短的流程里完成,失败就重建会话重来,而不是指望对方修复。MuSig2Cleanup 正是为此存在:明显不会成功的会话提前释放,不留悬账。签名时的清理旗标同理——若本节点不负责合并最终签名,带上旗标等于宣告「我这份已交付,此会话对我可以关门」,节点不必为等待本节点而悬挂资源。
高度实验性的运维清单
给使用这组接口的系统三条建议:部署文档钉死 LND 版本,别让钱包后端顺手升级 signer 接口;每次协议联调保留一份完整流程的记录样本,将来字段变动时有可对账的基线;资金层留出迁移窗口——聚合输出先进小额,等接口从实验走向稳定再放量。不保证向后兼容这句话,翻译成运维动作就是这三件。
会话流程四步走
签名会话是这组接口的核心抽象。MuSig2CreateSession 用本地密钥定位器(key locator,由 key_family 加 key_index 构成)开一个会话,注释要求提供全部签名参与方的公钥列表——包括本节点自己那枚;若其他方的 public nonce 已经知道,可以在建会话时一并带上。MuSig2RegisterNonces 按会话 ID 登记其他参与方的 public nonce,注释明确这个 RPC 可以被多次调用,直到所有 nonce 登记完毕。MuSig2Sign 只有在所有参与方的 public nonce 都已知并登记后才能调用,用建会话时指定的本地密钥产出部分签名;注释特别提到,如果本节点不负责最终合并,就应当在签名时设置清理旗标,表明这个会话对本节点而言已经用完。MuSig2CombineSig 把其他方的部分签名与本地那份(如果已存在)合并,当所有参与方的部分签名都注册齐了,最终签名在此产出。
CombineKeys:不建会话的那一步
六个接口里 MuSig2CombineKeys 是个特例:注释写明它是完全无状态、确定性的辅助接口,不创建任何签名会话,输入所有签名方的公钥列表,算出聚合后的 MuSig2 公钥。它的典型时机在资金进场之前——一旦要决定链上输出该写哪个 Taproot 公钥,用 CombineKeys 先算出来,无需为地址推导开一个会话。
Cleanup 与不保证兼容的声明
MuSig2Cleanup 允许调用方提前释放会话资源,适用于签名会话明显不会成功的情况。真正要写进部署文档的是 proto 注释里反复出现的声明:MuSig2 的 BIP 尚未定稿,这套 API 必须被视为高度实验性,后续版本可能变动,向后兼容性不保证。这意味着给生产系统接 MuSig2 时,要把接口版本锁死、把会话状态当作可丢弃的中间量,并准备好签名流程在升级窗口内回退到旧版单签或多签路径。
另需注意密钥聚合与签名是两条独立流程:MuSig2CombineKeys 是无会话的纯聚合,用来算接收地址;MuSig2CombineSig 才属于一次具体的签名会话。把两者混进同一段封装代码,往往意味着会话生命周期还没理顺。
从运维视角看,聚合公钥与参与方名单要一起存档:MuSig2 的聚合结果依赖密钥排序,人员名单或顺序变化都会得到不同聚合键。只存最终地址不存构成,日后对账无从下手。
多签资金的可用性取决于所有参与方的密钥备份,任何一环丢失都可能让聚合输出无法支出;本文描述接口行为,不构成投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。