export-ton-verifier
Version:
Tool for generating a Groth16 verifier code for the TON blockchain from SnarkJS .zkey files.
83 lines (79 loc) • 2.33 kB
JavaScript
// src/groth16CompressProof.js
import { buildBls12381 as buildBls123812, utils } from "ffjavascript";
// src/utils.js
import { buildBn128, buildBls12381 } from "ffjavascript";
async function getCurveFromName(name, options) {
let curve;
let singleThread = options && options.singleThread;
const normName = normalizeName(name);
if (["BN128", "BN254", "ALTBN128"].indexOf(normName) >= 0) {
curve = await buildBn128(singleThread);
} else if (["BLS12381"].indexOf(normName) >= 0) {
curve = await buildBls12381(singleThread);
} else {
throw new Error(`Curve not supported: ${name}`);
}
return curve;
function normalizeName(n) {
return n.toUpperCase().match(/[A-Za-z0-9]+/g).join("");
}
}
function toHexString(byteArray) {
return Array.from(
byteArray,
(byte) => ("0" + (byte & 255).toString(16)).slice(-2)
).join("");
}
function g1Compressed(curve, p1Raw) {
const p1 = curve.G1.fromObject(p1Raw);
const buff = new Uint8Array(48);
curve.G1.toRprCompressed(buff, 0, p1);
if (buff[0] & 128) buff[0] |= 32;
buff[0] |= 128;
return toHexString(buff);
}
function g2Compressed(curve, p2Raw) {
const p2 = curve.G2.fromObject(p2Raw);
const buff = new Uint8Array(96);
curve.G2.toRprCompressed(buff, 0, p2);
if (buff[0] & 128) buff[0] |= 32;
buff[0] |= 128;
return toHexString(buff);
}
// src/groth16CompressProof.js
async function groth16CompressProof(proof, publicSignals) {
const curve = await buildBls123812();
const proofProc = utils.unstringifyBigInts(proof);
const pi_aS = g1Compressed(curve, proofProc.pi_a);
const pi_bS = g2Compressed(curve, proofProc.pi_b);
const pi_cS = g1Compressed(curve, proofProc.pi_c);
const pi_a = Buffer.from(pi_aS, "hex");
const pi_b = Buffer.from(pi_bS, "hex");
const pi_c = Buffer.from(pi_cS, "hex");
const pubInputs = publicSignals.map((s) => BigInt(s));
return {
pi_a,
pi_b,
pi_c,
pubInputs
};
}
// src/dictFromInputList.ts
import { Dictionary } from "@ton/core";
function dictFromInputList(list) {
const dict = Dictionary.empty(
Dictionary.Keys.Int(32),
Dictionary.Values.BigInt(256)
);
for (let i = 0; i < list.length; i++) {
dict.set(i, list[i]);
}
return dict;
}
export {
dictFromInputList,
g1Compressed,
g2Compressed,
getCurveFromName,
groth16CompressProof
};