硬币混合的信任死角
CoinJoin 把多个人的输入拼进一笔交易,让外人分不清哪个输出归谁,原理可先看CoinJoin是什么?混币的隐私逻辑怎么理解。但对参与签名的硬件钱包来说这里有个死角:交易里既有”你的输入”也有”别人的输入”,而钱包界面必须算出”你这次花了多少”才能显示。如果协调者使坏,把你的真实输入谎标成外部输入、把别人的输出标成你的找零,钱包屏幕显示的金额就是错的——这是能直接导致资金被盗的显示欺骗。规范 Motivation 部分给了一个双签场景的具体攻击:构造两笔输入价值相同、伪装成两轮不同 CoinJoin 的交易,让用户以为自己花的是两份独立资金,实际把同一批币的一半付给了攻击者。 Lightning 网络开双资金通道时面临同样的问题。

一个哈希当门牌号
HD 钱包无法靠遍历派生路径来判断任意 scriptPubKey 的归属——候选路径数量以十亿计,设备算不动。SLIP-0019 的思路是反过来:让钱包预先用一把保密的”身份标识密钥”给每个脚本算一个门牌号。密钥按同一颗助记词能派生加密钥匙吗?SLIP-0021 对称密钥树详解讲的 SLIP-0021 对称密钥派生法从主种子导出,路径写法是 m/”SLIP-0019”/“Ownership identification key”;门牌号则是对该 scriptPubKey 做 HMAC-SHA256 得到的 32 字节。多签脚本 SHOULD 把所有共同所有人的门牌号都收进证明。关键约束是:钱包绝不允许为不属于自己的脚本生成门牌号——那种假门牌号会被用来发动拒绝服务攻击。
证明体、页脚与签名
一份所有权证明等于证明体加证明签名。证明体依次是:4 字节版本魔数(ASCII 的 SL 加 0x00 0x19,即 SLIP-0019 的压缩写法)、1 字节标志位、VarInt 个数的门牌号串。标志位第 0 位记录”这份证明是否经过用户确认生成”,第 1 到 7 位保留且必须为 0——设备遇到不认识的版本魔数或任何保留位被置起的证明必须中止。页脚包含 scriptPubKey 和一段应用自定义的承诺数据,但它不随证明传输:验证者要从上下文自己取得这两项,拼进哈希计算。签名环节要注意一个时间锚点:规范用的是 2020 年 10 月改写之前的 BIP-0322 通用消息签名格式,哈希对象是证明体加页脚的 SHA-256,输出为当时版本定义的 SignatureProof 容器——拿现版 BIP-322 的验签器直接对这类证明会失败。
协调者与承诺数据的防占位设计
所有权证明不只保护用户,也保护协调者:参与者注册输入时附上证明,等于出示”我能且我愿意签这笔输入”,捣乱者被迫用自己有限的 UTXO 作恶,作恶即暴露。但光有证明还不够——攻击者可以把同一份证明注册到另一轮 CoinJoin 里占坑。对策在承诺数据字段:CoinJoin 场景 SHOULD 填入全局唯一的 psbtId。注意它不能从交易数据派生(那是 TXID,而证明需要早于交易存在),所以协调者要么用全局服务器标识拼轮次编号,要么掷一个 256 位随机数。用户在设备上确认这串承诺数据,就等于确认”我参加的是这一轮”,跨轮挪用在验证端会直接对不上。
多签构造流程与设备纪律
多签脚本的证明需要监督钱包(只读观察端)牵头:它预先收集全体共同所有人的门牌号——通常在共建地址时就完成——再把证明体、页脚和派生路径发给每位签名人。每台设备的核对顺序是固定的:解析并验版本魔数与保留位;用页脚里的 scriptPubKey 重新推导门牌号;查这个门牌号是否真在证明体清单里,不在就中止;若确认位为 1 则弹屏让用户核对承诺数据。普通用户在这条链上的纪律只有一条:设备屏幕上出现所有权证明确认弹窗时,把它当作与交易签名同级的安全决策来读——确认位写 1 却从不在设备上复显承诺值的组合,说明协调端配置或版本有猫腻。
适用边界与状态说明
SLIP-0019 的官方状态是 Accepted,属 SatoshiLabs 的 SLIP 体系用词,不等同于比特币 BIP 体系里的 Final;它主要被 Trezor 系固件与相关 CoinJoin 生态实现,其他厂商设备是否支持需以各家文档为准。文档正文中的示例路径表(m/84’/0’/0’/1/0 等)用于展示门牌号计算样本,不是使用建议。最后强调:所有权证明解决的是”输入归属可验证”,不提供任何隐私承诺,也不改变 CoinJoin 参与行为在部分司法辖区面临的合规争议;本文仅作机制说明,不构成任何投资或使用建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。