The Bowe--Gabizon SNARK is a variation on the Groth16 SNARK. This challenge involves implementing the verifier algorithm for the Bowe--Gabizon SNARK using JavaScript or WebAssembly so that it can be run in a browser.
We'll use Typescript to give a specification of the functions your JavaScript program should implement.
The Bowe--Gabizon verifier consists of several functions. You can, if you choose, implement only these algorithms and default implementations will be provided for the rest.
We'll call the top-level verifier algorithm boweGabizonVerifier. Here is a "call graph" of functions used by boweGabizonVerifier:
boweGabizonVerifierhashToGroup
pedersenHashgroupMapboweGabizonVerifierCoreSo, boweGabizonVerifier calls into hashToGroup and boweGabizonVerifierCore. hashToGroup in turn calls into pedersenHash and groupMap.
You can implement as many of these functions as you like. If you implement a function, any implementations of "children functions" will be ignored and that function will be used.
For example, if you want to replace everything, you can implement boweGabizonVerifier.
If you only want to replace the Pedersen hash, you can just implement pedersenHash and the rest of the functions will be filled in with default implementations.
Your submission be a file called main.js containing implementations of any of the following 5 functions:
function boweGabizonVerifier(
vk : VerificationKey,
input : Fr,
proof : Proof) : boolean {
...
};
function groupMap (x : Fq) : AffineG1 {
...
};
function pedersenHash (ts : Array<[boolean, boolean, boolean]>) : Fq {
...
};
function hashToGroup (
a : AffineG1,
b : AffineG2,
c : AffineG1,
deltaPrime : AffineG2) : AffineG1 {
...
}
function verifierCore (
vk : VerificationKey,
input : Fr,
proof : ExtendedProof) : boolean {
...
};
where the types are defined as follows, with Fq representing an element of MNT4-753.\mathbb{F}_q. Please see
boweGabizonVerifier and verifierCore.pedersenHash, groupMap, and hashToGroup.
// An array of length 24.
type Fq = Uint32Array
type Fr = Fq;
type Fq3 = {
a : Fq,
b : Fq,
c : Fq,
};
type Fq6 = {
a : Fq3,
b : Fq3,
};
type AffinePoint<F> = {
x : F,
y : F,
};
type AffineG1 = AffinePoint<Fq>;
type AffineG2 = AffinePoint<Fq3>;
type Proof = {
a : AffineG1,
b : AffineG2,
c : AffineG1,
deltaPrime : AffineG2,
z : AffineG1,
};
type ExtendedProof = {
a : AffineG1,
b : AffineG2,
c : AffineG1,
deltaPrime : AffineG2,
z : AffineG1,
yS : AffineG1,
};
type VerificationKey = {
alphaBeta : Fq6,
delta : AffineG2,
query : Array<AffineG1>,
};
pedersenHash, groupMap, and hashToGroup. here, with the implementation of finite-field arithmetic stubbed out.