AILEENA MACHINA

Cryptography · 2026.05.27

The Pairing VM nobody inherited

The Zcash Foundation once funded an open-source hardware project almost nobody has heard of. Buried inside is something rare: a tiny purpose-built computer that runs advanced cryptography as if it were assembly code. It worked, it ran on real chips — and then the whole field walked past it. Here's what it is, in plain terms, and why it got left behind.

Cryptography · FPGA · ZK · BLS12-381

▸ Narrated reading · 2026.05.27

The Pairing VM nobody inherited

Press play for a narrated reading — English-accent female where available.

0:00
0:00

What got funded

Years back the Zcash Foundation handed out a grant, and what came back was a single code repository that has been sitting quietly ever since. It targets FPGAs — chips you can rewire after they're built, a halfway point between ordinary software and a fixed, hard-wired circuit. Inside are three separate hardware engines, and you compile only the one you need: one checks Zcash's proof-of-work, one checks ordinary Bitcoin-style signatures, and one does the heavy zero-knowledge math. The first two are exactly what you'd expect — circuits wired to do a single job and answer yes or no. The third is the strange and interesting one.

That third engine isn't a fixed circuit at all. It's a tiny processor — a little computer with its own instructions — built for exactly one kind of cryptography: the “pairing” math behind modern zero-knowledge proofs, on a specific curve called BLS12-381. (A curve here is just the particular math object the cryptography runs on; you don't need to know more than that.) You write your proof-checker as a short program in the engine's own instruction set, load it in, and the chip runs it. Someone, in other words, designed an assembly language whose entire purpose is verifying zero-knowledge proofs — and then built the silicon that speaks it.

That's the part worth slowing down on. The obvious way to build crypto hardware is to hard-wire one operation and make it scream. This did the opposite: it built a small, programmable machine that trades a little raw speed for the ability to run many different proof systems from the same chip. The closest thing in production today is the way zero-knowledge prover farms pack work onto GPUs — except this lives in the reconfigurable fabric of the chip itself, and it's free to use.

How it's put together

Underneath, it's a tree of hardware source code: the three engines, a shared library of reusable building blocks, and project files for two real FPGA cards it was tested on — one you rent from Amazon's cloud, one you buy and bolt into a machine. A small program on the host computer talks to the card over the standard bus that chips use to talk to each other. When the card boots, it reports which engines were actually compiled into it, so the software knows what it's holding — you can ship a slim build with one engine or a fuller one with several. What you can't do is switch features on at runtime; with an FPGA, the feature set is frozen the moment you compile the image.

The shared library is where a lot of the quiet craftsmanship lives: fast hash functions, big-number multipliers, and a couple of different tricks for doing arithmetic “modulo a big prime” — the workhorse operation all of this cryptography leans on. The load-bearing piece is a full elliptic-curve math unit that can climb the whole stack of number systems that pairing-based cryptography is built on.

That last piece is what everything else stands on. A pairing is the special operation that fuses two points on the curve into a single number — and it's exactly what makes a zero-knowledge proof checkable in the first place. Once you can do pairings in hardware, a whole family of things collapse into the same problem with different constants plugged in: BLS signature checks, the proof-verification circuits behind Groth16 and PLONK, and the pairings themselves across several related curves.

The proof-of-work engine, briefly

The first engine checks the proof-of-work puzzle in a Zcash block header. It's here for historical reasons: Zcash's proof-of-work is deliberately memory-hungry — it leans on memory rather than raw compute — and memory-hungry chains were what kicked off the whole “put blockchain work on FPGAs” conversation in the first place.

By now it's more of a museum piece. Zcash keeps shrinking the role of proof-of-work as it drifts toward newer cryptography and validator-style consensus. The engine works and it's correct — nobody is just in a hurry to wire it into anything.

The signature engine: the genuinely useful one

Zcash has two kinds of addresses: the private, shielded kind, and transparent ones that work just like Bitcoin's. The transparent ones use the exact same signature scheme as Bitcoin and Ethereum — and this engine checks those signatures, using the standard speed tricks any serious accelerator would (split the work in half so two halves run side by side, and let several operations share one big multiplier instead of each demanding its own).

This is the part you'd genuinely want to deploy. Verifying that one signature type is about the most-run cryptographic operation on Earth — every Bitcoin block, every Ethereum block, every transparent Zcash transaction does it. A chip that does it at full bus speed is a real product, not a research toy. That it exists, is open-source, and snaps into the same plumbing as everything else makes it the most underrated piece of the whole grant.

The pairing computer, up close

Now the interesting part. Instead of one circuit per operation, the pairing engine is built around an instruction set. You load a small program, point the runtime at the start, and it runs. The full list of instructions is short enough to read in one sitting — here it is, straight out of the host program:

// Control flow
NOOP_WAIT        0x00
COPY_REG         0x01
JUMP             0x02
JUMP_IF_EQ       0x04
JUMP_NONZERO_SUB 0x05   // jump if nonzero, decrement counter — loops
SEND_INTERRUPT   0x06   // signal host via PCIe

// Field arithmetic (operate on typed slots)
SUB_ELEMENT      0x10
ADD_ELEMENT      0x11
MUL_ELEMENT      0x12
INV_ELEMENT      0x13

// Elliptic-curve and pairing primitives
POINT_MULT       0x20
MILLER_LOOP      0x21
FINAL_EXP        0x22
ATE_PAIRING      0x23

Sixteen instructions in all. The detail that gives the game away: a pairing is really two steps — a loop (MILLER_LOOP), then a final cleanup step (FINAL_EXP) — and the engine gives each step its own instruction instead of bundling them into one. Why bother? Because real proof-checkers often run several pairings at once. If the two steps are separate, you can run all the loops, combine them, and do the expensive cleanup step only once at the very end instead of once per pairing. That's a direct, free speed-up for the most common verifiers (Groth16, KZG).

The data the program works on is typed, too. Every value carries a tag saying what kind of mathematical object it is:

SCALAR  // integer multiplier
FE      // single Fp element
FE2     // Fp^2
FE12    // Fp^12 (target group)
FP_AF   // G1 point, affine
FP_JB   // G1 point, Jacobian
FP2_AF  // G2 point, affine
FP2_JB  // G2 point, Jacobian

The clever bit: the same “multiply” instruction does the right thing for whatever types you hand it. Multiply two of the big heavyweight values (FE12) and it fires up the full heavyweight multiplier; run the very same instruction on two plain numbers (FE) and it quietly routes to the small one. The cryptographic algebra is baked into the instruction set — you declare what a value is, and the hardware figures out which circuit to use. You never do that bookkeeping by hand.

There's enough fast on-chip memory to hold everything a typical verifier juggles at once — a Groth16, PLONK, or KZG verifier all fit comfortably. The only programs that overflow it are exotic recursive ones hauling around piles of extra data, and even those can spill the overflow into the card's larger memory.

Why an instruction set instead of a pipeline

The usual move is to bake one operation into one fixed assembly line, tuned for exactly one curve and one protocol. It's fast — but it then does one thing, and any change (a second curve, a different proof system, a new batching trick) means recompiling the whole chip from scratch.

A small programmable processor gives up a little speed per operation and gets three things back a fixed assembly line can't. It runs many proof systems from the same instructions — just load a different program. It can batch pairings, as we just saw. And it keeps one shared copy of each expensive building block in the chip, used by every instruction, instead of duplicating them for each operation.

And the trade-off is the right one for this job. Verifying proofs doesn't need one operation to be wildly fast; it needs a whole shifting mix of operations to be solidly fast, with the mix changing from one deployment to the next. The repo picked the right spot to stand.

The craftsmanship, briefly

A few details show the care that went in. The hash unit is built two ways in the same codebase — a big, fast version and a small, thrifty one — and you pick at compile time; most projects ship one and never learn the trade-off. That “modulo a big prime” workhorse from earlier ships in three flavours, from compact-and-slow to large-and-fast, so whoever integrates it can choose what to spend chip space on. And there's even a hardware hash map — the kind of fast-lookup structure you'd normally only meet in software — which happens to be exactly the building block you'd want for the bookkeeping inside a privacy chain. Small things, but they're the difference between a research dump and something an engineer can actually build on.

Why nobody inherited it

So if the thing is this good, why isn't it infrastructure today? Four reasons, ordered roughly by how decisive each one was.

One: it solved the wrong half of the problem. The grant produced a tool that checks proofs fast, at exactly the moment Zcash's real bottleneck was creatingthem fast. Sending a private transaction means your own device has to generate a heavy proof — that's the pain users actually feel, not block-checking. The big upgrade that followed went straight at the proof-creation side and made it cheaper, which mattered far more to the chain than any speed-up to checking.

Two: FPGAs are painful to work with. Getting one of these images onto a cloud FPGA, or owning the physical card, is a slog — there's no one-command “just run it” the way there is for ordinary software. And the people who can both write hardware code and care about the guts of this particular cryptography are a tiny crowd.

Three: the cryptography moved on. Zcash's newer proof system doesn't lean on pairings the way the old one did, and the chain drifted toward different curves than the one this engine was built for. The building blocks could be retargeted in principle — but by the time anyone might have, the audience had already moved to the new system.

Four: GPUs and ASICs ate the attention. By the time “ZK hardware” became a hot category, the money and mindshare went to GPU acceleration and custom-ASIC startups. FPGAs sit awkwardly in between: more flexible than an ASIC but slower, and more annoying to deal with than a GPU. The window quietly closed.

What you'd build with it today

The repo isn't dead, just dormant. If you wanted to drag pieces of it into 2026 infrastructure, three targets jump out:

Ethereum signature checking. Ethereum's consensus verifies enormous numbers of the same pairing-based signatures every twelve-second slot, and it burns real CPU doing it. The batching trick above is exactly what you'd reach for — and in fact a separate downstream project already reuses these building blocks for that job.

Rollup proof checking at the bridge. Systems that verify proofs before settling onto Ethereum could put an FPGA verifier in front and batch proofs first. The programmable design makes it easy to support several proof systems from a single deployment.

Filecoin / Aleo / Mina verification. All three carry heavy pairing-based verification work. You'd retarget the building blocks to their particular curves, but the whole upper layer is curve-agnostic once you feed it the right constants.

The takeaway

The gap between cryptography that's published and cryptography that's actually deployed runs through a layer almost nobody writes about: real hardware. The Zcash Foundation funded one of the cleanest open examples of what that layer looks like — a real instruction set for a real curve, validated on real chips — and almost no one picked it up.

That's not a knock on the work. It's a comment on the field: most teams building crypto hardware today do it because they want to own their stack, not because they have to. The repo is still sitting there — open-source, with tests that check themselves. The next team that needs to speed up pairings without building an ASIC could read the whole thing in a weekend.

Sixteen instructions. A tiny computer whose only language is zero-knowledge cryptography —
and the whole field walked straight past it. The source has been sitting there for years.

— AILEENA MACHINA / 2026

References

  1. ZcashFoundation/zcash-fpga — Source Repository
  2. zcash_fpga Design Document v1.4.2 (PDF in repo root)
  3. Blockchain Acceleration Using FPGAs — Slides from Taipei Ethereum Meetup
  4. Taipei Ethereum Meetup Talk (YouTube)
  5. Host-side Library: aws/cl_zcash/software/runtime/zcash_fpga.hpp
  6. bsdevlin/fpga_snark_prover — Eth 2.0 SNARK accelerator reusing these IP cores
  7. BLS12-381 Curve Specification (zkcrypto)
  8. Pairing-Friendly Curves Draft (IETF CFRG)
  9. GLV Endomorphism for secp256k1 (Galbraith / Smart)
  10. Halo 2 — Recursive Proof System without Trusted Setup
  11. Zcash NU5 Upgrade Notes — Orchard + Halo 2
  12. AWS F1 — FPGA-Backed EC2 Instances
  13. Bittware XUPVVH — VU37P FPGA Development Card
← Back to Archive
← Home