术语表 /闪电网络与 Layer 2
撤销密钥
- 撤销密钥是什么?
- 撤销密钥是一种盲化公钥,用于锁定闪电网络承诺交易中的延迟输出和 HTLC 输出;一旦您披露使该状态作废的秘密值,通道对手方即可动用这些输出。
每笔闪电网络承诺交易都带有一个撤销分支,在任何一方披露某个逐承诺密钥之前,没有人能为该分支签名。BOLT 3将这些密钥从281,474,976,710,655起向下编号,接收方可以把它们全部保存在一个包含49个槽位的数组中。如果发布一个您已经撤销的状态,对方就可以取走整个通道余额,这也是助记词无法备份闪电网络的原因。
运作方式
撤销密钥在设计上刻意做到:通道的任何一方都无法单独算出其私钥的那一半。
当您的节点为对方准备新的承诺时,它取自己的 revocation_basepoint 和对方的 per_commitment_point,将这两者各自乘以两点拼接后的 SHA256(拼接时以该点写在前面),再把结果相加。BOLT 3用一句话说明了这一性质:该构造确保提供基点的节点和提供该点的节点,在没有对方节点密钥的情况下,都无法得知私钥。在另一半到达之前,私钥不存在于任何地方。
这一半是通过一条消息到达的。对方核对完您对其新承诺的签名后,会回复 revoke_and_ack,消息类型为133,其中携带刚刚作废状态的32字节 per_commitment_secret,以及下一个状态的点。从此,您可以算出旧状态的 revocationprivkey,而对方无法收回。
该密钥出现在两类输出中。to_local 输出是一个 P2WSH,其见证脚本依次为 OP_IF、revocationpubkey、OP_ELSE、to_self_delay、OP_CHECKSEQUENCEVERIFY、OP_DROP、local_delayedpubkey、OP_ENDIF、OP_CHECKSIG:所有者必须等待 to_self_delay 个区块,而持有撤销密钥的一方可以立即花费,见证栈为一个签名和一个1。每个 HTLC 输出带有同一个密钥,经 RIPEMD160 对 SHA256 结果的运算后缩短为20字节,并且 BOLT 5要求执行惩罚的节点同样使用该密钥清扫作弊方的 HTLC-success 和 HTLC-timeout 交易。
存储是这一设计巧妙之处。一个通道可以用掉281,474,976,710,655个逐承诺密钥,每个状态一个,全部由一个无法猜测的256位种子通过翻转比特位和哈希生成,索引是递减而非递增。由于索引以若干个零结尾的密钥可以推导出从该索引起直到下一个2的幂边界为止的所有密钥,接收节点只需保存49组值与索引的配对,其余按需重建。BOLT 3还要求接收方在每次收到新密钥时重新推导其较早的密钥作为校验,这样,悄悄更换种子的对方会当场被发现,而不是等到关闭通道时才被发现。
购买比特币时为何重要
撤销密钥是闪电网络余额与交易所发给您的链上比特币表现截然不同的原因。
在本站评测的41款钱包中,让您使用闪电网络的那些钱包处理状态问题的方式明显不同,这种差异也解释了它们的评分。Phoenix 在手机上运行一个真正独立的节点,使用标准的 BIP39 助记词,路径为 BIP84,本站评测明确指出,助记词是链上的后备手段,而不是通道的备份:如果 ACINQ 消失,您需要强制关闭通道,等待约720个区块(约五天),然后用 Electrum 在链上恢复。Muun 完全不使用词表,而是给您一个 Emergency Kit 文件,其中包含两个多重签名密钥和输出描述符,其公开的理由是:助记词备份的是密钥,而其比特币存放在脚本中,钱包还需要被告知这些脚本。Wallet of Satoshi 默认的托管模式通过让您置身事外来消除这一问题:该公司持有所有密钥,因此在本站被列为需谨慎对待,评分为2.7,也因此它得以在2023年11月23日停止向美国客户提供服务,并于2026年之交在整个欧盟停止提供该服务,只给欧盟持有者保留自托管模式。BlueWallet 在链上是自托管的,并因此获得4.2的评分,而其中的闪电网络余额存放在一个 LNDHub 账户中,您的链上助记词并不涵盖该账户。
协议确实为您提供了一道安全网,值得准确了解。如果您带着过期状态重新连接,channel_reestablish 会将其暴露:对方的消息会给出一个比您预期更高的撤销编号,并附回您发送的最后一个逐承诺密钥,以证明该声称属实。BOLT 2随后规定,您不得广播自己的承诺交易,而应发送一条错误消息,请对方使该通道失败。这是诚实的软件所遵循的规则,而不是共识层面的保证,只有在您自己不发布过期状态时,它才保护您。BOLT 5用直白的话写出了对应的义务:节点不得广播一笔其逐承诺密钥已经披露的承诺交易。
实际上,风险只存在于您的接收钱包内部,别处没有。在本站追踪的63家交易所中的任何一家购买比特币并通过闪电网络提币,不会使您面临这一风险,因为交易所的通道是交易所自己的问题。您的风险从比特币到达您应当自行运行节点的地方的那一刻开始。
BOLT 3测试向量,逐个密钥解读
BOLT 3在其附录中给出了一个推导示例,阅读它是了解撤销密钥的两半缺一不可的最快方式。
先从 revocation_basepoint 为036d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2、per_commitment_point 为025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486 开始。把基点放在前面拼接后做哈希,得到 efbf7ba5a074276701798376950a64a90f698997cce0dff4d24a6d2785d20963,把该点放在前面拼接后做哈希,得到 cbcdd70fcfad15ea8e9e5c5a12365cf00912504f08ce01593689dd426bca9ff0。将每个点乘以以它开头的哈希,再把两个结果相加,得到 revocationpubkey 02916e326636d19c33f13e8c0c3a03dd157f332f3e99c317c141dd865eb01f8ff0。
这个公钥不会泄露任何有关私钥的信息。只有当对方披露对应的 per_commitment_secret(1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100)之后,私钥才会出现,此时同样的两个哈希与该密钥以及基点密钥结合,得到 revocationprivkey d09ffff62ddb2297ab000cc85bcb4283fdeb6aa052affbc9dddcf33b61078110。一次通道更新,一次披露,原本只是摆设的公钥就变成了对整个输出的索取权。
撤销密钥 vs 助记词
撤销密钥和助记词都是您的资金所依赖的密钥,但只有其中一个可以写在纸上。
助记词是静态的。十二个或二十四个单词决定了钱包将来推导出的所有密钥,多备份几份更安全,旧的副本与新的副本效力完全相同。撤销密钥则在这三点上完全相反。它们随每次通道更新到达,在 revoke_and_ack 中从另一方传来;真正重要的副本是对方的披露,而您自己的助记词无法重新生成这些副本;通道状态的旧副本不是备份而是隐患,因为依据它采取行动与作弊无法区分。49个槽位的存储方案之所以存在,正是因为这些密钥变化过于频繁,无法写下来。
由此带来的实际后果,就是每个闪电网络钱包都会重复的警告。仅凭单词恢复闪电网络钱包并开始支出,您就重新发布了一个已经撤销的状态,这正是 BOLT 5明令禁止的唯一一件事,也是通道对方的撤销密钥一直在等待的唯一一件事。