Skip to content

Commit

Permalink
Merge branch 'master' into feature/plonk
Browse files Browse the repository at this point in the history
  • Loading branch information
Hrom131 committed Aug 2, 2024
2 parents 8e99ff6 + 4f3e73c commit bef3809
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 19 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ Creates a Solidity verifier contract on `verifierDirPath` path, which was specif
await multiplier.createVerifier();
```

#### calculateWitness()

Calculates a witness in the `tmp` directory and returns its json representation.

```typescript
/// witness = [1n, 200n, 20n, 10n]
const witness = await multiplier.calculateWitness({ a: 10, b: 20 });
```

#### generateProof()

Generates a proof for the given inputs.
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@solarity/zkit",
"version": "0.2.3",
"version": "0.2.4",
"license": "MIT",
"author": "Distributed Lab",
"readme": "README.md",
Expand Down
29 changes: 26 additions & 3 deletions src/core/CircuitZKit.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import fs from "fs";
import path from "path";
import * as os from "os";
import * as snarkjs from "snarkjs";

import { ArtifactsFileType, CircuitZKitConfig } from "../types/circuit-zkit";
import { Inputs } from "../types/proof-utils";
import { Signals } from "../types/proof-utils";
import { CalldataByProtocol, IProtocolImplementer, ProofStructByProtocol, ProtocolType } from "../types/protocols";

/**
Expand All @@ -27,16 +29,37 @@ export class CircuitZKit<Type extends ProtocolType> {
this._implementer.createVerifier(this._config.circuitName, vKeyFilePath, verifierFilePath);
}

/**
* Calculates a witness for the given inputs.
*
* @param {Signals} inputs - The inputs for the circuit.
* @returns {Promise<bigint[]>} The generated witness.
*/
public async calculateWitness(inputs: Signals): Promise<bigint[]> {
const tmpDir = path.join(os.tmpdir(), ".zkit");

if (!fs.existsSync(tmpDir)) {
fs.mkdirSync(tmpDir, { recursive: true });
}

const wtnsFile = path.join(tmpDir, `${this.getCircuitName()}.wtns`);
const wasmFile = this.mustGetArtifactsFilePath("wasm");

await snarkjs.wtns.calculate(inputs, wasmFile, wtnsFile);

return (await snarkjs.wtns.exportJson(wtnsFile)) as bigint[];
}

/**
* Generates a proof for the given inputs.
*
* @dev The `inputs` should be in the same order as the circuit expects them.
*
* @param {Inputs} inputs - The inputs for the circuit.
* @param {Signals} inputs - The inputs for the circuit.
* @returns {Promise<ProofStructByProtocol<Type>>} The generated proof.
* @todo Add support for other proving systems.
*/
public async generateProof(inputs: Inputs): Promise<ProofStructByProtocol<Type>> {
public async generateProof(inputs: Signals): Promise<ProofStructByProtocol<Type>> {
const zKeyFile = this.mustGetArtifactsFilePath("zkey");
const wasmFile = this.mustGetArtifactsFilePath("wasm");

Expand Down
6 changes: 3 additions & 3 deletions src/core/protocols/AbstractImplementer.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import ejs from "ejs";
import fs from "fs";
import ejs from "ejs";
import path from "path";

import { Inputs } from "../../types/proof-utils";
import { Signals } from "../../types/proof-utils";
import { IProtocolImplementer, ProtocolType, ProofStructByProtocol, CalldataByProtocol } from "../../types/protocols";

export abstract class AbstractProtocolImplementer<T extends ProtocolType> implements IProtocolImplementer<T> {
Expand All @@ -22,7 +22,7 @@ export abstract class AbstractProtocolImplementer<T extends ProtocolType> implem
}

public abstract generateProof(
inputs: Inputs,
inputs: Signals,
zKeyFilePath: string,
wasmFilePath: string,
): Promise<ProofStructByProtocol<T>>;
Expand Down
4 changes: 2 additions & 2 deletions src/core/protocols/Groth16Implementer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import * as snarkjs from "snarkjs";

import { AbstractProtocolImplementer } from "./AbstractImplementer";

import { Inputs } from "../../types/proof-utils";
import { Signals } from "../../types/proof-utils";
import { Groth16ProofStruct, ProtocolType, Groth16Calldata } from "../../types/protocols";

export class Groth16Implementer extends AbstractProtocolImplementer<"groth16"> {
public async generateProof(inputs: Inputs, zKeyFilePath: string, wasmFilePath: string): Promise<Groth16ProofStruct> {
public async generateProof(inputs: Signals, zKeyFilePath: string, wasmFilePath: string): Promise<Groth16ProofStruct> {
return (await snarkjs.groth16.fullProve(inputs, wasmFilePath, zKeyFilePath)) as Groth16ProofStruct;
}

Expand Down
4 changes: 2 additions & 2 deletions src/core/protocols/PlonkImplementer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import * as snarkjs from "snarkjs";

import { AbstractProtocolImplementer } from "./AbstractImplementer";

import { Inputs } from "../../types/proof-utils";
import { Signals } from "../../types/proof-utils";
import { PlonkCalldata, PlonkProofStruct, ProtocolType } from "../../types/protocols";

export class PlonkImplementer extends AbstractProtocolImplementer<"plonk"> {
public async generateProof(inputs: Inputs, zKeyFilePath: string, wasmFilePath: string): Promise<PlonkProofStruct> {
public async generateProof(inputs: Signals, zKeyFilePath: string, wasmFilePath: string): Promise<PlonkProofStruct> {
return (await snarkjs.plonk.fullProve(inputs, wasmFilePath, zKeyFilePath)) as PlonkProofStruct;
}

Expand Down
6 changes: 3 additions & 3 deletions src/types/proof-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ export type NumericString = `${number}` | string;

export type PublicSignals = NumericString[];

export type NumberLike = number | bigint | string;
export type NumberLike = number | bigint | `${number}`;
export type ArrayLike = NumberLike[] | ArrayLike[];
export type InputLike = NumberLike | ArrayLike;

export type Inputs = Record<string, InputLike>;
export type Signal = NumberLike | ArrayLike;
export type Signals = Record<string, Signal>;
4 changes: 2 additions & 2 deletions src/types/protocols/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Groth16ProofStruct, Groth16Calldata } from "./groth16";
import { PlonkProofStruct, PlonkCalldata } from "./plonk";

import { Inputs } from "../proof-utils";
import { Signals } from "../proof-utils";

export * from "./groth16";
export * from "./plonk";

export interface IProtocolImplementer<T extends ProtocolType> {
createVerifier(circuitName: string, vKeyFilePath: string, verifierFilePath: string): Promise<void>;

generateProof(inputs: Inputs, zKeyFilePath: string, wasmFilePath: string): Promise<ProofStructByProtocol<T>>;
generateProof(inputs: Signals, zKeyFilePath: string, wasmFilePath: string): Promise<ProofStructByProtocol<T>>;

verifyProof(proof: ProofStructByProtocol<T>, vKeyFilePath: string): Promise<boolean>;

Expand Down
29 changes: 28 additions & 1 deletion test/CircuitZKit.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ejs from "ejs";
import path from "path";
import fs from "fs";
import path from "path";
import * as os from "os";

import { expect } from "chai";
import { useFixtureProject } from "./helpers";
Expand Down Expand Up @@ -288,6 +289,32 @@ describe("CircuitZKit", () => {
});
});

describe("calculateWitness", () => {
useFixtureProject("simple-circuits");

it("should correctly create witness", async () => {
const circuitName = "Multiplier";
const circuitArtifactsPath = getArtifactsFullPath(`${circuitName}.circom`);

const multiplierCircuit = getCircuitZKit<"groth16">(circuitName, "groth16", {
circuitName,
circuitArtifactsPath,
verifierDirPath: getVerifiersDirFullPath(),
});

const b = 10,
a = 20;

const tmpDir = path.join(os.tmpdir(), ".zkit");

fs.rmSync(tmpDir, { force: true, recursive: true });

expect(await multiplierCircuit.calculateWitness({ a, b })).to.deep.eq([1n, 200n, 20n, 10n]);
expect(await multiplierCircuit.calculateWitness({ a, b })).to.deep.eq([1n, 200n, 20n, 10n]);
expect(await multiplierCircuit.calculateWitness({ a, b: 30 })).to.deep.eq([1n, 600n, 20n, 30n]);
});
});

describe("generateProof/verifyProof", () => {
useFixtureProject("simple-circuits");

Expand Down

0 comments on commit bef3809

Please sign in to comment.