Skip to content

RSW 时间锁谜题

较新版本的 Cap 加入了一种实验性的质询类型:RSW(Rivest-Shamir-Wagner)时间锁谜题。它是默认 SHA-256 工作量证明的一种更抗 GPU 的替代方案。

提示

RSW 是可选启用的。Cap 的默认流程仍然使用 SHA-256 PoW。除非你显式启用它,否则现有的验证组件和服务端行为不会改变。

为什么需要 RSW

Cap 默认的 SHA-256 PoW 验证起来快速且廉价,但每个谜题理论上都可以被 GPU 或 ASIC 加速。我们尚未在实际环境中观察到这种情况,但随着 GPU 越来越便宜、越来越易得,基于哈希的 PoW 的安全余量正在逐渐削弱。

RSW 是一种顺序谜题,其设计目标就是抵抗 GPU 加速。我们还在测试和评估它的性能,尚未准备好用于生产环境,但目前的结果相当不错。

事实上,根据我们的测试,RSW 在 A100 上比在 iPhone Air 这样的现代手机上还要。我们在几台租用的 GPU(使用 NVIDIA 自家的 CGBN 库)和消费级设备上做了基准测试:

硬件µs / 2048 位平方运算(单链)
Apple M3 Air,Chrome 1482.39
Apple iPhone Air,iOS 26 + Chrome3.07
Pixel 9,Chrome 1455.14
iPhone 12,iOS 17(WebKit)8.57
NVIDIA H100,32 线程协作处理单链2.70
NVIDIA L4,32 线程协作2.69
NVIDIA A100,32 线程协作4.82

协议如何工作

初始化(启动时执行一次)

服务端生成一个 2048 位的 RSA 风格模数 N = p·q,将 pq 保密,只公开 N。密钥对生成耗时约 0.5–3 秒(取决于素数抽取的运气),因此服务端应把结果持久化,并在各进程间复用。

每次质询的铸造(≈ 2 ms)

朴素的做法是服务端从头计算 y = x^(2^t) mod N,和客户端付出一样昂贵的计算。我们用短指数技巧避开了这一步:

  1. 初始化时,服务端利用陷门 φ(N) = (p-1)(q-1) 预先计算一次 h = g^(2^t) mod N。这只需要一次全强度模幂运算。
  2. 对每个质询,服务端选取一个随机的 256 位标量 r,然后计算:
    • x = g^r mod N
    • y = h^r mod N
  3. 代数上有 x^(2^t) = (g^r)^(2^t) = (g^(2^t))^r = h^r = y

g^rh^r 都是 256 位指数的模幂运算,各约 4 次短乘法。配合基于 pq 的中国剩余定理加速,整个铸造过程在现代 CPU 上大约只需 2 毫秒。

客户端只能看到 (N, x, t)。从 x 恢复 r(Z/N)* 上的离散对数问题,与分解 N 一样困难。256 位指数也不会带来捷径(在 2048 位模数子群中使用短指数的 DLP 尚无已知的亚指数攻击)。

客户端求解

给定 (N, x, t),客户端要做的只是计算:

js
let y = x;
for (let i = 0; i < t; i++) y = (y * y) % N;

在大多数硬件上这大约需要 300–800 毫秒。

服务端验证(≈ 100 µs)

服务端的加密状态令牌中已经包含预期的 y(在铸造时写入)。验证只是把提交的 y 与之做一次常数时间的 BigInt 比较,无需重新推导。

RSW 无法防御什么

RSW 无法防御 FPGA / ASIC 硬件。定制芯片在 FPGA 上完成一次 2048 位模平方只需 50–100 ns(约为 CPU 核心的 15–20 倍),在 ASIC 上只需个位数纳秒(约 200–300 倍)。不过对刷 CAPTCHA 的场景来说,这在经济上仍然不划算,因为定制 ASIC 的一次性工程费用高达数百万美元。但如果你的威胁模型包含国家级攻击者,那基本无计可施了。

试一试

RSW 的 cap-core API 接口记录在 RSW 质询中。验证组件会自动检测 format-2 响应,服务端只需升级二进制即可。

如果你在运行 Cap Standalone,RSW 在控制台中以按密钥开关的形式提供,详见 Standalone 选项页面。