7Block Labs
Blockchain Technology

ByAUJay

I’m Designing a Bridge: Best Way to Aggregate Thousands of Plonk Proofs With BLS for One On-Chain Attest?

Summary: The fastest, cheapest way in 2026 to collapse thousands of PLONK proofs into a single on‑chain attestation on Ethereum is: verify proofs off‑chain, have a BLS12‑381 committee co‑sign one batch root, and verify that aggregate signature on‑chain using the Pectra-era BLS precompiles (EIP‑2537). For fully trustless settlement, combine this with periodic or continuous recursive aggregation (e.g., Halo2‑KZG/aPlonK) to produce a cryptographic super‑proof when latency allows. (eips.ethereum.org)


TL;DR for decision‑makers

  • If you need sub‑second to low‑seconds latency and you’re cost‑sensitive: use BLS aggregate signatures over a single batch message (FastAggregateVerify) and verify on‑chain via EIP‑2537. Typical gas: ≈103k for the pairing check plus small overhead if you store an aggregated public key. (eips.ethereum.org)
  • If you need hard, cryptographic finality with minimal trust in any committee: roll the proofs up off‑chain into one Halo2‑KZG/PLONKish aggregated proof and verify once on‑chain (≈350–420k gas per batch), optionally still gated by a BLS attestation to throttle inclusion. (docs.nebra.one)

Both approaches can be combined: BLS attestation for “fast path” settlement and periodic recursive aggregation for “final settlement.”


What changed since 2025 and why it matters

  • Ethereum Pectra (May 7, 2025) activated EIP‑2537: native BLS12‑381 precompiles. You now have seven EC/pairing ops at fixed addresses 0x0b–0x11, with pairing gas 37,700 + 32,600 × k (k = pairs). This makes on‑chain BLS aggregate signature verification practical on L1 and L2s that inherit Pectra. (blog.ethereum.org)
  • Cancun/Deneb (March 2024) added the KZG point‑evaluation precompile at 0x0a (exactly 50,000 gas) for blob commitments. You can bind a big batch manifest (hundreds of KB) to a transaction cheaply and refer to it in your attestation. (eips.ethereum.org)

Your design space: three viable aggregation patterns

  1. BLS-attested off‑chain verification (fastest, cheapest)
  • Each prover (or an aggregator) checks many PLONK proofs off‑chain.
  • A committee of N BLS signers signs one identical batch message M that commits to “all proofs in batch B verified.”
  • On‑chain, verify one aggregate signature via EIP‑2537 using FastAggregateVerify (k = 2 pairings). Gas for the pairing core ≈ 37,700 + 2 × 32,600 = 102,900 gas; store/update an aggregated public key to avoid summing pubkeys on‑chain. (eips.ethereum.org)
  • Security depends on your committee/incentives (e.g., restaked operators + slashing), not pure cryptography. Aligned Layer’s verification model is a production example of BLS‑attested off‑chain verification. (blog.alignedlayer.com)
  1. Cryptographic aggregation (trustless, higher latency)
  • Aggregate many proofs into one using PLONKish accumulation/recursion (e.g., Halo2‑KZG, aPlonK). On‑chain verify once (≈350k–420k gas per batch) and let claimants present cheap inclusion proofs. This yields ≈20k–50k amortized gas per included proof for batch sizes in the 32–1,000 range. (docs.nebra.one)
  • Prior art: SnarkPack for Groth16 (logarithmic verify), aPlonK for PLONK aggregation; production docs/measurements from Nebra UPA. (eprint.iacr.org)
  1. Hybrid (what we ship most)
  • Submit a BLS‑attested batch immediately to meet latency/SLOs, and roll a cryptographic super‑proof periodically (e.g., every X minutes/blocks) for “hard” finality and auditability. This hedges against committee failures with bounded economic risk.

The BLS‑first architecture that works today

Below is a concrete, production‑grade pattern tuned for Ethereum post‑Pectra and Pectra‑aligned L2s.

1) Choose the BLS ciphersuite and serialization

  • Use the IETF CFRG BLS12‑381 “minimal‑pubkey‑size, proof‑of‑possession” ciphersuite:
    BLS_SIG_BLS12381G2_XMD:SHA‑256_SSWU_RO_POP_ (pubkeys in G1, signatures in G2; 48‑byte pubkeys, 96‑byte signatures; PoP at registration prevents rogue‑key attacks). This matches Ethereum consensus practice and has mature tooling. (docs.rs)
  • Hash‑to‑curve per RFC 9380. On‑chain, you can do hash_to_field (SHA‑256) in EVM and use the MAP_FP2_TO_G2 precompile (0x11) to map to G2; or precompute off‑chain and pass uncompressed points. (ietf.org)

Encoding details (EIP‑2537 ABI):

  • G1 point: 128 bytes (x||y), G2 point: 256 bytes, big‑endian, uncompressed; infinity is all zeros. The pairing check costs 32,600 × k + 37,700 gas; mapping costs 5,500 (Fp→G1) / 23,800 (Fp2→G2). (eips.ethereum.org)

2) Register a committee with Proof‑of‑Possession

  • At setup, each signer submits:
    • pk_i (48‑byte compressed public key, expanded off‑chain to 128‑byte uncompressed G1 for precompile),
    • PoP_i over a fixed domain string to prevent rogue‑key attacks,
    • optional stake/bond to enable slashing.
  • Store either:
    • the whole validator set and maintain an “aggregated public key” AP = Σ pk_i in state, updated on churn events, or
    • a Merkle root of the committee and an on‑chain AP updated only when the set changes.
      This avoids adding O(N) G1 additions per verification. (G1ADD = 375 gas each if you ever need it.) (eips.ethereum.org)

3) Define the batch message M precisely

Use one identical message M for all signers (required for FastAggregateVerify). Make it self‑describing, resistant to replay across chains, and tied to the exact proofs you claim to have checked.

A robust byte layout:

M = keccak256(encode({
  version:     uint16,                      // protocol message version
  srcChainId:  uint64,
  dstChainId:  uint64,
  bridgeId:    bytes16,                     // contract identity
  batchIndex:  uint64,                      // monotonically increasing
  batchCount:  uint32,                      // number of proofs claimed
  vkRoot:      bytes32,                     // Merkle root of verifying keys used
  proofsRoot:  bytes32,                     // Merkle root of per-proof commitments
  blobHash:    bytes32,                     // OPTIONAL: EIP-4844 versioned-hash bound to manifest blob
  timeWindow:  uint64[2],                   // [notBefore, notAfter] seconds since epoch
  dstProgram:  bytes32,                     // what program/contract tuple is authorized to consume
  domainTag:   "7BLK-PLONK-BATCH-v1"        // DST for hash_to_curve per RFC 9380
}))

Notes:

  • proofsRoot commits to a per‑proof tuple, e.g., (proofId, vkHash, pubInputsHash).
  • blobHash, if present, binds a batch manifest in a blob (cheap DA); you can check the 0x0a point‑evaluation precompile or at least the versioned hash via the BLOBHASH opcode in the same transaction. (eips.ethereum.org)

4) Off‑chain workflow

  • Aggregator(s) collect proofs, verify each PLONK proof off‑chain (any flavor: PLONK, TurboPLONK, Halo2‑KZG, etc.), and build:
    • proofsRoot over proof descriptors,
    • vkRoot over registered verifying keys actually used,
    • optional 4844 blob carrying the manifest (proof descriptors, inclusion paths, etc.).
  • The BLS committee signs M. Aggregate signatures off‑chain into S = Σ sig_i, and compute AP if needed (or use stored AP).

Performance reference: production systems that BLS‑attest off‑chain checks report batches settling on‑chain for ≈350k gas including bookkeeping, with the BLS verification itself ≈100–120k gas. (blog.alignedlayer.com)

5) On‑chain verification function sketch (FastAggregateVerify)

  • Compute H = hash_to_field(M, domainTag), then MAP_FP2_TO_G2(H) to get H(M) in G2.
  • Call the pairing precompile once with k = 2 pairs:
    • Pair 1: (AP, H(M))
    • Pair 2: (−G1, S)
  • Accept iff e(AP, H(M)) · e(−G1, S) == 1.
    Gas for the pairing core: ≈102,900 gas; mapping adds ≈23,800 if done on‑chain; keccak/SHA‑256 adds a few thousand gas. (eips.ethereum.org)

Implementation facts you’ll care about:

  • EIP‑2537 performs subgroup checks in MSM/pairing. Don’t pass unvalidated additions into MSM; only store AP you computed from registered pubkeys. (eips.ethereum.org)
  • Use the IETF domain‑separation guidance from RFC 9380; tag includes protocol name and version. (ietf.org)

Gas and latency you can actually budget for

  • FastAggregateVerify on L1 with pre‑stored AP:
    • Pairing: 102,900 gas (k = 2).
    • Hash_to_field + map‑to‑curve: ~3k–5k + 23,800 gas if done on‑chain; many teams precompute H(M) off‑chain and pass the point directly.
    • Total verification path: ~110k–135k gas, plus event/storage if you store batch metadata. (eips.ethereum.org)
  • If instead you sum K pubkeys on‑chain, add ≈375 × (K−1) gas for G1ADD; hence the push to store AP in state. (eips.ethereum.org)
  • Cryptographic aggregation reference (Halo2‑KZG batch verify):
    • ≈350k gas to verify the aggregated proof + ~7–22k gas per included proof for bookkeeping/queries depending on your contract design; amortized ≈20k–50k gas per proof for reasonable N. (docs.nebra.one)
  • Blob linkage (optional): the 0x0a point‑evaluation precompile is a flat 50,000 gas per check. Use it if your bridge contract must verify a value from the blob on‑chain (e.g., a spot consistency check). (eips.ethereum.org)

Security and ops guardrails (don’t skip these)

  • Rogue‑key resistance: enforce Proof‑of‑Possession at key registration and re‑registration; reject keys without PoP. Use the POP ciphersuite. (datatracker.ietf.org)
  • Replay safety: include src/dst chain IDs, bridge contract ID, and a monotonically increasing batchIndex in M. Expire stale signatures with timeWindow.
  • Liveness/redundancy: at least 2 aggregators and an M‑of‑N committee. If you use restaking (e.g., AVSs), slash operators that sign invalid batches or miss deadlines. (blog.alignedlayer.com)
  • Anti‑censorship: optionally support both on‑chain and off‑chain proof submission paths. On‑chain submissions cost more but are harder to censor; this is how Nebra UPA balances economics with safety. (docs.nebra.one)
  • Blob hygiene: if you use blobHash, record the versioned hash and, if necessary, call the 0x0a precompile on critical values. Never assume application contracts can retrieve blob bytes; reference commitments instead. (eips.ethereum.org)
  • Upgradability: keep the verifier behind a timelock or point to an upgradeable verifier target so you can swap BN254↔BLS12‑381 paths without migrating all state. (7blocklabs.com)

Where PLONK‑level aggregation still shines

Even with cheap BLS:

  • Compliance/finality: Some counterparties require a cryptographic proof of inclusion/validity, not just a committee signature. Aggregated Halo2‑KZG or aPlonK proofs give you that with one on‑chain verify. (eprint.iacr.org)
  • Large‑N economics: At N in the thousands, amortized per‑proof costs via cryptographic aggregation drop below any signature‑per‑proof model, especially when end users need inclusion checks later (~16–22k gas each). (docs.nebra.one)
  • Multi‑system compatibility: SnarkPack can aggregate Groth16 proofs from heterogeneous producers; similar lines exist for PLONK variants. If your ecosystem is mixed, “universal” aggregation buys simplicity. (eprint.iacr.org)

A concrete example bridge plan (what we’d ship in 6–8 weeks)

  1. Committee + contracts
  • Deploy CommitteeRegistry with PoP‑verified BLS public keys and keep AP in state.
  • Deploy BridgeAttestor with verifyBatch(M, S) using EIP‑2537 precompiles; store batch roots and emit events. (eips.ethereum.org)
  1. Batch format
  • Each proof descriptor d_i = keccak256(vkHash_i || pubInputsHash_i || proofId_i).
  • proofsRoot = MerkleRoot(d_1…d_N).
  • Optionally embed the manifest in a blob; record blobHash in M. (eips.ethereum.org)
  1. Off‑chain
  • Aggregators verify all proofs, build the manifest, post a blob‑carrying tx, then solicit BLS signatures over the exact M.
  • Aggregate signatures S and submit once to BridgeAttestor.verifyBatch.
  1. Consumption path
  • Consumers on destination chain call isBatchValid(batchIndex) and present a Merkle path to d_i to claim.
  • For higher assurance windows, schedule a parallel recursive aggregation job every Y minutes; post the aggregated proof to an AggregatedVerifier contract. (docs.nebra.one)

Budget example:

  • N = 1,024 PLONK proofs
    • BLS verify once: ≈110–135k gas.
    • Each claimant’s inclusion check (Merkle path + small bookkeeping): typically 15–25k gas.
    • Optional aggregated super‑proof: ≈350–420k gas once per batch if/when produced. (docs.nebra.one)

PLONK‑specific tuning tips

  • Use SHPLONK‑style multi‑opening to minimize on‑chain verifier cost if you insist on direct PLONK verifies; otherwise keep everything off‑chain and just commit to vkRoot and proofsRoot. (hackmd.io)
  • If your stack already targets BLS12‑381 (KZG), Pectra removed the main obstacle to verifying BLS‑curve proofs natively on EVM. Re‑evaluate any legacy BN254 wrapping purely “for the precompiles.” (eips.ethereum.org)
  • For recursion, Halo2‑KZG with modern accumulation schemes and GPU provers can build 32‑way batches in a few seconds; plan batches around your arrival rate λ (N/λ is your fill time). (docs.snarkify.io)

When to pick which (quick rubric)

  • Latency SLO ≤ 5s and economic finality is fine: BLS attestation only.
  • Latency SLO 5–30s and auditors demand crypto proofs: BLS now, aggregate proof every 1–5 minutes.
  • High‑value bridge where courts or counterparties require mathematical finality per batch: aggregated proof every batch; optionally still use BLS for a fast pre‑attestation.

References you can hand to engineering and audit

  • EIP‑2537 (BLS12‑381 precompiles): addresses, ABIs, gas (pairing: 37,700 + 32,600·k; map precompiles 0x10/0x11). (eips.ethereum.org)
  • EIP‑4844 (KZG point‑evaluation precompile 0x0a, 50,000 gas): for blob‑bound manifests. (eips.ethereum.org)
  • Pectra mainnet activation (May 7, 2025; epoch 364032). (blog.ethereum.org)
  • IETF RFC 9380 (Hashing to Elliptic Curves) and CFRG BLS signature draft (ciphersuites incl. POP). (ietf.org)
  • PLONK/Groth16 aggregation: aPlonK and SnarkPack. (eprint.iacr.org)
  • Production aggregation economics and gas numbers (Nebra UPA; verification layers). (docs.nebra.one)

Bottom line

  • If your question is “what’s the best way to aggregate thousands of PLONK proofs into one on‑chain attest for a bridge”: do off‑chain verification + one BLS aggregate signature over a carefully designed batch root M, and verify it with EIP‑2537’s pairings. It’s fast, cheap, and now first‑class on Ethereum.
  • If you need stronger assurances (or want to compress per‑claim gas further), add a periodic Halo2‑KZG/aPlonK super‑proof. The hybrid gets you the latency of BLS and the cryptographic finality of ZK, with clean operational boundaries.

If you’d like, we can share a hardened Solidity snippet for FastAggregateVerify using the 0x0f pairing precompile, and a tested message encoder/hasher aligned with RFC 9380 and the POP ciphersuite, plus a batch manifest template that plugs into your bridge contracts. (eips.ethereum.org)


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

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

Related Posts

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.

© 2025 7BlockLabs. All rights reserved.