Idea: a BN254 pairing-check opcode (unlock KZG/PLONK, universal trusted setup)

I built a working shielded pool on Kaspa L1 using the Toccata verifyGroth16 opcode — live on testnet-10, full deposit → withdraw → private-payout cycle under real consensus. It works great, with one recurring wall: Groth16 needs a fresh per-circuit trusted setup. Every new privacy circuit means organizing another multi-party ceremony, which is a real barrier to permissionless ZK app development on Kaspa.

Proposal: expose a low-level BN254 pairing-check (+ MSM) opcode — the way Ethereum did with EIP-197 — rather than more packaged verifiers. One small, auditable primitive lets covenants verify KZG openings, PLONK, and Groth16 (and future schemes) in script. Critically, KZG/PLONK use a universal, updatable setup — so we could inherit Ethereum’s existing KZG ceremony (140k+ contributors) instead of running a new ceremony per circuit.

Why not STARKs: proofs are tens–hundreds of KB and verification is heavy — rough for an L1 where every node verifies every tx at ~10 BPS. Small-proof/cheap-verify is what L1 wants; this keeps that.

Why not Halo2-IPA: transparent, but runs over Pasta curves with recursive IPA — doesn’t reduce to a BN254 pairing, so it doesn’t fit the existing precompile. Halo2+KZG does fit, via the same primitive.

Is a pairing/MSM primitive on anyone’s roadmap? Would core devs entertain it post-Toccata?

Since my earlier post (shielded pool on TN10 via verifyGroth16 / 0x20), we built out the other side too: a full post-quantum shielded pool and a proof-carrying KAS price oracle on 0x21 (RISC0 succinct) — both live on testnet-10, proven under real consensus. Having now used both Toccata ZK precompiles in anger, I can put real numbers on the gap that motivates this ask. (All prototype / unaudited / testnet.)

See it here..https://kaspa-app.vercel.app/

Two verifiers, one gap

Toccata gives us two ZK paths, and they sit at opposite corners. A third option (KZG/PLONK) would land exactly where an L1 wants:

0x20 Groth16 0x21 RISC0 STARK KZG / PLONK (proposed primitive)
proof size ~128–256 B ~217 KB (seal) ~hundreds of B
verify cost ~140k grams ~250k grams ~a few pairings (≈ Groth16)
tx mass small ~483k (≈ half the 500k block limit) small
on-chain fee ~0.15 KAS ~0.5 KAS ~0.15 KAS
trusted setup per-circuit ceremony none universal, updatable (once, reused)
post-quantum no yes no

The measured 0x21 figures are from the pool/oracle running now: a single succinct verify is ~250k grams, the tx mass is ~483k (near the 500k per-block compute limit — one verify ≈ half a block), the seal is ~217 KB, and the on-chain fee is ~0.5 KAS.

So the gap is precise: 0x20 is small and cheap but needs a fresh multi-party ceremony per circuit — the real barrier to permissionless ZK app dev. 0x21 needs no ceremony but is too heavy for high-throughput or per-tx use. KZG/PLONK give you 0x20’s cost profile with a universal, updatable setup — you run one ceremony, ever, and reuse it across all circuits. That’s the missing third option.

The ask: a low-level pairing-check + MSM primitive

Rather than more packaged verifiers, expose the primitive — a pairing check plus multi-scalar-multiplication, the way Ethereum did with EIP-196/197 (BN254) and EIP-2537 (BLS12-381). One small, auditable opcode-pair lets covenants verify KZG openings, PLONK, Groth16, and future schemes in script — and, critically, inherit an existing universal ceremony instead of organizing a new one per circuit.

Curve decision (this is the crux, so let me be explicit)

  • BN254 / alt_bn128 (EIP-196/197): cheapest verify, the curve most tooling targets. Universal ceremonies already exist — Perpetual Powers of Tau, Aztec Ignition. Downside: security is now ~100–110-bit after exTNFS, not 128.
  • BLS12-381 (EIP-2537): the curve of Ethereum’s EIP-4844 KZG “Summoning” ceremony (~140k contributors) and ~128-bit security — at ~2–4× the op cost of BN254.

I’d lean BN254 to keep verify cheap (the whole point on an L1 where every node verifies every tx at ~10 BPS) and inherit Perpetual Powers of Tau. If the ~100-bit floor is a concern for a base-layer primitive, BLS12-381 buys the bigger ceremony and margin at a cost. Either fits the same primitive — I’d rather the debate be which curve than packaged verifier vs primitive.

Why not just lean on 0x21 (STARKs)

We do — it’s the right tool for post-quantum and no-setup, and we’ve shipped on it. But at ~half a block and ~0.5 KAS per verify, it can’t be the substrate for cheap, high-frequency, or per-tx ZK. A KZG/PLONK verify is a few hundred bytes and a handful of pairings. They’re complements, not substitutes.

Why not Halo2-IPA

Transparent (no setup), but it runs over Pasta with recursive IPA — it doesn’t reduce to a BN254/BLS pairing, so it can’t share this primitive. Halo2+KZG does fit, via the same opcode.

Question for core devs

Is a pairing + MSM primitive anywhere on the roadmap post-Toccata? And if so, is the curve question (BN254 for cost vs BLS12-381 for the 4844 ceremony + security margin) open for input? Happy to bring the shielded-pool + oracle work as concrete driving use-cases.

1 Like