Skip to content

Commit

Permalink
Partial verifier step 4 (#30)
Browse files Browse the repository at this point in the history
* WIP continuing fiat-shamir (step 20)

* Upto step 20 implemented

* Upto step 22

* Upto step 28

* Added tests

* Fix build errors

* Small fix

* Finished fiatshamir, except from some details

* Build fixes

* Fix errors

* Partially implemented PolishToken

* Implemented cell variant in evaluate

* Fix srs

* Format verifier_circuit_tests

* Ignore inv test

* Fixed scalar and polycomm tests

* Added extended euclidean for scalar inverse

* WIP updating VerifierIndex deser

* WIP

* WIP VerifierIndex serde

* Finished VerifierIndex serde

* Added ft_eval1 field to proof serde

* Fix absorbScalars()

* Fixed powers of alpha

* Fix alphas

* Finished fiat-shamir

* Fmt and tidy up rust crate

* Fix clippy

* Added 4th step

* Update kimchi branch (#31)

* Update kimchi branch

* Fix clippy
  • Loading branch information
xqft authored Oct 11, 2023
1 parent 101df38 commit 8287413
Show file tree
Hide file tree
Showing 13 changed files with 3,914 additions and 220 deletions.
24 changes: 20 additions & 4 deletions verifier_circuit/src/prover/expr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,22 @@ export class Variable {
point_evaluations = evals.genericSelector;
break;
}
case GateType.CompleteAdd: {
point_evaluations = evals.completeAddSelector;
break;
}
case GateType.VarBaseMul: {
point_evaluations = evals.mulSelector;
break;
}
case GateType.EndoMul: {
point_evaluations = evals.emulSelector;
break;
}
case GateType.EndoMulScalar: {
point_evaluations = evals.endomulScalarSelector;
break;
}
}
break;
}
Expand Down Expand Up @@ -144,8 +160,8 @@ export namespace PolishToken {
export type Sub = {
kind: "sub"
}
export type VanishesOnLast4Rows = {
kind: "vanishesonlast4rows"
export type VanishesOnZeroKnowledgeAndPreviousRows = {
kind: "vanishesonzeroknowledgeandpreviousrows"
}
export type UnnormalizedLagrangeBasis = {
kind: "unnormalizedlagrangebasis"
Expand Down Expand Up @@ -216,7 +232,7 @@ export namespace PolishToken {
stack.push(c.mds[t.row][t.col]);
break;
}
case "vanishesonlast4rows": {
case "vanishesonzeroknowledgeandpreviousrows": {
const ZK_ROWS = 3;
const w4 = powScalar(domain_gen, domain_size - (ZK_ROWS + 1));
const w3 = domain_gen.mul(w4);
Expand Down Expand Up @@ -312,7 +328,7 @@ export type PolishToken =
| PolishToken.Add
| PolishToken.Mul
| PolishToken.Sub
| PolishToken.VanishesOnLast4Rows
| PolishToken.VanishesOnZeroKnowledgeAndPreviousRows
| PolishToken.UnnormalizedLagrangeBasis
| PolishToken.Store
| PolishToken.Load
Expand Down
26 changes: 25 additions & 1 deletion verifier_circuit/src/prover/prover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export class ProverProof {
const evals = ProofEvaluations.combine(this.evals, powers_of_eval_points_for_chunks);

//~ 29. Compute the evaluation of $ft(\zeta)$.
const zkp = index.zkpm.evaluate(zeta);
const zkp = index.permutation_vanishing_polynomial_m.evaluate(zeta);
const zeta1m1 = zeta1.sub(Scalar.from(1));

const PERMUTATION_CONSTRAINTS = 3; // FIXME: hardcoded here
Expand Down Expand Up @@ -456,6 +456,14 @@ export class ProofEvaluations<Evals> {
genericSelector: Evals
/* evaluation of the poseidon selector polynomial */
poseidonSelector: Evals
/** evaluation of the elliptic curve addition selector polynomial */
completeAddSelector: Evals
/** evaluation of the elliptic curve variable base scalar multiplication selector polynomial */
mulSelector: Evals
/** evaluation of the endoscalar multiplication selector polynomial */
emulSelector: Evals
/** evaluation of the endoscalar multiplication scalar computation selector polynomial */
endomulScalarSelector: Evals

constructor(
w: Array<Evals>,
Expand All @@ -464,6 +472,10 @@ export class ProofEvaluations<Evals> {
coefficients: Array<Evals>,
genericSelector: Evals,
poseidonSelector: Evals,
completeAddSelector: Evals,
mulSelector: Evals,
emulSelector: Evals,
endomulScalarSelector: Evals,
lookup?: LookupEvaluations<Evals>,
public_input?: Evals,
) {
Expand All @@ -474,6 +486,10 @@ export class ProofEvaluations<Evals> {
this.lookup = lookup;
this.genericSelector = genericSelector;
this.poseidonSelector = poseidonSelector;
this.completeAddSelector = completeAddSelector;
this.mulSelector = mulSelector;
this.emulSelector = emulSelector;
this.endomulScalarSelector = endomulScalarSelector;
this.public_input = public_input;
return this;
}
Expand All @@ -499,6 +515,10 @@ export class ProofEvaluations<Evals> {
//lookup,
genericSelector,
poseidonSelector,
completeAddSelector,
mulSelector,
emulSelector,
endomulScalarSelector,
} = this;

let public_input = undefined;
Expand All @@ -511,6 +531,10 @@ export class ProofEvaluations<Evals> {
coefficients.map(f),
f(genericSelector),
f(poseidonSelector),
f(completeAddSelector),
f(mulSelector),
f(emulSelector),
f(endomulScalarSelector),
undefined, // FIXME: ignoring lookup
public_input
)
Expand Down
16 changes: 8 additions & 8 deletions verifier_circuit/src/serde/serde_index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export type VariableJSON = {

export namespace PolishTokenJSON {
export type UnitVariant = string
export type Literal = Scalar
export type Literal = string // Scalar
export type Cell = VariableJSON
export type Pow = number
export type Mds = {
Expand Down Expand Up @@ -91,7 +91,7 @@ interface VerifierIndexJSON {

//powers_of_alpha: AlphasJSON
shift: string[]
zkpm: PolynomialJSON
permutation_vanishing_polynomial_m: PolynomialJSON
w: string
endo: string
linear_constant_term: PolishTokenJSON[]
Expand Down Expand Up @@ -144,16 +144,16 @@ export function deserPolishToken(json: PolishTokenJSON): PolishToken | undefined
case "Alpha": return { kind: "alpha" }
case "Beta": return { kind: "beta" }
case "Gamma": return { kind: "gamma" }
case "EndoCoefficint": return { kind: "endocoefficient" }
case "EndoCoefficient": return { kind: "endocoefficient" }
case "Dup": return { kind: "dup" }
case "Add": return { kind: "add" }
case "Mul": return { kind: "mul" }
case "Sub": return { kind: "sub" }
case "VanishesOnLast4Rows": return { kind: "vanishesonlast4rows" }
case "VanishesOnZeroKnowledgeAndPreviousRows": return { kind: "vanishesonzeroknowledgeandpreviousrows" }
case "Store": return { kind: "store" }
}
} else {
if (json.Literal != null) return { kind: "literal", lit: json.Literal };
if (json.Literal != null) return { kind: "literal", lit: deserHexScalar(json.Literal) };
if (json.Cell != null) {
return { kind: "cell", cell: deserVariable(json.Cell) };
}
Expand Down Expand Up @@ -184,7 +184,7 @@ export function deserVerifierIndex(json: VerifierIndexJSON): VerifierIndex {
endomul_scalar_comm,
//powers_of_alpha,
shift,
zkpm,
permutation_vanishing_polynomial_m,
w,
endo,
linear_constant_term,
Expand All @@ -199,7 +199,7 @@ export function deserVerifierIndex(json: VerifierIndexJSON): VerifierIndex {
[ArgumentType.id({ kind: "gate", type: GateType.Zero }), [0, 21]],
[ArgumentType.id({ kind: "permutation" }), [21, 3]]
]
));
));

return new VerifierIndex(
domain_size,
Expand All @@ -216,7 +216,7 @@ export function deserVerifierIndex(json: VerifierIndexJSON): VerifierIndex {
deserPolyComm(endomul_scalar_comm),
powers_of_alpha,
shift.map(deserHexScalar),
deserPolynomial(zkpm),
deserPolynomial(permutation_vanishing_polynomial_m),
deserHexScalar(w),
deserHexScalar(endo),
linear_constant_term.map((token) => deserPolishToken(token)!),
Expand Down
35 changes: 31 additions & 4 deletions verifier_circuit/src/serde/serde_proof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ interface ProofEvalsJSON {
s: PointEvalsJSON[] // of size 7 - 1, total num of wirable registers minus one
coefficients: PointEvalsJSON[] // of size 15, total num of registers (columns)
//lookup?: LookupEvaluationsJSON
lookup: null,
generic_selector: PointEvalsJSON
poseidon_selector: PointEvalsJSON
complete_add_selector: PointEvalsJSON
mul_selector: PointEvalsJSON
emul_selector: PointEvalsJSON
endomul_scalar_selector: PointEvalsJSON
}

interface ProverCommitmentsJSON {
Expand Down Expand Up @@ -64,8 +67,20 @@ export function deserProofEvals(json: ProofEvalsJSON): ProofEvaluations<PointEva
const [
z,
genericSelector,
poseidonSelector
] = [json.z, json.generic_selector, json.poseidon_selector].map(deserPointEval);
poseidonSelector,
completeAddSelector,
mulSelector,
emulSelector,
endomulScalarSelector,
] = [
json.z,
json.generic_selector,
json.poseidon_selector,
json.complete_add_selector,
json.mul_selector,
json.emul_selector,
json.endomul_scalar_selector
].map(deserPointEval);

// in the current json, there isn't a non-null lookup, so TS infers that it'll always be null.
let lookup = undefined;
Expand All @@ -82,7 +97,19 @@ export function deserProofEvals(json: ProofEvalsJSON): ProofEvaluations<PointEva
// lookup = { sorted, aggreg, table, runtime };
// }

return new ProofEvaluations(w, z, s, coefficients, genericSelector, poseidonSelector, lookup);
return new ProofEvaluations(
w,
z,
s,
coefficients,
genericSelector,
poseidonSelector,
completeAddSelector,
mulSelector,
emulSelector,
endomulScalarSelector,
lookup
);
}

export function deserProverCommitments(json: ProverCommitmentsJSON): ProverCommitments {
Expand Down
47 changes: 28 additions & 19 deletions verifier_circuit/src/verifier/batch.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import { PolyComm } from "../poly_commitment/commitment.js";
import { ProverProof, PointEvaluations } from "../prover/prover.js";
import { ProverProof, PointEvaluations, ProofEvaluations } from "../prover/prover.js";
import { Verifier, VerifierIndex } from "./verifier.js";
import { Group, Scalar } from "o1js";

export class Context {
verifier_index: VerifierIndex
proof: ProverProof
public_input: Scalar[]

constructor(verifier_index: VerifierIndex, proof: ProverProof, public_input: Scalar[]) {
this.verifier_index = verifier_index;
this.proof = proof;
this.public_input = public_input;
}
}

export class Batch extends Verifier {
/**
* will take verifier_index, proof and public inputs as args.
Expand All @@ -24,26 +36,23 @@ export class Batch extends Verifier {
.maskCustom(non_hiding_public_comm,
new PolyComm([Scalar.from(1)], undefined))?.commitment!;

proof.oracles(verifier_index, public_comm, public_input);

/*
Check the length of evaluations inside the proof.
Commit to the negated public input polynomial.
Run the Fiat-Shamir argument.
Combine the chunked polynomials’ evaluations (TODO: most likely only the quotient polynomial is chunked) with the right powers of $\zeta^n$ and $(\zeta * \omega)^n$.
*/

let original_evals = proof.evals;

//original_evals.combine();
//~ 3. Run the Fiat-Shamir heuristic.
const {
fq_sponge,
oracles,
all_alphas,
public_evals,
powers_of_eval_points_for_chunks,
polys,
zeta1: zeta_to_domain_size,
ft_eval0,
combined_inner_product
} = proof.oracles(verifier_index, public_comm, public_input);

// let evals = proof.evals.combine(&powers_of_eval_points_for_chunks);
//let context = Context {
// verifier_index,
// proof,
// public_input,
//};

//~ 4. Combine the chunked polynomials' evaluations
const evals = ProofEvaluations.combine(proof.evals, powers_of_eval_points_for_chunks);
const context = new Context(verifier_index, proof, public_input);

/*
Compute the commitment to the linearized polynomial $f$. To do this, add the constraints of all of the gates, of the permutation, and optionally of the lookup. (See the separate sections in the constraints section.) Any polynomial should be replaced by its associated commitment, contained in the verifier index or in the proof, unless a polynomial has its evaluation provided by the proof in which case the evaluation should be used in place of the commitment.
Expand Down
2 changes: 1 addition & 1 deletion verifier_circuit/src/verifier/batching.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import proof_json from "../../test/proof.json" assert { type: "json" };
import verifier_index_json from "../../test/verifier_index.json" assert { type: "json" };
import { deserVerifierIndex } from "../serde/serde_index.js";

test("toBatch() step 1 and 2", () => {
test("Partial verification integration test", () => {
const srs = SRS.createFromJSON();
const domain_size = 32; // extracted from test in Rust.
const vi = deserVerifierIndex(verifier_index_json);
Expand Down
6 changes: 3 additions & 3 deletions verifier_circuit/src/verifier/verifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class VerifierIndex {
/** Wire coordinate shifts */
shift: Scalar[] // of size PERMUTS
/** Zero knowledge polynomial */
zkpm: Polynomial
permutation_vanishing_polynomial_m: Polynomial
/** Domain offset for zero-knowledge */
w: Scalar
/** Endoscalar coefficient */
Expand All @@ -78,7 +78,7 @@ export class VerifierIndex {
endomul_scalar_comm: PolyComm<Group>,
powers_of_alpha: Alphas,
shift: Scalar[],
zkpm: Polynomial,
permutation_vanishing_polynomial_m: Polynomial,
w: Scalar,
endo: Scalar,
linear_constant_term: PolishToken[]
Expand All @@ -98,7 +98,7 @@ export class VerifierIndex {
this.endomul_scalar_comm = endomul_scalar_comm;
this.powers_of_alpha = powers_of_alpha;
this.shift = shift;
this.zkpm = zkpm;
this.permutation_vanishing_polynomial_m = permutation_vanishing_polynomial_m;
this.w = w;
this.endo = endo;
this.linear_constant_term = linear_constant_term;
Expand Down
Loading

0 comments on commit 8287413

Please sign in to comment.