Groth16 on BN254
This section provides a technical deep dive into the proof system that underpins all zero-knowledge operations in Specter: Groth16 over the BN254 elliptic curve.
The BN254 Curve
Specter's ZK proofs operate over BN254 (also known as alt_bn128 or bn256), a Barreto-Naehrig pairing-friendly elliptic curve. BN254 is the de facto standard for on-chain ZK verification because Ethereum provides native precompiled contracts for its operations.
| Parameter | Value |
|---|---|
| Curve equation | |
| Base field prime | |
| Scalar field prime | |
| Field size | 254 bits |
| Security level | ~100-128 bits (see note below) |
| Embedding degree | 12 |
| Pairing type | Optimal Ate pairing |
BN254 defines two groups used in Groth16 proofs:
- : points on the curve over the base field . Elements are 64 bytes (two 256-bit coordinates).
- : points on a degree-2 twist of the curve over . Elements are 128 bytes (four 256-bit coordinates).
- : the target group of the pairing, a subgroup of .
The Number Field Sieve attacks against BN curves have improved over the years, and BN254's concrete security is estimated at ~100-110 bits rather than the originally claimed 128 bits. This remains sufficient for Specter's threat model. A future curve migration (e.g., to BLS12-381 at ~120 bits) is possible without changing the circuit logic, only the trusted setup and verification contract.
Groth16 Proof Structure
A Groth16 proof consists of exactly three group elements:
where:
| Element | Group | Size | Description |
|---|---|---|---|
| 64 bytes | Encodes the prover's commitment to the witness | ||
| 128 bytes | Encodes the verification challenge | ||
| 64 bytes | Encodes the prover's response |
Total proof size: 256 bytes uncompressed, ~128 bytes compressed (using point compression on and ). This is the smallest proof size of any deployed ZK proof system.
The proof size is constant — it does not grow with the number of constraints in the circuit. Whether the circuit has 1,000 constraints or 1,000,000 constraints, the proof is always three group elements.
Verification Equation
The core of Groth16 verification is a single pairing equation. Given a proof , public inputs , and verification key parameters , the verifier checks:
where is the bilinear pairing.
Breaking this down:
| Term | Purpose |
|---|---|
| The prover's claim | |
| A constant from the verification key (precomputed) | |
| Linear combination of public inputs with the verification key's IC (input commitments) points | |
| Binds the proof to the circuit-specific setup |
The verifier performs:
- scalar multiplications in to compute
- 3 pairing evaluations (or 4, with if not precomputed)
- 1 equality check in
For Specter's Redemption Circuit (), this means 9 scalar multiplications and 3-4 pairings. For the Access Proof Circuit (), it is 5 scalar multiplications and 3-4 pairings. Both complete in constant time regardless of circuit complexity.
On-Chain Verification
Specter verifies Groth16 proofs on-chain using Ethereum's precompiled contracts for BN254 operations. These precompiles are available at fixed addresses and provide gas-efficient implementations of the curve arithmetic:
| Address | Precompile | Operation | Gas Cost |
|---|---|---|---|
0x06 | ecAdd | Point addition in | 150 gas |
0x07 | ecMul | Scalar multiplication in | 6,000 gas |
0x08 | ecPairing | Bilinear pairing check | 34,000 + 45,000 per pair |
The verification flow on-chain:
Gas Cost Breakdown
For the Redemption Circuit (8 public inputs):
| Operation | Count | Per-Op Gas | Total Gas |
|---|---|---|---|
ecMul (IC computation) | 9 | 6,000 | 54,000 |
ecAdd (IC accumulation) | 8 | 150 | 1,200 |
ecPairing (base) | 1 | 34,000 | 34,000 |
ecPairing (per pair) | 4 | 45,000 | 180,000 |
| Calldata + overhead | — | — | ~30,000 |
| Total | ~200,000 gas |
At typical gas prices, this makes on-chain ZK verification affordable for every commit/reveal operation. The cost scales linearly only with the number of public inputs (which is fixed per circuit), not with the circuit's internal complexity.
Why Not PLONK or STARKs?
PLONK
PLONK offers a universal trusted setup — one ceremony works for all circuits. This is appealing for general-purpose ZK platforms, but Specter has a fixed set of circuits (Redemption + Access Proof) that change infrequently. The universal setup advantage is less relevant when you only need to run a ceremony once or twice.
PLONK proofs are ~3-4x larger than Groth16 proofs and verification requires more group operations, translating to higher gas costs. For a protocol that verifies proofs on every reveal, this matters.
STARKs
STARKs require no trusted setup and are post-quantum secure. However, STARK proofs are orders of magnitude larger (50-200 KB vs. 128 bytes) and verification is significantly more expensive on-chain. The absence of EVM precompiles for STARK-friendly hash functions means verification requires custom Solidity logic, further increasing gas costs.
Specter addresses the trusted setup concern through a rigorous multi-party computation ceremony and quantum defense-in-depth (see Trusted Setup). For the specific requirements of on-chain data privacy — small proofs, fast verification, low gas — Groth16 on BN254 remains the optimal choice.
Summary
| Criteria | Groth16 | PLONK | STARKs |
|---|---|---|---|
| Proof size | ~128 B | ~400-500 B | ~50-200 KB |
| Verification gas | ~200K | ~300-500K | ~1-2M |
| Trusted setup | Per-circuit | Universal | None |
| Post-quantum | No | No | Yes |
| EVM precompile support | Native | Partial | None |
| Best for Specter? | Yes | No | No |