Groth16 Verifier
settlementGroth16Pallet
Statement hash components
 context:
keccak256(b"groth16")
 vk:
keccak256(vk.encode())
 pubs:
keccak256(pubs)
where pubs are the concatenated scalars bytes
The submitProof
extrinsic can be used to verify Groth16 proofs.
Verifier
implementation
This verifier leverages the arkworks arkgroth16
library for proof verification.
The notation and serialization of the fields which make up the proof and verification keys also closely mirror the ones of that library.
Therefore, if your proofs and verification keys are generated using arkgroth16
, integrating with this pallet should be straightforward.
Instead, if your proofs and verification keys are generated using snarkJS
, the snarkjs2zkv
cli utility is available for performing the conversion.
If your proofs and verification keys are generated with other tools, the encodings section describes in detail the encoding of the various arguments.

verify_proof()
deserialize the proof and public inputs and then verify them against the given verification key. 
Define the following types:
pub enum Curve {
Bn254,
Bls12_381,
}
pub struct G1(pub Vec<u8>); // 64 bytes for Bn256 and 96 for Bls12381
pub struct G2(pub Vec<u8>); // 128 bytes for Bn256 and 192 for Bls12381
pub struct Scalar(pub Vec<u8>); // 32 bytes
pub struct ProofInner {
pub a: G1,
pub b: G2,
pub c: G1,
}
pub struct Vk {
pub curve: Curve,
pub alpha_g1: G1,
pub beta_g2: G2,
pub gamma_g2: G2,
pub delta_g2: G2,
pub gamma_abc_g1: Vec<G1>,
}
pub struct Proof {
pub curve: Curve,
pub proof: ProofInner,
}
pub type Pubs = Vec<Scalar>; 
hash context data is
b"groth16"

pubs_bytes()
are the concatenated scalars bytespubs.iter()
.flat_map(s s.0.iter().cloned())
.collect::<Vec<_>>() 
validate_vk
check the fields value and curve points
Encodings
The Proof
, verification key Vk
, and public inputs Pubs
are composed of cryptographic primitives, namely elliptic curve points (belonging to either G1
or G2
) and Scalars
.

Elliptic curve points are represented in an uncompressed form, as the concatenation of the encoding of the
x
andy
affine coordinates. An element of the base field of the BN254 curve can be represented with 32 bytes, therefore the affine representation of a BN254 G1 point requires
2 * 32 = 64
bytes. Instead, sinceG2
is an extension field of degree 2, the affine representation of a BN254G2
point requires double the space, namely128
bytes.  An element of the base field of the BLS12381 curve can be represented with
48
bytes. Therefore, the encoding of a BLS12381G1
point requires2 * 48 = 96
bytes, and the encoding of a BLS12381G2
point requires2 * 96 = 192
bytes. Thex
andy
coordinates of the G1 and G2 points are encoded in littleendian format for BN254 curve, and in bigendian format for BLS12381 curve. This is coherent with arkworks implementation.
 An element of the base field of the BN254 curve can be represented with 32 bytes, therefore the affine representation of a BN254 G1 point requires

Scalars
are littleendian encoded. The scalar field of both the BN254 and BLS12381 curves can be represented with32
bytes.
The following table summarizes the size of the encodings:
BN254  BLS12381  

G1 point  64 bytes  96 bytes 
G2 point  128 bytes  192 bytes 
Scalar  32 bytes  32 bytes 