diff --git a/setup.sh b/setup.sh old mode 100644 new mode 100755 diff --git a/verifier_circuit/src/alphas.ts b/verifier_circuit/src/alphas.ts new file mode 100644 index 00000000..9b326011 --- /dev/null +++ b/verifier_circuit/src/alphas.ts @@ -0,0 +1,39 @@ +import { ArgumentType } from "./circuits/gate" +import { Scalar } from "o1js" + +/** + * This type can be used to create a mapping between powers of alpha and constraint types. + * See `default()` to create one (not implemented yet), + * and `register()` to register a new mapping (not implemented yet). + * Once you know the alpha value, you can convert this type to a `Alphas`. +*/ +export class Alphas { + /** + * The next power of alpha to use. + * The end result will be [1, alpha^(next_power - 1)] + */ + next_power: number + /** The mapping between constraint types and powers of alpha */ + mapping: Map + /** + * The powers of alpha: 1, alpha, alpha^2, .. + * If not undefined, you can't register new contraints. + */ + alphas?: Scalar[] + + /** + * Instantiates the ranges with an actual field element `alpha`. + * Once you call this function, you cannot register new constraints. + */ + instantiate(alpha: Scalar) { + let last_power = Scalar.from(1); + let alphas = Array(this.next_power); + alphas.push(last_power); + + for (let _ = 1; _ < this.next_power; _++) { + last_power = last_power.mul(alpha); + alphas.push(last_power); + } + this.alphas = alphas; + } +} diff --git a/verifier_circuit/src/circuits/gate.ts b/verifier_circuit/src/circuits/gate.ts new file mode 100644 index 00000000..77bd2b0a --- /dev/null +++ b/verifier_circuit/src/circuits/gate.ts @@ -0,0 +1,62 @@ +export enum GateType { + /** Zero gate */ + Zero, + /** Generic arithmetic gate */ + Generic, + /** Poseidon permutation gate */ + Poseidon, + /** Complete EC addition in Affine form */ + CompleteAdd, + /** EC variable base scalar multiplication */ + VarBaseMul, + /** EC variable base scalar multiplication with group endomorphim optimization */ + EndoMul, + /** Gate for computing the scalar corresponding to an endoscaling */ + EndoMulScalar, + /** Lookup */ + Lookup, + // Cairo + CairoClaim, + CairoInstruction, + CairoFlags, + CairoTransition, + // Range check + RangeCheck0, + RangeCheck1, + ForeignFieldAdd, + ForeignFieldMul, + // Gates for Keccak + Xor16, + Rot64, +} + +/** + * A constraint type represents a polynomial that will be part of the final + * equation f (the circuit equation) + */ +export namespace ArgumentType { + /** + * Gates in the PLONK constraint system. + * As gates are mutually exclusive (a single gate is set per row), + * we can reuse the same powers of alpha across gates. + */ + export type Gate = { + kind: "gate", + type: GateType + } + + /** The permutation argument */ + export type Permutation = { + kind: "permutation", + } + + /** The lookup argument */ + export type Lookup = { + kind: "lookup", + } +} + +export type ArgumentType = + | ArgumentType.Gate + | ArgumentType.Permutation + | ArgumentType.Lookup diff --git a/verifier_circuit/src/poly_commitment/commitment.test.ts b/verifier_circuit/src/poly_commitment/commitment.test.ts new file mode 100644 index 00000000..8af3b85b --- /dev/null +++ b/verifier_circuit/src/poly_commitment/commitment.test.ts @@ -0,0 +1,23 @@ +import { Scalar } from "o1js" +import { bPoly, bPolyCoefficients } from "./commitment"; + +test("bPoly", () => { + const coeffs = [42, 25, 420].map(Scalar.from); + const x = Scalar.from(10); + + const res = bPoly(coeffs, x); + const expected = Scalar.from(15809371031233); + // expected value taken from verify_circuit_tests/ + + expect(res).toEqual(expected); +}) + +test("bPolyCoefficients", () => { + const coeffs = [42, 25].map(Scalar.from); + + const res = bPolyCoefficients(coeffs); + const expected = [1, 19, 42]; + // expected values taken from verify_circuit_tests/ + + expect(res).toEqual(expected); +}) diff --git a/verifier_circuit/src/poly_commitment/commitment.ts b/verifier_circuit/src/poly_commitment/commitment.ts index 621d0e8f..f6299aec 100644 --- a/verifier_circuit/src/poly_commitment/commitment.ts +++ b/verifier_circuit/src/poly_commitment/commitment.ts @@ -1,6 +1,6 @@ import { Group, Scalar } from "o1js"; -/* +/** * A polynomial commitment */ export class PolyComm { @@ -12,7 +12,7 @@ export class PolyComm { this.shifted = shifted; } - /* + /** * Zips two commitments into one */ zip(other: PolyComm): PolyComm<[A, B]> { @@ -22,7 +22,7 @@ export class PolyComm { return new PolyComm<[A, B]>(unshifted, shifted); } - /* + /** * Maps over self's `unshifted` and `shifted` */ map(f: (x: A) => B): PolyComm { @@ -31,7 +31,7 @@ export class PolyComm { return new PolyComm(unshifted, shifted); } - /* + /** * Execute a simple multi-scalar multiplication */ static naiveMSM(points: Group[], scalars: Scalar[]) { @@ -46,7 +46,7 @@ export class PolyComm { return result; } - /* + /** * Executes multi-scalar multiplication between scalars `elm` and commitments `com`. * If empty, returns a commitment with the point at infinity. */ @@ -94,10 +94,49 @@ export class PolyComm { } } -/* -* Represents a blinded commitment -*/ +/** + * Represents a blinded commitment + */ export class BlindedCommitment { commitment: PolyComm blinders: PolyComm } + +/** + * Returns the product of all elements of `xs` + */ +export function product(xs: Scalar[]): Scalar { + return xs.reduce((acc, x) => acc.mul(x), Scalar.from(1)); +} + +/** + * Returns (1 + chal[-1] x)(1 + chal[-2] x^2)(1 + chal[-3] x^4) ... + */ +export function bPoly(chals: Scalar[], x: Scalar): Scalar { + const k = chals.length; + + let prev_x_squared = x; + let terms = []; + for (let i = k - 1; i >= 0; i--) { + terms.push(Scalar.from(1).add(chals[i].mul(prev_x_squared))); + prev_x_squared = prev_x_squared.mul(prev_x_squared); + } + + return product(terms); +} + +export function bPolyCoefficients(chals: Scalar[]) { + const rounds = chals.length; + const s_length = 1 << rounds; + + let s = Array(s_length).fill(Scalar.from(1)); + let k = 0; + let pow = 1; + for (let i = 1; i < s_length; i++) { + k += i === pow ? 1 : 0; + pow <<= i === pow ? 1 : 0; + s[i] = s[i - (pow >> 1)].mul(chals[rounds - 1 - (k - 1)]); + } + + return s; +} diff --git a/verifier_circuit/src/polynomial.ts b/verifier_circuit/src/polynomial.ts index 4e2236e7..391b9218 100644 --- a/verifier_circuit/src/polynomial.ts +++ b/verifier_circuit/src/polynomial.ts @@ -14,4 +14,9 @@ export class Polynomial { } return result } + + static buildAndEvaluate(coeffs: Scalar[], x: Scalar): Scalar { + const poly = new Polynomial(coeffs); + return poly.evaluate(x); + } } diff --git a/verifier_circuit/src/prover/prover.ts b/verifier_circuit/src/prover/prover.ts index d62f6ffc..8f6bc38c 100644 --- a/verifier_circuit/src/prover/prover.ts +++ b/verifier_circuit/src/prover/prover.ts @@ -1,16 +1,20 @@ import { Polynomial } from "../polynomial.js" import { Field, Group, Scalar } from "o1js" -import { PolyComm } from "../poly_commitment/commitment"; +import { PolyComm, bPoly, bPolyCoefficients } from "../poly_commitment/commitment"; import { getLimbs64 } from "../util/bigint"; import { Sponge } from "../verifier/sponge"; import { Verifier, VerifierIndex } from "../verifier/verifier.js"; +import { invScalar, powScalar } from "../util/scalar.js"; /** The proof that the prover creates from a ProverIndex `witness`. */ export class ProverProof { - evals: ProofEvaluations>> + evals: ProofEvaluations> prev_challenges: RecursionChallenge[] commitments: ProverCommitments + /** Required evaluation for Maller's optimization */ + ft_eval1: Scalar + constructor( evals: ProofEvaluations>, prev_challenges: RecursionChallenge[], @@ -24,7 +28,7 @@ export class ProverProof { /** * Will run the random oracle argument for removing prover-verifier interaction (Fiat-Shamir transform) */ - oracles(index: VerifierIndex, public_comm: PolyComm, public_input: Scalar[]) { + oracles(index: VerifierIndex, public_comm: PolyComm, public_input?: Scalar[]) { let sponge_test = new Sponge(); const fields = [Field.from(1), Field.from(2)]; fields.forEach((f) => { @@ -35,6 +39,14 @@ export class ProverProof { const endo_r = Scalar.from("0x397e65a7d7c1ad71aee24b27e308f0a61259527ec1d4752e619d1840af55f1b1"); // FIXME: ^ currently hard-coded, refactor this in the future + let chunk_size; + if (index.domain_size < index.max_poly_size) { + chunk_size = 1; + } else { + chunk_size = index.domain_size / index.max_poly_size; + } + + let zk_rows = index.zk_rows; //~ 1. Setup the Fq-Sponge. let fq_sponge = new Sponge(); @@ -99,257 +111,350 @@ export class ProverProof { // more-expensive 'optional sponge'. let fr_sponge_aux = new Sponge(); this.prev_challenges.forEach((prev) => fr_sponge_aux.absorbScalars(prev.chals)); - fr_sponge.absorbScalar(fr_sponge.digest()); - - // // prepare some often used values - // let zeta1 = zeta.pow([n]); - // let zetaw = zeta * index.domain.group_gen; - // let evaluation_points = [zeta, zetaw]; - // let powers_of_eval_points_for_chunks = PointEvaluations { - // zeta: zeta.pow([index.max_poly_size as u64]), - // zeta_omega: zetaw.pow([index.max_poly_size as u64]), - // }; - - // //~ 1. Compute evaluations for the previous recursion challenges. - // let polys: Vec<(PolyComm, _)> = self - // .prev_challenges - // .iter() - // .map(|challenge| { - // let evals = challenge.evals( - // index.max_poly_size, - // &evaluation_points, - // &[ - // powers_of_eval_points_for_chunks.zeta, - // powers_of_eval_points_for_chunks.zeta_omega, - // ], - // ); - // let RecursionChallenge { chals: _, comm } = challenge; - // (comm.clone(), evals) - // }) - // .collect(); - - // // retrieve ranges for the powers of alphas - // let mut all_alphas = index.powers_of_alpha.clone(); - // all_alphas.instantiate(alpha); - - // // compute Lagrange base evaluation denominators - // let w: Vec<_> = index.domain.elements().take(public_input.len()).collect(); - - // let mut zeta_minus_x: Vec<_> = w.iter().map(|w| zeta - w).collect(); - - // w.iter() - // .take(public_input.len()) - // .for_each(|w| zeta_minus_x.push(zetaw - w)); - - // ark_ff::fields::batch_inversion::(&mut zeta_minus_x); - - // //~ 1. Evaluate the negated public polynomial (if present) at $\zeta$ and $\zeta\omega$. - // //~ - // //~ NOTE: this works only in the case when the poly segment size is not smaller than that of the domain. - // let public_evals = if public_input.is_empty() { - // [vec![G::ScalarField::zero()], vec![G::ScalarField::zero()]] - // } else { - // [ - // vec![ - // (public_input - // .iter() - // .zip(zeta_minus_x.iter()) - // .zip(index.domain.elements()) - // .map(|((p, l), w)| -*l * p * w) - // .fold(G::ScalarField::zero(), |x, y| x + y)) - // * (zeta1 - G::ScalarField::one()) - // * index.domain.size_inv, - // ], - // vec![ - // (public_input - // .iter() - // .zip(zeta_minus_x[public_input.len()..].iter()) - // .zip(index.domain.elements()) - // .map(|((p, l), w)| -*l * p * w) - // .fold(G::ScalarField::zero(), |x, y| x + y)) - // * index.domain.size_inv - // * (zetaw.pow([n]) - G::ScalarField::one()), - // ], - // ] - // }; - - // //~ 1. Absorb the unique evaluation of ft: $ft(\zeta\omega)$. - // fr_sponge.absorb(&self.ft_eval1); - - // //~ 1. Absorb all the polynomial evaluations in $\zeta$ and $\zeta\omega$: - // //~~ * the public polynomial - // //~~ * z - // //~~ * generic selector - // //~~ * poseidon selector - // //~~ * the 15 register/witness - // //~~ * 6 sigmas evaluations (the last one is not evaluated) - // fr_sponge.absorb_multiple(&public_evals[0]); - // fr_sponge.absorb_multiple(&public_evals[1]); - // fr_sponge.absorb_evaluations(&self.evals); - - // //~ 1. Sample $v'$ with the Fr-Sponge. - // let v_chal = fr_sponge.challenge(); - - // //~ 1. Derive $v$ from $v'$ using the endomorphism (TODO: specify). - // let v = v_chal.to_field(endo_r); - - // //~ 1. Sample $u'$ with the Fr-Sponge. - // let u_chal = fr_sponge.challenge(); - - // //~ 1. Derive $u$ from $u'$ using the endomorphism (TODO: specify). - // let u = u_chal.to_field(endo_r); - - // //~ 1. Create a list of all polynomials that have an evaluation proof. - - // let evals = self.evals.combine(&powers_of_eval_points_for_chunks); - - // //~ 1. Compute the evaluation of $ft(\zeta)$. - // let ft_eval0 = { - // let zkp = index.zkpm().evaluate(&zeta); - // let zeta1m1 = zeta1 - G::ScalarField::one(); - - // let mut alpha_powers = - // all_alphas.get_alphas(ArgumentType::Permutation, permutation::CONSTRAINTS); - // let alpha0 = alpha_powers - // .next() - // .expect("missing power of alpha for permutation"); - // let alpha1 = alpha_powers - // .next() - // .expect("missing power of alpha for permutation"); - // let alpha2 = alpha_powers - // .next() - // .expect("missing power of alpha for permutation"); - - // let init = (evals.w[PERMUTS - 1].zeta + gamma) * evals.z.zeta_omega * alpha0 * zkp; - // let mut ft_eval0 = evals - // .w - // .iter() - // .zip(evals.s.iter()) - // .map(|(w, s)| (beta * s.zeta) + w.zeta + gamma) - // .fold(init, |x, y| x * y); - - // ft_eval0 -= if public_evals[0].is_empty() { - // G::ScalarField::zero() - // } else { - // public_evals[0][0] - // }; - - // ft_eval0 -= evals - // .w - // .iter() - // .zip(index.shift.iter()) - // .map(|(w, s)| gamma + (beta * zeta * s) + w.zeta) - // .fold(alpha0 * zkp * evals.z.zeta, |x, y| x * y); - - // let numerator = ((zeta1m1 * alpha1 * (zeta - index.w())) - // + (zeta1m1 * alpha2 * (zeta - G::ScalarField::one()))) - // * (G::ScalarField::one() - evals.z.zeta); - - // let denominator = (zeta - index.w()) * (zeta - G::ScalarField::one()); - // let denominator = denominator.inverse().expect("negligible probability"); - - // ft_eval0 += numerator * denominator; - - // let constants = Constants { - // alpha, - // beta, - // gamma, - // joint_combiner: joint_combiner.as_ref().map(|j| j.1), - // endo_coefficient: index.endo, - // mds: &G::sponge_params().mds, - // }; - - // ft_eval0 -= PolishToken::evaluate( - // &index.linearization.constant_term, - // index.domain, - // zeta, - // &evals, - // &constants, - // ) - // .unwrap(); - - // ft_eval0 - // }; - - // let combined_inner_product = { - // let ft_eval0 = vec![ft_eval0]; - // let ft_eval1 = vec![self.ft_eval1]; - - // #[allow(clippy::type_complexity)] - // let mut es: Vec<(Vec>, Option)> = - // polys.iter().map(|(_, e)| (e.clone(), None)).collect(); - // es.push((public_evals.to_vec(), None)); - // es.push((vec![ft_eval0, ft_eval1], None)); - // for col in [ - // Column::Z, - // Column::Index(GateType::Generic), - // Column::Index(GateType::Poseidon), - // ] - // .into_iter() - // .chain((0..COLUMNS).map(Column::Witness)) - // .chain((0..COLUMNS).map(Column::Coefficient)) - // .chain((0..PERMUTS - 1).map(Column::Permutation)) - // .chain( - // index - // .lookup_index - // .as_ref() - // .map(|li| { - // (0..li.lookup_info.max_per_row + 1) - // .map(Column::LookupSorted) - // .chain([Column::LookupAggreg, Column::LookupTable].into_iter()) - // .chain( - // li.runtime_tables_selector - // .as_ref() - // .map(|_| [Column::LookupRuntimeTable].into_iter()) - // .into_iter() - // .flatten(), - // ) - // }) - // .into_iter() - // .flatten(), - // ) { - // es.push(( - // { - // let evals = self - // .evals - // .get_column(col) - // .ok_or(VerifyError::MissingEvaluation(col))?; - // vec![evals.zeta.clone(), evals.zeta_omega.clone()] - // }, - // None, - // )) - // } - - // combined_inner_product(&evaluation_points, &v, &u, &es, index.srs().g.len()) - // }; - - // let oracles = RandomOracles { - // joint_combiner, - // beta, - // gamma, - // alpha_chal, - // alpha, - // zeta, - // v, - // u, - // zeta_chal, - // v_chal, - // u_chal, - // }; - - // Ok(OraclesResult { - // fq_sponge, - // digest, - // oracles, - // all_alphas, - // public_evals, - // powers_of_eval_points_for_chunks, - // polys, - // zeta1, - // ft_eval0, - // combined_inner_product, - // }) - }// + fr_sponge.absorbScalar(fr_sponge_aux.digest()); + + // prepare some often used values + + let zeta1 = powScalar(zeta, n); + const zetaw = zeta.mul(index.domain_gen); + const evaluation_points = [zeta, zetaw]; + const powers_of_eval_points_for_chunks: PointEvaluations = { + zeta: powScalar(zeta, index.max_poly_size), + zetaOmega: powScalar(zetaw, index.max_poly_size) + }; + + //~ 20. Compute evaluations for the previous recursion challenges. + const polys = this.prev_challenges.map((chal) => { + const evals = chal.evals( + index.max_poly_size, + evaluation_points, + [ + powers_of_eval_points_for_chunks.zeta, + powers_of_eval_points_for_chunks.zetaOmega + ] + ); + return [chal.comm, evals]; + }); + + // retrieve ranges for the powers of alphas + let all_alphas = index.powers_of_alpha; + all_alphas.instantiate(alpha); + + let public_evals: Scalar[][] | undefined; + if (this.evals.public_input) { + public_evals = [this.evals.public_input.zeta, this.evals.public_input.zetaOmega]; + } else if (chunk_size > 1) { + // FIXME: missing public input eval error + } else if (public_input) { + // compute Lagrange base evaluation denominators + let w = [Scalar.from(1)]; + for (let i = 0; i < public_input.length; i++) { + w.push(powScalar(index.domain_gen, i)); + } + + let zeta_minus_x = w.map((w_i) => zeta.sub(w_i)); + + w.forEach((w_i) => zeta_minus_x.push(zetaw.sub(w_i))) + + zeta_minus_x = zeta_minus_x.map(invScalar); + + //~ 21. Evaluate the negated public polynomial (if present) at $\zeta$ and $\zeta\omega$. + // NOTE: this works only in the case when the poly segment size is not smaller than that of the domain. + if (public_input.length === 0) { + public_evals = [[Scalar.from(0)], [Scalar.from(0)]]; + } else { + let pe_zeta = Scalar.from(0); + const min_len = Math.min( + zeta_minus_x.length, + w.length, + public_input.length + ); + for (let i = 0; i < min_len; i++) { + const p = public_input[i]; + const l = zeta_minus_x[i]; + const w_i = w[i]; + + pe_zeta = pe_zeta.add(l.neg().mul(p).mul(w_i)); + } + const size_inv = invScalar(Scalar.from(index.domain_size)); + pe_zeta = pe_zeta.mul(zeta1.sub(Scalar.from(1))).mul(size_inv); + + let pe_zetaOmega = Scalar.from(0); + const min_lenOmega = Math.min( + zeta_minus_x.length - public_input.length, + w.length, + public_input.length + ); + for (let i = 0; i < min_lenOmega; i++) { + const p = public_input[i]; + const l = zeta_minus_x[i + public_input.length]; + const w_i = w[i]; + + pe_zetaOmega = pe_zetaOmega.add(l.neg().mul(p).mul(w_i)); + } + pe_zetaOmega = pe_zetaOmega + .mul(powScalar(zetaw, n).sub(Scalar.from(1))) + .mul(size_inv); + + public_evals = [[pe_zeta], [pe_zetaOmega]]; + } + } else { + public_evals = undefined; + // FIXME: missing public input eval error + } + + //~ 22. Absorb the unique evaluation of ft: $ft(\zeta\omega)$. + fr_sponge.absorbScalar(this.ft_eval1); + + //~ 23. Absorb all the polynomial evaluations in $\zeta$ and $\zeta\omega$: + //~~ * the public polynomial + //~~ * z + //~~ * generic selector + //~~ * poseidon selector + //~~ * the 15 register/witness + //~~ * 6 sigmas evaluations (the last one is not evaluated) + + fr_sponge.absorbScalars(public_evals![0]); + fr_sponge.absorbScalars(public_evals![1]); + fr_sponge.absorbEvals(this.evals) + + //~ 24. Sample $v'$ with the Fr-Sponge. + const v_chal = new ScalarChallenge(fr_sponge.challenge()); + + //~ 25. Derive $v$ from $v'$ using the endomorphism (TODO: specify). + const v = v_chal.toField(endo_r); + + //~ 26. Sample $u'$ with the Fr-Sponge. + const u_chal = new ScalarChallenge(fr_sponge.challenge()); + + //~ 27. Derive $u$ from $u'$ using the endomorphism (TODO: specify). + const u = u_chal.toField(endo_r); + + //~ 28. Create a list of all polynomials that have an evaluation proof. + + const evals = ProofEvaluations.combine(this.evals, powers_of_eval_points_for_chunks); + + //~ 29. Compute the evaluation of $ft(\zeta)$. + // let ft_eval0 = { + // let permutation_vanishing_polynomial = + // index.permutation_vanishing_polynomial_m().evaluate(&zeta); + // let zeta1m1 = zeta1 - G::ScalarField::one(); + + // let mut alpha_powers = + // all_alphas.get_alphas(ArgumentType::Permutation, permutation::CONSTRAINTS); + // let alpha0 = alpha_powers + // .next() + // .expect("missing power of alpha for permutation"); + // let alpha1 = alpha_powers + // .next() + // .expect("missing power of alpha for permutation"); + // let alpha2 = alpha_powers + // .next() + // .expect("missing power of alpha for permutation"); + + // let init = (evals.w[PERMUTS - 1].zeta + gamma) + // * evals.z.zeta_omega + // * alpha0 + // * permutation_vanishing_polynomial; + // let mut ft_eval0 = evals + // .w + // .iter() + // .zip(evals.s.iter()) + // .map(|(w, s)| (beta * s.zeta) + w.zeta + gamma) + // .fold(init, |x, y| x * y); + + // ft_eval0 -= DensePolynomial::eval_polynomial( + // &public_evals[0], + // powers_of_eval_points_for_chunks.zeta, + // ); + + // ft_eval0 -= evals + // .w + // .iter() + // .zip(index.shift.iter()) + // .map(|(w, s)| gamma + (beta * zeta * s) + w.zeta) + // .fold( + // alpha0 * permutation_vanishing_polynomial * evals.z.zeta, + // |x, y| x * y, + // ); + + // let numerator = ((zeta1m1 * alpha1 * (zeta - index.w())) + // + (zeta1m1 * alpha2 * (zeta - G::ScalarField::one()))) + // * (G::ScalarField::one() - evals.z.zeta); + + // let denominator = (zeta - index.w()) * (zeta - G::ScalarField::one()); + // let denominator = denominator.inverse().expect("negligible probability"); + + // ft_eval0 += numerator * denominator; + + // let constants = Constants { + // alpha, + // beta, + // gamma, + // joint_combiner: joint_combiner.as_ref().map(|j| j.1), + // endo_coefficient: index.endo, + // mds: &G::sponge_params().mds, + // zk_rows, + // }; + + // ft_eval0 -= PolishToken::evaluate( + // &index.linearization.constant_term, + // index.domain, + // zeta, + // &evals, + // &constants, + // ) + // .unwrap(); + + // ft_eval0 + // }; + + // let combined_inner_product = + // { + // let ft_eval0 = vec![ft_eval0]; + // let ft_eval1 = vec![self.ft_eval1]; + + // #[allow(clippy::type_complexity)] + // let mut es: Vec<(Vec>, Option)> = + // polys.iter().map(|(_, e)| (e.clone(), None)).collect(); + // es.push((public_evals.to_vec(), None)); + // es.push((vec![ft_eval0, ft_eval1], None)); + // for col in [ + // Column::Z, + // Column::Index(GateType::Generic), + // Column::Index(GateType::Poseidon), + // Column::Index(GateType::CompleteAdd), + // Column::Index(GateType::VarBaseMul), + // Column::Index(GateType::EndoMul), + // Column::Index(GateType::EndoMulScalar), + // ] + // .into_iter() + // .chain((0..COLUMNS).map(Column::Witness)) + // .chain((0..COLUMNS).map(Column::Coefficient)) + // .chain((0..PERMUTS - 1).map(Column::Permutation)) + // .chain( + // index + // .range_check0_comm + // .as_ref() + // .map(|_| Column::Index(GateType::RangeCheck0)), + // ) + // .chain( + // index + // .range_check1_comm + // .as_ref() + // .map(|_| Column::Index(GateType::RangeCheck1)), + // ) + // .chain( + // index + // .foreign_field_add_comm + // .as_ref() + // .map(|_| Column::Index(GateType::ForeignFieldAdd)), + // ) + // .chain( + // index + // .foreign_field_mul_comm + // .as_ref() + // .map(|_| Column::Index(GateType::ForeignFieldMul)), + // ) + // .chain( + // index + // .xor_comm + // .as_ref() + // .map(|_| Column::Index(GateType::Xor16)), + // ) + // .chain( + // index + // .rot_comm + // .as_ref() + // .map(|_| Column::Index(GateType::Rot64)), + // ) + // .chain( + // index + // .lookup_index + // .as_ref() + // .map(|li| { + // (0..li.lookup_info.max_per_row + 1) + // .map(Column::LookupSorted) + // .chain([Column::LookupAggreg, Column::LookupTable].into_iter()) + // .chain( + // li.runtime_tables_selector + // .as_ref() + // .map(|_| [Column::LookupRuntimeTable].into_iter()) + // .into_iter() + // .flatten(), + // ) + // .chain( + // self.evals + // .runtime_lookup_table_selector + // .as_ref() + // .map(|_| Column::LookupRuntimeSelector), + // ) + // .chain( + // self.evals + // .xor_lookup_selector + // .as_ref() + // .map(|_| Column::LookupKindIndex(LookupPattern::Xor)), + // ) + // .chain( + // self.evals + // .lookup_gate_lookup_selector + // .as_ref() + // .map(|_| Column::LookupKindIndex(LookupPattern::Lookup)), + // ) + // .chain( + // self.evals.range_check_lookup_selector.as_ref().map(|_| { + // Column::LookupKindIndex(LookupPattern::RangeCheck) + // }), + // ) + // .chain(self.evals.foreign_field_mul_lookup_selector.as_ref().map( + // |_| Column::LookupKindIndex(LookupPattern::ForeignFieldMul), + // )) + // }) + // .into_iter() + // .flatten(), + // ) { + // es.push(( + // { + // let evals = self + // .evals + // .get_column(col) + // .ok_or(VerifyError::MissingEvaluation(col))?; + // vec![evals.zeta.clone(), evals.zeta_omega.clone()] + // }, + // None, + // )) + // } + + // combined_inner_product(&evaluation_points, &v, &u, &es, index.srs().g.len()) + // }; + + // let oracles = RandomOracles { + // joint_combiner, + // beta, + // gamma, + // alpha_chal, + // alpha, + // zeta, + // v, + // u, + // zeta_chal, + // v_chal, + // u_chal, + // }; + + // Ok(OraclesResult { + // fq_sponge, + // digest, + // oracles, + // all_alphas, + // public_evals, + // powers_of_eval_points_for_chunks, + // polys, + // zeta1, + // ft_eval0, + // combined_inner_product, + // }) + } } export class Context { @@ -369,6 +474,8 @@ export class Context { * **Non chunked evaluations** `Field` is instantiated with a field, so they are single-sized#[serde_as] */ export class ProofEvaluations { + /* public input polynomials */ + public_input?: Evals /* witness polynomials */ w: Array // of size 15, total num of registers (columns) /* permutation polynomial */ @@ -387,12 +494,16 @@ export class ProofEvaluations { /* evaluation of the poseidon selector polynomial */ poseidonSelector: Evals - constructor(w: Array, - z: Evals, s: Array, + constructor( + w: Array, + z: Evals, + s: Array, coefficients: Array, - lookup: LookupEvaluations, genericSelector: Evals, - poseidonSelector: Evals) { + poseidonSelector: Evals, + lookup?: LookupEvaluations, + public_input?: Evals, + ) { this.w = w; this.z = z; this.s = s; @@ -400,6 +511,7 @@ export class ProofEvaluations { this.lookup = lookup; this.genericSelector = genericSelector; this.poseidonSelector = poseidonSelector; + this.public_input = public_input; return this; } @@ -414,6 +526,43 @@ export class ProofEvaluations { let ret = new PointEvaluations(zeta, zetaOmega); return ret; } + + map(f: (e: Evals) => Evals2): ProofEvaluations { + let { + w, + z, + s, + coefficients, + //lookup, + genericSelector, + poseidonSelector, + } = this; + + let public_input = undefined; + if (this.public_input) public_input = f(this.public_input); + + return new ProofEvaluations( + w.map(f), + f(z), + s.map(f), + coefficients.map(f), + f(genericSelector), + f(poseidonSelector), + undefined, // FIXME: ignoring lookup + public_input + ) + } + + static combine( + evals: ProofEvaluations>, + pt: PointEvaluations + ): ProofEvaluations> { + return evals.map((orig) => new PointEvaluations( + Polynomial.buildAndEvaluate(orig.zeta, pt.zeta), + Polynomial.buildAndEvaluate(orig.zetaOmega, pt.zetaOmega) + )); + } + /* pub fn combine(&self, pt: &PointEvaluations) -> ProofEvaluations> { self.map_ref(&|evals| PointEvaluations { @@ -478,6 +627,48 @@ export class PointEvaluations { export class RecursionChallenge { chals: Scalar[] comm: PolyComm + + evals( + max_poly_size: number, + evaluation_points: Scalar[], + powers_of_eval_points_for_chunks: Scalar[] + ): Scalar[][] { + const chals = this.chals; + // Comment copied from Kimchi code: + // + // No need to check the correctness of poly explicitly. Its correctness is assured by the + // checking of the inner product argument. + const b_len = 1 << chals.length; + let b: Scalar[] | undefined = undefined; + + return [0, 1, 2].map((i) => { + const full = bPoly(chals, evaluation_points[i]) + if (max_poly_size === b_len) { + return [full]; + } + + let betacc = Scalar.from(1); + let diffs: Scalar[] = []; + for (let j = max_poly_size; j < b_len; j++) { + let b_j; + if (b) { + b_j = b[j]; + } else { + const t = bPolyCoefficients(chals); + const res = t[j]; + b = t; + b_j = res; + } + + const ret = betacc.mul(b_j); + betacc = betacc.mul(evaluation_points[i]); + diffs.push(ret); + } + + const diff = diffs.reduce((x, y) => x.add(y), Scalar.from(0)); + return [full.sub(diff.mul(powers_of_eval_points_for_chunks[i])), diff]; + }); + } } export class ProverCommitments { diff --git a/verifier_circuit/src/serde/serde_proof.ts b/verifier_circuit/src/serde/serde_proof.ts index 336be8eb..bd4dbbd9 100644 --- a/verifier_circuit/src/serde/serde_proof.ts +++ b/verifier_circuit/src/serde/serde_proof.ts @@ -78,10 +78,7 @@ export function deserProofEvals(json: ProofEvalsJSON): ProofEvaluations(); - - return new ProofEvaluations(w, z, s, coefficients, lookup2, genericSelector, poseidonSelector); + return new ProofEvaluations(w, z, s, coefficients, genericSelector, poseidonSelector, lookup); } export function deserProverCommitments(json: ProverCommitmentsJSON): ProverCommitments { diff --git a/verifier_circuit/src/util/scalar.test.ts b/verifier_circuit/src/util/scalar.test.ts new file mode 100644 index 00000000..d9ce9e0d --- /dev/null +++ b/verifier_circuit/src/util/scalar.test.ts @@ -0,0 +1,20 @@ +import { Scalar } from "o1js"; +import { invScalar, powScalar } from "./scalar"; + +test("powScalar", () => { + const n = Scalar.from(42); + const exp = 5; + const res = Scalar.from(130691232); // from python + + expect(powScalar(n, exp)).toEqual(res); +}) + + +test("invScalar", () => { + // Create random Scalar + const rand_base = Scalar.from(Math.floor(Math.random() * 16)); + const rand_exp = Math.floor(Math.random() * 32); + const n = powScalar(rand_base, rand_exp); + + expect(n.mul(invScalar(n))).toEqual(Scalar.from(1)); +}) diff --git a/verifier_circuit/src/util/scalar.ts b/verifier_circuit/src/util/scalar.ts new file mode 100644 index 00000000..c353f659 --- /dev/null +++ b/verifier_circuit/src/util/scalar.ts @@ -0,0 +1,27 @@ +import { Scalar } from "o1js"; + +export function powScalar(f: Scalar, exp: number): Scalar { + let res = f; + for (let _ = 1; _ < exp; _++) { + res = res.mul(f); + } + return f +} + +export function powScalarBig(f: Scalar, exp: bigint): Scalar { + let res = f; + for (let _ = 1n; _ < exp; _++) { + res = res.mul(f); + } + return f +} + +export function invScalar(f: Scalar): Scalar { + if (f === Scalar.from(0)) { + return Scalar.from(0); + // FIXME: error + } + + // using fermat's little theorem: + return powScalarBig(f, Scalar.ORDER - 2n); +} diff --git a/verifier_circuit/src/verifier/sponge.ts b/verifier_circuit/src/verifier/sponge.ts index 06cd9416..d13b8b51 100644 --- a/verifier_circuit/src/verifier/sponge.ts +++ b/verifier_circuit/src/verifier/sponge.ts @@ -1,5 +1,6 @@ import { Field, Group, Poseidon, Scalar } from "o1js" import { PolyComm } from "../poly_commitment/commitment"; +import { PointEvaluations, ProofEvaluations } from "../prover/prover"; /** * Wrapper over o1js' poseidon `Sponge` class which extends its functionality. @@ -74,6 +75,37 @@ export class Sponge { if (commitment.shifted) this.absorbGroup(commitment.shifted); } + absorbEvals(evals: ProofEvaluations>) { + const { + public_input, + w, + z, + s, + coefficients, + //lookup, + genericSelector, + poseidonSelector + } = evals; + let points = [ + z, + genericSelector, + poseidonSelector, + ] + // arrays: + points = points.concat(w); + points = points.concat(s); + points = points.concat(coefficients); + + // optional: + if (public_input) points.push(public_input); + //if (lookup) points.push(lookup); // FIXME: ignoring lookups + + points.forEach((p) => { + this.absorbScalars.bind(this)(p.zeta); + this.absorbScalars.bind(this)(p.zetaOmega); + }); + } + /** * This squeezes until `numLimbs` 64-bit high entropy limbs are retrieved. */ diff --git a/verifier_circuit/src/verifier/verifier.ts b/verifier_circuit/src/verifier/verifier.ts index 44c4a384..11f95632 100644 --- a/verifier_circuit/src/verifier/verifier.ts +++ b/verifier_circuit/src/verifier/verifier.ts @@ -4,6 +4,7 @@ import { circuitMain, Circuit, Group, Scalar, public_, Field } from 'o1js'; import { PolyComm } from '../poly_commitment/commitment.js'; import { SRS } from '../SRS.js'; import { Sponge } from './sponge.js'; +import { Alphas } from '../alphas.js'; let steps: bigint[][]; try { @@ -20,7 +21,13 @@ let { g, h } = SRS.createFromJSON(); export class VerifierIndex { srs: SRS domain_size: number + domain_gen: Scalar + /** number of public inputs */ public: number + /** maximal size of polynomial section */ + max_poly_size: number + /** the number of randomized rows to achieve zero knowledge */ + zk_rows: number /** permutation commitments */ sigma_comm: PolyComm[] // size PERMUTS @@ -39,6 +46,9 @@ export class VerifierIndex { /** endoscalar multiplication scalar computation selector polynomial commitment */ endomul_scalar_comm: PolyComm + /** The mapping between powers of alpha and constraints */ + powers_of_alpha: Alphas + constructor( domain_size: number, public_size: number, diff --git a/verifier_circuit/test/proof.json b/verifier_circuit/test/proof.json index 8ca835df..31850157 100644 --- a/verifier_circuit/test/proof.json +++ b/verifier_circuit/test/proof.json @@ -3,206 +3,206 @@ "w": [ { "zeta": [ - "b7bf8c34e3f74900c634a846e8cfefdcf71dae4d6b7253f87c8686c3fe42c41c" + "77411ba9253a5268826e5d5ce819310f87effa3cb7dfd4d84c9f53a29c55d838" ], "zeta_omega": [ - "eb30a68efbd08aa9d633a28d1e7b155c1673ca5af63ce1045f30573dcf4e7204" + "84554ae03840f0d2264c24139e736a64006db432095c77237327d6da6e472131" ] }, { "zeta": [ - "5100acfa74425a767a17cf9e1425c346cd310384607d8ccc82eb423784eeff33" + "de18a16dc2511943c78864547df7e0cdb018e6def0a88dfeebf0d649c9f6e702" ], "zeta_omega": [ - "2449e017c5d0fb59a2278825f5af6205ad88e8589a62d60cec903b64bbb26907" + "926bd2c74ca4fe84015395a7fc28bb36d8ac06ca47344f65ffdbaf14b5b8c72f" ] }, { "zeta": [ - "08d957b0b2b018b8e7e9ca1207d22bc3fc85bac1c3f4ca32a657c83839d50d3b" + "c5ab870e08d3fd64e51060989cd1b033508de83a1fa97c8d72c9accbc673c23c" ], "zeta_omega": [ - "c3812c152660bf668d55910ab835cc81d721b747de5dbcefdc39a7879d6d1027" + "9c846a8e1bf2bb5ff718ce5fba19387427312e0f0536e18d2566909c849a572a" ] }, { "zeta": [ - "0d1710e6874a280975d4c7797f5bec63ba1174af845e2b37176e90a250fdc121" + "2e7f68ab37f1c3656b0b495b99b65a343dffa73c4a1c88d6959e326e038ced3c" ], "zeta_omega": [ - "3e9edf37af6e19aa1ba56bfc374f3828cd0ad3b1e5d4b467b859bc124f69fc38" + "a98d2018fa53af752b9990bb13e532cf119ce9839c278682410ea71d81453016" ] }, { "zeta": [ - "1812329ab1d277ad1c65e7e0d786043a7a2e120ca9d699f326a9bccc02d00321" + "48ff57974719e0657c87ad9f6ae0c0823ac28cb4f84c008c6a75b910f1c91012" ], "zeta_omega": [ - "680c1d33332b8cc0633504e7759ae21a548b5acc33737803d868b1260aa1b72a" + "69ec65ea896e6d84f1810443e5b20179461e42f46e2f34c447f62ed7435a053e" ] }, { "zeta": [ - "20d129bce3b7e509b6d4253104b889ffb91fc1ede7f1ab2feaadb57e4f769a2c" + "b7c7df18d41ba3af69ddb5622bd7433c7670adf825724707ab7752d3e8b07b23" ], "zeta_omega": [ - "05ef4dba51d7ddb1fce945cc8a52b92a0ce03be0b9c2666c4b322917ff394103" + "403128ac7c082141edc1f7135ad0db19a7eedc22fd4d8819909978d19486871e" ] }, { "zeta": [ - "88a445626334a6b0070330887e5510b0067508342ac44c9effbfb900bda21518" + "ba03c12ea791b1207db77994dc3aea85f29bfd34a0d19a819b370778c9c74f02" ], "zeta_omega": [ - "428bf11d65ab0aa4c06477bd60c4001382eeec4a83e8095abb75be9243517238" + "02c6dff65dc35ad9fb89474cb776b888dfb97b8bcf17363a7d1eee8ce6019838" ] }, { "zeta": [ - "8b4bc78185e7c1868966af518cded76e510140158060ee8cf860c89a6d6b853b" + "a89499ecdfb4847680641d6892ce0eae6d76b95de241288612ffda1f9f48bb01" ], "zeta_omega": [ - "daea15d894808e9f39158be8ca175a5ae434f2fbb319713b5e941d7568563f00" + "127357b3b60a405f8daf223eb05fad34fc11cd53582efaeed9fdb3cc4cc47137" ] }, { "zeta": [ - "3123130d4f570e09f8ac28933ed8b1ba4b0c3ebf860ab9d1605b42106db78717" + "a225b457ee74f55a07c967816b906185144238ab8ebdea592ba55fdf90d81839" ], "zeta_omega": [ - "e6172bf361fdd4f7c082fc86ca03d5e5d3beaea8857f10f1a17fe02438f34f0f" + "0c0d33cf848fce27ec919a7f2b0eb280d38b7095b58bf15aa0c471f22f9ee533" ] }, { "zeta": [ - "281482cc688e5a53d706c8bd73f2ccd353ebf593cd436191c3d639324405b61d" + "f8c0750a6de921b855050ac7512e71e5f2de49e218a947a92ea480e7acf25b3d" ], "zeta_omega": [ - "2e90b0f69e03bce27fd1a1ef3efa80a78dd69f07c432e9111e247a7e90f68507" + "ea00ddcf81a6c10ed5903cb858d60d54577b68a8c05c3ba7e625c51d4d887e16" ] }, { "zeta": [ - "68c1ae48fb20adf5611c78852241f1bfd321c0e969040045bc95a05a591df027" + "21238328dc44e33ade05070cfce6fa782fb921f67b189ee68b16504989f8562e" ], "zeta_omega": [ - "6dc09ccc001628be45746c458312353847866932d0a7a57ae1330ce5b63d3228" + "386a2e62cccb68173a1b472215e23dd7961d6246b079d1c3569a113395168127" ] }, { "zeta": [ - "f257fd7aab0402f8b832b973fb5ed570edd115fdfe0c419f21a0fa5e47178318" + "362658dbd5638c8762bd79a87119ea42aae7fefdfdb17a3f950f1f5e95a33e02" ], "zeta_omega": [ - "b8c62326b1af1650d9eca1eec077c9ccd087409cdca08a7e859512f2f5c4bb30" + "32d00f082c4831258079dbecea040d00b88aaf66acb0407384aa7152c1be7135" ] }, { "zeta": [ - "c0f11b627e92a715b6b43316c3fd46fc3bc5566ebcc73fdb80a2bc79a751d80c" + "9995519ce75b351118524fec10b579d60d833915151549ad2fe5dc2fdffe6537" ], "zeta_omega": [ - "e80f5cdeb49b704e5d06a5dda0be909d1b152ba532164f1b682c805c36dccd38" + "ea863ad41e67e96f0a7da2dcc3ae736baf471a2d591fd93f0be74a0b999b6631" ] }, { "zeta": [ - "05d79030ff4a45719e5cf0c76577bcdf499fa0b00b60c459f36054ea1f27df0e" + "009f40255180603ee81eb1ba364a39c764431fbbae6e79fd9e8795e3047c752e" ], "zeta_omega": [ - "0e2e9a7e0c2799187b1880c016e30e32f1f0dc4a8162d8a55d652f185280412f" + "25a6e3339eb70d82d6c6ab6e75e5144c107f25eceafae63e8cbe98418863941c" ] }, { "zeta": [ - "18699cb299d8123abbda8e2c762e7ca1dc2e03b07e9d03de36f5f06b99944722" + "7bc5eb4d2b9cd1509757a75f5aca6e56304c4f602e96a080bc1e624baf441303" ], "zeta_omega": [ - "7acc8d865326797f0816638da0066e0921cfd2f7ee46ac35a31abe6af6eb3715" + "b4b3819a7e3dfe61da6ea9bec51f401a7bd1059332b32781f2b243e7be82cc35" ] } ], "z": { "zeta": [ - "7796b40453a9d14c4ca0cd85b8a5ba5e6a1cd09f07ef577240a4324b8714bc1c" + "2ce02aa25358a397c5be9f03b0f9e0240a0d1009d283b6c517f5e2bf0ddc5634" ], "zeta_omega": [ - "5d4176b0c8be3b064112713b23db11b7ec70f1bc76d607ce2e61ae04a59baa16" + "509a47782492f31692975e7180a841273a3eb6dda02b5281c2894e233b5de127" ] }, "s": [ { "zeta": [ - "79e4ac4578293c16d23b4fe201b921d17032d899c4a68885cc541eec71a2f33e" + "cae0a15147c6d5b1dd182f49ca563711437061eaf77c3647d0b0acf8db634134" ], "zeta_omega": [ - "7eccfbd1e200852f42b255f94296943f88f325ac8fa3d32373e656fc8b9e9033" + "ff412e9377989fd2e11b6c2aa9be413aaa7493cf92a47b4e33cf8091b1eb431a" ] }, { "zeta": [ - "2c2f9d6670fc5b52450c7d87ae1e8a6e986c6f028f49e3fc7748073b11f4323b" + "4d99d4c99ed542d2b91e229ada365f501fbed0789cb7ec6c692786fc3f60c323" ], "zeta_omega": [ - "45b2694550d733f70fe5d7931d4c04e89b6ec2357ca6cce3f38da82a634fed34" + "72c2305096ea489887705df32e5c77e8210ce0e4126d3e672f8755f729833229" ] }, { "zeta": [ - "8b7dcb15009576293fb8280797f431e0a0a30620420f0fd2bf7656393c86130e" + "68b1edb8ad2b8c524a68b7139ee59cb3ffed6fe1b9ea05e14836c9c4286eb129" ], "zeta_omega": [ - "ef15d2d4b1364a3cd1c755b1f89a4e4d60008b7a8196e02095db95ba1329af02" + "715257823eec069463fdfa33a664c270437ce0509d25ce10f43f3ad9aa76f416" ] }, { "zeta": [ - "4a211114d1fce49bcdb0db3ae1f31df9f63e80015b9e52a687b1cf3e281bff23" + "ae711e657d1e23a3e2725ec24f222512bcaf25ea79b9a71532a6253855acbb27" ], "zeta_omega": [ - "808faca7cf98b49514f1f340f49ad42f4dd2fa9851d03cf011a100bbc423e102" + "42c3d2cf734fcd10950fcd31fffe81171a30f497b431b383877176dc7cbaf62f" ] }, { "zeta": [ - "fd6f0cce5f56bd7288c49a6761974da323bd30eb52d573f7a5ea4e810ddf1721" + "f02bfde1e995bdfcfd11b058c21344b138a899a5dce314e0c7f707cb8c7d490e" ], "zeta_omega": [ - "7e007d367be70a818a0956bc42bcbebfdf8606a306b240afb6c817165cc78f3d" + "3911674ae835f2254934121e41910b741b9cfdc19f99913d7a4129e88ad4482b" ] }, { "zeta": [ - "3a858a165ee614b69a505deec6ee511df35ff4a91531a13f6b12020f56fd6726" + "c1cb3c021a28cce6669a1479ab09602ab5d62b62ce95cbaa4263f13eb7a0ff2e" ], "zeta_omega": [ - "09c1b99984426352bf82bde4e46db17934932c434522d6a1a8bfe0bf48c5be3a" + "d139d4c2a2a4e1be24f94c595cd98afadccab20278c3b4b8323b45b45a44fa01" ] } ], "coefficients": [ { "zeta": [ - "c63b677ad73972fc0b62f9752c8d168d1c1af6517e249e6560119c05490c2912" + "0a8120882621768064b42e873c9fff0bd1cef0829761e874a6979ac914a7ee20" ], "zeta_omega": [ - "872bd8572f4fe3e843ee9278dec97530bdaacb7a0229bcb6d86c755b295ddb0d" + "1e284313e276c29511cad8a6bae9e56b898dd31315909f4dc4d360fc26f79e09" ] }, { "zeta": [ - "44ceef5b76d361d5daeff72f366ea168b266606aa0073821bc0b1f4e9d582108" + "9c0fef9e13bb54b5be59b9ccedf68ec0e0837e38ed8a70a8e8c1de06b26fdb2f" ], "zeta_omega": [ - "8a5309c9c61ac31c94fae4fc9b81b0a370110c74ef92dc5b8c90952d9e126320" + "d52ca9183c0b2875ca0ad0a96de10d3ad966555f826277cf602945da60c7503a" ] }, { "zeta": [ - "ea65058cee006416a020bb4bebeba39ec4dddf3175fd979f16fc4a3b76e2f427" + "77a505cb5965fb9c5f1a49145a8b9220b57e804206278572b2140b536f856105" ], "zeta_omega": [ - "7d3952121ef02b25c3e48f5975b2dcd42ffafb8305cf0b8c2625cef075a4890a" + "ba9bc7f70c923965ef4f4f2682f841646288e38ad4892d1035f2e8618abd8f2c" ] }, { @@ -215,18 +215,18 @@ }, { "zeta": [ - "f31abaec1011526c9472a0d7ac5fa4e35c187e74259a5df09ad74a3dc233a611" + "7f8c8d06c14239c06ee5c14034b2d6be6d17acaf2666b749f5fa0eaa737a0f0d" ], "zeta_omega": [ - "f6d080c1591860eea5d8c09cfcbc95343911a903e817a837024a351b22fbd036" + "7bb4dfde95a6e0b395ac45b53d245cf63cbeda2343b298e613ae22e5ebe1731d" ] }, { "zeta": [ - "b0a16c06c63ad612ac82b4c11779ba2be1f7d583f3213605770de740bfee1d3a" + "812626538086711dc4ce779b962a922c864d71c59d886de758aca51c842c5026" ], "zeta_omega": [ - "04652a6a4d3f0f0e07d322d2537c5205eda4c7fe07f8c742ff91434c9f016518" + "d8c30a0bef08fcfa001a28cd3ce227d0eb15b79ee919cd5df9c5495eb1b42e36" ] }, { @@ -239,26 +239,26 @@ }, { "zeta": [ - "ea65058cee006416a020bb4bebeba39ec4dddf3175fd979f16fc4a3b76e2f427" + "77a505cb5965fb9c5f1a49145a8b9220b57e804206278572b2140b536f856105" ], "zeta_omega": [ - "7d3952121ef02b25c3e48f5975b2dcd42ffafb8305cf0b8c2625cef075a4890a" + "ba9bc7f70c923965ef4f4f2682f841646288e38ad4892d1035f2e8618abd8f2c" ] }, { "zeta": [ - "2e34f5e764d4c5eb7a10b37b215a45077744409c1505d0c0d2076a89133b1630" + "13b5f4696d2050521e7402e1478221e19502ff7af3b1f51a9bd6e95921f53c35" ], "zeta_omega": [ - "078d5bdbe40aef4157df745611348d78a00b08f8f461e8e7b2b5631e14b7ec2a" + "8ec8701028b21a4edcb18ac6f340097c3bef38ea56eca4df951b2e3ceb84e026" ] }, { "zeta": [ - "95d7e0dfc671335ff7be6067759fbcd09a28d26c3e56f1e5acbc7cbb43566a1d" + "7e3f4160e1209d11c4f0661303f6f887617cc924eb54dc7a43a2c3706b216f00" ], "zeta_omega": [ - "ee062cedbe9941d297327bf854c4f0295fc71906d82718b20326ae82e3f70606" + "cd2ccac8f96a76d64eca1e2ebc91999a65926ce66f7efe2a21228f2889781631" ] }, { @@ -305,10 +305,10 @@ "lookup": null, "generic_selector": { "zeta": [ - "c63b677ad73972fc0b62f9752c8d168d1c1af6517e249e6560119c05490c2912" + "0a8120882621768064b42e873c9fff0bd1cef0829761e874a6979ac914a7ee20" ], "zeta_omega": [ - "872bd8572f4fe3e843ee9278dec97530bdaacb7a0229bcb6d86c755b295ddb0d" + "1e284313e276c29511cad8a6bae9e56b898dd31315909f4dc4d360fc26f79e09" ] }, "poseidon_selector": { @@ -326,8 +326,8 @@ { "unshifted": [ { - "x": "17891892875055871057707654820593518437593973657648733977847965669597727989655", - "y": "12678698692268364153885756200595334207962486877854011334045624490056558416402" + "x": "12633880790950753786905061903449659284460688441469387448898415312852924838891", + "y": "9610877590746022888430632456486948369176178585628310581726898920529264841989" } ], "shifted": null @@ -335,8 +335,8 @@ { "unshifted": [ { - "x": "19982112771755820422619812738983107649683681595747905470668083079416056375283", - "y": "19595210036292495074255855479183894040090118114999470338608408013897173630274" + "x": "5678905031997765822053487190591160982795992676714141101026877273508046540114", + "y": "11559762729025918402874245287901974971618384558363696463248567149997593947447" } ], "shifted": null @@ -344,8 +344,8 @@ { "unshifted": [ { - "x": "4175356402475780750330226334884206294796531328904984219064072211264937374754", - "y": "14153077276789509547516034378203274957015622828066111407569313573999346414625" + "x": "13665109909051635290398532802517413093174042573395614553760127054937110913943", + "y": "14715409298231239926155564380445859775266010420117157391213691086078377783689" } ], "shifted": null @@ -353,8 +353,8 @@ { "unshifted": [ { - "x": "25954553292199394419693161052656780436258010059097683784291462417350551305175", - "y": "12532734665737788999368822957066680598767395591792964590595554963685999205423" + "x": "690627761202140066190052458492547528981517620476425347404673294194087899513", + "y": "23243436379189690243614910551673127649888237520944887818958221943442055316926" } ], "shifted": null @@ -362,8 +362,8 @@ { "unshifted": [ { - "x": "23423064986361450444114848607207244092945219110086884191763656398938457383496", - "y": "16972362343478760481632286418658386227897066151799027163964259055210524077252" + "x": "22547274866263884224783327833732012760410796762970553552563665307235891271799", + "y": "11234376405651968376341588174295203744329728440458927832886030475254518231785" } ], "shifted": null @@ -371,8 +371,8 @@ { "unshifted": [ { - "x": "5153510988701494014826619373584622538574994998146674763384863892056136575183", - "y": "7144507570502305695487184793232812896673455076405949336702963633088045334236" + "x": "19744844409274912355674295888442686548008317897560080373895549074552260450528", + "y": "24308975575803062485831165480564899043712091086819190720073251363529578229522" } ], "shifted": null @@ -380,8 +380,8 @@ { "unshifted": [ { - "x": "24974196155190875956580160220257268936966756258988148243233935128390642842219", - "y": "20234216752718985937120807253583387893068327864621147311593297000028143696653" + "x": "14088528168946294111078411637349552942593067129140124112473047650790234788064", + "y": "3504515007772430193554634130238304613264305018616633483825978531631395496948" } ], "shifted": null @@ -389,8 +389,8 @@ { "unshifted": [ { - "x": "26282358638408959673834884414182534751301444038767767212125866963270320612754", - "y": "178195256945723971512948496000376461222437929868281831508278482933877338457" + "x": "5502150242452056908433398946570494511662652183776626897585806721850849712007", + "y": "16721999312277688003798306405992388923086506645733044241140004015841743837290" } ], "shifted": null @@ -398,8 +398,8 @@ { "unshifted": [ { - "x": "22270601727946769101051561092997603102748451262123527815446750231213668301221", - "y": "10426549930818429634469880614903968292399097194464084558580277209957101221492" + "x": "4831442170859689201120735832875001673545263231843128938571024219776115027782", + "y": "10659182961798213377483205473346728548606150142485318485229331237931398547744" } ], "shifted": null @@ -407,8 +407,8 @@ { "unshifted": [ { - "x": "15541880029826579018357392225324736416904733331835413250676303196896794196951", - "y": "7834416355915273849575927269981352297282741006918376384105747043712826931260" + "x": "16823106900719801963634389132339768608720508428014772584450934729920201773666", + "y": "17914185791444808029671214112486854483473600625106504783192732754464819835691" } ], "shifted": null @@ -416,8 +416,8 @@ { "unshifted": [ { - "x": "2490187402242813487457805846181181939583571135352882000339301975390104800706", - "y": "15901781875934876394031290077358022459329217980171461371796413248412862380441" + "x": "16800107329163738640020897149337825819725032438233543368094124155643589842182", + "y": "5978741661421235329130281733552019458613590535912889034468027294548555216091" } ], "shifted": null @@ -425,8 +425,8 @@ { "unshifted": [ { - "x": "16502030927850576288405722954895265539182955080684362304973320809700155531832", - "y": "15058541116984333132397877152733813097442995227031849552972811088235216241249" + "x": "16736656329840968796591292364459861337726558145304943283688842219220739636048", + "y": "22141273336936688663079902865332653372906411588170278463285277886090038156733" } ], "shifted": null @@ -434,8 +434,8 @@ { "unshifted": [ { - "x": "14431983793826986552834362529259514353935366861037423091256470584660566819663", - "y": "28116823532514248922185725976291500060602203333434228427700177331531525672496" + "x": "9276787338820114884678917756595624201387047266892790806632778740204373456877", + "y": "21303132217207162831251009998256655166588135836104973604576899904852056835402" } ], "shifted": null @@ -443,8 +443,8 @@ { "unshifted": [ { - "x": "19641832141486457319277607587609582882570162089030117917830862577082565612924", - "y": "21607678054693962597419012444021709809091758799427049303938838248992517928601" + "x": "12441680528200550960679368076232679060550755309639638414873539026178917333077", + "y": "26165829476324833802834316422042485632318543961455835944997221767965281888005" } ], "shifted": null @@ -452,8 +452,8 @@ { "unshifted": [ { - "x": "6172283323648145215799399783321611937953391549222056490004487294331577969911", - "y": "1067852594922043355552528496194257047332212260934391872330319863266901709265" + "x": "20894687751680637558721501587395365289716730328080625855338858578902058221850", + "y": "6498417608825468684998325241064372519264189763122610415963774942020072567333" } ], "shifted": null @@ -462,8 +462,8 @@ "z_comm": { "unshifted": [ { - "x": "18284229914339298938164222725256982167537455349392626222468001693608883665051", - "y": "5785336212749582379249639970737035161878572122715475280842866607030833458660" + "x": "13959794191203869156413609967073288182298404414284799403512428914103408533422", + "y": "16818332628057911198906974249854045702390481128330768816398666947145685554486" } ], "shifted": null @@ -471,36 +471,36 @@ "t_comm": { "unshifted": [ { - "x": "10930820938963063680902194565730509367811309197753846797953405313873329480302", - "y": "27423066616412521819606209577662318739256944082138728395598110762811190640421" + "x": "19823149663976475582400986055925213562106277390850750059490402338793424663176", + "y": "4373903871534132299373024937476199301285839127196363101178016942292051581885" }, { - "x": "25837181759127048567461808166938702419348303485721756229334751534689276021531", - "y": "2152550139361544850746268432004280569486382237987263423590295434158737961091" + "x": "394661539423727111643595507569221785893208252614718429126007415843818311645", + "y": "13908331740019086595935698350134366197171950052948867707806765641883795567505" }, { - "x": "10306813574652459082317244631507066230791461684002640308570516109034509165682", - "y": "15532169473207797102674111331815681810711569132267485747281666937599338208297" + "x": "8757002646081709692398143564798886508221987272410231460482423411687401036945", + "y": "25881966993699941731015170136279697008828682224105843885381413128295672429024" }, { - "x": "28314210039006492628582015855420136461123626153862658662729251375850911456695", - "y": "22498968071049690035512766340364913991965560586584526689351584196458932449318" + "x": "18305815196607570282357402502704589345471934778654749834102563742173051905504", + "y": "8805749212497170531116302180185070223740008716637013554663728824586376105386" }, { - "x": "491368890145771119676792828256591023910755740397773620881401116416349364604", - "y": "10459912932965836256107304210490792251057644227116396984134060895110668636244" + "x": "3133624641959678518987326646118307443610073395642225291187718829451960110523", + "y": "146496891285888647293591851243004684977654452140409197472356073959743011343" }, { - "x": "7837993249016688080797363740411164470810970545723991789033812834494832596325", - "y": "27290540795137270806545709588185133377447016929713664618557184751497298885275" + "x": "25985122828215367010446058073796967769408756834280586385036260175611866077845", + "y": "24524249412843068389218589176443914941316775534826398557961336107476074388787" }, { - "x": "23221638274526969682015478777814876801031783081355068530625389770533423995793", - "y": "28873929251235734567231795601072639318148950142939498009207772385952381653070" + "x": "24231671673848340949057961436755272722836097930686429487910003839269988334316", + "y": "28109571819259923694080796257578269546587534526790250297699795975848727100881" } ], "shifted": null }, "lookup": null } -} +} \ No newline at end of file diff --git a/verifier_circuit_tests/src/main.rs b/verifier_circuit_tests/src/main.rs index f0dcb0ac..08839fcc 100644 --- a/verifier_circuit_tests/src/main.rs +++ b/verifier_circuit_tests/src/main.rs @@ -80,7 +80,7 @@ fn main() { #[cfg(test)] mod unit_tests { - use kimchi::mina_poseidon::sponge::ScalarChallenge; + use kimchi::{mina_poseidon::sponge::ScalarChallenge, poly_commitment::commitment::{b_poly, b_poly_coefficients}}; use num_bigint::BigUint; use verifier_circuit_tests::PallasScalar; @@ -96,6 +96,25 @@ mod unit_tests { let length_in_bits = 10; let result = chal.to_field_with_length(length_in_bits, &endo_coeff); - println!("{}", result); + println!("to_field_with_length: {}", result); + } + + #[test] + fn b_poly_test() { + // arbitrary values + let coeffs = vec![PallasScalar::from(42), PallasScalar::from(25), PallasScalar::from(420)]; + let x = PallasScalar::from(12); + + let result = b_poly(&coeffs, x); + println!("b_poly_test: {}", result); + } + + #[test] + fn b_poly_coefficients_test() { + // arbitrary values + let coeffs = vec![PallasScalar::from(42), PallasScalar::from(25)]; + + let result = b_poly_coefficients(&coeffs); + println!("b_poly_coefficients_test: {:?}", result); } }