UNPKG

snarkjs

Version:

zkSNARKs implementation in JavaScript

149 lines (109 loc) 4.31 kB
/* Copyright 2018 0KIMS association. This file is part of snarkJS. snarkJS is a free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. snarkJS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with snarkJS. If not, see <https://www.gnu.org/licenses/>. */ import * as binFileUtils from "@iden3/binfileutils"; import * as zkeyUtils from "./zkey_utils.js"; import {getCurveFromQ as getCurve} from "./curves.js"; import {utils} from "ffjavascript"; import {FFLONK_PROTOCOL_ID} from "./zkey_constants.js"; const {stringifyBigInts} = utils; export default async function zkeyExportVerificationKey(zkeyName, logger) { if (logger) logger.info("EXPORT VERIFICATION KEY STARTED"); const {fd, sections} = await binFileUtils.readBinFile(zkeyName, "zkey", 2); const zkey = await zkeyUtils.readHeader(fd, sections); if (logger) logger.info("> Detected protocol: " + zkey.protocol); let res; if (zkey.protocol === "groth16") { res = await groth16Vk(zkey, fd, sections); } else if (zkey.protocol === "plonk") { res = await plonkVk(zkey); } else if (zkey.protocolId && zkey.protocolId === FFLONK_PROTOCOL_ID) { res = await exportFFlonkVk(zkey, logger); } else { throw new Error("zkey file protocol unrecognized"); } await fd.close(); if (logger) logger.info("EXPORT VERIFICATION KEY FINISHED"); return res; } async function groth16Vk(zkey, fd, sections) { const curve = await getCurve(zkey.q); const sG1 = curve.G1.F.n8 * 2; const alphaBeta = await curve.pairing(zkey.vk_alpha_1, zkey.vk_beta_2); let vKey = { protocol: zkey.protocol, curve: curve.name, nPublic: zkey.nPublic, vk_alpha_1: curve.G1.toObject(zkey.vk_alpha_1), vk_beta_2: curve.G2.toObject(zkey.vk_beta_2), vk_gamma_2: curve.G2.toObject(zkey.vk_gamma_2), vk_delta_2: curve.G2.toObject(zkey.vk_delta_2), vk_alphabeta_12: curve.Gt.toObject(alphaBeta) }; // Read IC Section /////////// await binFileUtils.startReadUniqueSection(fd, sections, 3); vKey.IC = []; for (let i = 0; i <= zkey.nPublic; i++) { const buff = await fd.read(sG1); const P = curve.G1.toObject(buff); vKey.IC.push(P); } await binFileUtils.endReadSection(fd); vKey = stringifyBigInts(vKey); return vKey; } async function plonkVk(zkey) { const curve = await getCurve(zkey.q); let vKey = { protocol: zkey.protocol, curve: curve.name, nPublic: zkey.nPublic, power: zkey.power, k1: curve.Fr.toObject(zkey.k1), k2: curve.Fr.toObject(zkey.k2), Qm: curve.G1.toObject(zkey.Qm), Ql: curve.G1.toObject(zkey.Ql), Qr: curve.G1.toObject(zkey.Qr), Qo: curve.G1.toObject(zkey.Qo), Qc: curve.G1.toObject(zkey.Qc), S1: curve.G1.toObject(zkey.S1), S2: curve.G1.toObject(zkey.S2), S3: curve.G1.toObject(zkey.S3), X_2: curve.G2.toObject(zkey.X_2), w: curve.Fr.toObject(curve.Fr.w[zkey.power]) }; vKey = stringifyBigInts(vKey); return vKey; } async function exportFFlonkVk(zkey, logger) { const curve = await getCurve(zkey.q); let vKey = { protocol: zkey.protocol, curve: curve.name, nPublic: zkey.nPublic, power: zkey.power, k1: curve.Fr.toObject(zkey.k1), k2: curve.Fr.toObject(zkey.k2), w: curve.Fr.toObject(curve.Fr.w[zkey.power]), //wW: curve.Fr.toObject(curve.Fr.w[zkey.power + 1]), w3: curve.Fr.toObject(zkey.w3), w4: curve.Fr.toObject(zkey.w4), w8: curve.Fr.toObject(zkey.w8), wr: curve.Fr.toObject(zkey.wr), X_2: curve.G2.toObject(zkey.X_2), C0: curve.G1.toObject(zkey.C0), }; return stringifyBigInts(vKey); }