协议演进 / BIP/比特币改进提案 / BIP-89

BIP-89 链码委托

在多签钱包里把 BIP32 链码只交给受托方保管,非特权共签人只拿到逐笔的标量微调值来签名,看不到钱包全局的派生、余额与其他消费组合。本 BIP 目前处于已部署状态。

一、档案卡

档案卡
编号BIP-89
标题Chain Code Delegation
作者Jesse Posner <[email protected]>, Jurvis Tan <[email protected]>
指定日期2025-12-03
层级Applications(应用)
类型Specification(规范类)
状态Deployed(已部署)
前置依赖BIP-32, BIP-340, BIP-341
阅读版https://bips.dev/89
官方原文https://github.com/bitcoin/bips/blob/master/bip-0089.mediawiki

二、放在哪一族

多签钱包的隐私与权限控制族。它建立在三份前置规范之上:

BIP-32:链码与扩展密钥——本 BIP 委托的对象正是链码

BIP-340:Schnorr 签名——两种签名模式最终都产出 BIP-340 签名

BIP-341:Taproot——盲签模式的微调序列兼容其 X-only 微调

近邻是 BIP-87(多签层级)与描述符、PSBT 一族:那些方案默认每个共签人都拿到 xpub 或描述符、能自行派生全部地址;BIP-89 恰恰反其道——它要研究的是“怎样让某个共签人派生不出全部地址,仍然能完成共签”。其盲签部分的记法与算法风格借自 BIP-327(MuSig2)与 FROST 签名的相关 BIP 草案。

三、它要解决什么

多签部署的通行做法是共享扩展公钥(xpub)或描述符。这样做的代价是隐私:任何参与方都能扫描整条链,推断出其他参与方的活动——钱包里有多少币、从哪些组合花过钱、与其他哪些对手方往来,全都一览无余。

在协作托管(collaborative custody)场景里,这个代价尤其别扭:钱包主人可能正希望托管方看不到自己的余额。原文给出的解法不是加密或隐藏交易,而是从密钥结构入手做权限切分:

这样非特权方能共签、能核验自己正签的是本钱包的输入、能核验找零与净流出以便执行消费策略,却推导不出钱包的整个地址空间,也识别不了其他路径上的密钥。被委托的是链码,不是签名权——原文特意点明这一术语:交出链码的一方叫 Delegator。

四、规则本身

4.1 密钥材料与设置

4.2 微调的计算:ComputeBIP32Tweak

Delegatee 为某一目标路径计算聚合微调:从自己保管的扩展公钥出发,沿剩余路径逐级做 BIP32 非硬化派生 CKDpub,每级取出其标量分量 δ(即 BIP32 中 parse256(I_L) 一项),逐级累加 t = (t + δ) mod n,最终返回聚合标量 t 与末级公钥 P′。路径为空时 t 为 0、P′ 即原公钥。任何试图使用硬化索引(≥ 2^31)的计算都必须失败。

直觉上,这相当于把“从基础公钥到子公钥的位移”打包成一个数:Delegator 用自己的基础私钥加上 t,就得到该子密钥的私钥,全程不需要链码。

4.3 委托包(Delegation Bundle)

签名时 Delegatee 必须向每个 Delegator 提供一组元组 (P_i, t_i):P_i 是向 Delegator 公示的参与方基础公钥,t_i 是上述算法算出的聚合微调,以 32 字节大端整数编码。对找零输出的微调只在 Delegator 需要计算自己花了多少钱时才必须提供。传输方式不在本 BIP 范围内:可用 PSBT 专有键、RPC 载荷或自定义消息,但 Delegator 必须能验证数据来源的真实性;当期望 Delegator 核验输入或对找零执行策略时,Delegatee 应附上用微调后密钥构建的见证脚本(或足够的脚本模板信息)。待签消息本身不属于 CCD 委托包,它走标准签名协议。

4.4 核验(可选但关键)

非盲模式下 Delegator 可以、也应当在签名前核验:

4.5 签名:两种模式

非盲模式(Non-blinded):Delegator 拿到子公钥的微调与待签消息,像平常一样签名。它只了解到自己经手的具体子密钥与交易,了解不到更广的地址空间。签名算法 DelegatorSign 很直接:x′ = (x + t) mod n,用 x′ 对消息产出签名,交回 Delegatee 放入 PSBT、交易见证或适配器签名流程。

盲模式(Blinded):Delegator 只收到一个被盲化的挑战 e′ 与两个奇偶位(pk_parity、nonce_parity),对消息、挑战原值与所用公钥一无所知。三轮流程为:

  1. Delegator 运行 BlindNonceGen 生成盲随机数,公开部分发给 Delegatee;
  2. Delegatee 运行 BlindChallengeGen,结合消息、盲随机数、基础公钥与一串普通微调及 X-only 微调(兼容 Taproot),算出会话上下文并回送盲挑战与奇偶位;
  3. Delegator 运行 BlindSign 产出盲签名,Delegatee 用 UnblindSignature 还原出一份标准的 BIP-340 签名。

盲模式的安全红线原文写得明确:文中的“plain”盲 Schnorr 流程不具备并发安全性——签名方不得并行或交错运行多个盲签会话;有未完成的盲随机数承诺时,必须拒绝新请求,或先不可恢复地废弃旧承诺。盲随机数 k′ 若在两轮 BlindSign 中重用,将泄露基础私钥;实现应在 BlindSign 读取后把 blindsecnonce 的前 64 字节覆写为零。真正需要并发安全时,要用带加密与零知识证明的变体(可顺带把限额、频率等策略编码进证明),但那不在本 BIP 范围内。

另有一条贯穿全篇的安全要点:单个微调标量 t 的泄漏只危及它派生出的那个子密钥,且它通常在花费前一刻才下发、存活期很短;Delegatee 则必须保证路径全程非硬化且微调算对——算错的微调会让 Delegator 根本签不出名。

原文附有 JSON 测试向量、Python 参考实现与一份 CCD 实际运行的示例代码链接。

五、谁必须动

普通持币人:单签用户无须理会;采用协作托管多签的用户可借此让托管方在不知余额的情况下共签。

钱包开发者(Delegator 侧):保管好非扩展基础密钥;实现微调加私钥的签名流程,认真执行输入与找零核验;盲模式下严格执行“不并发会话、随机数用后即毁”。

钱包开发者(Delegatee / 协调方):保管被委托的链码与 xpub 且不向 Delegator 泄漏;正确实现 ComputeBIP32Tweak 与委托包的组装、找零微调的提供,以及盲模式的挑战生成与去盲还原。

全节点与矿工、共识层:无须改动;链上看到的只是普通的多签花费与 BIP-340 签名,CCD 的分工发生在链下。

六、现在算不算数,以及一个常见误读

状态为 Deployed,表示该规范已被实际部署使用。它是钱包协作层面的约定,不改变任何共识规则,也不要求其他钱包跟进。

常见误读:“链码委托就是把签名权委托出去,Delegator 可以什么都不管、让受托方代签。”

不对。被委托的只是链码(派生能力),私钥始终在 Delegator 自己手里,每一笔仍须 Delegator 本人用“私钥 + 微调”算出签名。受托方只有链码、没有私钥,独自花不了任何一聪;Delegator 若跳过输入与找零核验就盲目签名,才会把这套隐私设计浪费掉。

七、延伸

本页内容整理自 bitcoin/bips 仓库与 bips.dev,事实已与仓库核对;解读仅供学习参考。