UNPKG

@jayanth-kumar-morem/snarkjs-to-solana

Version:

A comprehensive toolkit for converting snarkjs artifacts to Solana-compatible formats. This package provides both CLI tools and programmatic APIs for converting zero-knowledge proofs and verification keys from snarkjs to formats that work with Solana's gr

143 lines (126 loc) 4.91 kB
var ffjavascript = require('ffjavascript'); const {unstringifyBigInts, leInt2Buff} = ffjavascript.utils; var fs = require("fs") const path = require('path'); async function parseVerificationKeyToRust(inputPath, outputDir = '.') { return new Promise((resolve, reject) => { fs.readFile(inputPath, async function(err, fd) { if (err) { return reject(new Error(`Failed to read file: ${err.message}`)); } try { var mydata = JSON.parse(fd.toString()); for (var i in mydata) { if (i == 'vk_alpha_1') { for (var j in mydata[i]) { mydata[i][j] = leInt2Buff(unstringifyBigInts(mydata[i][j]), 32).reverse() } } else if (i == 'vk_beta_2') { for (var j in mydata[i]) { let tmp = Array.from(leInt2Buff(unstringifyBigInts(mydata[i][j][0]), 32)).concat(Array.from(leInt2Buff(unstringifyBigInts(mydata[i][j][1]), 32))).reverse() mydata[i][j][0] = tmp.slice(0,32) mydata[i][j][1] = tmp.slice(32,64) } } else if (i == 'vk_gamma_2') { for (var j in mydata[i]) { let tmp = Array.from(leInt2Buff(unstringifyBigInts(mydata[i][j][0]), 32)).concat(Array.from(leInt2Buff(unstringifyBigInts(mydata[i][j][1]), 32))).reverse() mydata[i][j][0] = tmp.slice(0,32) mydata[i][j][1] = tmp.slice(32,64) } } else if (i == 'vk_delta_2') { for (var j in mydata[i]) { let tmp = Array.from(leInt2Buff(unstringifyBigInts(mydata[i][j][0]), 32)).concat(Array.from(leInt2Buff(unstringifyBigInts(mydata[i][j][1]), 32))).reverse() mydata[i][j][0] = tmp.slice(0,32) mydata[i][j][1] = tmp.slice(32,64) } } else if (i == 'vk_alphabeta_12') { for (var j in mydata[i]) { for (var z in mydata[i][j]){ for (var u in mydata[i][j][z]){ mydata[i][j][z][u] = leInt2Buff(unstringifyBigInts(mydata[i][j][z][u])) } } } } else if (i == 'IC') { for (var j in mydata[i]) { for (var z in mydata[i][j]){ mydata[i][j][z] = leInt2Buff(unstringifyBigInts(mydata[i][j][z]), 32).reverse() } } } } const outputPath = path.join(outputDir, "vote_verifying_key.rs"); let resFile = fs.openSync(outputPath, "w") let s = `use groth16_solana::groth16::Groth16Verifyingkey;\n\npub const VERIFYINGKEY: Groth16Verifyingkey = Groth16Verifyingkey {\n\tnr_pubinputs: ${mydata.IC.length},\n\n` s += "\tvk_alpha_g1: [\n" for (var j = 0; j < mydata.vk_alpha_1.length -1 ; j++) { s += "\t\t" + Array.from(mydata.vk_alpha_1[j]) + ",\n" } s += "\t],\n\n" fs.writeSync(resFile,s) s = "\tvk_beta_g2: [\n" for (var j = 0; j < mydata.vk_beta_2.length -1 ; j++) { for (var z = 0; z < 2; z++) { s += "\t\t" + Array.from(mydata.vk_beta_2[j][z]) + ",\n" } } s += "\t],\n\n" fs.writeSync(resFile,s) s = "\tvk_gamme_g2: [\n" for (var j = 0; j < mydata.vk_gamma_2.length -1 ; j++) { for (var z = 0; z < 2; z++) { s += "\t\t" + Array.from(mydata.vk_gamma_2[j][z]) + ",\n" } } s += "\t],\n\n" fs.writeSync(resFile,s) s = "\tvk_delta_g2: [\n" for (var j = 0; j < mydata.vk_delta_2.length -1 ; j++) { for (var z = 0; z < 2; z++) { s += "\t\t" + Array.from(mydata.vk_delta_2[j][z]) + ",\n" } } s += "\t],\n\n" fs.writeSync(resFile,s) s = "\tvk_ic: &[\n" for (var ic in mydata.IC) { s += "\t\t[\n" for (var j = 0; j < mydata.IC[ic].length - 1 ; j++) { s += "\t\t\t" + mydata.IC[ic][j] + ",\n" } s += "\t\t],\n" } s += "\t]\n};" fs.writeSync(resFile,s) fs.closeSync(resFile) resolve(outputPath); } catch (parseError) { reject(new Error(`Failed to parse verification key: ${parseError.message}`)); } }); }); } async function main() { const process = require('process'); let inputPath = process.argv[2]; if (!inputPath) { throw new Error("inputPath not specified"); } let outputPath = "" if (process.argv[3]) { outputPath += process.argv[3] +"/"; } console.log = () => {}; // Disable console.log as in original try { await parseVerificationKeyToRust(inputPath, outputPath); } catch (error) { console.error(error.message); process.exit(1); } } module.exports = parseVerificationKeyToRust; if (require.main === module) { main(); }