本周的 Newsletter 跟进了之前关于 JoinMarket 中忠诚债券的描述,并包含了我们常规的部分,包括 Bitcoin Core PR 审查俱乐部会议的总结、关于为 Taproot 做准备的建议、发布与候选发布的公告,以及对流行基础设施项目的值得注意的更改描述。

新闻

  • 忠诚债券的实现: JoinMarket 0.9.0 实现了 coinjoin 支持忠诚债券。正如在 Newsletter #57 中所描述的,忠诚债券提高了 JoinMarket 系统的 Sybil 抵抗力,增强了 coinjoin 发起者(“takers”)选择独特流动性提供者(“makers”)的能力。发布几天后,超过 50 BTC(目前价值超过 200 万美元)已被投入到时锁定的忠诚债券中。

    尽管具体的实现是 JoinMarket 特有的,但整体设计可能对其他基于比特币构建的去中心化协议有一定的借鉴意义。

Bitcoin Core PR 审查俱乐部

在本月的这一部分,我们总结了最近一次 Bitcoin Core PR 审查俱乐部会议,重点介绍了一些重要的问题和答案。点击下面的问题查看会议中的答案总结。

Prefer to use txindex if available for GetTransaction 是 Jameson Lopp 提出的一个 PR,该 PR 通过在可能的情况下利用交易索引(txindex)来提升 GetTransaction(以及扩展的 getrawtransaction RPC)的性能。这个更改解决了一个意外的性能损失问题,即当在启用 txindex 的节点上通过区块哈希调用 getrawtransaction 时,速度显著变慢。审查俱乐部通过比较使用和不使用 txindex 获取交易的步骤来评估该性能问题的原因。

  • GetTransaction 获取交易的不同方式有哪些?

    交易可以从内存池中获取(如果未确认),通过从磁盘中获取整个区块并搜索交易,或者使用 txindex 从磁盘中单独获取交易。 

  • 为什么当提供区块哈希(启用 txindex 时)性能较差?

    参与者猜测瓶颈可能在于区块的反序列化。获取整个区块时的另一个过程 - 尽管消耗时间较少 - 是对整个交易列表进行线性搜索。 

  • 如果我们通过区块哈希查找交易,步骤是什么?需要反序列化多少数据?

    我们首先使用区块索引查找访问区块所需的文件和字节偏移量。然后获取并反序列化整个区块,扫描交易列表直到找到匹配项。这涉及反序列化大约 1-2MB 的数据。 

  • 如果我们使用 txindex 查找交易,步骤是什么?需要反序列化多少数据?

    txindex 将交易 ID 映射到文件、区块位置(类似于区块索引)以及交易在 blk*.dat 文件中的偏移位置。我们获取并反序列化区块头和交易。区块头为 80B,允许我们返回区块哈希给用户(这是 txindex 中没有存储的信息)。交易大小可以是任意的,但通常比区块小几千倍。 

  • 此 PR 的第一个版本包含了一个行为更改:当向 GetTransaction 提供错误的 block_index 时,仍然使用 txindex 查找并返回交易。你认为这个更改是改进吗?它应该包含在这个 PR 中吗?

    参与者一致认为这可能有帮助,但可能会误导用户,通知用户错误的区块哈希输入会更好。他们还指出,性能改进和行为更改应该分开在不同的 PR 中进行。 

准备 Taproot #8:多签随机数

这是一个关于开发者和服务提供者如何为即将激活的 Taproot 做准备的每周系列

在上周的专栏中,我们讨论了多签并通过 MuSig2 举例进行说明。我们所做的描述在技术上是正确的,但有几位参与 MuSig2 的密码学家担心我们建议的使用方法是危险的。我们更新了我们的描述,以解决他们的直接担忧,并开始更深入地研究这一问题。在本文中,我们将探讨我们所学到的,可能是安全实施多重签名的最大挑战:避免重用 nonce。

为了验证比特币中的签名,您需要通过签名、签名的消息(例如交易)、您的公钥和公有 nonce 来填充一个公开已知的方程式。只有在您知道私钥和私有nonce的情况下,才能平衡这个方程式。因此,任何看到该方程式的人都可以认为这个消息和公钥的签名是有效的。

将签名和消息包括在方程式中的动机是显而易见的。公钥是私钥的代替,那么公有 nonce 的作用是什么呢?如果它不存在,方程式中除了您的私钥以外的所有值都是已知的,这意味着我们可以使用基础代数来求解唯一的未知值。但代数无法求解两个未知数,因此 nonce 的私有形式能够保持您的私钥的秘密。正如公钥在签名方程式中是私钥的代替一样,nonce 的公有形式则代替其私有形式。

在这个背景下,nonce 不仅是一次性使用的数字,而且必须仅使用一次。如果您使用相同的 nonce 进行两次不同的签名,那么这两个签名方程式可以合并,nonce 可以被消除,从而有人可以解决唯一剩下的未知数——您的私钥。如果您使用BIP32 标准派生(非硬化派生),这可能是几乎所有多重签名钱包都会使用的方式,那么一旦暴露一个私钥,就意味着该BIP32路径下的所有其他私钥都会被暴露(甚至可能在其他路径中也是如此)。这意味着一个已经收到了比特币的多重签名钱包,如果其中一个签名者重用了一个 nonce,那么该签名者在这个钱包下的所有地址都会被泄露。

单签名钱包,或者使用基于脚本的多重签名的钱包,可以通过一个简单的技巧来避免重用 nonce:他们使得 nonce 依赖于他们签署的消息。如果消息发生任何变化,nonce 也会变化,因此它们不会重用 nonce。

但多重签名不能使用这个技巧。它们要求每个共同签名者不仅贡献一个部分签名,还要贡献一个部分公有 nonce。多个部分公有 nonce 被组合起来生成一个聚合公有 nonce,该 nonce 将与签名的消息一起使用。

这意味着,即使交易保持不变,也不应该多次使用相同的部分 nonce。如果第二次签署时,某个共同签名者改变了他们的部分 nonce(改变了聚合 nonce),您的第二个部分签名实际上就是为一个不同的消息签署的,这会暴露您的私钥。由于对于每个参与方来说,让他们的私有 nonce 依赖于所有其他方的部分公有 nonce 是完全不可能的,因此在多重签名中没有简单的方法来避免nonce重用。

乍一看,这似乎不是一个大问题。只需要让签名者每次签署时生成一个新的随机 nonce。实现起来比听起来要难得多——自 2012 年以来,人们一直在发现依赖生成随机 nonce 的钱包中的比特币丢失漏洞。

但即便钱包能够生成高质量的随机 nonce,它仍然需要确保每个 nonce 只使用一次。这是一个真正的挑战。在我们上周专栏的原始版本中,我们描述了一个MuSig2兼容的冷钱包或硬件签名设备,它会在首次运行时生成大量的 nonce。然后,钱包或设备需要确保每个nonce 从未与多个部分签名一起使用。虽然这听起来简单——每次使用 nonce 时递增计数器——但当软件和硬件可能因偶然原因出现故障,或者受到外部甚至恶意干预时,这可能会变得非常复杂。

也许钱包减少 nonce 重用风险的最简单方法是尽可能缩短 nonce 的存储时间。我们上周的示例建议将 nonce 存储几个月或几年,这不仅为出错提供了大量机会,而且还需要将 nonce 记录到持久化存储介质中,这些介质可能会被备份并恢复,或以其他方式被置于意外状态。使用MuSig2的另一种替代方式是仅在需要时创建 nonce ,例如在接收到 PSBT 时。 nonce 可以存储在易失性内存中,仅在需要时使用,因此在发生意外情况(例如软件崩溃或断电)时,它们会被自动销毁(使其无法重用)。

然而,致力于解决这个问题的密码学家们似乎对原始 MuSig 协议(MuSig1)和 MuSig2 中缺乏万无一失的方法来防止 nonce 重用感到非常担忧。MuSig-DN(确定性 nonce )确实提供了解决方案,但它复杂且速度较慢(一个 alpha 版本在 2.9 GHz 的 Intel i7 处理器上生成 nonce 证明几乎需要一秒钟;我们不知道在16 MHz硬件签名设备上,使用一个处理器不那么先进的设备需要多长时间)。

我们给所有实施多重签名签署的人提供的建议是,在进行任何重大时间或资源投入之前,考虑前往 #secp256k1 IRC 聊天室或比特币密码学家聚集的其他地方,描述您的计划。

发布与候选发布

流行的比特币基础设施项目的新发布和候选发布。请考虑升级到新发布版本或帮助测试候选发布。

  • C-Lightning 0.10.1 是一个包含若干新功能、几个 bug 修复以及对开发中协议(包括 dual fundingoffers)的更新的发布。

  • Bitcoin Core 22.0rc2 是下一个主要版本的发布候选版本,包括其完整节点实现及其相关的钱包和其他软件。此版本的主要更改包括支持 I2P 连接、移除对 版本 2 Tor 连接的支持,并增强了对硬件钱包的支持。

值得注意的代码与文档更改

本周在 Bitcoin CoreC-LightningEclairLNDRust-Lightninglibsecp256k1硬件钱包接口(HWI)Rust BitcoinBTCPay Server比特币改进提案(BIPs)闪电网络规范(BOLTs)中的值得注意的更改。

  • Bitcoin Core #21528 旨在改善 P2P 传播中的完整节点监听地址。在节点防止网络分区(如 eclipse 攻击)方面,暴露多样化的地址集非常重要。当 Bitcoin Core 节点接收到一个包含 10 个或更少地址的地址消息时,它会将其转发给 1 或 2 个对等节点。这是自我广告地址的主要技术,因此将地址发送给不会转发这些地址的对等节点实际上会停止或“黑洞”网络中的传播。虽然在恶意情况下无法防止传播失败,但此补丁改进了在诚实情况下的地址传播,例如在仅用于区块中继连接或轻客户端的情况下。

    此更新通过识别传入连接是否为转发地址的候选,来改善地址传播,具体是通过检查该连接是否发送过地址相关消息(如 addraddrv2getaddr)。如果网络中有依赖于接收地址消息但从不主动发送地址相关消息的软件,这一行为更改可能会造成问题。因此,作者在合并该更改之前,采取了在邮件列表上发布该提案并研究其他开源客户端以确认兼容性的措施。

  • LND #5484 允许将所有数据存储在一个外部 Etcd 数据库中。这通过使集群领导权的变化变得即时,改善了高可用性部署。相应的 LND 集群文档曾在 Newsletter #157 中介绍过。

  • Rust-Lightning #1004PaymentForwarded 添加了一个新事件,该事件允许追踪支付是否已成功转发。由于成功的转发可能为节点带来费用收入,这使得用户能够跟踪该收入并记录到会计记录中。

  • BTCPay Server #2730 在生成发票时使金额变为可选。这简化了支付流程,尤其是在操作员将金额选择委托给用户的情况下,例如当用户为账户充值时。