UNPKG

@nori-zk/proof-conversion

Version:

Verifying zkVM proofs inside o1js circuits, to generate Mina compatible proof

100 lines 3.34 kB
import { G1Affine, G2Affine } from '../ec/index.js'; import fs from 'fs'; import { ATE_LOOP_COUNT, Fp2, FpC, FrC } from '../towers/index.js'; import { Provable, Struct } from 'o1js'; import { G2Line, computeLineCoeffs } from '../lines/index.js'; import { computePI } from './compute_pi.js'; const getNumOfLines = () => { let cnt = 0; for (let i = 1; i < ATE_LOOP_COUNT.length; i++) { cnt += 1; if (ATE_LOOP_COUNT[i] !== 0) cnt += 1; } // add two more for frobenius return cnt + 2; }; // Cache for dynamically created Proof classes const proofClassCache = new Map(); function createProofClass(inputCount) { if (inputCount < 0 || inputCount > 6) { throw new Error(`Unsupported input count: ${inputCount}. Supported range: 0-6`); } const cached = proofClassCache.get(inputCount); if (cached !== undefined) { return cached; } const ProofClass = class extends Struct({ negA: G1Affine, B: G2Affine, C: G1Affine, PI: G1Affine, b_lines: Provable.Array(G2Line, getNumOfLines()), pis: Provable.Array(FrC.provable, inputCount), }) { static parse(vk, path) { const json = JSON.parse(fs.readFileSync(path, 'utf-8')); // Get public inputs (pi1, pi2, etc). const publicInputs = []; for (let i = 1; i <= inputCount; i++) { const key = `pi${i}`; const val = json[key]; if (val) { publicInputs.push(FrC.from(val)); } } const negA = new G1Affine({ x: FpC.from(json.negA.x), y: FpC.from(json.negA.y), }); const C = new G1Affine({ x: FpC.from(json.C.x), y: FpC.from(json.C.y), }); const B = new G2Affine({ x: new Fp2({ c0: FpC.from(json.B.x_c0), c1: FpC.from(json.B.x_c1), }), y: new Fp2({ c0: FpC.from(json.B.y_c0), c1: FpC.from(json.B.y_c1), }), }); // FIXME CHECK THIS VS RUST const piBn = computePI(vk, publicInputs); const PI = new G1Affine({ x: FpC.from(piBn.x).assertCanonical(), y: FpC.from(piBn.y).assertCanonical(), }); return new ProofClass({ negA, B, C, PI, b_lines: computeLineCoeffs(B), pis: publicInputs, }); } }; proofClassCache.set(inputCount, ProofClass); return ProofClass; } export function detectInputCountFromProof(path) { const json = JSON.parse(fs.readFileSync(path, 'utf-8')); let count = 0; for (let i = 1; i <= 6; i++) { if (json[`pi${i}`]) count++; } return count; } export function parseProof(vk, path) { const inputCount = detectInputCountFromProof(path); const ProofClass = createProofClass(inputCount); return ProofClass.parse(vk, path); } // Legacy Proof for backward compatibility (fixed 5 inputs) const Proof = createProofClass(5); export { Proof }; //# sourceMappingURL=proof.js.map