协议演进 / 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,委托方)只持有一对普通的、非扩展的密钥,连自己的链码都不持有;
- 链码由受托方(Delegatee)保管,签名时它只下发这一笔所需的最小数据——逐输入的标量微调值(scalar tweak)。
这样非特权方能共签、能核验自己正签的是本钱包的输入、能核验找零与净流出以便执行消费策略,却推导不出钱包的整个地址空间,也识别不了其他路径上的密钥。被委托的是链码,不是签名权——原文特意点明这一术语:交出链码的一方叫 Delegator。
四、规则本身
4.1 密钥材料与设置
- Delegator 密钥:每个 Delegator 生成一对普通 secp256k1 密钥,把公钥交给各对手方;Delegator 不得保留、也不得被提供该密钥对应的链码。
- 被委托的链码:指定的 Delegatee 为 Delegator 的公钥计算并保管一个 BIP32 链码,拼成一个 xpub;这个 xpub 不得透露给 Delegator,但 Delegatee 可以与其他 Delegatee 共享。
- 其他参与方:非 Delegator 的参与方照常使用扩展密钥,按钱包描述符共享其公钥部分。
- 派生约束:Delegatee 持有的是 Delegator 的扩展公钥,从它出发的全部派生必须是非硬化派生(索引小于 2^31)——硬化派生需要私钥,而 Delegatee 没有。
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 可以、也应当在签名前核验:
- 输入核验 InputVerification:Delegatee 应公开描述符模板、未微调的参与方密钥、该输入的见证脚本与每位参与方的微调。Delegator 对每把密钥算出微调后密钥 P′_i(有私钥时用 d′=(d+t) mod n 再乘 G,否则用 P + t·G),把模板中的 P_i 全部替换为 P′_i 重新导出见证脚本 W′,与对方给的 W 完全一致才算通过——这证明自己签的确实是本钱包、符合既定策略的输入。
- 找零核验 ChangeOutputVerification:同样的替换与比较,用于确认找零回到符合策略的脚本,并据此算出净流出、执行限额等消费策略。原文在安全部分进一步要求:只要提供了找零的微调数据,Delegator 就必须核验找零输出,以免授权了意料之外的脚本。
4.5 签名:两种模式
非盲模式(Non-blinded):Delegator 拿到子公钥的微调与待签消息,像平常一样签名。它只了解到自己经手的具体子密钥与交易,了解不到更广的地址空间。签名算法 DelegatorSign 很直接:x′ = (x + t) mod n,用 x′ 对消息产出签名,交回 Delegatee 放入 PSBT、交易见证或适配器签名流程。
盲模式(Blinded):Delegator 只收到一个被盲化的挑战 e′ 与两个奇偶位(pk_parity、nonce_parity),对消息、挑战原值与所用公钥一无所知。三轮流程为:
- Delegator 运行 BlindNonceGen 生成盲随机数,公开部分发给 Delegatee;
- Delegatee 运行 BlindChallengeGen,结合消息、盲随机数、基础公钥与一串普通微调及 X-only 微调(兼容 Taproot),算出会话上下文并回送盲挑战与奇偶位;
- 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 若跳过输入与找零核验就盲目签名,才会把这套隐私设计浪费掉。
