@nori-zk/proof-conversion
Version:
Verifying zkVM proofs inside o1js circuits, to generate Mina compatible proof
283 lines • 13.2 kB
JavaScript
import { Field, Poseidon, Provable } from 'o1js';
import { ArrayListHasher, KzgAccumulator, KzgProof, KzgState, } from '../../kzg/structs.js';
import { compute_alpha_square_lagrange_0, compute_commitment_linearized_polynomial_split_0, compute_commitment_linearized_polynomial_split_1, compute_commitment_linearized_polynomial_split_2, customPiLagrange, evalVanishing, fold_quotient_split_0, fold_quotient_split_1, fold_state_0, fold_state_1, fold_state_2, opening_of_linearized_polynomial, pi_contribution, preparePairing_0, preparePairing_1, } from '../piop/plonk_utils.js';
import { VK } from '../vk.js';
import { G1Affine } from '../../ec/index.js';
import { Fp12 } from '../../towers/fp12.js';
import { G2Line } from '../../lines/index.js';
import { KZGLineAccumulator } from '../mm_loop/accumulate_lines.js';
import { ATE_LOOP_COUNT } from '../../towers/consts.js';
import { make_w27 } from '../helpers.js';
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const g2_lines_required = require('../mm_loop/g2_lines.json');
const tau_lines_required = require('../mm_loop/tau_lines.json');
//import g2_lines_required from '../mm_loop/g2_lines.json';
//import tau_lines_required from '../mm_loop/tau_lines.json';
const g2_lines_path = JSON.stringify(g2_lines_required); //fs.readFileSync(`./src/plonk/mm_loop/g2_lines.json`, 'utf8');
const tau_lines_path = JSON.stringify(tau_lines_required); //fs.readFileSync(`./src/plonk/mm_loop/tau_lines.json`, 'utf8');
let parsed_g2_lines = JSON.parse(g2_lines_path);
let g2_lines = parsed_g2_lines.map((g) => G2Line.fromJSON(g));
let parsed_tau_lines = JSON.parse(tau_lines_path);
let tau_lines = parsed_tau_lines.map((tau) => G2Line.fromJSON(tau));
class WitnessTracker {
constructor(acc) {
this.acc = acc.deepClone();
}
zkp0() {
this.acc.fs.squeezeGamma(this.acc.proof, this.acc.state.pi0, this.acc.state.pi1, VK);
this.acc.fs.squeezeBeta();
return this.acc.deepClone();
}
zkp1() {
this.acc.fs.squeezeAlpha(this.acc.proof);
this.acc.fs.squeezeZeta(this.acc.proof);
const [zeta_pow_n, zh_eval] = evalVanishing(this.acc.fs.zeta, VK);
const alpha_2_l0 = compute_alpha_square_lagrange_0(zh_eval, this.acc.fs.zeta, this.acc.fs.alpha, VK);
this.acc.state.zeta_pow_n = zeta_pow_n;
this.acc.state.zh_eval = zh_eval;
this.acc.state.alpha_2_l0 = alpha_2_l0;
return this.acc.deepClone();
}
zkp2() {
const [hx, hy] = fold_quotient_split_0(this.acc.proof.h0_x, this.acc.proof.h0_y, this.acc.proof.h1_x, this.acc.proof.h1_y, this.acc.proof.h2_x, this.acc.proof.h2_y, this.acc.fs.zeta, this.acc.state.zeta_pow_n);
this.acc.state.hx = hx;
this.acc.state.hy = hy;
return this.acc.deepClone();
}
zkp3() {
const [hx, hy] = fold_quotient_split_1(this.acc.state.hx, this.acc.state.hy, this.acc.state.zh_eval);
this.acc.state.hx = hx;
this.acc.state.hy = hy;
const pis = pi_contribution([this.acc.state.pi0, this.acc.state.pi1], this.acc.fs.zeta, this.acc.state.zh_eval, VK.inv_domain_size, VK.omega);
// ~32k
const l_pi_commit = customPiLagrange(this.acc.fs.zeta, this.acc.state.zh_eval, this.acc.proof.qcp_0_wire_x, this.acc.proof.qcp_0_wire_y, VK);
const pi = pis.add(l_pi_commit).assertCanonical();
// very cheap
const linearized_opening = opening_of_linearized_polynomial(this.acc.proof, this.acc.fs.alpha, this.acc.fs.beta, this.acc.fs.gamma, pi, this.acc.state.alpha_2_l0);
this.acc.state.pi = pi;
this.acc.state.linearized_opening = linearized_opening;
return this.acc.deepClone();
}
zkp4() {
const [lcm_x, lcm_y] = compute_commitment_linearized_polynomial_split_0(this.acc.proof, VK);
this.acc.state.lcm_x = lcm_x;
this.acc.state.lcm_y = lcm_y;
return this.acc.deepClone();
}
zkp5() {
const [lcm_x, lcm_y] = compute_commitment_linearized_polynomial_split_1(this.acc.state.lcm_x, this.acc.state.lcm_y, this.acc.proof, VK, this.acc.fs.beta, this.acc.fs.gamma, this.acc.fs.alpha);
this.acc.state.lcm_x = lcm_x;
this.acc.state.lcm_y = lcm_y;
return this.acc.deepClone();
}
zkp6() {
const [lcm_x, lcm_y] = compute_commitment_linearized_polynomial_split_2(this.acc.state.lcm_x, this.acc.state.lcm_y, this.acc.proof, VK, this.acc.fs.beta, this.acc.fs.gamma, this.acc.fs.alpha, this.acc.fs.zeta, this.acc.state.alpha_2_l0, this.acc.state.hx, this.acc.state.hy);
this.acc.state.lcm_x = lcm_x;
this.acc.state.lcm_y = lcm_y;
return this.acc.deepClone();
}
zkp7() {
let H = this.acc.fs.gammaKzgDigest_part0(this.acc.proof, VK, this.acc.state.lcm_x, this.acc.state.lcm_y, this.acc.state.linearized_opening);
this.acc.state.H = H;
return this.acc.deepClone();
}
zkp8() {
this.acc.fs.gammaKzgDigest_part1(this.acc.proof, this.acc.state.H);
this.acc.fs.squeezeGammaKzgFromDigest();
const [cm_x, cm_y, cm_opening] = fold_state_0(this.acc.proof, this.acc.state.lcm_x, this.acc.state.lcm_y, this.acc.state.linearized_opening, this.acc.fs.gamma_kzg);
this.acc.state.cm_x = cm_x;
this.acc.state.cm_y = cm_y;
this.acc.state.cm_opening = cm_opening;
return this.acc.deepClone();
}
zkp9() {
const [cm_x, cm_y] = fold_state_1(VK, this.acc.proof, this.acc.state.cm_x, this.acc.state.cm_y, this.acc.fs.gamma_kzg);
this.acc.state.cm_x = cm_x;
this.acc.state.cm_y = cm_y;
return this.acc.deepClone();
}
zkp10() {
const [cm_x, cm_y] = fold_state_2(VK, this.acc.proof, this.acc.state.cm_x, this.acc.state.cm_y, this.acc.fs.gamma_kzg);
const kzg_random = this.acc.fs.squeezeRandomForKzg(this.acc.proof, cm_x, cm_y);
this.acc.state.cm_x = cm_x;
this.acc.state.cm_y = cm_y;
this.acc.state.kzg_random = kzg_random;
return this.acc.deepClone();
}
zkp11() {
const [kzg_cm_x, kzg_cm_y, neg_fq_x, neg_fq_y] = preparePairing_0(VK, this.acc.proof, this.acc.state.kzg_random, this.acc.state.cm_x, this.acc.state.cm_y, this.acc.state.cm_opening);
this.acc.state.kzg_cm_x = kzg_cm_x;
this.acc.state.kzg_cm_y = kzg_cm_y;
this.acc.state.neg_fq_x = neg_fq_x;
this.acc.state.neg_fq_y = neg_fq_y;
return this.acc.deepClone();
}
zkp12(shift_power, c) {
const [kzg_cm_x, kzg_cm_y] = preparePairing_1(VK, this.acc.proof, this.acc.state.kzg_random, this.acc.state.kzg_cm_x, this.acc.state.kzg_cm_y, this.acc.fs.zeta);
// this.acc.state.kzg_cm_x = kzg_cm_x;
// this.acc.state.kzg_cm_y = kzg_cm_y;
const A = new G1Affine({ x: kzg_cm_x, y: kzg_cm_y });
const negB = new G1Affine({
x: this.acc.state.neg_fq_x,
y: this.acc.state.neg_fq_y,
});
let kzgProof = new KzgProof({
A,
negB,
shift_power,
c,
c_inv: c.inverse(),
pi0: this.acc.state.pi0,
pi1: this.acc.state.pi1,
});
let kzgState = new KzgState({
f: c.inverse(),
lines_hashes_digest: ArrayListHasher.empty(),
});
let kzgAccumulator = new KzgAccumulator({
proof: kzgProof,
state: kzgState,
});
this.g = KZGLineAccumulator.accumulate(g2_lines, tau_lines, A, negB);
this.line_hashes = new Array(ArrayListHasher.n).fill(Field(0n));
this.kzg = kzgAccumulator.deepClone();
return [this.kzg.deepClone(), [...this.line_hashes]];
}
zkp13() {
for (let i = 1; i < ATE_LOOP_COUNT.length - 46; i++) {
this.line_hashes[i - 1] = Poseidon.hashPacked(Fp12, this.g[i - 1]);
}
this.kzg.state.lines_hashes_digest = ArrayListHasher.hash(this.line_hashes);
return [this.kzg.deepClone(), [...this.line_hashes]];
}
zkp14() {
for (let i = ATE_LOOP_COUNT.length - 46; i < ATE_LOOP_COUNT.length - 26; i++) {
this.line_hashes[i - 1] = Poseidon.hashPacked(Fp12, this.g[i - 1]);
}
this.kzg.state.lines_hashes_digest = ArrayListHasher.hash(this.line_hashes);
return [this.kzg.deepClone(), [...this.line_hashes]];
}
zkp15() {
for (let i = ATE_LOOP_COUNT.length - 26; i < ATE_LOOP_COUNT.length - 6; i++) {
this.line_hashes[i - 1] = Poseidon.hashPacked(Fp12, this.g[i - 1]);
}
this.kzg.state.lines_hashes_digest = ArrayListHasher.hash(this.line_hashes);
return [this.kzg.deepClone(), [...this.line_hashes]];
}
zkp16() {
for (let i = ATE_LOOP_COUNT.length - 6; i < ATE_LOOP_COUNT.length; i++) {
this.line_hashes[i - 1] = Poseidon.hashPacked(Fp12, this.g[i - 1]);
}
this.line_hashes[ATE_LOOP_COUNT.length - 1] = Poseidon.hashPacked(Fp12, this.g[ATE_LOOP_COUNT.length - 1]);
this.kzg.state.lines_hashes_digest = ArrayListHasher.hash(this.line_hashes);
return [this.kzg.deepClone(), [...this.line_hashes]];
}
zkp17() {
let idx = 0;
for (let i = 1; i < 10; i++) {
idx = i - 1;
this.kzg.state.f = this.kzg.state.f.square().mul(this.g[idx]);
if (ATE_LOOP_COUNT[i] == 1) {
this.kzg.state.f = this.kzg.state.f.mul(this.kzg.proof.c_inv);
}
if (ATE_LOOP_COUNT[i] == -1) {
this.kzg.state.f = this.kzg.state.f.mul(this.kzg.proof.c);
}
}
return this.kzg.deepClone();
}
zkp18() {
let idx = 0;
for (let i = 10; i < 21; i++) {
idx = i - 1;
this.kzg.state.f = this.kzg.state.f.square().mul(this.g[idx]);
if (ATE_LOOP_COUNT[i] == 1) {
this.kzg.state.f = this.kzg.state.f.mul(this.kzg.proof.c_inv);
}
if (ATE_LOOP_COUNT[i] == -1) {
this.kzg.state.f = this.kzg.state.f.mul(this.kzg.proof.c);
}
}
return this.kzg.deepClone();
}
zkp19() {
let idx = 0;
for (let i = 21; i < 32; i++) {
idx = i - 1;
this.kzg.state.f = this.kzg.state.f.square().mul(this.g[idx]);
if (ATE_LOOP_COUNT[i] == 1) {
this.kzg.state.f = this.kzg.state.f.mul(this.kzg.proof.c_inv);
}
if (ATE_LOOP_COUNT[i] == -1) {
this.kzg.state.f = this.kzg.state.f.mul(this.kzg.proof.c);
}
}
return this.kzg.deepClone();
}
zkp20() {
let idx = 0;
for (let i = 32; i < 43; i++) {
idx = i - 1;
this.kzg.state.f = this.kzg.state.f.square().mul(this.g[idx]);
if (ATE_LOOP_COUNT[i] == 1) {
this.kzg.state.f = this.kzg.state.f.mul(this.kzg.proof.c_inv);
}
if (ATE_LOOP_COUNT[i] == -1) {
this.kzg.state.f = this.kzg.state.f.mul(this.kzg.proof.c);
}
}
return this.kzg.deepClone();
}
zkp21() {
let idx = 0;
for (let i = 43; i < 54; i++) {
idx = i - 1;
this.kzg.state.f = this.kzg.state.f.square().mul(this.g[idx]);
if (ATE_LOOP_COUNT[i] == 1) {
this.kzg.state.f = this.kzg.state.f.mul(this.kzg.proof.c_inv);
}
if (ATE_LOOP_COUNT[i] == -1) {
this.kzg.state.f = this.kzg.state.f.mul(this.kzg.proof.c);
}
}
return this.kzg.deepClone();
}
zkp22() {
let idx = 0;
for (let i = 54; i < 65; i++) {
idx = i - 1;
this.kzg.state.f = this.kzg.state.f.square().mul(this.g[idx]);
if (ATE_LOOP_COUNT[i] == 1) {
this.kzg.state.f = this.kzg.state.f.mul(this.kzg.proof.c_inv);
}
if (ATE_LOOP_COUNT[i] == -1) {
this.kzg.state.f = this.kzg.state.f.mul(this.kzg.proof.c);
}
}
return this.kzg.deepClone();
}
zkp23() {
this.kzg.state.f = this.kzg.state.f.mul(this.g[ATE_LOOP_COUNT.length - 1]);
this.kzg.state.f = this.kzg.state.f
.mul(this.kzg.proof.c_inv.frobenius_pow_p())
.mul(this.kzg.proof.c.frobenius_pow_p_squared())
.mul(this.kzg.proof.c_inv.frobenius_pow_p_cubed());
const w27 = make_w27();
const w27_sq = w27.square();
const shift = Provable.switch([
this.kzg.proof.shift_power.equals(Field(0)),
this.kzg.proof.shift_power.equals(Field(1)),
this.kzg.proof.shift_power.equals(Field(2)),
], Fp12, [Fp12.one(), w27, w27_sq]);
this.kzg.state.f = this.kzg.state.f.mul(shift);
this.kzg.state.f.assert_equals(Fp12.one());
return this.kzg.deepClone();
}
fullGHashes() {
const h = this.g.map((gi) => Poseidon.hashPacked(Fp12, gi));
return ArrayListHasher.hash(h);
}
}
export { WitnessTracker };
//# sourceMappingURL=witness_tracker.js.map