From b2da0a685aa2a937d1b6819230e9d13451700584 Mon Sep 17 00:00:00 2001 From: Cedoor Date: Wed, 31 Jul 2024 10:38:02 +0100 Subject: [PATCH] fix(proof): replace root public signal with actual root (#843) The public signal of proof related to the Merkle root could obviously be different from what is expected to be the root of the group. Therefore, for the proof to be valid, it is necessary that the group root passed as a parameter matches the proof/circuit root output. re #842 --- packages/proof/src/generate-proof.ts | 6 +++--- packages/proof/tests/index.test.ts | 20 +++++++++++++++----- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/proof/src/generate-proof.ts b/packages/proof/src/generate-proof.ts index e7251973a..c1fc1c5ba 100644 --- a/packages/proof/src/generate-proof.ts +++ b/packages/proof/src/generate-proof.ts @@ -1,11 +1,11 @@ import type { Group, MerkleProof } from "@semaphore-protocol/group" import type { Identity } from "@semaphore-protocol/identity" import { MAX_DEPTH, MIN_DEPTH } from "@semaphore-protocol/utils/constants" +import { Project, maybeGetSnarkArtifacts, type SnarkArtifacts } from "@zk-kit/artifacts" import { requireDefined, requireNumber, requireObject, requireTypes } from "@zk-kit/utils/error-handlers" import { packGroth16Proof } from "@zk-kit/utils/proof-packing" -import { maybeGetSnarkArtifacts, Project, type SnarkArtifacts } from "@zk-kit/artifacts" import type { BigNumberish } from "ethers" -import { type NumericString, groth16 } from "snarkjs" +import { groth16, type NumericString } from "snarkjs" import hash from "./hash" import toBigInt from "./to-bigint" import type { SemaphoreProof } from "./types" @@ -118,7 +118,7 @@ export default async function generateProof( return { merkleTreeDepth, - merkleTreeRoot: publicSignals[0], + merkleTreeRoot: merkleProof.root.toString(), nullifier: publicSignals[1], message: message.toString() as NumericString, scope: scope.toString() as NumericString, diff --git a/packages/proof/tests/index.test.ts b/packages/proof/tests/index.test.ts index 0fec8d6ec..c435c0e30 100644 --- a/packages/proof/tests/index.test.ts +++ b/packages/proof/tests/index.test.ts @@ -55,7 +55,7 @@ describe("Proof", () => { expect(typeof proof).toBe("object") expect(BigInt(proof.merkleTreeRoot)).toBe(group.root) - }, 80000) + }) it("Should generate a Semaphore proof passing a Merkle proof instead of a group", async () => { const group = new Group([1n, 2n, identity.commitment]) @@ -64,7 +64,7 @@ describe("Proof", () => { expect(typeof proof).toBe("object") expect(BigInt(proof.merkleTreeRoot)).toBe(group.root) - }, 80000) + }) it("Should generate a Semaphore proof without passing the tree depth", async () => { const group = new Group([1n, 2n, identity.commitment]) @@ -73,7 +73,7 @@ describe("Proof", () => { expect(typeof proof).toBe("object") expect(BigInt(proof.merkleTreeRoot)).toBe(group.root) - }, 80000) + }) it("Should throw an error because snarkArtifacts is not an object", async () => { const group = new Group([1n, 2n, identity.commitment]) @@ -103,7 +103,7 @@ describe("Proof", () => { await expect(fun).rejects.toThrow("tree depth must be") }) - it("Should verify a Semaphore proof", async () => { + it("Should return true if the proof is valid", async () => { const group = new Group([1n, 2n, identity.commitment]) const proof = await generateProof(identity, group, message, scope, treeDepth) @@ -111,6 +111,16 @@ describe("Proof", () => { const response = await verifyProof(proof) expect(response).toBe(true) - }, 80_000) + }) + + it("Should return false if the proof is not valid", async () => { + const group = new Group([1n, 2n, identity.commitment]) + + const proof = await generateProof(identity, group.generateMerkleProof(0), message, scope, treeDepth) + + const response = await verifyProof(proof) + + expect(response).toBe(false) + }) }) })