From d32bbbd7a6db281698f95d56a6d4a7fdf7a8df4f Mon Sep 17 00:00:00 2001 From: Nasi Jofce Date: Fri, 18 Feb 2022 20:29:26 +0100 Subject: [PATCH] feat(zk-protocol): structure the public signals array obtained while generating a proof from snarkjs The generated proof using snarkjs will return an object of type PublicSignals for the public signals Former-commit-id: deadf7159137f98343e42dbb2cfef813a3adffc3 [formerly 1f7dd580bbd27f39e0975b8bc2967dca191f2e75] [formerly d0641f8a46fd888b44d45020d8393871672759f8 [formerly 422bcbb07e3675b3c124313ce265dd661856075c]] [formerly c93bbaee62c8969bb91c9b75efe642781d740b49 [formerly d5a4c2359230f114287796b6ad502d881ec554c4] [formerly 5f155f5f9927762e8418d9930dda1d0af414af57 [formerly 462a4bb74522d9418ffa11475b5f4ae780562788]]] Former-commit-id: 1f3f2470e637188e7ef3311a15c40d6f9368b1ee [formerly 884540bf7bd1e87311c7e72557e983c6bc769ee5] [formerly d060f4aacfe7f2c5bec5da817b4e785ced9de9d8 [formerly 471a8074b86fb074707ab4981f2831bcf7242a57]] Former-commit-id: 9d93b210d84bf65134e25a970ec42af8afb50253 [formerly c1c1a33c3edd09bf908482185f3ec11914c52131] Former-commit-id: fed1b20295686aef5fdf5597f9bcece2933d984d --- packages/protocols/src/rln.ts | 32 +++++++++++++++++++++- packages/protocols/src/semaphore.ts | 30 +++++++++++++++++++- packages/protocols/src/types/index.ts | 11 ++++++-- packages/protocols/src/zk-protocol.ts | 31 +-------------------- packages/protocols/tests/rln.test.ts | 4 +-- packages/protocols/tests/semaphore.test.ts | 10 ++++++- 6 files changed, 81 insertions(+), 37 deletions(-) diff --git a/packages/protocols/src/rln.ts b/packages/protocols/src/rln.ts index 544ee77..1639660 100644 --- a/packages/protocols/src/rln.ts +++ b/packages/protocols/src/rln.ts @@ -1,10 +1,40 @@ import { MerkleProof } from "@zk-kit/incremental-merkle-tree" import { poseidon } from "circomlibjs" -import { StrBigInt } from "./types" +import { groth16 } from "snarkjs" +import { FullProof, RLNPublicSignals, StrBigInt } from "./types" import { Fq, genSignalHash } from "./utils" import ZkProtocol from "./zk-protocol" export default class RLN extends ZkProtocol { + /** + * The number of public signals that should be returned by snarkjs when generating a proof. + */ + private static PUBLIC_SIGNALS_COUNT: number = 6 + + /** + * Generates a SnarkJS full proof with Groth16. + * @param witness The parameters for creating the proof. + * @param wasmFilePath The WASM file path. + * @param finalZkeyPath The ZKey file path. + * @returns The full SnarkJS proof. + */ + public static async genProof(witness: any, wasmFilePath: string, finalZkeyPath: string): Promise { + const { proof, publicSignalsArray } = await groth16.fullProve(witness, wasmFilePath, finalZkeyPath, null) + + if (publicSignalsArray.length !== RLN.PUBLIC_SIGNALS_COUNT) throw new Error("Error while generating proof") + + const publicSignals: RLNPublicSignals = { + yShare: publicSignalsArray[0], + merkleRoot: publicSignalsArray[1], + internalNullifier: publicSignalsArray[2], + signalHash: publicSignalsArray[3], + epoch: publicSignalsArray[4], + rlnIdentifier: publicSignalsArray[5] + } + + return { proof, publicSignals } + } + /** * Creates witness for rln proof * @param identitySecret identity secret diff --git a/packages/protocols/src/semaphore.ts b/packages/protocols/src/semaphore.ts index 03e6bd7..5e9738d 100644 --- a/packages/protocols/src/semaphore.ts +++ b/packages/protocols/src/semaphore.ts @@ -1,10 +1,38 @@ import { MerkleProof } from "@zk-kit/incremental-merkle-tree" import { poseidon } from "circomlibjs" -import { SemaphoreWitness, StrBigInt } from "./types" +import { groth16 } from "snarkjs" +import { FullProof, StrBigInt, SemaphoreWitness, SemaphorePublicSignals } from "./types" import { genSignalHash } from "./utils" import ZkProtocol from "./zk-protocol" export default class Semaphore extends ZkProtocol { + /** + * The number of public signals that should be returned by snarkjs when generating a proof. + */ + private static PUBLIC_SIGNALS_COUNT: number = 6 + + /** + * Generates a SnarkJS full proof with Groth16. + * @param witness The parameters for creating the proof. + * @param wasmFilePath The WASM file path. + * @param finalZkeyPath The ZKey file path. + * @returns The full SnarkJS proof. + */ + public static async genProof(witness: any, wasmFilePath: string, finalZkeyPath: string): Promise { + const { proof, publicSignalsArray } = await groth16.fullProve(witness, wasmFilePath, finalZkeyPath, null) + + if (publicSignalsArray.length !== Semaphore.PUBLIC_SIGNALS_COUNT) throw new Error("Error while generating proof") + + const publicSignals: SemaphorePublicSignals = { + merkleRoot: publicSignalsArray[0], + nullifierHash: publicSignalsArray[1], + signalHash: publicSignalsArray[2], + externalNullifier: publicSignalsArray[3] + } + + return { proof, publicSignals } + } + /** * Creates a Semaphore witness for the Semaphore ZK proof. * @param identityTrapdoor The identity trapdoor. diff --git a/packages/protocols/src/types/index.ts b/packages/protocols/src/types/index.ts index 0f9812f..df8d759 100644 --- a/packages/protocols/src/types/index.ts +++ b/packages/protocols/src/types/index.ts @@ -10,10 +10,10 @@ export type Proof = { export type FullProof = { proof: Proof - publicSignals: PublicSignals + publicSignals: RLNPublicSignals | SemaphorePublicSignals } -export type PublicSignals = { +export type RLNPublicSignals = { yShare: StrBigInt merkleRoot: StrBigInt internalNullifier: StrBigInt @@ -22,6 +22,13 @@ export type PublicSignals = { rlnIdentifier: StrBigInt } +export type SemaphorePublicSignals = { + merkleRoot: StrBigInt + nullifierHash: StrBigInt + signalHash: StrBigInt + externalNullifier: StrBigInt +} + export type SolidityProof = StrBigInt[] export type SemaphoreWitness = { diff --git a/packages/protocols/src/zk-protocol.ts b/packages/protocols/src/zk-protocol.ts index 40ecea1..89db91b 100644 --- a/packages/protocols/src/zk-protocol.ts +++ b/packages/protocols/src/zk-protocol.ts @@ -1,37 +1,8 @@ /* istanbul ignore file */ import { groth16 } from "snarkjs" -import { FullProof, PublicSignals, SolidityProof, StrBigInt } from "./types" +import { FullProof, SolidityProof, StrBigInt } from "./types" export default class ZkProtocol { - /** - * The number of public signals that should be returned by snarkjs when generating a proof. - */ - private static PUBLIC_SIGNALS_COUNT: number = 6 - - /** - * Generates a SnarkJS full proof with Groth16. - * @param witness The parameters for creating the proof. - * @param wasmFilePath The WASM file path. - * @param finalZkeyPath The ZKey file path. - * @returns The full SnarkJS proof. - */ - public static async genProof(witness: any, wasmFilePath: string, finalZkeyPath: string): Promise { - const { proof, publicSignalsArray } = await groth16.fullProve(witness, wasmFilePath, finalZkeyPath, null) - - if (publicSignalsArray.length !== ZkProtocol.PUBLIC_SIGNALS_COUNT) throw new Error("Error while generating proof") - - const publicSignals: PublicSignals = { - yShare: publicSignalsArray[0], - merkleRoot: publicSignalsArray[1], - internalNullifier: publicSignalsArray[2], - signalHash: publicSignalsArray[3], - epoch: publicSignalsArray[4], - rlnIdentifier: publicSignalsArray[5] - } - - return { proof, publicSignals } - } - /** * Verifies a zero-knowledge SnarkJS proof. * @param verificationKey The zero-knowledge verification key. diff --git a/packages/protocols/tests/rln.test.ts b/packages/protocols/tests/rln.test.ts index 172a26a..de5d6d6 100644 --- a/packages/protocols/tests/rln.test.ts +++ b/packages/protocols/tests/rln.test.ts @@ -4,7 +4,7 @@ import * as fs from "fs" import * as path from "path" import { RLN } from "../src" import { generateMerkleProof, genExternalNullifier, genSignalHash } from "../src/utils" -import { PublicSignals } from "../src/types" +import { RLNPublicSignals } from "../src/types" describe("RLN", () => { const zkeyFiles = "./packages/protocols/zkeyFiles" @@ -67,7 +67,7 @@ describe("RLN", () => { const [y, nullifier] = RLN.calculateOutput(secretHash, BigInt(epoch), rlnIdentifier, signalHash) - const publicSignals: PublicSignals = { + const publicSignals: RLNPublicSignals = { yShare: y, merkleRoot: merkleProof.root, internalNullifier: nullifier, diff --git a/packages/protocols/tests/semaphore.test.ts b/packages/protocols/tests/semaphore.test.ts index 29f27ea..9718254 100644 --- a/packages/protocols/tests/semaphore.test.ts +++ b/packages/protocols/tests/semaphore.test.ts @@ -3,6 +3,7 @@ import { getCurveFromName } from "ffjavascript" import fs from "fs" import path from "path" import { Semaphore } from "../src" +import { SemaphorePublicSignals } from "../src/types" import { generateMerkleProof, genExternalNullifier, genSignalHash } from "../src/utils" describe("Semaphore", () => { @@ -64,11 +65,18 @@ describe("Semaphore", () => { const vkeyPath = path.join("./packages/protocols/zkeyFiles", "semaphore", "verification_key.json") const vKey = JSON.parse(fs.readFileSync(vkeyPath, "utf-8")) const nullifierHash = Semaphore.genNullifierHash(externalNullifier, identity.getNullifier()) - const publicSignals = [merkleProof.root.toString(), nullifierHash, genSignalHash(signal), externalNullifier] + + const publicSignals: SemaphorePublicSignals = { + merkleRoot: merkleProof.root.toString(), + nullifierHash, + signalHash: genSignalHash(signal), + externalNullifier + } const response = await Semaphore.verifyProof(vKey, { proof: fullProof.proof, publicSignals }) expect(response).toBe(true) + expect(fullProof.publicSignals).toEqual(publicSignals) }, 30000) }) })