ByAUJay
How Does BLS Signature Aggregation Actually Reduce Gas Cost When Batching Groth16 Proofs on Ethereum?
Short Summary
Since Ethereum rolled out its Pectra upgrade on May 7, 2025, there's been a game-changing addition: the BLS12‑381 precompiles. This means you can swap out a bunch of those costly on-chain Groth16 verifications--those multiple BN254 pairings and the hefty calldata--with just a single BLS aggregate signature check on a Merkle root of proofs. The outcome? A dramatic drop in gas fees and calldata under the new EIP‑7623 pricing. Plus, there are clear design patterns to keep everything secure. Check it out for more details on the Ethereum blog.
TL;DR for decision‑makers
- When you're checking n Groth16 proofs on L1, you're looking at a hefty cost of around 45,000 + 34,000×(3n) gas just for the pairings (thanks to the BN254 precompile), which really eats up your budget. Even if you decide to batch-verify Groth16, the costs still rise with the number of pairings. On the flip side, using a BLS fast-aggregate signature (assuming you're using the same message) keeps it pretty steady at about ~102,900 gas for the pairing check and an additional ~23,800 gas to map the message to G2, no matter how many you have. (eips.ethereum.org)
- With EIP‑7623 bumping up calldata floor prices in Pectra, keeping payload sizes in check has become a bigger deal: consider swapping out O(n) Groth16 proof bytes for just one BLS signature along with a Merkle root. (eips.ethereum.org)
Why this changed in 2025
- Pectra just rolled out EIP‑2537 (those BLS12‑381 precompiles) and EIP‑7623 (which reprices calldata). Now, pairing on BLS12‑381 will set you back 32,600×k + 37,700 gas per call, where k represents the number of (G1, G2) pairs. Plus, these precompiles also provide mapping and MSM helpers to make aggregation way more efficient. Check it out here.
- As for the BN254 (alt_bn128) pairing precompile, that one still costs 34,000×k + 45,000 gas. This is the go-to for most L1 Groth16 verifiers out there today. The good news? BLS pairings are now a tad cheaper per pair and are built on a more robust curve. You can find more details here.
Baseline: what verifying Groth16 costs on L1
- So, when it comes to a Groth16 verification, technically, you only need 3 pairings. However, a lot of Solidity templates still use 4 pairings because of how the product equation is set up (like the snarkjs verifier template). This adds an unnecessary 34k gas to the mix. (docs.pantherprotocol.io)
- Let's break down the gas math (only considering pairing costs, using BN254 on 0x08):
Gas ≈ 45,000 + 34,000 × (3 to 4) = 147,000-181,000 per proof, before we even think about the elliptic curve additions/multiplications and calldata. (eips.ethereum.org) - Now for the calldata footprint for each Groth16 proof (again, using BN254): A∈G1 takes up 64 bytes, B∈G2 is 128 bytes, and C∈G1 is another 64 bytes, which adds up to about 256 bytes. And that's not even counting the public inputs. If we switch to BLS12‑381, the sizes get larger (G1=128 bytes, G2=256 bytes according to the EIP‑2537 uncompressed ABI), but remember--we're not planning to send individual proofs on-chain. (eips.ethereum.org)
On‑chain batch verification of Groth16 helps, but still scales with n
When you keep verification on-chain and utilize the standard random-linear-combination trick, you can verify n Groth16 proofs with around n+2 pairings (instead of the usual 3n), along with some MSMs and field operations. That’s definitely an improvement, but it’s still linear in n. Plus, you'll need to make sure the randomness is generated in a way that prevents the aggregator from influencing it. (fractalyze.gitbook.io)
- Example: n=20.
When you batch verify pairings, you're looking at about 45,000 + 34,000×(22) = 793,000 gas just for the pairings. Don't forget, you’ll still need to handle MSMs and carry O(n) calldata. If your proofs are using BN254, your calldata will be around 20 × 256 B = 5,120 B. This is getting pretty pricey with EIP‑7623’s new higher threshold for data-heavy transactions. (eips.ethereum.org)
The BLS aggregation pivot: verify attestations, not every proof
Instead of checking each Groth16 proof one by one, why not let a group of verifiers handle the proofs off-chain? They can BLS-sign a single message that represents the Merkle root of all the (proof, public input) pairs. You only need to submit that root once, along with a single aggregate signature. When it comes to the on-chain part, you just verify the BLS aggregate signature and, if you want, you can also store or emit the root. This approach really lightens the load on-chain, shifting from “a bunch of BN254 pairings and hefty calldata” to just “one BLS signature check and a tiny bit of calldata.” Check it out here: (eips.ethereum.org).
What Makes This Cheap Now:
- Market Fluctuations: Prices can drop due to changes in supply and demand. When there’s an oversupply, you’ll often see prices take a hit.
- Seasonal Sales: Retailers frequently clear out inventory to make way for new products, leading to discounts and sales events.
- End of Product Life Cycle: When companies release new versions of products, older models often get significant price cuts.
- Economic Factors: Economic downturns, inflation, and other financial factors can lead to reduced prices as sellers try to attract buyers.
- Competitive Pricing: If competitors lower their prices, businesses might follow suit to keep their customer base.
- Clearance Events: Stores often hold clearance sales to get rid of stock that’s taking up space. This can lead to some serious bargains.
- Coupons and Discounts: Keep an eye out for special offers, coupons, or promo codes that can make items way cheaper.
- Second-Hand Goods: Buying used items can save you a ton of cash, especially if they’re in good condition.
So, if you're looking for bargains, these are the reasons why you might find some sweet deals right now!
- The BLS fast-aggregate verify (where all signers are signing the same message) only needs 2 pairings, no matter how many signers you have. With EIP-2537, you're looking at around 37,700 + 32,600×2 = 102,900 gas just for the pairing check. On top of that, you’ll spend about 23,800 gas to map the message to G2, plus a few hundred more for G1 operations if you’re aggregating pubkeys on-chain. So, all in all, it’s about ~125-135k gas for the whole process. (eips.ethereum.org)
- When it comes to calldata, it’s pretty compact: you’ve got one G2 signature (which is 256 B in EIP-2537 encoding), one G1 aggregate pubkey if you’re not storing it (that’s 128 B), and the 32-byte Merkle root. You’ve also ditched O(n) Groth16 proof bytes completely from the transaction calldata, which is super important now that EIP-7623 is in play. (eips.ethereum.org)
Security notes that make this robust:
- Strong Passwords: Always use complex passwords that mix letters, numbers, and special characters. A passphrase can be even better--think of a little sentence that's easy for you to remember but tough for others to guess.
- Two-Factor Authentication (2FA): Enable 2FA wherever it’s available. This adds an extra layer of security beyond just your password, making it way harder for unauthorized folks to get in.
- Regular Software Updates: Keep your software and apps up-to-date. Developers release patches to fix vulnerabilities, so staying current can help protect you from the latest threats.
- Firewalls and Antivirus Software: Use a good firewall and reliable antivirus programs. They act as your first line of defense against malware and other nasty stuff.
- Data Encryption: Encrypt sensitive data, especially if you're storing or transmitting it online. This way, even if someone intercepts your files, they won't be able to read them easily.
- Backup Your Data: Regular backups are a lifesaver. Whether it’s cloud-based or an external hard drive, having copies of your important files means you won’t lose everything if something goes wrong.
- Educate Yourself and Your Team: Stay informed about the latest security threats. Whether you’re a solo user or working with a team, knowing what to look out for (like phishing scams) is super important.
- Access Controls: Implement proper access controls to limit who can view or edit sensitive information. Not everyone needs access to everything, so keep it tight!
- Monitor Your Accounts: Keep an eye on your accounts regularly. If you notice anything suspicious, like unauthorized transactions, jump on it right away.
By following these tips, you can build a solid security stance that keeps your data safe and sound!
- To keep rogue-key attacks at bay, go with the IETF BLS “FastAggregateVerify” and include a proof-of-possession (POP). You can either get committee keys pre-registered on the blockchain or make sure to require POPs during the setup phase. Check out the details here.
- When it comes to hashing to a curve, stick to the guidelines in RFC 9380 and the ABI from EIP-2537. For MinPk (which means having public keys in G1 and signatures in G2--think Ethereum consensus), you should implement
hash_to_fieldaccording to RFC 9380 and then call the0x11 map-to-G2precompile, which will set you back about 23,800 gas. More info is available here.
Concrete gas: side‑by‑side
Assume BN254 Groth16 proofs with n set to 20:
- Individual Groth16 verifies on chain (4 pairings template):
We're looking at about 45,000 gas for the base setup plus 34,000 times 80 for the pairings, which brings us to roughly 2,765,000 gas just for those pairings--don't forget to tack on the EC operations and calldata as well. You can find more about it here. - Batch Groth16 on chain (n+2 pairings):
For the batch approach, it starts at 45,000 gas plus 34,000 times 22 for the pairings, so that totals around 793,000 gas just for that part. On top of that, factor in the MSMs and you'll need about 5,120 B of calldata for the proofs. Check it out here. - BLS aggregate attestation (same message):
When it comes to pairings, we’re looking at 37,700 gas plus 32,600 times 2, giving us 102,900 gas overall. Don’t forget about the mapping to G2, which adds another 23,800 gas, bringing the total to about 126,700 gas (plus a little fixed overhead). On the calldata side, expect 256 B for the signature, 128 B for the agg‑pubkey (or nothing if it's stored), and 32 B for the root. More details can be found here.
Even if your on-chain Groth16 verifier is pretty tight (with just 3 pairings) and you’ve got those public inputs compressed, going the BLS route can still give you a solid 5-15× boost for moderate n. Plus, as your batch size increases, this advantage grows because the cost stays pretty constant. Check it out here!
Architecture pattern we see winning in production
- Off-chain aggregation service (or decentralized committee):
- Inputs: n Groth16 proofs and public inputs.
- Steps:
- Start by verifying each Groth16 proof off-chain using a standard library like arkworks/gnark. You can check it out here.
- Next, create a Merkle tree from the canonicalized (proof_commitment, public_inputs_hash) leaves to get the Merkle root R.
- Then, each committee member needs to BLS-sign the concatenated string of domain_sep || chain_id || contract_addr || R || batch_metadata. Don’t forget to aggregate all the signatures! For more info, you can visit this link.
On-chain Contract:
An on-chain contract is a type of smart contract that’s fully executed and enforced on the blockchain. Unlike traditional contracts, which might require a third party to oversee compliance, these contracts run automatically, ensuring that every term is honored as soon as the conditions are met.
Key Features:
- Transparency: Since everything happens on the blockchain, anyone can see the contract and its execution history. This level of openness helps build trust among parties.
- Security: On-chain contracts are safeguarded by cryptographic techniques, making them resistant to tampering and fraud.
- Automation: These contracts self-execute without needing intermediaries, which can save time and reduce costs.
How they Work:
- Creation: A developer writes the contract code and uploads it to the blockchain.
- Deployment: Once on the blockchain, it becomes part of the network and can start interacting with other contracts or accounts.
- Execution: When the agreed-upon conditions are met, the contract automatically executes, transferring assets or triggering actions as specified.
Use Cases:
- Decentralized Finance (DeFi): On-chain contracts are the backbone of protocols allowing users to lend, borrow, and trade assets without a central authority.
- Supply Chain Management: They can track goods and verify conditions (like temperature or location) throughout the supply chain.
- Digital Identity: Smart contracts can manage and validate identities on blockchain platforms, ensuring data privacy and security.
Conclusion:
On-chain contracts are revolutionizing the way we think about agreements in the digital world, offering a reliable, efficient, and transparent alternative to traditional contracts. If you're curious to dive deeper into smart contracts and their applications, check out this great resource.
- Keeps track of the committee's public keys and their aggregate (G1).
- Checks the AggregateSignature on R using one 0x0f call with k=2 pairs (this is the fast-aggregate verify method).
- Either outputs or saves R; optionally, it posts a small index for future per-item inclusion proofs (Merkle proofs provided by users). (eips.ethereum.org)
Why This Aligns with 2025+ Ethereum:
When we think about the future of Ethereum beyond 2025, several key aspects come into play that make this alignment crucial:
- Scalability: Ethereum is constantly working to improve its transaction speed and capacity. The shift from Proof of Work to Proof of Stake is just the beginning. By 2025 and beyond, we can expect even more upgrades that will enhance the network’s scalability, allowing it to handle thousands of transactions per second.
- Sustainability: With environmental concerns on the rise, Ethereum’s commitment to sustainability is a big deal. The transition to Proof of Stake drastically reduces energy consumption, and future developments will likely focus on making the network even more eco-friendly.
- Interoperability: As the blockchain ecosystem expands, Ethereum aims to work seamlessly with other chains. The goal is to create a truly interconnected web of decentralized applications. In 2025, we can expect more bridges and collaborations that enhance user experiences across different platforms.
- Security: Security is always a priority. As Ethereum rolls out its upgrades, they’ll be focusing on making the network safer from hacks and vulnerabilities. You can count on robust mechanisms to protect user assets and data.
- Decentralized Finance (DeFi) and NFTs: Ethereum has pioneered the DeFi and NFT spaces. By 2025, these sectors will likely be even more mature, with greater innovations and a wider user base, further cementing Ethereum’s place as a leader in these markets.
- Community and Governance: The Ethereum community is one of its strongest assets. The future will see even more involvement from users in governance and decision-making, making the network more democratic and responsive to its members.
In short, as we look ahead to 2025 and beyond, Ethereum's roadmap aligns perfectly with these evolving trends and needs. It’s all about creating a more efficient, secure, and user-friendly blockchain experience for everyone.
- EIP‑7623 has bumped up the costs for calldata, but no worries--this pattern is designed to use minimal calldata right from the start. (eips.ethereum.org)
- When you attach proof batches to the 4844 blobs, your data availability (DA) is now priced in blob gas and gets verified by the 0x0a point-evaluation precompile. Meanwhile, your correctness attestation still relies on that same old BLS signature check. (eips.ethereum.org)
Implementation details that save real gas
- Curve and Precompiles: You’ll want to use EIP‑2537 addresses from 0x0b to 0x11; pairings are found at 0x0f, and map_to_G2 lives at 0x11. Just a heads up, encodings are big-endian and uncompressed: G1 is 128 bytes, while G2 is 256 bytes. The infinity point is represented by all zeros. To dodge any endianness hiccups, build your calldata using
abi.encodePacked. (eips.ethereum.org) - Ciphersuite: Stick with the Ethereum/IRTF ciphersuites and the POP flow. If you’re going for “FastAggregateVerify,” make sure your keys are POP-validated. (ietf.org)
- Hash-to-Curve: You should implement the RFC 9380 hash_to_field in Solidity and call 0x11 to map Fp2 to G2 (this will cost about 23,800 gas). If you trust the source, doing byte-to-field operations off-chain and passing those field elements is totally fine; the precompile will enforce subgroup checks. (ietf.org)
- Aggregate Public Key Storage: Keep the aggregate public key in contract storage. Recomputing it on every call with G1ADD or MSM is not too expensive but can be avoided. If you need to compute aggregates on-chain, the precompile offers G1MSM/G2MSM with some discounts. (eips.ethereum.org)
- Gas Constants: Treat gas constants as specific to the chain you’re targeting. Avoid hardcoding EIP‑1108 pairing gas if you’re aiming for multiple EVM chains--many of them have taken different paths. (infsec.io)
What about using BLS for the proofs themselves?
You’ve got two choices right next to each other:
- Stick with Groth16 on BN254 and use BLS for attestation (as mentioned above). This is the least disruptive option if you’re already set up with BN254 in your circuits and tools.
- If you're feeling a bit adventurous, consider shifting the Groth16 system to BLS12‑381 (good news--gnark has your back on this!) and handle verification on-chain using the BLS precompile. Just a heads up: running three pairings on BLS12‑381 will set you back about 37,700 + 32,600×3 = 135,500 gas. It's a bit cheaper per verification than BN254 and offers better security. Just keep in mind that you’ll still be looking at O(n) in pairings for n proofs. But on the bright side, BLS aggregation shines when you scale up. Check out the details here!
Numbers you can plan around (post‑Pectra L1)
- BN254 pairing (0x08): This one costs you about 34,000×k + 45,000 gas. Just so you know, a typical Groth16 template usually needs 4 pairings. (eips.ethereum.org)
- BLS12‑381 pairing (0x0f): This comes in at 32,600×k + 37,700 gas. If you're looking into fast-aggregate verification, that’s k=2. For distinct-message aggregate verification, it's k = n+1. (eips.ethereum.org)
- Map Fp2→G2 (0x11): This mapping will set you back 23,800 gas. On the other hand, mapping Fp→G1 (0x10) is a bit friendlier at 5,500 gas. (eips.ethereum.org)
- EIP‑7623 calldata repricing: This update bumps the minimum cost to 10/40 gas per byte for those data-heavy transactions, which is a rise from 4/16. It’s an extra nudge against those O(n)-size proof payloads. (eips.ethereum.org)
Worked example: 100‑proof batch
- When it comes to pure on-chain Groth16 with 4 pairings: for k = 400, we’re looking at about 45,000 gas plus 34,000 multiplied by 400, which totals around 13,645,000 gas just for the pairings. Oh, and don’t forget the proof calldata, which is roughly 25.6 KB. That’s way above what we usually see for a transaction and is pushing up against the block gas limit. (eips.ethereum.org)
- For Groth16 batch verification with (n+2 pairings): if k = 102, you’re looking at 45,000 gas plus 34,000 times 102, leading to about 3,513,000 gas for the pairings, along with MSMs and around 25.6 KB of calldata. (fractalyze.gitbook.io)
- Now, for BLS aggregate fast verification with k=2: that involves 102,900 gas for pairings and an additional 23,800 gas for the mapping, bringing the total to approximately 126,700 gas. For calldata, we've got a 256 B signature, a 32 B root, and optionally a 128 B aggregation public key (or none if it's stored elsewhere). (eips.ethereum.org)
Result: Over 25 times cheaper on pairings and around 100 times smaller calldata when n=100, and the costs remain steady as n increases.
Security and correctness tips (don’t skip)
- Randomness in Groth16 batch verification: When you're doing on-chain batch verification, make sure to pull your randomness, r_i, from something that the submitter can't precompute. A good way to do this is by using something like
keccak(commitment||block.prevrandao)right in the same transaction. This trick helps you dodge the whole batch-forgery mess. Check out the details on ethresear.ch. - POPs for BLS aggregation: It’s essential to require Proofs of Possession (POPs) upfront on your committee keys. The “FastAggregateVerify” function just assumes the keys are POP-validated. If they're not, it opens the door to some pretty easy rogue-key attacks. Want to learn more? Head over to ietf.org.
- Encoding fidelity: EIP-2537 has some strict rules about encoding. It specifies that you should use big-endian and uncompressed coordinates where infinity is represented as all zeros. Make sure you’re feeding in exactly 128 bytes for G1, 256 bytes for G2, and 384 bytes per pairing pair. If you get any malformed input, it should fail gracefully. More info can be found on eips.ethereum.org.
When not to use BLS aggregation
- If your trust model needs L1 to cryptographically check every proof without relying on an attesting committee, you’ll need to verify Groth16 on-chain (and you might even look into using a recursive SNARK to pack multiple proofs into one). Tools like SnarkPack and recursive constructions can help lighten the load for verifiers, but keep in mind that they can also add some overhead for provers. Use these when the balance between trust and user experience calls for solid on-chain proof reliability. (research.protocol.ai)
Emerging best practices we recommend
- Go with BLS MinPk (where you’ve got pubkeys in G1 and signatures in G2) paired with POP--this is the same setup Ethereum uses for its consensus, which means you can lean on those nice, well-audited libraries and mental models. Check it out here.
- For domain separation, make sure to tag your batch attestation message with versioned domains (think BATCH_ATTESTATION_V1|chainid|contract|R) and use the RFC‑9380 hash_to_curve with those explicit DSTs. You can find more info here.
- Store committee keys and their aggregate just once, and only rotate them during governance events. Keep that ‘fast path’ call simple: verify the aggregate sig → update/emit the batch root. You can read more on this here.
- If you’re also posting data to blobs (thanks to EIP‑4844), make sure to validate them using the 0x0a point‑evaluation precompile, and keep your correctness attestation on BLS. This way, you keep both data availability and correctness low-cost and straightforward. More details on this are available here.
- Just a heads up: don’t assume gas constants will be the same across chains. If you’re deploying to multiple EVMs, grab those chain-specific precompile prices or leave a little buffer--some rollups don’t stick to EIP‑1108’s schedule. Dive deeper into this topic here.
Bottom line
With EIP‑2537 in action, the best way to save costs while "batching Groth16 proofs" on Ethereum L1 isn’t by cramming more pairings onto the chain. Instead, it’s all about verifying them off-chain and then using a BLS aggregate signature on a Merkle root to attest everything at once. This shifts the complexity from O(n) pairings and hefty calldata down to an almost constant ~130k gas and just a handful of bytes. When you pair this approach with EIP‑7623’s calldata repricing and 4844 blobs, you’ve got a smart way to scale zk-heavy applications on the mainnet without skimping on security. (blog.ethereum.org)
References and specs cited
- EIP‑1108 (gas repricing for BN254 precompile), along with EIP‑196/197 (BN254 precompiles). Check it out here.
- Got some insights on EIP‑2537 (BLS12‑381 precompiles; gas schedule, encodings, mapping). More details can be found here.
- Big news: the Pectra mainnet announcement is out, bringing along an EIP set and an activation date! Plus, don’t miss EIP‑7623 (calldata repricing). You can read more about it here.
- If you’re into BLS signatures, check out the IETF draft that covers fast/aggregate verification and Proof of Possession (POP). Dive into the details here.
- There’s been some chatter about batch verification of Groth16 and the caveats that come with it. Here’s where you can learn more here.
- For those working on tooling, don’t miss arkworks/circom‑compat and gnark curves. Check out the repository on GitHub.
- And just a heads up on some gotchas: be mindful of chain‑specific precompile pricing. Get the lowdown here.
Like what you're reading? Let's build together.
Get a free 30-minute consultation with our engineering team.
Related Posts
ByAUJay
Building 'Private Social Networks' with Onchain Keys
Creating Private Social Networks with Onchain Keys
ByAUJay
Tokenizing Intellectual Property for AI Models: A Simple Guide
## How to Tokenize “Intellectual Property” for AI Models ### Summary: A lot of AI teams struggle to show what their models have been trained on or what licenses they comply with. With the EU AI Act set to kick in by 2026 and new publisher standards like RSL 1.0 making things more transparent, it's becoming more crucial than ever to get this right.
ByAUJay
Creating 'Meme-Utility' Hybrids on Solana: A Simple Guide
## How to Create “Meme‑Utility” Hybrids on Solana Dive into this handy guide on how to blend Solana’s Token‑2022 extensions, Actions/Blinks, Jito bundles, and ZK compression. We’ll show you how to launch a meme coin that’s not just fun but also packs a punch with real utility, slashes distribution costs, and gets you a solid go-to-market strategy.

