LLM 让形式化验证变得可行
来自 Anthropic Research · 期号 2026-10-22
摘要
形式化验证过去需要专家花几年时间,所以只用在航空电子这类关键任务上。LLM 让这件事变得可行了。 Anthropic 用 Claude 在 123 个开源库的 RISC-V 汇编代码上证明了安全属性:对于 64 MB 以内的任何输入,这些程序永远不会崩溃。Claude 写了约 1.8 亿行 Rocq 证明代码,典型证明约 60 万行,覆盖的中位数二进制只有 1.8 万条指令。 写证明的过程中 Claude 还发现了多年未被发现的 bug——尽管这些库已经被万亿次测试跑过。证明由 Rocq 检查器自动验证,几乎不需要人工审查。 Anthropic 把部分证明和 RISC-V 语义开源了。合作方 Theorem 也开放了同样的验证流水线给其他开源项目。 这是首次用 AI 对生产级软件做汇编级形式化验证的大规模尝试。随着模型能力提升,形式化验证有望成为安全开发的标准环节。
深读
导读 这是首次用 AI 对生产级软件做汇编级形式化验证的大规模尝试。Anthropic 让 Claude 为 123 个开源库的 RISC-V 二进制代码编写了形式化证明,证明了这些程序在 64 MB 以内的任何输入下永远不会崩溃。这项工作不仅产出了约 1.8 亿行证明代码,还在过程中发现了多年未被发现的 bug。它展示了 LLM 如何将过去需要专家数年时间的形式化验证变得可行,为安全开发提供了新的路径。 关键信息 - 覆盖 123 个开源库的 239 个 fuzz 入口点,证明这些程序在 64 MB 以内任何输入、单线程静态二进制、固定内存预算的 RISC-V Linux 环境下不会崩溃。 - Claude 写了约 1.8 亿行 Rocq 证明代码,典型证明约 60 万行,覆盖的中位数二进制只有 1.8 万条 RISC-V 指令。 - 证明过程中发现了数百个 bug,包括一个解压器中的计数器下溢(需要约 20 MB 且具有特定布局的输入才能触发),以及一个图像解码器中的越界读取(需要 64 MB 输入和超过 2 GB 内存)。 - 证明了 cpp-httplib 库的栈不会溢出,为此 Claude 需要在机器码层面证明 libc++ 红黑树重平衡算法能正确保持树深度对数有界。 - 在验证一个广泛使用的 PDF 阅读器时,一周内发现的安全 bug 数量相当于通常一年的报告量。 - 在 zlib 验证实验中,Claude 为 RFC 1950 编写了形式化规范,并直接对 x86 编译的二进制进行了证明。 - 新模型 Opus 5.5 完成一半验证任务所需的 token 比 Opus 5 少约 40%,且允许代理共享证明空间后 token 消耗再减少 17%。 逐节讲解 从测试到证明 形式化验证的第一步是定义「正确」的含义,即规范(spec)。对于大多数程序(如文本编辑器),获得一个全面且无歧义的规范本身就是重大障碍。Anthropic 的解决方法是:将开源库已有的可编译测试套件自动转化为规范。具体来说,他们把 fuzz 测试(开发者编写的入口点,任何导致崩溃的输入即视为 bug)转化为一条规范:对于所有小于 64 MB 的输入,该 fuzz 测试不会崩溃。如果 Claude 能证明这条规范,那么对该入口点的 fuzz 测试就变得多余了,因为已经证明不存在任何能导致崩溃的输入。 这项工作基于 Google 的 OSS-Fuzz 项目,该项目为开源项目提供持续 fuzz 测试。OSS-Fuzz 自动用 AddressSanitizer(ASan)插桩 C/C++ 程序,使其在内存访问错误时崩溃。Claude 将编译后的 RISC-V 二进制、Theorem 提供的 RISC-V 和操作系统形式语义、以及「不崩溃」属性结合起来,自动生成证明必须满足的规范,然后用 R…