本文介绍了量子安全比特币交易(QSB)的第一部分,详细阐述了如何通过哈希和Lamport签名替代ECDSA来抵御量子攻击。
你不需要了解 Binohash 也能跟随本指南,我们会解释我们使用的所有内容。
注意:这并不是一个将比特币迁移到后量子时代的严肃计划。论文本身称之为最后手段。但它读起来很有价值,因为它展示了如何灵活运用 Script。
比特币交易通常使用 ECDSA 签名。
该签名承诺了交易。
如果交易中的任何内容发生变化,签名就会失效。
让我们看看签名是如何构建的。
看 z:
s 依赖于 z,而 z 依赖于交易数据。
如果我们改变交易 → z 改变 → 签名失效
记住这一点,这对后续所有内容至关重要。
比特币容易受到量子攻击,这是因为 Shor 算法
。
这是因为量子计算机可以使用 Shor 算法从公钥中恢复私钥。
这就是问题的所在:
Alice 想给 Bob 发送 10 BTC。她用她的私钥签名交易并广播。
Eve(攻击者)有一台量子计算机。她监视内存池,看到 Alice 的交易等待被挖矿。
该交易揭示了:Alice 的公钥
Eve 在 Alice 的公钥上运行 Shor 算法 → 恢复 Alice 的私钥
现在 Eve 可以随意花费 Alice 的 UTXO。她用相同的输入(相同的 UTXO)构建自己的交易,但将输出发送给自己而不是 Bob。
她用 Alice 的私钥签名并广播。
如果矿工首先包含 Eve 的交易,Bob 永远收不到 BTC。
如果量子计算机可以破解 ECDSA,我们可以依赖什么?
答案:哈希
我们在比特币中使用的哈希函数不依赖于椭圆曲线。
它们具有原像抗性:给定一个输出,很难找到产生它的输入。
Shor 算法无法逆转哈希
还有另一种量子算法,Grover 算法
确实会影响哈希函数,但只是削弱它们。它减少了执行暴力搜索所需的时间。
使用 Grover 算法,256 位密钥的原像抗性将接近 128 位密钥的安全性。
所以:
SHA-256:2²⁵⁶ → 2¹²⁸
RIPEMD-160:2¹⁶⁰ → 2⁸⁰
这更弱了,但 2⁸⁰ 仍然远超出当今量子攻击者的能力,特别是因为 Grover 算法无法并行化。
QSB 论文建立在使用哈希代替 ECDSA 的想法之上。
策略是:
“移除对椭圆曲线的安全依赖。仅保留基于哈希的安全性。”
第一步:推导出交易的一个指纹 D。
第二步:用 Lamport 签名签署 D(参见我们上一篇关于 Lamport 签名的文章)。
由于 Lamport 签名是后量子的,并且 D 绑定整个交易,攻击者无法在不伪造 Lamport 签名的情况下替换成不同的交易。为什么这能阻止 Eve:
如果 Eve 改变交易 → D 改变
→ 需要一个新的 Lamport 签名
→ 需要秘密哈希原像
→ Eve 没有它们 ✗
这就是核心思想。
第二步是容易的部分。
第一步(构建 D)是所有工作发生的地方。
我们将在接下来的部分逐步分解第一步:
交易固定
寻找 D:第一轮
寻找 D:第二轮
让我们从交易固定开始。
在这一步中,Alice 创建一笔交易并“固定”它。
意思是:对交易的任何更改都变得代价高昂。
为了实现这一点,我们使用两个技巧。
私钥 → 公钥 → 签名。
但 ECDSA 也可以反向工作
。
如果你有:
一个签名
消息哈希 z
你可以恢复公钥:签名 + 消息 z → 公钥
public_key = Recover(signature, z)
(此步骤不需要私钥)
如果你喜欢数学:
Q = r⁻¹(sR − zG)
注意:Q 依赖于 z,而 z 依赖于交易数据
如果我们改变交易 → z 改变 → 恢复的公钥改变
ECDSA 签名有两个值:r 和 s。
当编码为 DER
时,如下所示:
0x30 <total_len> 0x02 <r_len> <r> 0x02 <s_len> <s> <flag>
技巧:构建尽可能小的 DER 签名,其中:
r = 1 字节
s = 1 字节
这产生了一个 9 字节的签名。
这是一个硬编码的假签名。它满足 DER 编码规则,但没有人签署任何东西。它只需要看起来像一个有效的签名。
我们称其为 sig_nonce
sig_nonce = 30 07 02 01 [r] 02 01 [s] 01
这个 sig_nonce 被硬编码在锁定脚本中。
如果图中的锁定脚本看起来令人困惑,别担心。在本指南结束时,你将能够逐行阅读它。目前,唯一值得注意的是它有多短:只需 5 个操作码来固定一笔交易(Binohash* 需要 13 个)。
是本文在其基础上构建的方案。我们将在后面的指南中介绍它。
现在我们将两个技巧结合起来:
公钥恢复
假签名(sig_nonce)
我们在 sig_nonce 上使用 Recover() 来计算 key_nonce,一个与假签名对应的公钥:
key_nonce = Recover(sig_nonce, z)
Alice 在链下计算它,使用她发给 Bob 的支出交易作为 z 的值。她在解锁脚本中提供 key_nonce。
key_nonce 现在被绑定到支出交易。更改任何内容 → z 改变 → key_nonce 改变。
为了构建 D,我们需要两件事:
一个依赖于支出交易的值。更改交易 → 该值改变。
一种使更改交易变得代价高昂的方法。这样就没有人能廉价地尝试数百万次变化以获得与 #1 相同的值。
我们刚刚解决了第一个问题。✓ key_nonce = Recover(sig_nonce, z) 与交易绑定。更改任何内容 → z 改变 → key_nonce 改变。
但这本身并没有用。我们仍然需要第二个条件。让我们接下来做这个。
如果没有固定,Eve 可以这样做:
她看到 Alice 的交易在内存池中,并想将其替换为自己的交易。因为她更改了交易输出以将钱发送给自己而不是 Bob,所以她尝试的每个交易变体都会产生不同的 z,进而产生不同的 key_nonce,进而产生不同的 D。因此,她廉价地运行成千上万个变体,寻找一个导致 D 与 Alice 原始交易匹配的变体。然后她可以重用 Alice 的 Lamport 签名。
这对 Eve 来说既廉价又快速。
(我们将在第 2 部分中确切看到 D 是如何构建的。现在,只需知道 Eve 的整个攻击依赖于廉价地搜索交易)
我们需要让每一次尝试都付出实际的工作。具体来说,每次尝试大约需要 2⁴⁶ 次哈希操作。
还记得 Alice 在她的解锁脚本中提供的 <key_puzzle> 吗?这就是哈希到签名谜题的用武之地。
思路如下。
脚本获取 key_nonce 并使用 RIPEMD-160 对其进行哈希处理
RIPEMD-160(key_nonce) → 20 个看似随机的字节
让我们称这 20 个字节为:
sig_puzzle = RIPEMD-160(key_nonce)
现在技巧来了:我们希望这 20 个字节(sig_puzzle)看起来像一个有效的 DER 编码签名。正如我们之前所见,DER 签名具有以下结构:
30 [len] 02 [r-len] [r] 02 [s-len] [s] [flag]
得到看起来像有效 DER 的字节串的概率非常低,大约为 2⁴⁶ 分之一
所以大多数尝试都会失败。
但在多次尝试后,RIPEMD-160(key_nonce) 会产生看起来像有效 DER 签名的字节。
这就是谜题。
如果 key_nonce 保持不变,RIPEMD-160(key_nonce) 总是给出相同的输出。
诀窍在于 Alice 可以更改 key_nonce。
请记住:key_nonce 依赖于 z。而 z 依赖于交易数据。
因此 Alice 可以调整交易字段,例如:
nLocktime
nSequence
等等。
每次调整都会得到:
新交易
→ 新 z
→ 新 key_nonce
→ 新 RIPEMD-160(key_nonce)
所以 RIPEMD-160 是确定性的,但 Alice 不断给它新的输入。
好的,但我们如何在 Script 中检查有效的 DER?
使用 OP_CHECKSIG 作为 DER 验证器:
我们将 sig_puzzle(那 20 个字节)作为签名输入 OP_CHECKSIG:
如果 CHECKSIG 通过 → ✓ 有效 DER → 谜题解决
如果 CHECKSIG 失败 → ✗ 无效 → 重试
现在我们知道我们在寻找什么:
一笔交易,其中:RIPEMD-160(key_nonce) 看起来像一个有效的 DER 签名。
大多数尝试都失败。
因此 Alice 不断调整交易,直到某个输出具有 DER 形状。
平均而言,这大约需要 2⁴⁶ 次尝试。
这就是固定。
一旦 Alice 找到一笔可行的交易,之后对它的任何更改都意味着重新开始并重做大约 2⁴⁶ 的工作。
等等,那 key_puzzle 呢?:
还记得之前,当 Alice 的解锁脚本是 <key_puzzle> <key_nonce> 时?
我们告诉过你先忽略 key_puzzle。
现在我们可以解释它了。
key_puzzle 只是另一个恢复的公钥,这次是针对 sig_puzzle。Alice 使用之前相同的 Recover() 技巧在链下计算它:
key_puzzle = Recover(sig_puzzle, z)
脚本执行:
还记得前面的固定脚本吗?现在我们逐步运行它:
解锁脚本:
<key_puzzle> <key_nonce>
锁定脚本:
<sig_nonce>
OP_OVER
OP_CHECKSIGVERIFY
OP_RIPEMD160
OP_SWAP
OP_CHECKSIGVERIFY
脚本执行两次检查。
key_nonce 绑定到这笔交易。
RIPEMD-160(key_nonce) 作为与 key_puzzle 一起使用的签名有效。
现在让我们逐步执行堆栈。
在第 2 部分中,我们将涵盖:
SIGHASH_SINGLE 漏洞
150 个虚拟签名
FindAndDelete
查找摘要 D
使用 HORS 签署 D
- 原文链接: x.com/bitcoin_devs/statu...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!
作者暂未设置收款二维码