From 739f136345d807f3a38d24dcf37dff3181c50f2d Mon Sep 17 00:00:00 2001 From: Andrew Twyman Date: Mon, 30 Sep 2024 17:27:49 -0700 Subject: [PATCH 1/9] Clean up @types/circomlibjs dependencies --- apps/zupoll-client/package.json | 1 - package.json | 1 - packages/lib/pod/package.json | 1 + packages/pcd/eddsa-pcd/package.json | 1 + .../zk-eddsa-event-ticket-pcd/package.json | 1 + packages/pcd/zk-eddsa-frog-pcd/package.json | 1 + .../zupass-feed-server/package.json | 1 - yarn.lock | 33 ++++++++++++++++--- 8 files changed, 33 insertions(+), 7 deletions(-) diff --git a/apps/zupoll-client/package.json b/apps/zupoll-client/package.json index 015f9541e6..f4e75e3c88 100644 --- a/apps/zupoll-client/package.json +++ b/apps/zupoll-client/package.json @@ -66,7 +66,6 @@ "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@pcd/eslint-config-custom": "0.11.4", "@pcd/tsconfig": "0.11.4", - "@types/circomlibjs": "^0.1.5", "@types/expect": "^24.3.0", "@types/fuzzy-search": "^2.1.5", "@types/json-stable-stringify": "^1.0.34", diff --git a/package.json b/package.json index c42706406e..2460ce002c 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,6 @@ "postinstall": "patch-package" }, "devDependencies": { - "@types/circomlibjs": "0.1.6", "@types/node": "^20.11.28", "plop": "^4.0.1", "prettier": "^3.0.0", diff --git a/packages/lib/pod/package.json b/packages/lib/pod/package.json index 41ca2974cf..074f90e7b8 100644 --- a/packages/lib/pod/package.json +++ b/packages/lib/pod/package.json @@ -43,6 +43,7 @@ "@pcd/pcd-types": "0.11.4", "@pcd/tsconfig": "0.11.4", "@semaphore-protocol/identity": "^3.15.2", + "@types/circomlibjs": "^0.1.6", "@types/chai": "^4.3.5", "@types/mocha": "^10.0.1", "circomlibjs": "^0.1.7", diff --git a/packages/pcd/eddsa-pcd/package.json b/packages/pcd/eddsa-pcd/package.json index 91bbc88a4b..82ffef6cf8 100644 --- a/packages/pcd/eddsa-pcd/package.json +++ b/packages/pcd/eddsa-pcd/package.json @@ -40,6 +40,7 @@ "devDependencies": { "@pcd/eslint-config-custom": "0.11.4", "@pcd/tsconfig": "0.11.4", + "@types/circomlibjs": "^0.1.6", "@types/mocha": "^10.0.1", "@types/uuid": "^9.0.0", "chai": "^4.3.7", diff --git a/packages/pcd/zk-eddsa-event-ticket-pcd/package.json b/packages/pcd/zk-eddsa-event-ticket-pcd/package.json index d4f69a6411..e9678fc106 100644 --- a/packages/pcd/zk-eddsa-event-ticket-pcd/package.json +++ b/packages/pcd/zk-eddsa-event-ticket-pcd/package.json @@ -51,6 +51,7 @@ "@pcd/artifacts": "0.4.4", "@pcd/eslint-config-custom": "0.11.4", "@pcd/tsconfig": "0.11.4", + "@types/circomlibjs": "^0.1.6", "@types/json-bigint": "^1.0.1", "@types/mocha": "^10.0.1", "@types/snarkjs": "^0.7.5", diff --git a/packages/pcd/zk-eddsa-frog-pcd/package.json b/packages/pcd/zk-eddsa-frog-pcd/package.json index 760d2b42dc..2886890806 100644 --- a/packages/pcd/zk-eddsa-frog-pcd/package.json +++ b/packages/pcd/zk-eddsa-frog-pcd/package.json @@ -50,6 +50,7 @@ "@pcd/artifacts": "0.4.4", "@pcd/eslint-config-custom": "0.11.4", "@pcd/tsconfig": "0.11.4", + "@types/circomlibjs": "^0.1.6", "@types/json-bigint": "^1.0.1", "@types/mocha": "^10.0.1", "@types/snarkjs": "^0.7.5", diff --git a/test-packaging/zupass-feed-server/package.json b/test-packaging/zupass-feed-server/package.json index dc1b800b84..f34bf92304 100644 --- a/test-packaging/zupass-feed-server/package.json +++ b/test-packaging/zupass-feed-server/package.json @@ -9,7 +9,6 @@ "private": true, "devDependencies": { "@pcd/eslint-config-custom": "*", - "@types/circomlibjs": "^0.1.6", "@types/cors": "^2.8.14", "@types/express": "^4.17.17", "@types/json-bigint": "^1.0.2", diff --git a/yarn.lock b/yarn.lock index 6d1aad63fe..3fee28f868 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6664,7 +6664,7 @@ resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.11.tgz#e95050bf79a932cb7305dd130254ccdf9bde671c" integrity sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ== -"@types/circomlibjs@0.1.6", "@types/circomlibjs@^0.1.5": +"@types/circomlibjs@^0.1.6": version "0.1.6" resolved "https://registry.yarnpkg.com/@types/circomlibjs/-/circomlibjs-0.1.6.tgz#dba1b9cc68ae4f75da045b8b14c50f3444b31d7f" integrity sha512-yF174bPDaiKgejlZzCSqKwZaqXhlxMcVEHrAtstFohwP05OjtvHXOdxO6HQeTg8WwIdgMg7MJb1WyWZdUCGlPQ== @@ -20285,7 +20285,16 @@ string-template@~0.2.1: resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -20418,7 +20427,14 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -22827,7 +22843,7 @@ workspace-tools@^0.36.4: js-yaml "^4.1.0" micromatch "^4.0.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -22845,6 +22861,15 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From d1f6eccb7c728bef323a5c13c124f079f6cffe43 Mon Sep 17 00:00:00 2001 From: Andrew Twyman Date: Mon, 30 Sep 2024 17:35:12 -0700 Subject: [PATCH 2/9] poseidon-lite 0.3.0 --- packages/lib/gpc/package.json | 2 +- packages/lib/pod/package.json | 2 +- packages/pcd/eddsa-pcd/package.json | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/lib/gpc/package.json b/packages/lib/gpc/package.json index 9365cc5688..b79d8ec0d4 100644 --- a/packages/lib/gpc/package.json +++ b/packages/lib/gpc/package.json @@ -49,7 +49,7 @@ "eslint": "^8.57.0", "fix-esm-import-path": "^1.10.0", "mocha": "^10.2.0", - "poseidon-lite": "^0.2.1", + "poseidon-lite": "^0.3.0", "ts-mocha": "^10.0.0", "typescript": "^5.3.3" }, diff --git a/packages/lib/pod/package.json b/packages/lib/pod/package.json index 074f90e7b8..8e85eb8eab 100644 --- a/packages/lib/pod/package.json +++ b/packages/lib/pod/package.json @@ -35,7 +35,7 @@ "@zk-kit/utils": "1.2.1", "js-sha256": "^0.10.1", "json-bigint": "^1.0.0", - "poseidon-lite": "^0.2.1" + "poseidon-lite": "^0.3.0" }, "devDependencies": { "@pcd/eddsa-pcd": "0.6.5", diff --git a/packages/pcd/eddsa-pcd/package.json b/packages/pcd/eddsa-pcd/package.json index 82ffef6cf8..b7e6338837 100644 --- a/packages/pcd/eddsa-pcd/package.json +++ b/packages/pcd/eddsa-pcd/package.json @@ -35,6 +35,7 @@ "@pcd/pcd-types": "0.11.4", "@pcd/util": "0.5.4", "circomlibjs": "^0.1.7", + "poseidon-lite": "^0.3.0", "uuid": "^9.0.0" }, "devDependencies": { From a0f180e540e53a94ed2c5cc59a4e271a6a6a60e2 Mon Sep 17 00:00:00 2001 From: Andrew Twyman Date: Mon, 30 Sep 2024 18:06:40 -0700 Subject: [PATCH 3/9] unit test config --- .vscode/launch.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index 4eef458919..76dcbbbb77 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -19,6 +19,23 @@ "port": 4321, "restart": true, "cwd": "${workspaceRoot}" + }, + { + "args": [ + "-r", + "ts-node/register", + "--config", + "${workspaceFolder}/.mocharc.js", + "--no-timeouts", + "--exit", + "${file}" + ], + "cwd": "${fileDirname}", + "internalConsoleOptions": "openOnSessionStart", + "name": "TS Mocha Test (Current File)", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "request": "launch", + "type": "node" } ] } From cda2648ac5cff73c4951721a249660e2ac5ecf89 Mon Sep 17 00:00:00 2001 From: Andrew Twyman Date: Mon, 30 Sep 2024 18:09:38 -0700 Subject: [PATCH 4/9] Use zk-kit in eddsa-pcd --- packages/lib/gpcircuits/package.json | 2 +- packages/pcd/eddsa-pcd/package.json | 2 +- packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts | 92 ++++++++++--------- yarn.lock | 5 - 4 files changed, 52 insertions(+), 49 deletions(-) diff --git a/packages/lib/gpcircuits/package.json b/packages/lib/gpcircuits/package.json index 8860dba7d6..8665120c11 100644 --- a/packages/lib/gpcircuits/package.json +++ b/packages/lib/gpcircuits/package.json @@ -56,7 +56,7 @@ "fix-esm-import-path": "^1.10.0", "lodash": "^4.17.21", "mocha": "^10.2.0", - "poseidon-lite": "^0.2.1", + "poseidon-lite": "^0.3.0", "ts-mocha": "^10.0.0", "typescript": "^5.3.3" }, diff --git a/packages/pcd/eddsa-pcd/package.json b/packages/pcd/eddsa-pcd/package.json index b7e6338837..bdce8f15cf 100644 --- a/packages/pcd/eddsa-pcd/package.json +++ b/packages/pcd/eddsa-pcd/package.json @@ -34,7 +34,7 @@ "dependencies": { "@pcd/pcd-types": "0.11.4", "@pcd/util": "0.5.4", - "circomlibjs": "^0.1.7", + "@zk-kit/eddsa-poseidon": "1.0.3", "poseidon-lite": "^0.3.0", "uuid": "^9.0.0" }, diff --git a/packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts b/packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts index f7f0f3b8a3..500398a020 100644 --- a/packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts +++ b/packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts @@ -1,6 +1,20 @@ import { DisplayOptions, PCDPackage, SerializedPCD } from "@pcd/pcd-types"; import { fromHexString, requireDefinedParameter, toHexString } from "@pcd/util"; -import { Eddsa, Point, buildEddsa } from "circomlibjs"; +import { Point } from "@zk-kit/baby-jubjub"; +import { + derivePublicKey, + packSignature, + signMessage, + unpackSignature, + verifySignature +} from "@zk-kit/eddsa-poseidon"; +import { + poseidon1, + poseidon12, + poseidon13, + poseidon2, + poseidon3 +} from "poseidon-lite"; import { v4 as uuid } from "uuid"; import { EdDSAInitArgs, @@ -12,31 +26,11 @@ import { EdDSAPublicKey } from "./EdDSAPCD"; -let initializedPromise: Promise | undefined; -let eddsa: Eddsa; - -/** - * A promise designed to make sure that the EdDSA algorithm - * of the `circomlibjs` package has been properly initialized. - * It only initializes them once. - */ -async function ensureInitialized(): Promise { - if (!initializedPromise) { - initializedPromise = (async (): Promise => { - eddsa = await buildEddsa(); - })(); - } - - await initializedPromise; -} - /** * Creates a new {@link EdDSAPCD} by generating an {@link EdDSAPCDProof} * and deriving an {@link EdDSAPCDClaim} from the given {@link EdDSAPCDArgs}. */ export async function prove(args: EdDSAPCDArgs): Promise { - await ensureInitialized(); - let message; if (!args.privateKey.value) throw new Error("No private key value provided"); @@ -60,16 +54,12 @@ export async function prove(args: EdDSAPCDArgs): Promise { const id = typeof args.id.value === "string" ? args.id.value : uuid(); const prvKey = fromHexString(args.privateKey.value); - const hashedMessage = eddsa.poseidon(message); + const hashedMessage = poseidonHashMessage(message); const publicKey = await getEdDSAPublicKey(prvKey); // Make the signature on the message. - // Note: packSignature converts the R8 coordinates from Mongtomery form to - // standard form for use outside of circomlibjs. - // This is a reference to Montgomery form of numbers for modular - // multiplication, NOT Montgomery form of eliptic curves. See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#Montgomery_form const signature = toHexString( - eddsa.packSignature(eddsa.signPoseidon(prvKey, hashedMessage)) + packSignature(signMessage(prvKey, hashedMessage)) ); return new EdDSAPCD(id, { message, publicKey }, { signature }); @@ -81,22 +71,20 @@ export async function prove(args: EdDSAPCDArgs): Promise { */ export async function verify(pcd: EdDSAPCD): Promise { try { - await ensureInitialized(); - - const signature = eddsa.unpackSignature(fromHexString(pcd.proof.signature)); + const signature = unpackSignature(fromHexString(pcd.proof.signature)); // Note: `F.fromObject` converts a coordinate from standard format to // Montgomery form, which is expected by circomlibjs. unpackSignature above // does the same for its R8 point. // This is a reference to Montgomery form of numbers for modular // multiplication, NOT Montgomery form of eliptic curves. See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#Montgomery_form - const pubKey = pcd.claim.publicKey.map((p) => - eddsa.F.fromObject(p) + const pubKey = pcd.claim.publicKey.map((coordinateString: string) => + BigInt("0x" + coordinateString) ) as Point; - const hashedMessage = eddsa.poseidon(pcd.claim.message); + const hashedMessage = poseidonHashMessage(pcd.claim.message); - return eddsa.verifyPoseidon(hashedMessage, signature, pubKey); + return verifySignature(hashedMessage, signature, pubKey); } catch { return false; } @@ -205,17 +193,37 @@ export const EdDSAPCDPackage: PCDPackage< export async function getEdDSAPublicKey( privateKey: string | Uint8Array ): Promise { - await ensureInitialized(); - if (typeof privateKey === "string") { privateKey = fromHexString(privateKey); } - return eddsa.prv2pub(privateKey).map((p) => - // Note: `F.toObject` converts a point from the Montgomery format used by - // circomlibjs to standard form. - // This is a reference to Montgomery form of numbers for modular - // multiplication, NOT Montgomery form of eliptic curves. See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#Montgomery_form - eddsa.F.toObject(p).toString(16).padStart(64, "0") + return derivePublicKey(privateKey).map((coordinate: bigint) => + coordinate.toString(16).padStart(64, "0") ) as EdDSAPublicKey; } + +function poseidonHashMessage(message: bigint[]): bigint { + switch (message.length) { + case 1: + // Used by PODs for value hashing, so no extra bundle size impact. + return poseidon1(message); + case 2: + // UYsed by PODs for Merkle tree hasing, so no extra bundle size impact. + return poseidon2(message); + case 3: + // Needed for backward-compatibility tests. + // TODO(artwyman): Alter backward-compatibility test case to use a different size + return poseidon3(message); + case 12: + // Tailored to the size of EdDSATicketPCD. + return poseidon12(message); + case 13: + // Tailored to the size of EdDSAFrogPCD. + return poseidon13(message); + default: + break; + } + throw new Error( + `Unsupported EdDSAMessagePCD message size ${message.length}.` + ); +} diff --git a/yarn.lock b/yarn.lock index 3fee28f868..346d9316d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18010,11 +18010,6 @@ poseidon-lite@^0.0.2: resolved "https://registry.yarnpkg.com/poseidon-lite/-/poseidon-lite-0.0.2.tgz#dc1a7c57f9393a586c5c9efc21b72b77e2c1acb6" integrity sha512-bGdDPTOQkJbBjbtSEWc3gY+YhqlGTxGlZ8041F8TGGg5QyGGp1Cfs4b8AEnFFjHbkPg6WdWXUgEjU1GKOKWAPw== -poseidon-lite@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/poseidon-lite/-/poseidon-lite-0.2.1.tgz#7ad98e3a3aa5b91a1fd3a61a87460e9e46fd76d6" - integrity sha512-xIr+G6HeYfOhCuswdqcFpSX47SPhm0EpisWJ6h7fHlWwaVIvH3dLnejpatrtw6Xc6HaLrpq05y7VRfvDmDGIog== - poseidon-lite@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/poseidon-lite/-/poseidon-lite-0.3.0.tgz#93c42f6f9b870f154f2722dfd686b909c4285765" From 60e12c6038d9a6f1ef42e444b6a104e491447354 Mon Sep 17 00:00:00 2001 From: Andrew Twyman Date: Mon, 30 Sep 2024 18:17:13 -0700 Subject: [PATCH 5/9] eddsa-pcd cleanups --- packages/pcd/eddsa-pcd/package.json | 1 - packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/pcd/eddsa-pcd/package.json b/packages/pcd/eddsa-pcd/package.json index bdce8f15cf..3475ae4c18 100644 --- a/packages/pcd/eddsa-pcd/package.json +++ b/packages/pcd/eddsa-pcd/package.json @@ -41,7 +41,6 @@ "devDependencies": { "@pcd/eslint-config-custom": "0.11.4", "@pcd/tsconfig": "0.11.4", - "@types/circomlibjs": "^0.1.6", "@types/mocha": "^10.0.1", "@types/uuid": "^9.0.0", "chai": "^4.3.7", diff --git a/packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts b/packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts index 500398a020..849551dfce 100644 --- a/packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts +++ b/packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts @@ -1,6 +1,5 @@ import { DisplayOptions, PCDPackage, SerializedPCD } from "@pcd/pcd-types"; import { fromHexString, requireDefinedParameter, toHexString } from "@pcd/util"; -import { Point } from "@zk-kit/baby-jubjub"; import { derivePublicKey, packSignature, @@ -80,7 +79,7 @@ export async function verify(pcd: EdDSAPCD): Promise { // multiplication, NOT Montgomery form of eliptic curves. See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#Montgomery_form const pubKey = pcd.claim.publicKey.map((coordinateString: string) => BigInt("0x" + coordinateString) - ) as Point; + ) as [bigint, bigint]; const hashedMessage = poseidonHashMessage(pcd.claim.message); From 0a41ab314e370b634d1f315fa3355ad659297baa Mon Sep 17 00:00:00 2001 From: Andrew Twyman Date: Mon, 30 Sep 2024 18:19:44 -0700 Subject: [PATCH 6/9] Use zk-kit in zk-eddsa-event-ticket-pcd --- .../zk-eddsa-event-ticket-pcd/package.json | 3 +- .../src/ZKEdDSAEventTicketPCDPackage.ts | 32 +++---------------- 2 files changed, 5 insertions(+), 30 deletions(-) diff --git a/packages/pcd/zk-eddsa-event-ticket-pcd/package.json b/packages/pcd/zk-eddsa-event-ticket-pcd/package.json index e9678fc106..f0766b49ad 100644 --- a/packages/pcd/zk-eddsa-event-ticket-pcd/package.json +++ b/packages/pcd/zk-eddsa-event-ticket-pcd/package.json @@ -42,7 +42,7 @@ "@pcd/snarkjs": "0.7.7", "@pcd/util": "0.5.4", "@semaphore-protocol/identity": "^3.15.2", - "circomlibjs": "^0.1.7", + "@zk-kit/eddsa-poseidon": "1.0.3", "json-bigint": "^1.0.0", "snarkjs": "^0.7.4", "uuid": "^9.0.0" @@ -51,7 +51,6 @@ "@pcd/artifacts": "0.4.4", "@pcd/eslint-config-custom": "0.11.4", "@pcd/tsconfig": "0.11.4", - "@types/circomlibjs": "^0.1.6", "@types/json-bigint": "^1.0.1", "@types/mocha": "^10.0.1", "@types/snarkjs": "^0.7.5", diff --git a/packages/pcd/zk-eddsa-event-ticket-pcd/src/ZKEdDSAEventTicketPCDPackage.ts b/packages/pcd/zk-eddsa-event-ticket-pcd/src/ZKEdDSAEventTicketPCDPackage.ts index a0fdcff2da..48a031568a 100644 --- a/packages/pcd/zk-eddsa-event-ticket-pcd/src/ZKEdDSAEventTicketPCDPackage.ts +++ b/packages/pcd/zk-eddsa-event-ticket-pcd/src/ZKEdDSAEventTicketPCDPackage.ts @@ -34,7 +34,7 @@ import { requireDefinedParameter, uuidToBigInt } from "@pcd/util"; -import { Eddsa, buildEddsa } from "circomlibjs"; +import { unpackSignature } from "@zk-kit/eddsa-poseidon"; import JSONBig from "json-bigint"; import { v4 as uuid } from "uuid"; import vkey from "../artifacts/circuit.json"; @@ -52,8 +52,6 @@ export const STATIC_TICKET_PCD_NULLIFIER = generateSnarkMessageHash( "dummy-nullifier-for-eddsa-event-ticket-pcds" ); -let depsInitializedPromise: Promise | undefined; -let eddsa: Eddsa; let savedInitArgs: ZKEdDSAEventTicketPCDInitArgs | undefined = undefined; /** @@ -63,23 +61,6 @@ export async function init(args: ZKEdDSAEventTicketPCDInitArgs): Promise { savedInitArgs = args; } -async function ensureDepsInitialized(): Promise { - if (!depsInitializedPromise) { - depsInitializedPromise = (async (): Promise => { - // TODO: This object is expensive to build, and duplicates some work, - // including buiding curves which aren't cached and thus have to be - // re-built by groth16. We need this object only for eddsa.F.toObject - // and eddsa.unpackSignature. To improve performance, we could tweak - // circomlibjs and/or zk-kit/groth16 either to expose those functions in a - // more limited way, or to cache all the expensive parts which will be - // needed later. - eddsa = await buildEddsa(); - })(); - } - - await depsInitializedPromise; -} - async function ensureInitialized(): Promise { if (!savedInitArgs) { throw new Error( @@ -87,7 +68,6 @@ async function ensureInitialized(): Promise { ); } - await ensureDepsInitialized(); return savedInitArgs; } @@ -180,11 +160,7 @@ function snarkInputForProof( const ticketAsBigIntArray = ticketDataToBigInts(ticketPCD.claim.ticket); const pubKey = ticketPCD.proof.eddsaPCD.claim.publicKey; - // Note: unpackSignature leaves the R8 point's coordinates in Montgomery - // form, which is then reversed by toObject below. - // This is a reference to Montgomery form of numbers for modular - // multiplication, NOT Montgomery form of eliptic curves. See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#Montgomery_form - const rawSig = eddsa.unpackSignature( + const rawSig = unpackSignature( fromHexString(ticketPCD.proof.eddsaPCD.proof.signature) ); @@ -235,8 +211,8 @@ function snarkInputForProof( // Ticket signature fields ticketSignerPubkeyAx: hexToBigInt(pubKey[0]).toString(), ticketSignerPubkeyAy: hexToBigInt(pubKey[1]).toString(), - ticketSignatureR8x: eddsa.F.toObject(rawSig.R8[0]).toString(), - ticketSignatureR8y: eddsa.F.toObject(rawSig.R8[1]).toString(), + ticketSignatureR8x: rawSig.R8[0].toString(), + ticketSignatureR8y: rawSig.R8[1].toString(), ticketSignatureS: rawSig.S.toString(), // Attendee identity secret From d217bd76c064962817209d3292360e3b2a0f928a Mon Sep 17 00:00:00 2001 From: Andrew Twyman Date: Mon, 30 Sep 2024 18:25:03 -0700 Subject: [PATCH 7/9] Use zk-kit in zk-eddsa-frog-pcd --- packages/pcd/zk-eddsa-frog-pcd/package.json | 3 +- .../src/ZKEdDSAFrogPCDPackage.ts | 32 +++---------------- 2 files changed, 5 insertions(+), 30 deletions(-) diff --git a/packages/pcd/zk-eddsa-frog-pcd/package.json b/packages/pcd/zk-eddsa-frog-pcd/package.json index 2886890806..268496e6e1 100644 --- a/packages/pcd/zk-eddsa-frog-pcd/package.json +++ b/packages/pcd/zk-eddsa-frog-pcd/package.json @@ -41,7 +41,7 @@ "@pcd/semaphore-signature-pcd": "0.11.6", "@pcd/util": "0.5.4", "@semaphore-protocol/identity": "^3.15.2", - "circomlibjs": "^0.1.7", + "@zk-kit/eddsa-poseidon": "1.0.3", "json-bigint": "^1.0.0", "snarkjs": "^0.7.4", "uuid": "^9.0.0" @@ -50,7 +50,6 @@ "@pcd/artifacts": "0.4.4", "@pcd/eslint-config-custom": "0.11.4", "@pcd/tsconfig": "0.11.4", - "@types/circomlibjs": "^0.1.6", "@types/json-bigint": "^1.0.1", "@types/mocha": "^10.0.1", "@types/snarkjs": "^0.7.5", diff --git a/packages/pcd/zk-eddsa-frog-pcd/src/ZKEdDSAFrogPCDPackage.ts b/packages/pcd/zk-eddsa-frog-pcd/src/ZKEdDSAFrogPCDPackage.ts index 3634384a2e..b5328e4d52 100644 --- a/packages/pcd/zk-eddsa-frog-pcd/src/ZKEdDSAFrogPCDPackage.ts +++ b/packages/pcd/zk-eddsa-frog-pcd/src/ZKEdDSAFrogPCDPackage.ts @@ -24,7 +24,7 @@ import { hexToBigInt, requireDefinedParameter } from "@pcd/util"; -import { Eddsa, buildEddsa } from "circomlibjs"; +import { unpackSignature } from "@zk-kit/eddsa-poseidon"; import JSONBig from "json-bigint"; import { Groth16Proof, groth16 } from "snarkjs"; import { v4 as uuid } from "uuid"; @@ -84,24 +84,6 @@ export function getProveDisplayOptions(): ProveDisplayOptions | undefined; -let eddsa: Eddsa; - -/** - * A promise designed to make sure that the EdDSA algorithm - * of the `circomlibjs` package has been properly initialized. - * It only initializes them once. - */ -async function ensureEddsaInitialized(): Promise { - if (!initializedPromise) { - initializedPromise = (async (): Promise => { - eddsa = await buildEddsa(); - })(); - } - - await initializedPromise; -} - async function checkProveInputs(args: ZKEdDSAFrogPCDArgs): Promise<{ frogPCD: EdDSAFrogPCD; identityPCD: SemaphoreIdentityPCD; @@ -154,11 +136,7 @@ function snarkInputForProof( const frogAsBigIntArray = frogDataToBigInts(frogPCD.claim.data); const signerPubKey = frogPCD.proof.eddsaPCD.claim.publicKey; - // Note: unpackSignature leaves the R8 point's coordinates in Montgomery - // form, which is then reversed by toObject below. - // This is a reference to Montgomery form of numbers for modular - // multiplication, NOT Montgomery form of eliptic curves. See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#Montgomery_form - const rawSig = eddsa.unpackSignature( + const rawSig = unpackSignature( fromHexString(frogPCD.proof.eddsaPCD.proof.signature) ); @@ -181,8 +159,8 @@ function snarkInputForProof( // Frog signature fields frogSignerPubkeyAx: hexToBigInt(signerPubKey[0]).toString(), frogSignerPubkeyAy: hexToBigInt(signerPubKey[1]).toString(), - frogSignatureR8x: eddsa.F.toObject(rawSig.R8[0]).toString(), - frogSignatureR8y: eddsa.F.toObject(rawSig.R8[1]).toString(), + frogSignatureR8x: rawSig.R8[0].toString(), + frogSignatureR8y: rawSig.R8[1].toString(), frogSignatureS: rawSig.S.toString(), // Owner identity secret @@ -237,8 +215,6 @@ export async function prove(args: ZKEdDSAFrogPCDArgs): Promise { throw new Error("cannot make proof: init has not been called yet"); } - await ensureEddsaInitialized(); - const { frogPCD, identityPCD, externalNullifier, watermark } = await checkProveInputs(args); From 4682ec22b3dc78a4e6c0855693e270d5a20de89b Mon Sep 17 00:00:00 2001 From: Andrew Twyman Date: Mon, 30 Sep 2024 20:19:21 -0700 Subject: [PATCH 8/9] Import poseidon the right way --- packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts b/packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts index 849551dfce..27af8afe04 100644 --- a/packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts +++ b/packages/pcd/eddsa-pcd/src/EDDSAPCDPackage.ts @@ -7,13 +7,11 @@ import { unpackSignature, verifySignature } from "@zk-kit/eddsa-poseidon"; -import { - poseidon1, - poseidon12, - poseidon13, - poseidon2, - poseidon3 -} from "poseidon-lite"; +import { poseidon1 } from "poseidon-lite/poseidon1"; +import { poseidon12 } from "poseidon-lite/poseidon12"; +import { poseidon13 } from "poseidon-lite/poseidon13"; +import { poseidon2 } from "poseidon-lite/poseidon2"; +import { poseidon3 } from "poseidon-lite/poseidon3"; import { v4 as uuid } from "uuid"; import { EdDSAInitArgs, @@ -207,11 +205,11 @@ function poseidonHashMessage(message: bigint[]): bigint { // Used by PODs for value hashing, so no extra bundle size impact. return poseidon1(message); case 2: - // UYsed by PODs for Merkle tree hasing, so no extra bundle size impact. + // Used by PODs for Merkle tree hasing, so no extra bundle size impact. return poseidon2(message); case 3: - // Needed for backward-compatibility tests. - // TODO(artwyman): Alter backward-compatibility test case to use a different size + // Used by unit tests, including backward-compatibility with fixed values. + // Used by GPCs for tuple hasing, so no extra bundle size impact. return poseidon3(message); case 12: // Tailored to the size of EdDSATicketPCD. From 0d9e6c3ffa33f14e98d4d2a82130033acf20ad7a Mon Sep 17 00:00:00 2001 From: Andrew Twyman Date: Mon, 30 Sep 2024 20:27:18 -0700 Subject: [PATCH 9/9] zk-kit versions --- apps/consumer-client/package.json | 2 +- apps/passport-server/package.json | 1 - packages/pcd/semaphore-identity-pcd/package.json | 2 +- yarn.lock | 4 ++-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/consumer-client/package.json b/apps/consumer-client/package.json index 21e522bcd6..3280029829 100644 --- a/apps/consumer-client/package.json +++ b/apps/consumer-client/package.json @@ -37,7 +37,7 @@ "@semaphore-protocol/identity": "^3.15.2", "@simplewebauthn/browser": "^7.2.0", "@simplewebauthn/server": "^7.2.0", - "@zk-kit/eddsa-poseidon": "1.0.2", + "@zk-kit/eddsa-poseidon": "1.0.3", "dotenv": "^16.0.3", "ethers": "^5.7.2", "json-bigint": "^1.0.0", diff --git a/apps/passport-server/package.json b/apps/passport-server/package.json index 25001a4d42..980446cd01 100644 --- a/apps/passport-server/package.json +++ b/apps/passport-server/package.json @@ -52,7 +52,6 @@ "@sendgrid/mail": "^7.7.0", "@types/lodash": "^4.14.191", "@types/pg": "^8.6.6", - "@zk-kit/eddsa-poseidon": "1.0.2", "async-lock": "^1.4.0", "cookie-parser": "^1.4.6", "cors": "^2.8.5", diff --git a/packages/pcd/semaphore-identity-pcd/package.json b/packages/pcd/semaphore-identity-pcd/package.json index a8b030a711..bc5d9d0c20 100644 --- a/packages/pcd/semaphore-identity-pcd/package.json +++ b/packages/pcd/semaphore-identity-pcd/package.json @@ -40,7 +40,7 @@ "json-bigint": "^1.0.0", "@types/json-bigint": "^1.0.3", "@zk-kit/eddsa-poseidon": "1.0.3", - "@zk-kit/utils": "^1.2.0", + "@zk-kit/utils": "^1.2.1", "js-sha256": "^0.11.0", "poseidon-lite": "^0.3.0", "uuid": "^9.0.0" diff --git a/yarn.lock b/yarn.lock index 346d9316d4..0d889fd765 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8171,14 +8171,14 @@ dependencies: buffer "^6.0.3" -"@zk-kit/utils@1.2.0", "@zk-kit/utils@^1.2.0": +"@zk-kit/utils@1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@zk-kit/utils/-/utils-1.2.0.tgz#7f5dfadb9512f1a090639c912395a6684b560ba2" integrity sha512-Ut9zfnlBVpopZG/s600Ds/FPSWXiPhO4q8949kmXTzwDXytjnvFbDZIFdWqE/lA7/NZjvykiTnnVwmanMxv2+w== dependencies: buffer "^6.0.3" -"@zk-kit/utils@1.2.1": +"@zk-kit/utils@1.2.1", "@zk-kit/utils@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@zk-kit/utils/-/utils-1.2.1.tgz#6cb38120535c73ab68cd0f09684882af148f256d" integrity sha512-H2nTsyWdicVOyvqC5AjgU7tsTgmR6PDrruFJNmlmdhKp7RxEia/E1B1swMZjaasYa2QMp4Zc6oB7cWchty7B2Q==