@nori-zk/proof-conversion
Version:
Verifying zkVM proofs inside o1js circuits, to generate Mina compatible proof
276 lines • 12.6 kB
JavaScript
import { Poseidon, verify, Cache, Provable, Field } from 'o1js';
import { zkp0 } from './zkp0.js';
import fs from 'fs';
import { AuXWitness } from '../../aux_witness.js';
import { parseProof, detectInputCountFromProof } from '../proof.js';
import { Accumulator } from './data.js';
import { WitnessTracker } from '../witness_tracker.js';
import { zkp1 } from './zkp1.js';
import { zkp2 } from './zkp2.js';
import { zkp3 } from './zkp3.js';
import { zkp4 } from './zkp4.js';
import { zkp5 } from './zkp5.js';
import { zkp6 } from './zkp6.js';
import { zkp7 } from './zkp7.js';
import { zkp8 } from './zkp8.js';
import { zkp9 } from './zkp9.js';
import { zkp10 } from './zkp10.js';
import { zkp11 } from './zkp11.js';
import { zkp12 } from './zkp12.js';
import { zkp13 } from './zkp13.js';
import { createZkp14 } from './zkp14.js';
import { createZkp15 } from './zkp15.js';
import { G1Affine } from '../../ec/index.js';
import { FrC } from '../../towers/fr.js';
import { VK } from '../vk_from_env.js';
// npm run build && node build/src/groth/recursion/prove_zkps.js zkp0 ./src/groth/jsons/proof.json ./src/groth/jsons/aux_witness.json ../scripts/risc_zero_example/work_dir ../scripts/risc_zero_example/cache_dir
const args = process.argv;
const proof = parseProof(VK, args[3]);
const auxWitness = AuXWitness.parse(args[4]);
const workDir = args[5];
const cacheDir = args[6];
const inputCount = detectInputCountFromProof(args[3]);
const { zkp14 } = createZkp14(inputCount);
const { zkp15 } = createZkp15(inputCount);
const wt = new WitnessTracker(proof, auxWitness);
const [acc_0, lines_0, all_b_lines] = wt.in0();
const [acc_1, lines_1] = wt.zkp0();
const [acc_2, lines_2] = wt.zkp1();
const [acc_3, lines_3] = wt.zkp2();
const [acc_4, lines_4] = wt.zkp3();
const [acc_5, lines_5] = wt.zkp4();
const [acc_6, lines_6] = wt.zkp5();
const [acc_7, final_line_hashes] = wt.zkp6();
const acc_8 = wt.zkp7();
const acc_9 = wt.zkp8();
const acc_10 = wt.zkp9();
const acc_11 = wt.zkp10();
const acc_12 = wt.zkp11();
const acc_13 = wt.zkp12();
const _ = wt.zkp13();
void _;
const partialPiAcc = wt.zkp14();
const g = wt.g;
async function prove_zkp0() {
const vk0 = (await zkp0.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin0 = Poseidon.hashPacked(Accumulator, acc_0);
const proof0 = await zkp0.compute(cin0, acc_0, lines_0, all_b_lines);
const valid = await verify(proof0.proof, vk0);
console.log('valid zkp0?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp0.json`, JSON.stringify(proof0.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk0.json`, JSON.stringify(vk0), 'utf8');
}
async function prove_zkp1() {
const vk1 = (await zkp1.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin1 = Poseidon.hashPacked(Accumulator, acc_1);
const proof1 = await zkp1.compute(cin1, acc_1, lines_1, all_b_lines);
const valid = await verify(proof1.proof, vk1);
console.log('valid zkp1?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp1.json`, JSON.stringify(proof1.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk1.json`, JSON.stringify(vk1), 'utf8');
}
async function prove_zkp2() {
const vk2 = (await zkp2.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin2 = Poseidon.hashPacked(Accumulator, acc_2);
const proof2 = await zkp2.compute(cin2, acc_2, lines_2, all_b_lines);
const valid = await verify(proof2.proof, vk2);
console.log('valid zkp2?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp2.json`, JSON.stringify(proof2.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk2.json`, JSON.stringify(vk2), 'utf8');
}
async function prove_zkp3() {
const vk3 = (await zkp3.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin3 = Poseidon.hashPacked(Accumulator, acc_3);
const proof3 = await zkp3.compute(cin3, acc_3, lines_3, all_b_lines);
const valid = await verify(proof3.proof, vk3);
console.log('valid zkp3?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp3.json`, JSON.stringify(proof3.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk3.json`, JSON.stringify(vk3), 'utf8');
}
async function prove_zkp4() {
const vk4 = (await zkp4.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin4 = Poseidon.hashPacked(Accumulator, acc_4);
const proof4 = await zkp4.compute(cin4, acc_4, lines_4, all_b_lines);
const valid = await verify(proof4.proof, vk4);
console.log('valid zkp4?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp4.json`, JSON.stringify(proof4.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk4.json`, JSON.stringify(vk4), 'utf8');
}
async function prove_zkp5() {
const vk5 = (await zkp5.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin5 = Poseidon.hashPacked(Accumulator, acc_5);
const proof5 = await zkp5.compute(cin5, acc_5, lines_5, all_b_lines);
const valid = await verify(proof5.proof, vk5);
console.log('valid zkp5?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp5.json`, JSON.stringify(proof5.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk5.json`, JSON.stringify(vk5), 'utf8');
}
async function prove_zkp6() {
const vk6 = (await zkp6.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin6 = Poseidon.hashPacked(Accumulator, acc_6);
const proof6 = await zkp6.compute(cin6, acc_6, lines_6, all_b_lines);
const valid = await verify(proof6.proof, vk6);
console.log('valid zkp6?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp6.json`, JSON.stringify(proof6.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk6.json`, JSON.stringify(vk6), 'utf8');
}
async function prove_zkp7() {
const vk7 = (await zkp7.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin7 = Poseidon.hashPacked(Accumulator, acc_7);
const proof7 = await zkp7.compute(cin7, acc_7, g.slice(0, 9), final_line_hashes.slice(9));
const valid = await verify(proof7.proof, vk7);
console.log('valid zkp7?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp7.json`, JSON.stringify(proof7.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk7.json`, JSON.stringify(vk7), 'utf8');
}
async function prove_zkp8() {
const vk8 = (await zkp8.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin8 = Poseidon.hashPacked(Accumulator, acc_8);
const proof8 = await zkp8.compute(cin8, acc_8, final_line_hashes.slice(0, 9), g.slice(9, 9 + 11), final_line_hashes.slice(20));
const valid = await verify(proof8.proof, vk8);
console.log('valid zkp8?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp8.json`, JSON.stringify(proof8.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk8.json`, JSON.stringify(vk8), 'utf8');
}
async function prove_zkp9() {
const vk9 = (await zkp9.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin9 = Poseidon.hashPacked(Accumulator, acc_9);
const proof9 = await zkp9.compute(cin9, acc_9, final_line_hashes.slice(0, 20), g.slice(20, 20 + 11), final_line_hashes.slice(31));
const valid = await verify(proof9.proof, vk9);
console.log('valid zkp9?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp9.json`, JSON.stringify(proof9.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk9.json`, JSON.stringify(vk9), 'utf8');
}
async function prove_zkp10() {
const vk10 = (await zkp10.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin10 = Poseidon.hashPacked(Accumulator, acc_10);
const proof10 = await zkp10.compute(cin10, acc_10, final_line_hashes.slice(0, 31), g.slice(31, 31 + 11), final_line_hashes.slice(42));
const valid = await verify(proof10.proof, vk10);
console.log('valid zkp10?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp10.json`, JSON.stringify(proof10.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk10.json`, JSON.stringify(vk10), 'utf8');
}
async function prove_zkp11() {
const vk11 = (await zkp11.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin11 = Poseidon.hashPacked(Accumulator, acc_11);
const proof11 = await zkp11.compute(cin11, acc_11, final_line_hashes.slice(0, 42), g.slice(42, 42 + 11), final_line_hashes.slice(53));
const valid = await verify(proof11.proof, vk11);
console.log('valid zkp11?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp11.json`, JSON.stringify(proof11.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk11.json`, JSON.stringify(vk11), 'utf8');
}
async function prove_zkp12() {
const vk12 = (await zkp12.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin12 = Poseidon.hashPacked(Accumulator, acc_12);
const proof12 = await zkp12.compute(cin12, acc_12, final_line_hashes.slice(0, 53), g.slice(53, 53 + 11), final_line_hashes.slice(64));
const valid = await verify(proof12.proof, vk12);
console.log('valid zkp12?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp12.json`, JSON.stringify(proof12.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk12.json`, JSON.stringify(vk12), 'utf8');
}
async function prove_zkp13() {
const vk13 = (await zkp13.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
let cin13 = Poseidon.hashPacked(Accumulator, acc_13);
const proof13 = await zkp13.compute(cin13, acc_13, final_line_hashes.slice(0, 64), g.slice(-1));
const valid = await verify(proof13.proof, vk13);
console.log('valid zkp13?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp13.json`, JSON.stringify(proof13.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk13.json`, JSON.stringify(vk13), 'utf8');
}
async function prove_zkp14() {
const vk14 = (await zkp14.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
const cin14 = Poseidon.hashPacked(G1Affine, proof.PI);
const proof14 = await zkp14.compute(cin14, proof.pis);
const valid = await verify(proof14.proof, vk14);
console.log('valid zkp14?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp14.json`, JSON.stringify(proof14.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk14.json`, JSON.stringify(vk14), 'utf8');
}
async function prove_zkp15() {
const vk15 = (await zkp15.compile({ cache: Cache.FileSystem(cacheDir) }))
.verificationKey;
const pi_hash = Poseidon.hashPacked(G1Affine, proof.PI);
const acc_hash = Poseidon.hashPacked(G1Affine, partialPiAcc);
// zkp15 input should match zkp14's output: hash([pi_hash, full_pis_hash, acc_hash])
// Both zkp14 and zkp15 use the SAME pis_hash (hash of ALL public inputs)
const full_pis_hash = Poseidon.hashPacked(Provable.Array(FrC.provable, proof.pis.length), proof.pis);
const cin15 = Poseidon.hashPacked(Provable.Array(Field, 3), [
pi_hash,
full_pis_hash,
acc_hash,
]);
const proof15 = await zkp15.compute(cin15, proof.PI, partialPiAcc, proof.pis);
const valid = await verify(proof15.proof, vk15);
console.log('valid zkp15?: ', valid);
fs.writeFileSync(`${workDir}/proofs/layer0/zkp15.json`, JSON.stringify(proof15.proof), 'utf8');
fs.writeFileSync(`${workDir}/vks/vk15.json`, JSON.stringify(vk15), 'utf8');
}
if (!fs.existsSync(workDir)) {
fs.mkdirSync(workDir);
}
switch (process.argv[2]) {
case 'zkp0':
await prove_zkp0();
break;
case 'zkp1':
await prove_zkp1();
break;
case 'zkp2':
await prove_zkp2();
break;
case 'zkp3':
await prove_zkp3();
break;
case 'zkp4':
await prove_zkp4();
break;
case 'zkp5':
await prove_zkp5();
break;
case 'zkp6':
await prove_zkp6();
break;
case 'zkp7':
await prove_zkp7();
break;
case 'zkp8':
await prove_zkp8();
break;
case 'zkp9':
await prove_zkp9();
break;
case 'zkp10':
await prove_zkp10();
break;
case 'zkp11':
await prove_zkp11();
break;
case 'zkp12':
await prove_zkp12();
break;
case 'zkp13':
await prove_zkp13();
break;
case 'zkp14':
await prove_zkp14();
break;
case 'zkp15':
await prove_zkp15();
break;
}
//# sourceMappingURL=prove_zkps.js.map