@nori-zk/proof-conversion
Version:
Verifying zkVM proofs inside o1js circuits, to generate Mina compatible proof
131 lines • 5.65 kB
JavaScript
import { resolve } from 'path';
import { computeAuxWitness } from '../../../pairing-utils/index.js';
import { createDirectories, createDirectory, } from '../../../utils/cache.js';
import { getRandomString } from '../../../utils/random.js';
import { range } from '../../../utils/range.js';
import rootDir from '../../../utils/root_dir.js';
import { readFileSync, rmSync, writeFileSync } from 'fs';
import { getMlo } from '../../../plonk/get_mlo.js';
const proofVkCacheStructure = {
proofs: range(6).map((i) => `layer${i}`),
vks: range(6).map((i) => `layer${i}`),
};
const nodeCacheStructure = range(4).map((i) => `node${i}`);
export class PlonkComputationalPlan {
constructor() {
this.name = 'PlonkConverter';
this.stages = [
{
name: 'CreateFileSystemCache',
type: 'main-thread',
execute: (state) => {
createDirectory(state.cacheDir);
createDirectory(state.workingDir);
createDirectories(state.workingDir, proofVkCacheStructure);
createDirectories(state.workingDir, nodeCacheStructure);
},
},
{
name: 'GenerateWitness',
type: 'main-thread',
execute: (state) => {
const mlo = getMlo(state.input.encodedProof, state.input.programVK, state.input.hexPi).toJSON();
const witness = computeAuxWitness(JSON.parse(mlo));
state.witnessPath = resolve(state.workingDir, 'aux_wtns.json');
// Write the mlo and witness to the cache dir
writeFileSync(resolve(state.workingDir, 'mlo.json'), mlo);
writeFileSync(state.witnessPath, JSON.stringify(witness));
return;
},
},
// If u wanna see stdout then you can change the capture boolean key in the plonk plan to emit
{
name: 'CompileRecursion',
type: 'serial-cmd',
processCmd: (state) => {
return {
cmd: 'node',
args: [
'--max-old-space-size=6000',
resolve(rootDir, 'build', 'src', 'compile_recursion_vks.js'),
state.workingDir,
state.cacheDir,
],
capture: true,
printableArgs: [0, 1, 2],
};
},
},
{
name: 'ComputeZPK',
type: 'parallel-cmd',
processCmds: (state) => {
return range(24).map((i) => {
return {
cmd: 'node',
args: [
'--max-old-space-size=6000',
resolve(rootDir, 'build', 'src', 'plonk', 'recursion', 'prove_zkps.js'),
`zkp${i}`,
state.input.encodedProof,
state.input.programVK,
state.input.hexPi,
state.witnessPath,
state.workingDir,
state.cacheDir,
],
capture: true,
printableArgs: [0, 1, 2],
};
});
},
numaOptimized: true,
},
...range(1, 6).map((i) => {
const stage = {
name: `CompressLayer${i}`,
type: 'parallel-cmd',
processCmds: (state) => {
const upperLimit = Math.pow(2, 5 - i) - 1;
return range(upperLimit + 1).map((ZKP_J) => {
return {
cmd: 'node',
args: [
'--max-old-space-size=6000',
resolve(rootDir, 'build', 'src', 'node_resolver.js'),
'24',
`${i}`,
`${ZKP_J}`,
state.workingDir,
state.cacheDir,
],
capture: true,
printableArgs: [0, 1, 2, 3, 4],
};
});
},
numaOptimized: true,
};
return stage;
}),
];
}
async init(state, input) {
state.input = input;
state.workingDirName = getRandomString(20);
const pwd = process.cwd();
state.workingDir = resolve(pwd, '.conversion-cache', state.workingDirName);
state.cacheDir = resolve(pwd, '.conversion-cache', 'plonk_cache');
}
async then(state) {
const output = {
vkData: JSON.parse(readFileSync(resolve(state.workingDir, 'vks', 'nodeVk.json'), 'utf8')),
proofData: JSON.parse(readFileSync(resolve(state.workingDir, 'proofs', 'layer5', 'p0.json'), 'utf8')),
};
return output;
}
async finally(state) {
rmSync(state.workingDir, { recursive: true, force: true });
}
}
//# sourceMappingURL=index.js.map