IGroth16Verifier
Title: IGroth16Verifier
Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from snarkjs (https://github.com/iden3/snarkjs)
External interface for a GENERIC Groth16 proof verifier over BN254 (alt_bn128). Unlike a snarkjs-generated verifier (which bakes one circuit's verifying key into bytecode), this takes the verifying key as a parameter, so a single deployed facet verifies proofs for ANY Groth16 circuit. The building block the ZK privacy modules (shielded transfers, membership, voting) plug their circuit's key into.
Verification is the standard Groth16 pairing check
e(-A, B) · e(alpha, beta) · e(vk_x, gamma) · e(C, delta) == 1, where
vk_x = IC[0] + Σ input[i]·IC[i+1], evaluated with the BN254 precompiles (0x06/0x07/0x08).
Public inputs are range-checked < SNARK_SCALAR_FIELD and proof coordinates < BASE_FIELD
(snarkjs PR#36 hardening) before the pairing.
G2 ENCODING: every G2 coordinate pair is given in PRECOMPILE order (c1, c0) — imaginary part
first, then real — matching snarkjs zkey export soliditycalldata output for the proof's b
and the EIP-197 pairing input. When building a VerifyingKey from a snarkjs vkey.json, swap
each G2 pair: e.g. beta.x = [vk_beta_2[0][1], vk_beta_2[0][0]].
KEY PINNING: the verifier does not authenticate vk; it checks the proof against whatever key
it is given. Whoever generates a key can know its trapdoor and forge a proof for any input,
so a consumer that forwards a caller-chosen key accepts every statement. Consumers MUST pin
the key: compile it in as constants, or fix keccak256(abi.encode(vk)) at deployment and
check it on every call. A key in writable storage is only as trustworthy as whoever can
write it, and the same holds for a verifier reached through a diamond whose cut authority
can replace this facet. See src/examples/privacy/ for both pinning patterns.
Functions
verifyProof
Verifies a Groth16 proof against vk for the given public input.
Returns false (does not revert) for an invalid proof, an out-of-range public input
(>= SNARK_SCALAR_FIELD), an off-curve / out-of-range proof point, or a failed pairing.
Reverts only on structural misuse (key/input arity mismatch).
function verifyProof(VerifyingKey calldata vk, Proof calldata proof, uint256[] calldata input)
external
view
returns (bool);Parameters
| Name | Type | Description |
|---|---|---|
| vk | VerifyingKey | The verifying key for the circuit. MUST be a key the consumer pins (see KEY PINNING above), never one taken from an untrusted caller. |
| proof | Proof | The Groth16 proof. |
| input | uint256[] | The public inputs, in the circuit's public-signal order. |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool | True iff the proof is valid for vk and input. |
Errors
Groth16InvalidVerifyingKey
Thrown when vk.ic.length != input.length + 1 (the key does not match the input arity).
error Groth16InvalidVerifyingKey();Structs
Proof
A Groth16 proof over BN254.
struct Proof {
uint256[2] a;
uint256[2][2] b;
uint256[2] c;
}Properties
| Name | Type | Description |
|---|---|---|
| a | uint256[2] | The G1 point A (x, y). |
| b | uint256[2][2] | The G2 point B, each coordinate pair in (c1, c0) precompile order. |
| c | uint256[2] | The G1 point C (x, y). |
VerifyingKey
A Groth16 verifying key over BN254.
struct VerifyingKey {
uint256[2] alpha;
uint256[2][2] beta;
uint256[2][2] gamma;
uint256[2][2] delta;
uint256[2][] ic;
}Properties
| Name | Type | Description |
|---|---|---|
| alpha | uint256[2] | The G1 point alpha_1. |
| beta | uint256[2][2] | The G2 point beta_2, in (c1, c0) order. |
| gamma | uint256[2][2] | The G2 point gamma_2, in (c1, c0) order. |
| delta | uint256[2][2] | The G2 point delta_2, in (c1, c0) order. |
| ic | uint256[2][] | The IC G1 points; length MUST equal publicInputs + 1. |