Skip to content
Lattice

IPlonkVerifier

Git Source

Title: IPlonkVerifier

Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from snarkjs (https://github.com/iden3/snarkjs)

External interface for a GENERIC PLONK 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 PLONK circuit. A reusable verifier primitive for the ZK privacy modules and consumers who bring PLONK circuits.

Verification follows the snarkjs (iden3) PLONK protocol (eprint 2019/953): Fiat-Shamir challenges via a keccak256 transcript, Lagrange/vanishing evaluation at xi, then the batched KZG pairing check e(-A1, X_2) · e(B1, [1]_2) == 1. Public inputs are range-checked &lt; SNARK_SCALAR_FIELD and proof coordinates &lt; BASE_FIELD.

G2 ENCODING: the X_2 coordinate pairs are given in PRECOMPILE order (c1, c0) — imaginary first, then real. When building from a snarkjs vkey.json, swap each pair: x2[0] = [X_2[0][1], X_2[0][0]]. G1 points use affine (x, y); the point at infinity is (0, 0).

KEY PINNING: the verifier does not authenticate vk; it checks the proof against whatever key it is given. Its well-formedness check (domain size, on-curve points) is structural, and a malicious key passes it. 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 (shown for Groth16).

Functions

verifyProof

Verifies a PLONK 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 on structural misuse (empty input) or a failed ecMul/ecAdd/modexp precompile call.

function verifyProof(VerifyingKey calldata vk, Proof calldata proof, uint256[] calldata input)
        external
        view
        returns (bool);

Parameters

NameTypeDescription
vkVerifyingKeyThe verifying key for the circuit. MUST be a key the consumer pins (see KEY PINNING
above), never one taken from an untrusted caller.
proofProofThe PLONK proof.
inputuint256[]The public inputs, in the circuit's public-signal order.

Returns

NameTypeDescription
<none>boolTrue iff the proof is valid for vk and input.

Errors

PlonkInvalidInputs

Thrown when the number of public inputs is zero or does not match the circuit.

error PlonkInvalidInputs();

PlonkPrecompileFailed

Thrown when an ecMul (0x07), ecAdd (0x06) or modexp (0x05) precompile call fails.

error PlonkPrecompileFailed(address precompile);

Parameters

NameTypeDescription
precompileaddressThe address of the failing precompile.

Structs

Proof

A PLONK proof over BN254 (snarkjs field order).

struct Proof {
        uint256[2] a;
        uint256[2] b;
        uint256[2] c;
        uint256[2] z;
        uint256[2] t1;
        uint256[2] t2;
        uint256[2] t3;
        uint256[2] wxi;
        uint256[2] wxiw;
        uint256 eval_a;
        uint256 eval_b;
        uint256 eval_c;
        uint256 eval_s1;
        uint256 eval_s2;
        uint256 eval_zw;
    }

Properties

NameTypeDescription
auint256[2]
buint256[2]
cuint256[2]
zuint256[2]
t1uint256[2]
t2uint256[2]
t3uint256[2]
wxiuint256[2]
wxiwuint256[2]
eval_auint256
eval_buint256
eval_cuint256
eval_s1uint256
eval_s2uint256
eval_zwuint256

VerifyingKey

A PLONK verifying key over BN254.

power is the log2 of the domain size (n = 2**power); omega is the n-th root of unity Fr.w[power]. x2 is the SRS element [x]_2 in (c1, c0) order.

struct VerifyingKey {
        uint256[2] qm;
        uint256[2] ql;
        uint256[2] qr;
        uint256[2] qo;
        uint256[2] qc;
        uint256[2] s1;
        uint256[2] s2;
        uint256[2] s3;
        uint256 k1;
        uint256 k2;
        uint256 power;
        uint256 omega;
        uint256[2][2] x2;
    }

Properties

NameTypeDescription
qmuint256[2]
qluint256[2]
qruint256[2]
qouint256[2]
qcuint256[2]
s1uint256[2]
s2uint256[2]
s3uint256[2]
k1uint256
k2uint256
poweruint256
omegauint256
x2uint256[2][2]