作者:ahmet-kurt

来源:https://delvingbitcoin.org/t/pqln-post-quantum-security-for-the-bitcoin-lightning-networks-off-chain-surfaces/2893

各位好,这是我在这个论坛的第一个帖子。我是 Ahmet Kurt ,来自 East Texas A&M 大学,正在研究闪电网络和它的多种应用。

我们开发了 PQLN,这是一个闪电网络的一个混合方法的后量子(PQ)插件,在 rust-lightning 中有一个完整的实现。就我们所知,它是第一个有实现、在真实节点上测试过的闪电网络后量子设计。这个主题之前就在论坛出现过,是 roasbeef 在今年 5 月提出的《Post Quantum Lightning: Layer by Layer》(中文译本), 分析了这些层级并估计了对应的 PQ 消息的大小。我的联合作者和我从大约 2025 年 12 月开始开发 PQLN 。做出完整的实现很花时间,而且我们希望做多一些测试、确定这套设计是可靠的。几天前,我们把论文发在了 arXiv ,代码也发在了 GitHub 上。

论文:[[2609.13781] PQLN: Post-Quantum Security for the Bitcoin Lightning Network’s Off-Chain Surfaces](https://arxiv.org/abs/2609.13781)

代码:pq-rust-lightning,在一个 post-quantum cargo 特性上添加了大约 11,000 行代码;而 pq-ldk-sample 是一个 LDK 样品节点,修改成能与我们的复刻一起工作。

范围:注资交易、承诺交易和惩罚交易中的密钥必须在比特币共识变更之后才能迁移成后量子形式,所以我们暂时不管。闪电网络的其余所有部分都是节点之间的消息,而它们都可以用一次软件升级来迁移。也必须这样做,因为比特币的后量子交易输出并不能影响闪电网络自身在区块链以外的界面。而且时间不等人。敌手可以记下今天闪电网络中的流量,等到足够强的量子计算机出现时再解密。所以,在我们的工作中,我们保护了闪电节点所有的链外界面,也即 BOLT 4、7、8、11 和 12 。各界面的细节见下文。

Gossip(BOLT 7):闪电网络没有认证(certificate)基础设施,所以我们通过 gossip 自身来分发后量子公钥。node_announcement 消息携带一个节点的 ML-DSA 公钥和 ML-KEM 公钥,以及一个 ML-DSA 签名;而 channel_update 消息只携带签名。每个节点都记录第一次看到的其它节点的公钥,并在此后,拒绝任何表示替换或弄丢密钥的宣告。我们留下 channel_announcement 消息不改,因为它的四个签名中有两个是根源于比特币协议的。只将其中两个换成后量子的,会让消息有一部分是可以伪造的,不会带来真实的 PQ 收益。

(译者注:“ML-DSA” 是 “基于模块格的数字签名算法”,“ML-KEM” 是 “基于模块格的密钥封装机制”。)

传输(BOLT 8):我们让 Noise_XK 的握手混合了两个 ML-KEM 的封装。一个用在响应者的静态密钥上,用来验证其身份;另一个用在刷新的临时密钥上,以提供前向保密性(forward secrecy)。两个共享秘密值都会跟传统密钥一起折叠进 Noise 的密钥链中。协议内不设任何关于这些密钥的协调机制。混合握手运行在自己的端口上,因为协商消息正是一个量子敌手可以重写、迫使协议降级的地方。

发票(BOLT 11): BOLT11 的问题是体积。一个带标签的字段最多可以使用 639 字节,但一个 ML-DSA-44 签名就是 2420 字节,无论如何不可能放得进去。所以,我们将一个签名分到四个字段中,并且可以选择用三个字段来表示公钥。一个只包含签名的 PQLN 发票就要 4286 格字符,依然可以放进最大规模的字母数字 QR 码中,还剩 10 个字符的空间。切换成 FN-DSA-512 ,事情就简单了,一个签名可以放进两个字段,而整个发票的大小大约是 1500 个字符,很显然在 QR 码的表示范围内。

(译者注:“FN-DSA” 是 “基于 NTRU 格上快速傅里叶变换的电子签名算法”,是 NIST 标注化的后量子签名算法中,同安全等级下签名体积最小的。)

Offer(BOLT 12):Gossip 固定公钥在这里没有太大用处。一个 offer 背后的节点通常是没有公告的,躲在一条盲化路径后面,所以从一开始就无法在 gossip 中看到其公钥。相反,Offer 携带自身的锚点。它承诺一个新的 ML-DSA 公钥(每个 offer 都有一个),然后,当发票返回时,支付者自己要检查公钥一致,然后再发送 HTLC 。

支付洋葱(BOLT 4):我们无法直接在洋葱中放置 ML-KEM ,因为光密文自身就已经快占满整个 1300 字节的空间。所以,支付洋葱保持其格式不变,而每一跳的 Sphinx 秘密值变成混合的。 密文放在节点间 update_add_htlc 消息中紧邻洋葱消息的位置,是一个固定的 20 槽(slot)的列表。诀窍在于,我们会用垃圾来填充没有使用的槽,使它看起来就像真实的密文,从而一个路由节点无法知道真正的数量,也不知道整条路径有多长。

开销:计算开销可以证明不是问题。我们实现的最慢运算是 ML-DSA 签名,是 0.33 毫秒。在一个模拟的互联网上,设定往返延迟为 50 毫秒、带宽为 10 Mbits/s ,支付速度是每一跳会多花 19 毫秒到 53 毫秒之间,而大部分时间是在移动 21.8 kB 的密文列表,而不是花在密码学运算上。

真正的开销是带宽。在真实节点的 regtest 网络上,一个 PQLN 节点下载的 gossip 数据量是普通节点的 10 倍,存储量是 9 倍。放到今天 33000 个节点的网络上,新加入的节点要下载大约 270 MB(而不是 26 MB)。作个对比,roasbeef 的估计是,将每一个 gossip 签名都变成 ML-DSA-44 签名,是一个 29 倍的膨胀。我们之所以只有 10 倍,是因为我们让最大体积的 gossip 消息 —— channel_announcement —— 保持不变。迁移到 FN-DSA-512,膨胀倍数将下降到 4 倍。

互操作性:我们运行了交叉 PQ 节点和普通节点的 12 格场景,从开启通道一直到 BOLT 12 退款和异步支付。简单来说,没有任何一个环节会卡住。当两个节点都使用 PQ 密码学时,支付的整个过程都受到保护。但是,当路径上有个普通节点时,支付会静默降级到传统模式,依然可以完成。如果你打开了 “require-PQ”(必须使用 PQ 密码学)标签,节点将拒绝降级,这样就不会回到传统模式,而是直接在发送 HTLC 之前就失败。最后这一点最重要。一个 PQLN 节点现在就可以加入网络,无需等待其他人先升级。

开放问题:一个开放问题是密钥固定。它采用的是 “第一次见面最可信” 模式,所以它只能保护两个在量子计算机出现之前就彼此知晓的节点。我有一些想法可以弥合这个裂痕而不需要共识变更,两种都写在论文里面但,但我更想先听听其他人会怎么处理这个问题。

TLV(类型-长度-数值 格式)的类型、发票标签和特性比特,都依然要靠 BOLT 来分配。针对其它实现(CLN、LND 和 Eclair)的严格互操作性研究还在待办事项中。

最后一个问题是留给 rust-lightning 库的维护者的。为了让 PQ gossip 分散到整个网络中,普通节点也必须转发这些消息。但现在,这是做不到的,因为 rust-lightning 中的 MAX_EXCESS_BYTES_FOR_RELAY 参数硬编码为 1024 字节,而 PQ 记录比这个数值大得多。所以 PQ gossip 消息只会在 PQ 节点之间传播。只要提高这个限制,普通节点也会转发它。有没有要提高 MAX_EXCESS_BYTES_FOR_RELAY 限制的讨论呢?

感谢各位的阅读,有反馈就更好了!

Ahmet

- - -

roasbeef 评论:

这个主题之前就在论坛出现过,是 roasbeef 在今年 5 月提出的《Post Quantum Lightning: Layer by Layer》(中文译本), 分析了这些层级并估计了对应的 PQ 消息的大小。

很高兴看到有人也在考虑这个问题!

为了实现保守的深度防御,我的看法是,在每一层都使用混合方案,因为传统密码学对象的大小相比 PQ 对象可以忽略不计。

闪电网络没有认证(certificate)基础设施,所以我们通过 gossip 自身来分发后量子公钥。

没错,gossip 层实际上就是我们独有的去中心化证书管理基础设施形式。现有的 gossip 协议是相当脆弱的,因为它并没有为新的通道形式(比如 “Taproot Channels”)设计足够的拓展空间。有一项开展中的工作想要改进这一点,正在修复旧协议的许多问题,同时为新的广告通道的方法铺平道路。

node_announcement 消息携带一个节点的 ML-DSA 公钥和 ML-KEM 公钥,以及一个 ML-DSA 签名;而 channel_update 消息只携带签名。

可以设想一个这样的过渡期:新的改进后的 gossip 消息保留现有的传统签名,而新的 PQ 签名和公钥依赖于现有的消息。那么不理解 PQ 签名的客户端也依然能验证载荷的完整性和真实性。

即使没有传统签名,就像我的帖子说的,也有扩大的带宽开销的问题。当前在 gossip 协议是非常低效的,因为节点之间不会进行主动的库存消息核对。相反,一个节点可能会一再从对等节点处拿到相同的更新和宣告消息。从今天来看,这也是一种浪费,只不过在带宽上特别明显。但是,如果选择了我那篇文章中的参数,简单的推断就表明稳定状态的 gossip 带宽增长接近 19 倍。初始化时候的图下载量也会增加,但因为节点只执行一次,所以也不是什么大问题。

切换成 FN-DSA-512 ,事情就简单了。

如果要这样做,那么未来我们要依赖的活跃密码系统数量将从大约 1 个上升到 4 个(ML-KEM、ML-DSA、FN-DSA-512、SLH-DSA —— 假设基础层会采用它)。如果 FN-DSA-512 是一个严肃的候选,为什么我们不放弃 ML-DSA,直接选择它呢?

同样没有理由绑死在 BOLT-11 以及它的一些设计缺陷上。BOLT12 包含一种当前尚未被利用的序列化格式,要合理得多。新的格式对带标签字段的大小没有限制,等等。

你只提到了签名字段,但公钥呢?据我所知, FN-DSA-512 支持一种公钥复原模式,但这只能节约几百个字节(相比以明文表示公钥)。

Offer(BOLT 12):Gossip 固定公钥在这里没有太大用处。一个 offer 背后的节点通常是没有公告的,躲在一条盲化路径后面,所以从一开始就无法在 gossip 中看到其公钥。

我在自己那篇帖子里没有说,但 BOLT 12 Offer 部分依赖于盲化路径。因此,任何跨层面的 PQ 升级都会影响盲化路径,这不可能避免会需要使用一个更大的 QR 码(因为 ML-KEM 的加入)。

举个例子,如果你希望使用一个仅仅 2 跳的盲化路径(一个入口节点加上收款者),最终的包裹就是大约 4.5 KB(大约 1KB 用于密钥封装,另外 1 KB 用于公钥)。假设采用保守的二维码封装,这已经不再能放进一个 QR 码中。

我们无法直接在洋葱中放置 ML-KEM ,因为光密文自身就已经快占满整个 1300 字节的空间。

当然,不过也没必要卡在旧的包裹格式上。如果旧的节点无法派生出新的混合共享秘密值,就已经有一个后向不兼容的变更。就我所知,这样做也没有节约任何空间。

密文放在节点间 update_add_htlc 消息中紧邻洋葱消息的位置,是一个固定的 20 槽(slot)的列表。

意味着这些信息将在洋葱 之外 ?相关的数据 MAC(消息认证码)检查会扩展到覆盖这些额外的数据吗?还有,为什么不直接扩大包裹的格式,就像我的文章里提到的那篇 KEM Sphinx 论文一样?

注意,KEM Sphinx 抛弃了每一跳的群元素盲化步骤,所以最终的性能可能持平(相比传统的 Sphinx)。

诀窍在于,我们会用垃圾来填充没有使用的槽,使它看起来就像真实的密文,从而一个路由节点无法知道真正的数量,也不知道整条路径有多长。

Sphinx 包裹格式的一个重要属性是,每个包裹都是无法关联的,每一个入站和出站的包裹都应该看起来无关。但是,就我所知,一个 ML-KEM 封装是无法随机化的。此外,如果每一跳都从这个附加包裹的一个固定的槽读取发给自己的密文,那就很容易能够确定自己在整条路径中的位置。

Sphinx 通过在每一跳重新随机化整个混淆网络(mixnet)包裹实现了不可关联性。任何新的格式都应该努力保持相似等级的安全性。

一个 PQLN 节点现在就可以加入网络,无需等待其他人先升级。

并不尽然。因为 LN 是一个 P2P 网络,一个新节点要真正参与整个网络,在不同层面需要不同程度的互操作性。

一个开放问题是密钥固定。它采用的是 “第一次见面最可信” 模式,所以它只能保护两个在量子计算机出现之前就彼此知晓的节点。

目前大致就是这样工作的。你可以通过让节点同时在旧身份和新身份下签名来过渡。

- - -

综上所述,我认为(迁移)最佳的起点是传输层。

如果我们都同意使用混合模式,而不是单独采用 PQ Noise 协议,我们可以直接叠加两种方法,从而在现有的传统通道内升级到 PQ 密码学。另一种办法是找出 以及/或者 挑选一种安全的混合接合器(combiner),转而使用它。

大多数人立即会遇到的障碍可能是获取经过安全验证的 ML-KEY 库。对 LND 来说,幸运的是,从 Go 1.26.1 开始,一个 ML-KEY 包已经是标准库的一部分。

Laolu