Skip to content
Tech News
← Back to articles

AI Meets Cryptography 2: What AI Found in OpenVM's ZkVM

read original more articles
Why This Matters

This article highlights the potential of AI-driven tools in uncovering critical security vulnerabilities in complex cryptographic systems like zkVMs. The discovery and subsequent patch of a significant bug demonstrate how AI can enhance security audits, benefiting both the tech industry and consumers by promoting safer blockchain and cryptographic applications.

Key Takeaways

This is the second post in the series. In case you have not read the first one on Cloudflare's CIRCL, it has more context on why we run these experiments and how our pipeline is set up. In this post, we pointed zkao, our AI auditor, at OpenVM's zkVM, and it found a critical soundness bug in its guest library openvm-pairing that lets a malicious prover forge any pairing equality. Note that this is not a soundness bug in the zkVM's proving system itself; it only affects code that uses the vulnerable library.

The bug in this post was assigned CVE-2026-46669 and fixed in OpenVM 1.6.0. As far as we know, all partners building on OpenVM have since upgraded to that version.

Note Clarification, same as in the first post: the AI produced a candidate finding, not a final report. Humans on our team then validated the issue, confirmed exploitability, understood the full impact and affected projects, and handled disclosure. In this case, a very quick manual triage was enough to decide it was worth sharing with the OpenVM team, thanks to the detailed report and a minimal PoC that zkao produced itself.

How it happened

Four months ago, we scanned OpenVM as part of our AI experiment, the same way we scan everything at first: an LLM with a simple prompt, and then an LLM with our expert-maintained skills. We ran it with Opus 4.6 and Codex 5.3. As soon as Opus 4.7 and Codex 5.4 came out, we ran them again. The candidate findings were all valid observations, and the models confidently labeled several of them as Critical or High, but none of them were actually exploitable.

Our hypothesis was that a zkVM is simply too complex for a naive LLM setup to handle with 300K tokens or even 1M tokens of context. The dependencies between modules are far denser than in a typical library. A cryptography library can often be audited in parallel by simply handing each subagent a folder that maps to a single cryptographic primitive. Each subagent reads a small number of lines, applies only the relevant skills, writes its findings to a markdown file, and the main agent stitches those files together. All of this happens out of the box with popular agentic coding tools such as Claude Code and Codex, with little human steering.

That approach does not transfer to a more complex codebase, like OpenVM. There, except for the low-hanging fruit, a subagent's useful output is not a list of bugs. You can have a provably secure module A and a provably secure module B whose composition is still not secure. So, hunting for bugs in that "isolated" mode cannot catch meaningful bugs. Instead, a subagent's output should be knowledge about a module: what it assumes, what it delegates to its callers, and what invariant it is silently relying on. However, representing that kind of output well is the hard part. Too short and it skips the implementation detail that the bug actually sits on. Too long and it overflows the main agent's context before it can be combined with anything else. From what we have seen, at least at the time of writing, this problem is not solved efficiently by the agentic coding tools mentioned above.

With that hypothesis in mind, we decided to run zkao on OpenVM, even though our original rule for these experiments was to run zkao only after the plain LLMs had already found a real bug. We have spent a lot of time on context engineering for zkao, and we have encoded the working methods of our own experts into it as reusable flows for finding vulnerabilities, so it seemed like the right tool for exactly this situation. After more than nine and a half hours of scanning, it returned many findings. Similar to the prior experiment, we did not have time to go over every finding in depth. After a quick pass, one stood out immediately: a critical soundness bug in the pairing check in one of the guest libraries. Our hypothesis held up, and months of effort had paid off!

Although there is only one bug to share, to stay consistent with the first post, here is the bug at a glance.

Severities and fixes at a glance

... continue reading