7Block Labs
Blockchain

ByAUJay

Wrapping STARKs to SNARKs: When Proof Compression Actually Pays Off

Short summary (for listings):

By wrapping STARK proofs into compact, EVM-friendly SNARKs, you can significantly reduce L1 gas costs and latency--assuming your pipeline and risk factors align. This post lays out specific thresholds, current best practices, and practical stacks (like RISC Zero, SP1, and Boojum) to help you determine when compression makes sense for your needs.

Why this matters now

If you're looking to settle on the Ethereum mainnet, you should know that verifying a raw STARK on-chain is still super costly when it comes to both calldata and execution gas. Ever since EIP‑1108 introduced discounts for pairing precompiles and EIP‑4844 made blob data cheaper without changing calldata prices, the economic landscape on Ethereum has shifted. It really makes more sense to post small pairing-based proofs now. That's why these days, a lot of modern STARK stacks wrap up with a Groth16/Plonk verifier on BN254. They often still use STARKs internally for their speed, transparency, and post-quantum benefits. You can check out more details about the EIPs here.


What “STARK → SNARK wrapping” actually is

At a broad level, the pipeline consists of three main layers:

  • First, let's show the computation using a STARK, which is known for its speedy proving and produces large proofs.
  • Next, we’ll take those STARKs and compress or aggregate them with a STARK recursion circuit, maintaining that "transparent" quality we love.
  • Finally, we’ll verify the recursive STARK within a compact SNARK (typically using Groth16 on BN254) and only publish the small SNARK on-chain.

Two Concrete Implementations:

  1. Implementation A:
    This implementation focuses on optimizing performance and efficiency. By leveraging advanced caching strategies, it minimizes the load time and enhances user experience. Here's a quick look at some of the key features:

    • Fast data retrieval
    • Reduced server load
    • User-friendly interface

    Check out the code snippet below to see it in action:

    def optimized_data_fetch():
        # This function fetches data with caching
        cached_data = load_from_cache()
        if cached_data:
            return cached_data
        else:
            data = fetch_from_database()
            store_in_cache(data)
            return data
  2. Implementation B:
    This one takes a different approach by prioritizing scalability and adaptability. It’s designed to handle growing amounts of data effortlessly. Here are some standout features:

    • Seamless integration with cloud services
    • Dynamic scaling capabilities
    • Robust error handling

    Here's a quick example of how it works:

    async function fetchData() {
        try {
            const response = await fetch('/api/data');
            const data = await response.json();
            return data;
        } catch (error) {
            console.error('Error fetching data:', error);
        }
    }

So, whether you're looking to enhance performance or scalability, these implementations offer solid foundations to build upon!

  • RISC Zero zkVM

    • It all starts with RISC‑V execution, leading to what we call STARK “segment receipts.” These then get recursively compressed into one neat “succinct receipt” that's about 200 kB in size. From there, we convert it into a STARK‑to‑SNARK circuit, which produces a Groth16 “receipt” for the on-chain verifier to check. You can dive deeper into it here.
  • Succinct’s SP1 zkVM

    • Here, the prover splits things into shards and goes through a recursive compression with STARKs. Once that’s done, it wraps everything up as Groth16 (around 260 bytes) or Plonk (about 868 bytes) for EVM verification, which usually falls in the range of 270-300k gas. Want to learn more? Check it out here.

Big picture: zkSync's Boojum is also shifting its proving to STARKs for better throughput, but it has clear plans for a final pairing-based wrapper. This will allow Ethereum to verify a succinct proof using BN254 precompiles. (zksync.mirror.xyz)


On-chain economics in 2025: why the wrap is cheap and the raw STARK is not

  • Pairing precompiles (EIP‑1108)

    • Ethereum's bn128/alt_bn254 precompiles really help with ECADD/ECMUL/pairing checks, making them fairly affordable. The gas cost for pairing is approximately 45,000 plus 34,000 times k, where k is the number of pairings. Most Groth16 verifiers don’t need to do too many pairings, so it's pretty manageable. Check out more details here.
  • Typical Groth16 verifier gas

    • From what we’ve seen in real-world scenarios, a Groth16 verification usually costs around 200,000 to 300,000 gas. A simple model puts it at about 207,700 plus 7,160 times l, with l representing the number of public signals (ex-caldatas). Various stacks and aggregators tend to report an on-chain verification gas usage closer to 250,000 to 300,000 gas. You can read more about it here.
  • Calldata still bites

    • So, EIP‑4844 brought us cheaper blob data availability for rollups, but unfortunately, it didn’t sweeten the deal for calldata costs. When you submit proof bytes to a verifier, it still hits your wallet at 4/16 gas per byte. Plus, there's EIP‑7623 on the table, suggesting that we might see a hike in calldata prices for data-heavy transactions. A typical ~260-byte Groth16 proof is hardly a problem, but a hefty ~200kB STARK proof can really add up. More on this here.
  • Raw STARK verification gas and size

    • STARK verifications involve quite a bit of work with Merkle openings and FRI queries. When we’re talking Ethereum, that can mean millions of gas plus a huge chunk of calldata. Community feedback and studies suggest that a single STARK verification might run you around 2.5 to 5.0 million gas, with proof sizes typically in the 100 to 200kB range. Dive deeper into it here.

Net result: With the current fee model, posting a Groth16/Plonk proof that attests to a STARK is way cheaper--like, significantly cheaper--than posting or validating the raw STARK directly on L1.


The break-even: when does wrapping actually pay?

Consider the on-chain cost per settlement as:

  • Raw STARK: Gas ≈ G_stark_verify + calldata_gas(proof_stark_bytes).
  • Wrapped: Gas ≈ G_snark_verify + calldata_gas(proof_snark_bytes).

Using some cautious figures from 2025:

  • For G_snark_verify, you're looking at around 230k-300k gas and proof sizes of 260-900 bytes (comparing Groth16 to Plonk). This translates to a calldata cost of approximately 4k-15k gas. So, in total, it's about 235k-315k gas. You can check it out here.
  • On the other hand, G_stark_verify is a bit heftier at around 2.5-5.0M gas, with proof sizes varying between 100-200kB. The calldata here can range from about 0.4-3.2M gas, depending on how those bytes are spread out. Altogether, you're looking at a total of around 2.9-8.2M gas. More details can be found here.

Even if your STARK verifier is super optimized, you still need to be 10× to 30× better than the usual baselines to compete with a Groth16 wrapped proof on Ethereum. Unless you’re doing verification off-chain (check out “Verification layers” below) or on a chain that has a native FRI/hash precompile, wrapping is pretty much the go-to choice for Ethereum L1.

Just a heads-up: EIP‑4844 helps cut down on data availability costs for rollups, but it doesn’t touch the costs related to proof bytes that go to a verifier contract (since those are calldata and not blobs). This situation gives a stronger advantage to SNARK‑wrapped proofs on Layer 1. If EIP‑7623, which aims to hike up the calldata price, gets approved, that gap is only going to get bigger. (blocknative.com)


Practical stacks that already do this (and what to copy)

  • RISC Zero (zkVM as an L1 coprocessor)

    • This architecture features a cool “STARK‑to‑SNARK” R1CS circuit, which takes the recursive STARK and spits out a Groth16 “receipt” that you can verify in a standard Solidity contract. The best part? On-chain verification happens in just milliseconds and is compact enough to fit right into normal application processes. Check it out here: (dev.risczero.com).
    • The security model is pretty neat--it keeps the transparent STARK (which is based on post‑quantum assumptions) separate from the BN254 Groth16 translator (which has a trusted setup and is a bit vulnerable to quantum attacks). The versioning uses a “control root” to manage allowed recursion programs, so there’s no need for new ceremonies every time something gets updated. Want to learn more? Dive in here: (dev.risczero.com).
  • SP1 (Succinct)

    • SP1 gives you three proof types: the compressed option (only STARK), Groth16 (around 260 bytes, ~270k gas), and Plonk (about 868 bytes, ~300k gas). Plus, it offers off‑chain/no_std and Wasm verification options along with a ready-to-go EVM verifier template. It's perfect when you're looking for a consistent gas usage and super small calldata on any EVM chain. If you're interested, check this out: (docs.succinct.xyz).
  • zkSync Boojum

    • Boojum has shifted proving to a STARK-centric library (using the Goldilocks field and is super GPU-friendly). It wraps things up with a pairing-based SNARK for Ethereum verification specifically aimed at taking advantage of EVM precompiles. Want to read more about it? Here’s the link: (docs.zksync.io).

Security and governance trade‑offs you must accept (or mitigate)

  • Trusted setup vs transparency

    • So, Groth16 needs a structured reference string. A lot of teams actually use Aztec’s “Ignition” ceremony, and SP1 mentions that it combines Groth16 keys from Ignition with a bit of extra entropy. If you’re not a fan of trusted setups, you might want to go for Plonk, which has a universal and updatable SRS. Just keep in mind that this will give you somewhat larger proofs (around 868 bytes) but with similar gas costs. (docs.succinct.xyz)
  • Quantum considerations

    • Your inner STARK is based on hashes and is post-quantum safe, but the final Groth16 translator uses BN254 pairings, which makes it a bit shaky against a big quantum adversary. Most teams are okay with this risk for now since a quantum threat isn’t just around the corner, and they can make upgrades if needed. RISC Zero clearly lays this out. (dev.risczero.com)
  • Upgradability hygiene

    • Think of your on-chain verifier address and verifying key hash as super important pieces of your setup. You might want to follow RISC Zero’s approach with versioned “control roots” for your recursion programs. Alternatively, you could align with SP1’s pinned VK bytes to make sure your upgrades are intentional and easy to audit. (dev.risczero.com)

Cost modeling you can take to a budgeting meeting

  • Groth16 Verify Gas (Rule of Thumb)

    • Generally, you're looking at around 207,700 gas plus about 7,160 for each public input, not counting calldata. On top of that, you'll need to tack on roughly 4-16 gas for every byte of calldata. Most production verifiers usually hover between 230k and 300k gas. To keep things efficient, try to condense bulky statements into a single field element by hashing. (hackmd.io)
  • STARK-to-SNARK Wrap Overhead

    • Just a heads up, proving time is going to be longer compared to pure STARK, since you're running a SNARK prover post-recursion. Both SP1 and RISC Zero offer dockerized provers, and for standard zkVM traces, the total time can range from tens of seconds to minutes on regular cloud GPUs/CPUs. You might want to consider using remote provers like Bonsai or the SP1 prover network to keep things running smoothly and predictably. (dev.risczero.com)
  • Aggregation Economics

    • If you're dealing with a lot of user proofs, going for on-chain SNARK aggregation can really lower your marginal costs. Think about it--around 380k fixed costs plus some minor per-proof inclusion fees. Just keep in mind, you'll need to manage the latency and liveness of the aggregator. (docs.electron.dev)

Emerging best practices we apply for clients

  1. Start STARK, end SNARK on Ethereum
    • If you’re looking to verify on the public mainnet, it's a good idea to wrap unless you've got someone else handling the verification (check out “Verification layers” for more on that). The bn128 subsidy is pretty compelling to consider. (eips.ethereum.org)

2. Recursion before wrapping

  • Make sure to always compress your STARK segments recursively before jumping into the SNARK step. It’s not a good idea to SNARK-wrap multiple large receipts on their own. For some solid references, check out RISC Zero’s “lift → join → identity_p254 → compress” flow and SP1’s shard → compress → Groth16/Plonk. You can find more details here.
  1. Keep public inputs to a minimum
    • Remember, the gas cost for Groth16 increases with the number of public signals. Instead of directly exposing bulky inputs, try hashing or using Merkle-commit to combine them into a single field element. Then, you can verify membership within the zkVM without revealing too much to the verifier. (hackmd.io)

4. Choose Your Final SNARK by Deployment Target

  • Ethereum L1/L2 EVMs: If you're looking for the best option, BN254 Groth16 is your go-to choice. It offers the smallest proof size and the lowest gas costs. However, if you're not cool with trusted setup assumptions, go for Plonk on BN254. Just keep in mind that you might see around 10-30k more in gas and your proof size will be about 3-4 times larger than Groth16, but it’s still pretty tiny compared to a STARK. You can check out more details here.

5. Keep “control” and “business” code apart

  • Take a page from RISC Zero’s control-root strategy. This way, when it’s time for protocol upgrades, you won’t need a new ceremony, and you won’t risk breaking old proofs. Just remember to keep those key hashes and versioning transparent and on-chain. Check it out here: (dev.risczero.com)

6. Exploit EIP‑4844 for Data, Not Proofs

  • Go ahead and post bulk witness/state data to blobs and keep the actual proof as a small calldata payload for your verifier. Avoid trying to verify directly from the blob data. Also, keep an eye on EIP‑7623--if the calldata price goes up, it’ll make wrapping even more appealing. (blocknative.com)

7. Operationalize Proving

  • Take advantage of managed proving like Bonsai for RISC Zero or the SP1 prover network to keep latency and capex in check. Make sure to include retries and fallbacks--proofs can fail for pretty basic reasons like OOM errors or timeouts. Check it out for more details: dev.risczero.com.

Verification layers: an alternative to on‑chain pairings

A cool new option out there is to send your heavy proof to an off-chain verification layer that's often restaked and decentralized. You get a signed attestation back and can verify that on Ethereum for just a fraction of the usual gas fees. For example, Aligned Layer claims it costs around ~40k gas to verify a signature over the verification result. This is especially handy for proof systems like RISC0/SP1, which would be way too pricey to verify directly on the EVM.

Of course, there are some trade-offs to consider: you’re putting a bit more trust in the operator set and the EigenLayer security assumptions, plus there’s some extra latency and batching involved. But for high-frequency B2B attestations or cross-chain proof markets, this could be a game changer. Check it out for more info: (blog.alignedlayer.com)


Concrete scenarios and our recommendations

  • L2 rollup or zk light client settling on Ethereum L1

    • Wrap things up. Make sure your settlement proof uses Groth16/Plonk on BN254. Keep those public inputs nice and small; just push any extra data into blobs. If you’re already using STARKs internally (like Boojum, RISC0, or SP1), stick with that setup and just SNARK-wrap the final recursive receipt. (zksync.mirror.xyz)
  • Application-specific coprocessor (for oracle verification, signature batching, and AI inference attestation)

    • Make sure to wrap it, unless you're sending it to a verification layer. Gas predictability is key for user experience, so aim for around 250-300k per verification and keep your calldata under 1 kB. Check out more details here.
  • Cross‑chain deployments

    • It’s a good idea to go with Groth16 on BN254 when the destination can handle pairings. This opens up a lot of possibilities since many EVM chains and even Solana (thanks to BN254 precompiles) are great options. Plus, SP1 comes with verifiers for both! Check it out here.
  • Strict no-trusted-setup governance

    • Utilize STARK internally and layer it with Plonk instead of Groth16. This way, you'll save a good chunk compared to the traditional STARK verification on Ethereum, all while skipping the hassle of a per-circuit ceremony. (docs.succinct.xyz)
  • Handling a ton of proof inclusions (think thousands daily) while keeping gas costs low is super important.

    • It might be a good idea to look into an attested verification layer to help bring down gas fees to just a few tens of thousands for each inclusion. Plus, having an on-chain pairing verifier as a backup can really boost resilience. Check out more about this here.

Implementation blueprint (90‑day plan)

  • Weeks 1-2: Pick Your zkVM and Wrap Strategy

    • Start by choosing between RISC Zero or SP1 based on what programming language or runtime you’re comfortable with and the ecosystem you’re targeting. You’ll also need to decide if you want to go with Groth16 (which costs the least in gas) or Plonk (which has no per-circuit ceremony). Once that’s sorted, get your dockerized provers up and running along with the template EVM verifiers from the vendor repositories. Check out the details here.
  • Weeks 3-5: Gas and Calldata Modeling

    • It's time to get your public inputs prototyped so they fit within about 4-8 field elements; everything else should be hashed inside the guest. Make sure to benchmark the verification gas using your actual public inputs, aiming for around 230-300k gas. For more insights, take a look at this link.
  • Weeks 6-8: Hardening the Proving Pipeline

    • Now you're going to implement recursion joins (like RISC0 lift/join/identity_p254) or go for SP1 shard compression. Don’t forget to add retries, telemetry, and artifact signing. Your goal is to keep the end-to-end proof latency under 2-5 minutes using standard cloud services. You can read more about this here.
  • Weeks 9-10: Security Review

    • It’s audit time! Dive into your guest code and verifier contract; lock those verifying key hashes. Implement a system for allow-listed control program IDs (if you’re using RISC0) or pinned VK bytes for SP1. For more info, check out this link.
  • Weeks 11-13: Mainnet Dress Rehearsal

    • Let’s simulate some high-watermark batches, blob DA for data, and do a few on-chain verifications at your target gas prices. If it feels necessary, you might want to integrate a verification layer for hot-path scaling, but keep that direct pairing verification as your backup. For more details, visit this article.

A worked micro‑example: zk light client checkpoint

Goal: regularly post an L1 checkpoint that verifies N number of L2 blocks.

  • Proving

    • To get things rolling, we’ll use zkVM to check the L2 consensus and state transition for those N blocks, and then create a recursive STARK receipt.
    • After that, we’ll convert it to Groth16. We’re looking at a proof size of about 260 bytes, with public inputs like {root, epoch, vkey hash, nonce} making up roughly 4-6 elements. You can dive into the details here.
  • On-chain verification

    • The gas cost will be around 207,700 + 7,160 × 6, which brings us to approximately 250-260k; plus, with calldata sitting at about 260 bytes, that adds another ~4k gas. So, we’re looking at a total of around 255k gas. We’ll just update a mapping using root/epoch. For more insights, check out this link here.
  • Cost avoidance

    • Now, without the wrapping, a single STARK verification could hit the roof at around 3-6M gas and 100-200kB calldata--talk about a hefty price, especially on busy days! If calldata costs go up, it could spell disaster. You can read more about it here.

Key risks and how to mitigate

  • Ceremony risk (Groth16): It's smart to stick with well-audited ceremonies like Ignition. Keeping your keys public, adding some multi-party contributions, or just going with Plonk are solid options too. Check out this link for more details: (docs.succinct.xyz).
  • Quantum risk: Be aware of the short-term challenges and think about a migration strategy. For instance, you might want to rotate to a post-quantum final wrapper down the line. Also, keep an eye on the Ethereum precompile roadmap for alternative curves and commitments. More info can be found here: (dev.risczero.com).
  • Vendor lock-in: It's best to go for open-source zkVMs like RISC0 or SP1. Make sure to export proofs in standard formats and keep your verifier code lean, clean, and properly audited. Learn more here: (dev.risczero.com).

Bottom line for decision‑makers

On Ethereum in 2025, wrapping STARKs into a pairing-based SNARK is pretty much the go-to move for verifying things on-chain. You get to enjoy the same proving speed, transparency, and scalability that STARKs offer, and it only costs you a few hundred thousand gas to verify a proof between 260 and 900 bytes. Plus, you'll take advantage of the bn128 precompiles, which helps protect you from those pesky calldata pricing challenges. Unless you're going the off-chain route with a restaked verification layer or if you're working on a chain that has native STARK precompiles, wrapping is the way to go. (eips.ethereum.org)


Further reading and engineering references

  • RISC Zero's take on recursion and the STARK‑to‑SNARK framework; diving into the security model and control roots. (dev.risczero.com)
  • All about SP1 proof types, on-chain gas, and those handy verifier templates; plus, we’ll touch on off‑chain/WASM verification. (docs.succinct.xyz)
  • Let’s break down Ethereum precompiles and gas (EIP‑1108), along with the context around calldata/4844/7623. (eips.ethereum.org)
  • Check out zkSync Boojum and how it handles the explicit STARK→SNARK final step in EVM verification. (zksync.mirror.xyz)

If you're interested, 7Block Labs can kick off a 2-week feasibility sprint. We’ll set up a basic zkVM guest, provide both STARK and wrapped SNARK proofs, benchmark verifier gas using your actual public inputs, and give you a go/no-go decision memo that includes cost curves based on realistic gas and price scenarios.

Like what you're reading? Let's build together.

Get a free 30-minute consultation with our engineering team.

7BlockLabs

Full-stack blockchain product studio: DeFi, dApps, audits, integrations.

7Block Labs is a trading name of JAYANTH TECHNOLOGIES LIMITED.

Registered in England and Wales (Company No. 16589283).

Registered Office address: Office 13536, 182-184 High Street North, East Ham, London, E6 2JA.

© 2026 7BlockLabs. All rights reserved.