术语表 /闪电网络与 Layer 2
盲化路径
- 盲化路径是什么?
- 盲化路径是通往闪电网络节点的一条路由,收款方将每一跳的公钥替换为经过调整的公钥,因此付款方始终无法得知真实的目的地。
接收方构建路径并将其交出,因此付款方只能路由到一个公开的引入点,无法再往前。如果 BOLT 12发票不带盲化路径,则会被拒绝,并且盲化跳点与路由的其余部分共用洋葱包固定的1300字节载荷。如果您公开发布闪电网络收款目的地,盲化可使您的节点 ID 不出现在其中。
运作方式
盲化路径是反向构建的,由希望被支付的节点构建,而不是由付款的节点构建。
接收方从一条通往自己的真实路由和一个随机临时密钥出发,由此派生出一串路径密钥,其排列方式使每个跳点无需被告知即可计算出下一个。每个跳点最终都与接收方共享一个 ECDH 密钥,由这个密钥产生两样东西。第一样是盲化因子,即以共享密钥对字符串 blinded_node_id 计算得到的 HMAC,接收方将其乘入该跳点的公钥。该跳点仍然可以用结果签名,因为它会派生出同一个因子并将其应用到自己的私钥上,但其他任何人都无法将该密钥与已公布的网络图匹配。第二样是加密密钥,用于以 ChaCha20-Poly1305 和全零随机数封存一小段给该跳点的指令数据。
公布的内容很简短:明文的引入点、一个起始路径密钥,然后是一列调整后的密钥,每个密钥配有各自封存的数据。数据中包含该跳点读取的字段:用于说明支付下一步去向的 short_channel_id 或 next_node_id,用于说明其必须应用的手续费和 CLTV 增量的 payment_relay,用于规定最大到期时间和最小 HTLC 大小的 payment_constraints,填充数据,以及最后一个跳点上的 path_id。
其中有三项设计是防御性的,而非功能性的。每个盲化跳点的手续费和时间锁由接收方而不是付款方确定,因此中间节点无法在路由途中提高价格并观察哪些支付失败。接收方将每段数据填充到同一长度,并可以追加之后会丢弃的虚设跳点,因此无法从形态上读出真实长度。path_id 中保存私有数据,例如原像,这样接收方可以确认路径是自己构建的,而不是接受攻击者向其怀疑的每个节点发出的路径。
BOLT 12还增加了最后一层伪装。发票并不为每个盲化跳点列出手续费,而是每条路径恰好带一个 blinded_payinfo:以毫聪计的基础费用、以百万分之一计的比例费率、一个汇总后的 CLTV 增量、最小和最大 HTLC 大小,以及一个功能向量。给出的理由是,逐跳的细节会轻易暴露可用于区分该路径的不一致之处。
购买比特币时为何重要
盲化路径改变的是闪电网络中间部分能了解到的您的信息,对您自己的第一跳所了解的信息没有任何改变。
路由盲化隐藏的是引入点之后的跳点,对您的钱包所连接的节点没有任何作用,而恰恰是该节点能看到您的金额和目的地。Phoenix(本站在41篇钱包评测中给予4.0分)对此异常坦率:ACINQ 自己的常见问题解答称,该钱包相对托管型钱包并无隐私优势,并且 ACINQ 知道支付的最终目的地和金额。您所支付的报价中带有盲化路径,也改变不了这一点。
托管则使这个问题彻底消失。Wallet of Satoshi(本站评分2.7并附有警示)在其托管模式下持有密钥,因此一笔支付的两端都是其自身的记录;它已于2023年11月23日停止为美国客户提供服务,此后又在整个欧盟取消了托管服务。当支付从未离开服务商的账簿时,您的任何信息都不会被盲化。
盲化能为您带来好处的地方是提币本身。Strike 是本站评分最高的以闪电网络为主的平台,评分4.6,转账时不另外收取自己的手续费,并向您提供的闪电网络目的地付款。如果您提供的是 BOLT 11发票,就等于交出了您的节点:签名中带有恢复 ID,因此可以由此恢复出收款方公钥。而报价在该处放置的则是引入点,前提是付款方支持。
代价体现在故障诊断上。盲化路径内部的跳点返回的失败信息不带归因数据,并且引入点被要求在转发错误前增加一段随机延迟,因此探测无法测出收款方有多远。所以,向盲化目的地的提币失败时,几乎无法从中获得任何信息,请先用您自己掌控的钱包测试,再把问题归咎于平台。
Dave 通过 Bob 和 Carol 把路径交给 Alice
闪电网络规范用四个名字演示了盲化路径的思路,这比代数推导更容易理解。
Dave 希望收款,但不想让 Alice 知道收款人是他。他选了一条经由两个公开节点(先 Bob 后 Carol)通往自己的路由,并构建路径密钥链,使三者各自派生出自己的密钥。然后他封存三段数据:一段告诉 Bob 转发给 Carol,一段告诉 Carol 转发给他,另一段留给他自己,内含元数据和 path_id。最后,他派生出将 Bob 变为 Bob prime、Carol 变为 Carol prime、Dave 变为 Dave prime 的因子。
Alice 收到三行内容:第一个节点是 Bob,这是第一个路径密钥,这是 Bob prime、Carol prime、Dave prime 的序列,每个后面附有一段封存的数据。她经由普通的公开网络图到达 Bob,这是有意为之:规范建议通往引入点的一段不做盲化,因为这不需要中间节点提供支持,并且返回的错误是可读的。Bob 解封自己的指令,只知道下一个是 Carol,并将派生出的路径密钥连同洋葱包一起传下去。Carol 使用该密钥两次,一次用于调整洋葱包(Alice 是为 Carol prime 而不是 Carol 加密的),另一次用于解封她自己的指令。Dave 最后收到,并在接受之前检查 path_id。
请数一数每个人最终知道什么。Alice 知道 Bob。Bob 知道自己是引入点,且下一个是 Carol。Carol 知道有一笔盲化支付经过了她,但无法判断 Dave 是收款方还是另一个中继。Dave 知道一切,因为只有他构建了这条路径。
盲化路径 vs 路由提示
盲化路径和路由提示回答的是同一个问题,即如何到达公开网络图看不到的节点,但二者透露的信息量截然相反。
路由提示是 BOLT 11发票中的 r 字段,是明文。每个条目都带有一个264位的公钥、一个64位的短通道 ID、一个基础费用、一个比例费率和一个 CLTV 增量,全部为明文,因此任何持有该发票的人都知道您挂靠在哪个连接良好的节点上。盲化路径只写明引入点,之后便隐去:每个后续跳点都是一个与网络图中任何内容都不匹配的调整后密钥,并且手续费以汇总形式给出,而不是逐项列出。盲化路径还承担了路由提示从未有过的职能,即替代 BOLT 11发票中的 payment_secret 和 payment_metadata 字段。
盲化路径 vs 洋葱路由
洋葱路由向各跳点隐藏付款方;盲化路径向付款方隐藏收款方。
在普通的洋葱路由中,发送方从公开网络图中选出每个跳点,并为每个跳点包裹一层加密,因此任何转发节点都不知道是谁在付款,也不知道自己处于路由的哪个位置。发送方仍然知道整条路由,包括目的地的真实节点 ID,这对向商店付款没有问题,但对发布可重复使用的收款目的地毫无用处。路由盲化在不替换任何东西的情况下补上了缺失的另一半:通过盲化路径的支付仍然是洋葱包,盲化只是叠加在其上的一次密钥调整。二者足够独立,以至于不想要隐私的接收方可以构建一条只包含自己的单跳路径,但仍会交出自己的节点 ID。