UNPKG

@nori-zk/proof-conversion

Version:

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

234 lines 8.89 kB
import { Struct } from 'o1js'; import { ATE_LOOP_COUNT } from './consts.js'; import { FpC } from './fp.js'; import { Fp2 } from './fp2.js'; import { Fp6 } from './fp6.js'; import { GAMMA_1S, GAMMA_2S, GAMMA_3S } from './precomputed.js'; // Fp6^2[w]/(w^2 - v) class Fp12 extends Struct({ c0: Fp6, c1: Fp6 }) { static zero() { return new Fp12({ c0: Fp6.zero(), c1: Fp6.zero() }); } static one() { return new Fp12({ c0: Fp6.one(), c1: Fp6.zero() }); } neg() { return new Fp12({ c0: this.c0.neg(), c1: this.c1.neg() }); } conjugate() { return new Fp12({ c0: this.c0, c1: this.c1.neg() }); } assert_equals(rhs) { this.c0.assert_equals(rhs.c0); this.c1.assert_equals(rhs.c1); } inverse() { let t0 = this.c0.mul(this.c0); let t1 = this.c1.mul(this.c1); t0 = t0.sub(t1.mul_by_v()); t1 = t0.inverse(); const c0 = this.c0.mul(t1); const c1 = this.c1.neg().mul(t1); return new Fp12({ c0, c1 }); } mul(rhs) { const t0 = this.c0.mul(rhs.c0); const t1 = this.c1.mul(rhs.c1); const c0 = t1.mul_by_v().add(t0); const a0_a1 = this.c0.add(this.c1); const b0_b1 = rhs.c0.add(rhs.c1); const c1 = a0_a1.mul(b0_b1).sub(t0).sub(t1); return new Fp12({ c0, c1 }); } // rhs.c0 b00 + 0v + 0v^2 // rhs.c1 b10 + b11v + 0v^2 sparse_mul(rhs) { const t0 = this.c0.mul_by_fp2(rhs.c0.c0); const t1 = this.c1.mul_by_sparse_fp6(rhs.c1); const c0 = t0.add(t1.mul_by_v()); const t2 = new Fp6({ c0: rhs.c0.c0.add(rhs.c1.c0), c1: rhs.c1.c1, c2: Fp2.zero(), }); let c1 = this.c0.add(this.c1).mul_by_sparse_fp6(t2); c1 = c1.sub(t0).sub(t1); return new Fp12({ c0, c1 }); } square() { let c0 = this.c0.sub(this.c1); let c3 = this.c0.sub(this.c1.mul_by_v()); let c2 = this.c0.mul(this.c1); c0 = c0.mul(c3).add(c2); const c1 = c2.mul_by_fp(FpC.from(2n)); c2 = c2.mul_by_v(); c0 = c0.add(c2); return new Fp12({ c0, c1 }); } frobenius_pow_p() { const t1 = this.c0.c0.conjugate(); let t2 = this.c1.c0.conjugate(); let t3 = this.c0.c1.conjugate(); let t4 = this.c1.c1.conjugate(); let t5 = this.c0.c2.conjugate(); let t6 = this.c1.c2.conjugate(); t2 = t2.mul(GAMMA_1S[0]); t3 = t3.mul(GAMMA_1S[1]); t4 = t4.mul(GAMMA_1S[2]); t5 = t5.mul(GAMMA_1S[3]); t6 = t6.mul(GAMMA_1S[4]); const c0 = new Fp6({ c0: t1, c1: t3, c2: t5 }); const c1 = new Fp6({ c0: t2, c1: t4, c2: t6 }); return new Fp12({ c0, c1 }); } frobenius_pow_p_with_gammas(gamma_1s) { const t1 = this.c0.c0.conjugate(); let t2 = this.c1.c0.conjugate(); let t3 = this.c0.c1.conjugate(); let t4 = this.c1.c1.conjugate(); let t5 = this.c0.c2.conjugate(); let t6 = this.c1.c2.conjugate(); t2 = t2.mul(gamma_1s[0]); t3 = t3.mul(gamma_1s[1]); t4 = t4.mul(gamma_1s[2]); t5 = t5.mul(gamma_1s[3]); t6 = t6.mul(gamma_1s[4]); const c0 = new Fp6({ c0: t1, c1: t3, c2: t5 }); const c1 = new Fp6({ c0: t2, c1: t4, c2: t6 }); return new Fp12({ c0, c1 }); } frobenius_pow_p_squared() { const t1 = this.c0.c0; const t2 = this.c1.c0.mul(GAMMA_2S[0]); const t3 = this.c0.c1.mul(GAMMA_2S[1]); const t4 = this.c1.c1.mul(GAMMA_2S[2]); const t5 = this.c0.c2.mul(GAMMA_2S[3]); const t6 = this.c1.c2.mul(GAMMA_2S[4]); const c0 = new Fp6({ c0: t1, c1: t3, c2: t5 }); const c1 = new Fp6({ c0: t2, c1: t4, c2: t6 }); return new Fp12({ c0, c1 }); } frobenius_pow_p_squared_with_gammas(gamma_2s) { const t1 = this.c0.c0; const t2 = this.c1.c0.mul(gamma_2s[0]); const t3 = this.c0.c1.mul(gamma_2s[1]); const t4 = this.c1.c1.mul(gamma_2s[2]); const t5 = this.c0.c2.mul(gamma_2s[3]); const t6 = this.c1.c2.mul(gamma_2s[4]); const c0 = new Fp6({ c0: t1, c1: t3, c2: t5 }); const c1 = new Fp6({ c0: t2, c1: t4, c2: t6 }); return new Fp12({ c0, c1 }); } frobenius_pow_p_cubed() { const t1 = this.c0.c0.conjugate(); let t2 = this.c1.c0.conjugate(); let t3 = this.c0.c1.conjugate(); let t4 = this.c1.c1.conjugate(); let t5 = this.c0.c2.conjugate(); let t6 = this.c1.c2.conjugate(); t2 = t2.mul(GAMMA_3S[0]); t3 = t3.mul(GAMMA_3S[1]); t4 = t4.mul(GAMMA_3S[2]); t5 = t5.mul(GAMMA_3S[3]); t6 = t6.mul(GAMMA_3S[4]); const c0 = new Fp6({ c0: t1, c1: t3, c2: t5 }); const c1 = new Fp6({ c0: t2, c1: t4, c2: t6 }); return new Fp12({ c0, c1 }); } frobenius_pow_p_cubed_with_gammas(gamma_3s) { const t1 = this.c0.c0.conjugate(); let t2 = this.c1.c0.conjugate(); let t3 = this.c0.c1.conjugate(); let t4 = this.c1.c1.conjugate(); let t5 = this.c0.c2.conjugate(); let t6 = this.c1.c2.conjugate(); t2 = t2.mul(gamma_3s[0]); t3 = t3.mul(gamma_3s[1]); t4 = t4.mul(gamma_3s[2]); t5 = t5.mul(gamma_3s[3]); t6 = t6.mul(gamma_3s[4]); const c0 = new Fp6({ c0: t1, c1: t3, c2: t5 }); const c1 = new Fp6({ c0: t2, c1: t4, c2: t6 }); return new Fp12({ c0, c1 }); } // when this is not in cyclotomic group (i.e. x^(p^6 + 1) not 1 ) pow(expBeWnaf) { let inv = this.inverse(); let c = new Fp12({ c0: this.c0, c1: this.c1 }); const n = expBeWnaf.length; for (let i = 1; i < n; i++) { c = c.square(); if (expBeWnaf[i] == 1) { c = c.mul(this); } else if (expBeWnaf[i] == -1) { c = c.mul(inv); } } return c; } // e = 6x + 2 + p - p^2 + p^3 exp_e() { const c0 = this.pow(ATE_LOOP_COUNT); const c1 = this.frobenius_pow_p(); const c2 = this.frobenius_pow_p_squared().inverse(); const c3 = this.frobenius_pow_p_cubed(); return c0.mul(c1).mul(c2).mul(c3); } display(name) { console.log(`${name}.g00: `, this.c0.c0.c0.toBigInt()); console.log(`${name}.g01: `, this.c0.c0.c1.toBigInt()); console.log(`${name}.g10: `, this.c0.c1.c0.toBigInt()); console.log(`${name}.g11: `, this.c0.c1.c1.toBigInt()); console.log(`${name}.g20: `, this.c0.c2.c0.toBigInt()); console.log(`${name}.g21: `, this.c0.c2.c1.toBigInt()); console.log(`${name}.h00: `, this.c1.c0.c0.toBigInt()); console.log(`${name}.h01: `, this.c1.c0.c1.toBigInt()); console.log(`${name}.h10: `, this.c1.c1.c0.toBigInt()); console.log(`${name}.h11: `, this.c1.c1.c1.toBigInt()); console.log(`${name}.h20: `, this.c1.c2.c0.toBigInt()); console.log(`${name}.h21: `, this.c1.c2.c1.toBigInt()); } toJSON() { const f = { g00: this.c0.c0.c0.toBigInt().toString(), g01: this.c0.c0.c1.toBigInt().toString(), g10: this.c0.c1.c0.toBigInt().toString(), g11: this.c0.c1.c1.toBigInt().toString(), g20: this.c0.c2.c0.toBigInt().toString(), g21: this.c0.c2.c1.toBigInt().toString(), h00: this.c1.c0.c0.toBigInt().toString(), h01: this.c1.c0.c1.toBigInt().toString(), h10: this.c1.c1.c0.toBigInt().toString(), h11: this.c1.c1.c1.toBigInt().toString(), h20: this.c1.c2.c0.toBigInt().toString(), h21: this.c1.c2.c1.toBigInt().toString(), }; return JSON.stringify(f); } static loadFromJSON(json) { const g00 = FpC.from(json.g00); const g01 = FpC.from(json.g01); const g0 = new Fp2({ c0: g00, c1: g01 }); const g10 = FpC.from(json.g10); const g11 = FpC.from(json.g11); const g1 = new Fp2({ c0: g10, c1: g11 }); const g20 = FpC.from(json.g20); const g21 = FpC.from(json.g21); const g2 = new Fp2({ c0: g20, c1: g21 }); const g = new Fp6({ c0: g0, c1: g1, c2: g2 }); const h00 = FpC.from(json.h00); const h01 = FpC.from(json.h01); const h0 = new Fp2({ c0: h00, c1: h01 }); const h10 = FpC.from(json.h10); const h11 = FpC.from(json.h11); const h1 = new Fp2({ c0: h10, c1: h11 }); const h20 = FpC.from(json.h20); const h21 = FpC.from(json.h21); const h2 = new Fp2({ c0: h20, c1: h21 }); const h = new Fp6({ c0: h0, c1: h1, c2: h2 }); return new Fp12({ c0: g, c1: h }); } } export { Fp12 }; //# sourceMappingURL=fp12.js.map