From 812b39c8790edb7a3df947404e4ff4ff2780dd9e Mon Sep 17 00:00:00 2001 From: Anton <14254374+0xmad@users.noreply.github.com> Date: Thu, 23 Jan 2025 12:07:03 -0600 Subject: [PATCH] feat: add poll joined vk --- .../ceremony-params/ceremonyParams.test.ts | 2 + packages/cli/tests/constants.ts | 5 + .../cli/ts/commands/checkVerifyingKeys.ts | 31 ++-- packages/cli/ts/commands/extractVkToFile.ts | 8 +- packages/cli/ts/commands/joinPoll.ts | 14 +- packages/cli/ts/commands/setVerifyingKeys.ts | 101 +++++------ packages/cli/ts/index.ts | 27 ++- packages/cli/ts/utils/interfaces.ts | 21 ++- packages/contracts/contracts/Poll.sol | 4 +- packages/contracts/contracts/VkRegistry.sol | 159 +++++++++++++----- .../contracts/interfaces/IVkRegistry.sol | 13 +- packages/contracts/deploy-config-example.json | 66 ++++++-- .../tasks/deploy/maci/08-vkRegistry.ts | 19 ++- packages/contracts/tests/Poll.test.ts | 15 +- packages/contracts/tests/Tally.test.ts | 26 ++- packages/contracts/tests/VkRegistry.test.ts | 63 +++++-- packages/contracts/tests/constants.ts | 10 +- packages/core/ts/index.ts | 2 +- packages/core/ts/utils/utils.ts | 17 +- 19 files changed, 413 insertions(+), 190 deletions(-) diff --git a/packages/cli/tests/ceremony-params/ceremonyParams.test.ts b/packages/cli/tests/ceremony-params/ceremonyParams.test.ts index 5de069dc31..dbe8655e70 100644 --- a/packages/cli/tests/ceremony-params/ceremonyParams.test.ts +++ b/packages/cli/tests/ceremony-params/ceremonyParams.test.ts @@ -44,6 +44,7 @@ import { ceremonyProcessMessagesNonQvWasmPath, ceremonyTallyVotesNonQvWasmPath, ceremonyPollJoiningZkeyPath, + ceremonyPollJoinedZkeyPath, } from "../constants"; import { clean, isArm } from "../utils"; @@ -68,6 +69,7 @@ describe("Stress tests with ceremony params (6,3,2,20)", function test() { voteOptionTreeDepth, messageBatchSize, pollJoiningZkeyPath: ceremonyPollJoiningZkeyPath, + pollJoinedZkeyPath: ceremonyPollJoinedZkeyPath, processMessagesZkeyPathQv: ceremonyProcessMessagesZkeyPath, tallyVotesZkeyPathQv: ceremonyTallyVotesZkeyPath, processMessagesZkeyPathNonQv: ceremonyProcessMessagesNonQvZkeyPath, diff --git a/packages/cli/tests/constants.ts b/packages/cli/tests/constants.ts index 053f77a49f..768ed0eacc 100644 --- a/packages/cli/tests/constants.ts +++ b/packages/cli/tests/constants.ts @@ -24,6 +24,7 @@ export const coordinatorPubKey = coordinatorKeypair.pubKey.serialize(); export const coordinatorPrivKey = coordinatorKeypair.privKey.serialize(); export const pollJoiningTestZkeyPath = "./zkeys/PollJoining_10_test/PollJoining_10_test.0.zkey"; +export const pollJoinedTestZkeyPath = "./zkeys/PollJoined_10_test/PollJoined_10_test.0.zkey"; export const processMessageTestZkeyPath = "./zkeys/ProcessMessages_10-20-2_test/ProcessMessages_10-20-2_test.0.zkey"; export const tallyVotesTestZkeyPath = "./zkeys/TallyVotes_10-1-2_test/TallyVotes_10-1-2_test.0.zkey"; export const processMessageTestNonQvZkeyPath = @@ -47,6 +48,7 @@ export const testTallyVotesWasmPath = "./zkeys/TallyVotes_10-1-2_test/TallyVotes_10-1-2_test_js/TallyVotes_10-1-2_test.wasm"; export const testRapidsnarkPath = `${homedir()}/rapidsnark/build/prover`; export const ceremonyPollJoiningZkeyPath = "./zkeys/PollJoining_10_test/PollJoining_10_test.0.zkey"; +export const ceremonyPollJoinedZkeyPath = "./zkeys/PollJoined_10_test/PollJoined_10_test.0.zkey"; export const ceremonyProcessMessagesZkeyPath = "./zkeys/ProcessMessages_6-9-2-3/processMessages_6-9-2-3.zkey"; export const ceremonyProcessMessagesNonQvZkeyPath = "./zkeys/ProcessMessagesNonQv_6-9-2-3/processMessagesNonQv_6-9-2-3.zkey"; @@ -98,6 +100,7 @@ export const setVerifyingKeysArgs: Omit = { voteOptionTreeDepth: VOTE_OPTION_TREE_DEPTH, messageBatchSize: MESSAGE_BATCH_SIZE, pollJoiningZkeyPath: pollJoiningTestZkeyPath, + pollJoinedZkeyPath: pollJoinedTestZkeyPath, processMessagesZkeyPathQv: processMessageTestZkeyPath, tallyVotesZkeyPathQv: tallyVotesTestZkeyPath, }; @@ -109,6 +112,7 @@ export const setVerifyingKeysNonQvArgs: Omit = { voteOptionTreeDepth: VOTE_OPTION_TREE_DEPTH, messageBatchSize: MESSAGE_BATCH_SIZE, pollJoiningZkeyPath: pollJoiningTestZkeyPath, + pollJoinedZkeyPath: pollJoinedTestZkeyPath, processMessagesZkeyPathNonQv: processMessageTestNonQvZkeyPath, tallyVotesZkeyPathNonQv: tallyVotesTestNonQvZkeyPath, }; @@ -119,6 +123,7 @@ export const checkVerifyingKeysArgs: Omit = { voteOptionTreeDepth: VOTE_OPTION_TREE_DEPTH, messageBatchSize: MESSAGE_BATCH_SIZE, pollJoiningZkeyPath: pollJoiningTestZkeyPath, + pollJoinedZkeyPath: pollJoinedTestZkeyPath, processMessagesZkeyPath: processMessageTestZkeyPath, tallyVotesZkeyPath: tallyVotesTestZkeyPath, }; diff --git a/packages/cli/ts/commands/checkVerifyingKeys.ts b/packages/cli/ts/commands/checkVerifyingKeys.ts index 805dbd8a9a..78f93aee7e 100644 --- a/packages/cli/ts/commands/checkVerifyingKeys.ts +++ b/packages/cli/ts/commands/checkVerifyingKeys.ts @@ -32,6 +32,7 @@ export const checkVerifyingKeys = async ({ processMessagesZkeyPath, tallyVotesZkeyPath, pollJoiningZkeyPath, + pollJoinedZkeyPath, vkRegistry, signer, useQuadraticVoting = true, @@ -69,30 +70,28 @@ export const checkVerifyingKeys = async ({ // extract the verification keys from the zkey files const processVk = VerifyingKey.fromObj(await extractVk(processMessagesZkeyPath)); const tallyVk = VerifyingKey.fromObj(await extractVk(tallyVotesZkeyPath)); - const pollVk = VerifyingKey.fromObj(await extractVk(pollJoiningZkeyPath)); + const pollJoiningVk = VerifyingKey.fromObj(await extractVk(pollJoiningZkeyPath)); + const pollJoinedVk = VerifyingKey.fromObj(await extractVk(pollJoinedZkeyPath)); try { logYellow(quiet, info("Retrieving verifying keys from the contract...")); // retrieve the verifying keys from the contract - const pollVkOnChain = await vkRegistryContractInstance.getPollVk(stateTreeDepth, voteOptionTreeDepth); + const mode = useQuadraticVoting ? EMode.QV : EMode.NON_QV; - const processVkOnChain = await vkRegistryContractInstance.getProcessVk( - stateTreeDepth, - voteOptionTreeDepth, - messageBatchSize, - useQuadraticVoting ? EMode.QV : EMode.NON_QV, - ); - - const tallyVkOnChain = await vkRegistryContractInstance.getTallyVk( - stateTreeDepth, - intStateTreeDepth, - voteOptionTreeDepth, - useQuadraticVoting ? EMode.QV : EMode.NON_QV, - ); + const [pollJoiningVkOnChain, pollJoinedVkOnChain, processVkOnChain, tallyVkOnChain] = await Promise.all([ + vkRegistryContractInstance.getPollJoiningVk(stateTreeDepth, voteOptionTreeDepth), + vkRegistryContractInstance.getPollJoinedVk(stateTreeDepth, voteOptionTreeDepth), + vkRegistryContractInstance.getProcessVk(stateTreeDepth, voteOptionTreeDepth, messageBatchSize, mode), + vkRegistryContractInstance.getTallyVk(stateTreeDepth, intStateTreeDepth, voteOptionTreeDepth, mode), + ]); // do the actual validation - if (!compareVks(pollVk, pollVkOnChain)) { + if (!compareVks(pollJoiningVk, pollJoiningVkOnChain)) { + logError("Poll verifying keys do not match"); + } + + if (!compareVks(pollJoinedVk, pollJoinedVkOnChain)) { logError("Poll verifying keys do not match"); } diff --git a/packages/cli/ts/commands/extractVkToFile.ts b/packages/cli/ts/commands/extractVkToFile.ts index 64d7a67fc6..177bb5f59b 100644 --- a/packages/cli/ts/commands/extractVkToFile.ts +++ b/packages/cli/ts/commands/extractVkToFile.ts @@ -15,20 +15,22 @@ export const extractVkToFile = async ({ processMessagesZkeyPathQv, tallyVotesZkeyPathQv, processMessagesZkeyPathNonQv, - tallyVotesZkeyPathNonQv, + pollJoinedZkeyPath, pollJoiningZkeyPath, + tallyVotesZkeyPathNonQv, outputFilePath, }: ExtractVkToFileArgs): Promise => { - const [processVkQv, tallyVkQv, processVkNonQv, tallyVkNonQv, pollVk] = await Promise.all([ + const [processVkQv, tallyVkQv, processVkNonQv, tallyVkNonQv, pollJoiningVk, pollJoinedVk] = await Promise.all([ extractVk(processMessagesZkeyPathQv), extractVk(tallyVotesZkeyPathQv), extractVk(processMessagesZkeyPathNonQv), extractVk(tallyVotesZkeyPathNonQv), extractVk(pollJoiningZkeyPath), + extractVk(pollJoinedZkeyPath), ]); await fs.promises.writeFile( outputFilePath, - JSON.stringify({ processVkQv, tallyVkQv, processVkNonQv, tallyVkNonQv, pollVk }), + JSON.stringify({ processVkQv, tallyVkQv, processVkNonQv, tallyVkNonQv, pollJoiningVk, pollJoinedVk }), ); }; diff --git a/packages/cli/ts/commands/joinPoll.ts b/packages/cli/ts/commands/joinPoll.ts index 4eb1e3bb2c..109b764f91 100644 --- a/packages/cli/ts/commands/joinPoll.ts +++ b/packages/cli/ts/commands/joinPoll.ts @@ -52,17 +52,17 @@ const getStateIndex = (pubKeys: PubKey[], userMaciPubKey: PubKey, stateIndex?: b * @param rapidsnarkExePath - the path to the rapidnsark binary * @param witnessExePath - the path to the compiled witness binary * @param wasmPath - the path to the wasm witness - * @param pollVk - Poll verifying key + * @param pollJoiningVk - Poll verifying key * @returns proof - an array of strings */ -const generateAndVerifyProof = async ( +const generateAndVerifyJoiningProof = async ( inputs: CircuitInputs, zkeyPath: string, useWasm: boolean | undefined, rapidsnarkExePath: string | undefined, witnessExePath: string | undefined, wasmPath: string | undefined, - pollVk: IVkObjectParams, + pollJoiningVk: IVkObjectParams, ): Promise => { const r = await genProof({ inputs, @@ -74,7 +74,7 @@ const generateAndVerifyProof = async ( }); // verify it - const isValid = await verifyProof(r.publicSignals, r.proof, pollVk); + const isValid = await verifyProof(r.publicSignals, r.proof, pollJoiningVk); if (!isValid) { throw new Error("Generated an invalid proof"); @@ -298,7 +298,7 @@ export const joinPoll = async ({ ) as unknown as CircuitInputs; } - const pollVk = await extractVk(pollJoiningZkey); + const pollJoiningVk = await extractVk(pollJoiningZkey); let pollStateIndex = ""; let receipt: ContractTransactionReceipt | null = null; @@ -308,14 +308,14 @@ export const joinPoll = async ({ try { // generate the proof for this batch - const proof = await generateAndVerifyProof( + const proof = await generateAndVerifyJoiningProof( circuitInputs, pollJoiningZkey, useWasm, rapidsnark, pollWitgen, pollWasm, - pollVk, + pollJoiningVk, ); // submit the message onchain as well as the encryption public key diff --git a/packages/cli/ts/commands/setVerifyingKeys.ts b/packages/cli/ts/commands/setVerifyingKeys.ts index 12d06f8d0e..c9d970ecac 100644 --- a/packages/cli/ts/commands/setVerifyingKeys.ts +++ b/packages/cli/ts/commands/setVerifyingKeys.ts @@ -1,6 +1,6 @@ import { extractVk } from "maci-circuits"; import { type IVerifyingKeyStruct, VkRegistry__factory as VkRegistryFactory, EMode } from "maci-contracts"; -import { genPollVkSig, genProcessVkSig, genTallyVkSig } from "maci-core"; +import { genPollJoinedVkSig, genPollJoiningVkSig, genProcessVkSig, genTallyVkSig } from "maci-core"; import { VerifyingKey } from "maci-domainobjs"; import fs from "fs"; @@ -29,6 +29,7 @@ export const setVerifyingKeys = async ({ voteOptionTreeDepth, messageBatchSize, pollJoiningZkeyPath, + pollJoinedZkeyPath, processMessagesZkeyPathQv, tallyVotesZkeyPathQv, processMessagesZkeyPathNonQv, @@ -83,7 +84,8 @@ export const setVerifyingKeys = async ({ } // extract the vks - const pollVk = pollJoiningZkeyPath && VerifyingKey.fromObj(await extractVk(pollJoiningZkeyPath)); + const pollJoiningVk = pollJoiningZkeyPath && VerifyingKey.fromObj(await extractVk(pollJoiningZkeyPath)); + const pollJoinedVk = pollJoinedZkeyPath && VerifyingKey.fromObj(await extractVk(pollJoinedZkeyPath)); const processVkQv = processMessagesZkeyPathQv && VerifyingKey.fromObj(await extractVk(processMessagesZkeyPathQv)); const tallyVkQv = tallyVotesZkeyPathQv && VerifyingKey.fromObj(await extractVk(tallyVotesZkeyPathQv)); const processVkNonQv = @@ -127,8 +129,16 @@ export const setVerifyingKeys = async ({ const vkRegistryContract = VkRegistryFactory.connect(vkRegistryAddress, signer); // check if the poll vk was already set - const pollVkSig = genPollVkSig(stateTreeDepth, voteOptionTreeDepth); - if (await vkRegistryContract.isPollVkSet(pollVkSig)) { + const pollJoiningVkSig = genPollJoiningVkSig(stateTreeDepth, voteOptionTreeDepth); + + if (await vkRegistryContract.isPollJoiningVkSet(pollJoiningVkSig)) { + logError("This poll verifying key is already set in the contract"); + } + + // check if the poll vk was already set + const pollJoinedVkSig = genPollJoinedVkSig(stateTreeDepth, voteOptionTreeDepth); + + if (await vkRegistryContract.isPollJoinedVkSet(pollJoinedVkSig)) { logError("This poll verifying key is already set in the contract"); } @@ -157,7 +167,6 @@ export const setVerifyingKeys = async ({ // actually set those values try { logYellow(quiet, info("Setting verifying keys...")); - const pollZkeys = (pollVk as VerifyingKey).asContractParam() as IVerifyingKeyStruct; const processZkeys = [processVkQv, processVkNonQv] .filter(Boolean) @@ -182,7 +191,8 @@ export const setVerifyingKeys = async ({ voteOptionTreeDepth, messageBatchSize, modes, - pollZkeys, + (pollJoiningVk as VerifyingKey).asContractParam() as IVerifyingKeyStruct, + (pollJoinedVk as VerifyingKey).asContractParam() as IVerifyingKeyStruct, processZkeys, tallyZkeys, ); @@ -196,62 +206,29 @@ export const setVerifyingKeys = async ({ logYellow(quiet, info(`Transaction hash: ${receipt!.hash}`)); // confirm that they were actually set correctly - if (useQuadraticVoting) { - const pollVkOnChain = await vkRegistryContract.getPollVk(stateTreeDepth, voteOptionTreeDepth); - - const processVkOnChain = await vkRegistryContract.getProcessVk( - stateTreeDepth, - voteOptionTreeDepth, - messageBatchSize, - EMode.QV, - ); - - const tallyVkOnChain = await vkRegistryContract.getTallyVk( - stateTreeDepth, - intStateTreeDepth, - voteOptionTreeDepth, - EMode.QV, - ); - - if (!compareVks(pollVk as VerifyingKey, pollVkOnChain)) { - logError("pollVk mismatch"); - } - - if (!compareVks(processVkQv as VerifyingKey, processVkOnChain)) { - logError("processVk mismatch"); - } - - if (!compareVks(tallyVkQv as VerifyingKey, tallyVkOnChain)) { - logError("tallyVk mismatch"); - } - } else { - const pollVkOnChain = await vkRegistryContract.getPollVk(stateTreeDepth, voteOptionTreeDepth); - - const processVkOnChain = await vkRegistryContract.getProcessVk( - stateTreeDepth, - voteOptionTreeDepth, - messageBatchSize, - EMode.NON_QV, - ); - - const tallyVkOnChain = await vkRegistryContract.getTallyVk( - stateTreeDepth, - intStateTreeDepth, - voteOptionTreeDepth, - EMode.NON_QV, - ); - - if (!compareVks(pollVk as VerifyingKey, pollVkOnChain)) { - logError("pollVk mismatch"); - } - - if (!compareVks(processVkNonQv as VerifyingKey, processVkOnChain)) { - logError("processVk mismatch"); - } - - if (!compareVks(tallyVkNonQv as VerifyingKey, tallyVkOnChain)) { - logError("tallyVk mismatch"); - } + const mode = useQuadraticVoting ? EMode.QV : EMode.NON_QV; + + const [pollJoiningVkOnChain, pollJoinedVkOnChain, processVkOnChain, tallyVkOnChain] = await Promise.all([ + vkRegistryContract.getPollJoiningVk(stateTreeDepth, voteOptionTreeDepth), + vkRegistryContract.getPollJoinedVk(stateTreeDepth, voteOptionTreeDepth), + vkRegistryContract.getProcessVk(stateTreeDepth, voteOptionTreeDepth, messageBatchSize, mode), + vkRegistryContract.getTallyVk(stateTreeDepth, intStateTreeDepth, voteOptionTreeDepth, mode), + ]); + + if (!compareVks(pollJoiningVk as VerifyingKey, pollJoiningVkOnChain)) { + logError("pollJoiningVk mismatch"); + } + + if (!compareVks(pollJoinedVk as VerifyingKey, pollJoinedVkOnChain)) { + logError("pollJoinedVk mismatch"); + } + + if (!compareVks(processVkQv as VerifyingKey, processVkOnChain)) { + logError("processVk mismatch"); + } + + if (!compareVks(tallyVkQv as VerifyingKey, tallyVkOnChain)) { + logError("tallyVk mismatch"); } } catch (error) { logError((error as Error).message); diff --git a/packages/cli/ts/index.ts b/packages/cli/ts/index.ts index 6c77ec630f..39e6b07016 100644 --- a/packages/cli/ts/index.ts +++ b/packages/cli/ts/index.ts @@ -105,8 +105,12 @@ program "the tally votes zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)", ) .requiredOption( - "--poll-joining-zkey ", - "the poll join zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)", + "--poll-joining-zkey ", + "the poll joining zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)", + ) + .requiredOption( + "--poll-joined-zkey ", + "the poll joined zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)", ) .action(async (cmdOptions) => { try { @@ -120,6 +124,7 @@ program processMessagesZkeyPath: cmdOptions.processMessagesZkey, tallyVotesZkeyPath: cmdOptions.tallyVotesZkey, pollJoiningZkeyPath: cmdOptions.pollJoiningZkey, + pollJoinedZkeyPath: cmdOptions.pollJoinedZkey, vkRegistry: cmdOptions.vkContract, quiet: cmdOptions.quiet, useQuadraticVoting: cmdOptions.useQuadraticVoting, @@ -283,8 +288,12 @@ program .requiredOption("-v, --vote-option-tree-depth ", "the vote option tree depth", parseInt) .requiredOption("-b, --msg-batch-size ", "the message batch size", parseInt) .option( - "--poll-joining-zkey ", - "the poll join zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)", + "--poll-joining-zkey ", + "the poll joining zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)", + ) + .option( + "--poll-joined-zkey ", + "the poll joined zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)", ) .option( "--process-messages-zkey-qv ", @@ -321,6 +330,7 @@ program voteOptionTreeDepth: cmdObj.voteOptionTreeDepth, messageBatchSize: cmdObj.msgBatchSize, pollJoiningZkeyPath: cmdObj.pollJoiningZkey, + pollJoinedZkeyPath: cmdObj.pollJoinedZkey, processMessagesZkeyPathQv: cmdObj.processMessagesZkeyQv, tallyVotesZkeyPathQv: cmdObj.tallyVotesZkeyQv, processMessagesZkeyPathNonQv: cmdObj.processMessagesZkeyNonQv, @@ -419,8 +429,12 @@ program .command("extractVkToFile") .description("extract vkey to json file") .requiredOption( - "--poll-joining-zkey ", - "the poll join zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)", + "--poll-joining-zkey ", + "the poll joining zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)", + ) + .requiredOption( + "--poll-joined-zkey ", + "the poll joined zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)", ) .requiredOption( "--process-messages-zkey-qv ", @@ -447,6 +461,7 @@ program processMessagesZkeyPathNonQv: cmdObj.processMessagesZkeyNonQv, tallyVotesZkeyPathNonQv: cmdObj.tallyVotesZkeyNonQv, pollJoiningZkeyPath: cmdObj.pollJoiningZkey, + pollJoinedZkeyPath: cmdObj.pollJoinedZkey, outputFilePath: cmdObj.outputFile, }); } catch (error) { diff --git a/packages/cli/ts/utils/interfaces.ts b/packages/cli/ts/utils/interfaces.ts index e31fdc1362..e8d0f5f461 100644 --- a/packages/cli/ts/utils/interfaces.ts +++ b/packages/cli/ts/utils/interfaces.ts @@ -176,10 +176,15 @@ export interface CheckVerifyingKeysArgs { messageBatchSize: number; /** - * The path to the poll zkey + * The path to the poll joining zkey */ pollJoiningZkeyPath: string; + /** + * The path to the poll joined zkey + */ + pollJoinedZkeyPath: string; + /** * The path to the process messages zkey */ @@ -891,10 +896,15 @@ export interface SetVerifyingKeysArgs { messageBatchSize: number; /** - * The path to the poll zkey + * The path to the poll joining zkey */ pollJoiningZkeyPath?: string; + /** + * The path to the poll joined zkey + */ + pollJoinedZkeyPath?: string; + /** * The path to the process messages qv zkey */ @@ -1193,10 +1203,15 @@ export interface DeployVkRegistryArgs { export interface ExtractVkToFileArgs { /** - * File path for poll zkey + * File path for poll joining zkey */ pollJoiningZkeyPath: string; + /** + * File path for poll joined zkey + */ + pollJoinedZkeyPath: string; + /** * File path for processMessagesQv zkey */ diff --git a/packages/contracts/contracts/Poll.sol b/packages/contracts/contracts/Poll.sol index 1e8ad71f28..e42e01e4a9 100644 --- a/packages/contracts/contracts/Poll.sol +++ b/packages/contracts/contracts/Poll.sol @@ -372,7 +372,7 @@ contract Poll is Params, Utilities, SnarkCommon, IPoll { uint256[8] memory _proof ) public view returns (bool isValid) { // Get the verifying key from the VkRegistry - VerifyingKey memory vk = extContracts.vkRegistry.getPollVk( + VerifyingKey memory vk = extContracts.vkRegistry.getPollJoiningVk( extContracts.maci.stateTreeDepth(), treeDepths.voteOptionTreeDepth ); @@ -394,7 +394,7 @@ contract Poll is Params, Utilities, SnarkCommon, IPoll { uint256[8] memory _proof ) public view returns (bool isValid) { // Get the verifying key from the VkRegistry - VerifyingKey memory vk = extContracts.vkRegistry.getPollVk( + VerifyingKey memory vk = extContracts.vkRegistry.getPollJoinedVk( extContracts.maci.stateTreeDepth(), treeDepths.voteOptionTreeDepth ); diff --git a/packages/contracts/contracts/VkRegistry.sol b/packages/contracts/contracts/VkRegistry.sol index 78b9691206..0c66306eb8 100644 --- a/packages/contracts/contracts/VkRegistry.sol +++ b/packages/contracts/contracts/VkRegistry.sol @@ -17,31 +17,37 @@ contract VkRegistry is Ownable(msg.sender), DomainObjs, SnarkCommon, IVkRegistry mapping(Mode => mapping(uint256 => VerifyingKey)) internal tallyVks; mapping(Mode => mapping(uint256 => bool)) internal tallyVkSet; - mapping(uint256 => VerifyingKey) internal pollVks; - mapping(uint256 => bool) internal pollVkSet; + mapping(uint256 => VerifyingKey) internal pollJoiningVks; + mapping(uint256 => bool) internal pollJoiningVkSet; - event PollVkSet(uint256 _sig); + mapping(uint256 => VerifyingKey) internal pollJoinedVks; + mapping(uint256 => bool) internal pollJoinedVkSet; + + event PollJoiningVkSet(uint256 _sig); + event PollJoinedVkSet(uint256 _sig); event ProcessVkSet(uint256 _sig, Mode _mode); event TallyVkSet(uint256 _sig, Mode _mode); - error PollVkAlreadySet(); - error ProcessVkAlreadySet(); - error TallyVkAlreadySet(); - error PollVkNotSet(); - error ProcessVkNotSet(); - error TallyVkNotSet(); - error SubsidyVkNotSet(); + error VkAlreadySet(); + error VkNotSet(); error InvalidKeysParams(); /// @notice Create a new instance of the VkRegistry contract // solhint-disable-next-line no-empty-blocks constructor() payable {} - /// @notice Check if the poll verifying key is set + /// @notice Check if the poll joining verifying key is set + /// @param _sig The signature + /// @return isSet whether the verifying key is set + function isPollJoiningVkSet(uint256 _sig) public view returns (bool isSet) { + isSet = pollJoiningVkSet[_sig]; + } + + /// @notice Check if the poll joined verifying key is set /// @param _sig The signature /// @return isSet whether the verifying key is set - function isPollVkSet(uint256 _sig) public view returns (bool isSet) { - isSet = pollVkSet[_sig]; + function isPollJoinedVkSet(uint256 _sig) public view returns (bool isSet) { + isSet = pollJoinedVkSet[_sig]; } /// @notice Check if the process verifying key is set @@ -60,13 +66,23 @@ contract VkRegistry is Ownable(msg.sender), DomainObjs, SnarkCommon, IVkRegistry isSet = tallyVkSet[_mode][_sig]; } - /// @notice generate the signature for the poll verifying key + /// @notice generate the signature for the poll joining verifying key /// @param _stateTreeDepth The state tree depth /// @param _voteOptionTreeDepth The vote option tree depth - function genPollVkSig(uint256 _stateTreeDepth, uint256 _voteOptionTreeDepth) public pure returns (uint256 sig) { + function genPollJoiningVkSig( + uint256 _stateTreeDepth, + uint256 _voteOptionTreeDepth + ) public pure returns (uint256 sig) { sig = (_stateTreeDepth << 64) + _voteOptionTreeDepth; } + /// @notice generate the signature for the poll joined verifying key + /// @param _stateTreeDepth The state tree depth + /// @param _voteOptionTreeDepth The vote option tree depth + function genPollJoinedVkSig(uint256 _stateTreeDepth, uint256 _voteOptionTreeDepth) public pure returns (uint256 sig) { + sig = (_stateTreeDepth << 128) + (_voteOptionTreeDepth << 64); + } + /// @notice generate the signature for the process verifying key /// @param _stateTreeDepth The state tree depth /// @param _voteOptionTreeDepth The vote option tree depth @@ -99,7 +115,8 @@ contract VkRegistry is Ownable(msg.sender), DomainObjs, SnarkCommon, IVkRegistry /// @param _voteOptionTreeDepth The vote option tree depth /// @param _messageBatchSize The message batch size /// @param _modes Array of QV or Non-QV modes (must have the same length as process and tally keys) - /// @param _pollVk The poll verifying key + /// @param _pollJoiningVk The poll joining verifying key + /// @param _pollJoinedVk The poll joined verifying key /// @param _processVks The process verifying keys (must have the same length as modes) /// @param _tallyVks The tally verifying keys (must have the same length as modes) function setVerifyingKeysBatch( @@ -108,7 +125,8 @@ contract VkRegistry is Ownable(msg.sender), DomainObjs, SnarkCommon, IVkRegistry uint256 _voteOptionTreeDepth, uint8 _messageBatchSize, Mode[] calldata _modes, - VerifyingKey calldata _pollVk, + VerifyingKey calldata _pollJoiningVk, + VerifyingKey calldata _pollJoinedVk, VerifyingKey[] calldata _processVks, VerifyingKey[] calldata _tallyVks ) public onlyOwner { @@ -118,7 +136,8 @@ contract VkRegistry is Ownable(msg.sender), DomainObjs, SnarkCommon, IVkRegistry uint256 length = _modes.length; - setPollVkKey(_stateTreeDepth, _voteOptionTreeDepth, _pollVk); + setPollJoiningVkKey(_stateTreeDepth, _voteOptionTreeDepth, _pollJoiningVk); + setPollJoinedVkKey(_stateTreeDepth, _voteOptionTreeDepth, _pollJoinedVk); for (uint256 index = 0; index < length; ) { setVerifyingKeys( @@ -173,7 +192,7 @@ contract VkRegistry is Ownable(msg.sender), DomainObjs, SnarkCommon, IVkRegistry ) public onlyOwner { uint256 processVkSig = genProcessVkSig(_stateTreeDepth, _voteOptionTreeDepth, _messageBatchSize); - if (processVkSet[_mode][processVkSig]) revert ProcessVkAlreadySet(); + if (processVkSet[_mode][processVkSig]) revert VkAlreadySet(); VerifyingKey storage processVk = processVks[_mode][processVkSig]; processVk.alpha1 = _processVk.alpha1; @@ -210,7 +229,7 @@ contract VkRegistry is Ownable(msg.sender), DomainObjs, SnarkCommon, IVkRegistry ) public onlyOwner { uint256 tallyVkSig = genTallyVkSig(_stateTreeDepth, _intStateTreeDepth, _voteOptionTreeDepth); - if (tallyVkSet[_mode][tallyVkSig]) revert TallyVkAlreadySet(); + if (tallyVkSet[_mode][tallyVkSig]) revert VkAlreadySet(); VerifyingKey storage tallyVk = tallyVks[_mode][tallyVkSig]; tallyVk.alpha1 = _tallyVk.alpha1; @@ -232,37 +251,70 @@ contract VkRegistry is Ownable(msg.sender), DomainObjs, SnarkCommon, IVkRegistry emit TallyVkSet(tallyVkSig, _mode); } - /// @notice Set the poll verifying key for a certain combination of parameters + /// @notice Set the poll joining verifying key for a certain combination of parameters + /// @param _stateTreeDepth The state tree depth + /// @param _voteOptionTreeDepth The vote option tree depth + /// @param _pollJoiningVk The poll joining verifying key + function setPollJoiningVkKey( + uint256 _stateTreeDepth, + uint256 _voteOptionTreeDepth, + VerifyingKey calldata _pollJoiningVk + ) public onlyOwner { + uint256 pollJoiningVkSig = genPollJoiningVkSig(_stateTreeDepth, _voteOptionTreeDepth); + + if (pollJoiningVkSet[pollJoiningVkSig]) revert VkAlreadySet(); + + VerifyingKey storage pollJoiningVk = pollJoiningVks[pollJoiningVkSig]; + pollJoiningVk.alpha1 = _pollJoiningVk.alpha1; + pollJoiningVk.beta2 = _pollJoiningVk.beta2; + pollJoiningVk.gamma2 = _pollJoiningVk.gamma2; + pollJoiningVk.delta2 = _pollJoiningVk.delta2; + + uint256 pollIcLength = _pollJoiningVk.ic.length; + for (uint256 i = 0; i < pollIcLength; ) { + pollJoiningVk.ic.push(_pollJoiningVk.ic[i]); + + unchecked { + i++; + } + } + + pollJoiningVkSet[pollJoiningVkSig] = true; + + emit PollJoiningVkSet(pollJoiningVkSig); + } + + /// @notice Set the poll joined verifying key for a certain combination of parameters /// @param _stateTreeDepth The state tree depth /// @param _voteOptionTreeDepth The vote option tree depth - /// @param _pollVk The poll verifying key - function setPollVkKey( + /// @param _pollJoinedVk The poll joined verifying key + function setPollJoinedVkKey( uint256 _stateTreeDepth, uint256 _voteOptionTreeDepth, - VerifyingKey calldata _pollVk + VerifyingKey calldata _pollJoinedVk ) public onlyOwner { - uint256 pollVkSig = genPollVkSig(_stateTreeDepth, _voteOptionTreeDepth); + uint256 pollJoinedVkSig = genPollJoinedVkSig(_stateTreeDepth, _voteOptionTreeDepth); - if (pollVkSet[pollVkSig]) revert PollVkAlreadySet(); + if (pollJoinedVkSet[pollJoinedVkSig]) revert VkAlreadySet(); - VerifyingKey storage pollVk = pollVks[pollVkSig]; - pollVk.alpha1 = _pollVk.alpha1; - pollVk.beta2 = _pollVk.beta2; - pollVk.gamma2 = _pollVk.gamma2; - pollVk.delta2 = _pollVk.delta2; + VerifyingKey storage pollJoinedVk = pollJoinedVks[pollJoinedVkSig]; + pollJoinedVk.alpha1 = _pollJoinedVk.alpha1; + pollJoinedVk.beta2 = _pollJoinedVk.beta2; + pollJoinedVk.gamma2 = _pollJoinedVk.gamma2; + pollJoinedVk.delta2 = _pollJoinedVk.delta2; - uint256 pollIcLength = _pollVk.ic.length; + uint256 pollIcLength = _pollJoinedVk.ic.length; for (uint256 i = 0; i < pollIcLength; ) { - pollVk.ic.push(_pollVk.ic[i]); + pollJoinedVk.ic.push(_pollJoinedVk.ic[i]); unchecked { i++; } } - pollVkSet[pollVkSig] = true; + pollJoinedVkSet[pollJoinedVkSig] = true; - emit PollVkSet(pollVkSig); + emit PollJoinedVkSet(pollJoinedVkSig); } /// @notice Check if the process verifying key is set @@ -286,7 +338,7 @@ contract VkRegistry is Ownable(msg.sender), DomainObjs, SnarkCommon, IVkRegistry /// @param _mode QV or Non-QV /// @return vk The verifying key function getProcessVkBySig(uint256 _sig, Mode _mode) public view returns (VerifyingKey memory vk) { - if (!processVkSet[_mode][_sig]) revert ProcessVkNotSet(); + if (!processVkSet[_mode][_sig]) revert VkNotSet(); vk = processVks[_mode][_sig]; } @@ -325,7 +377,7 @@ contract VkRegistry is Ownable(msg.sender), DomainObjs, SnarkCommon, IVkRegistry /// @param _mode QV or Non-QV /// @return vk The verifying key function getTallyVkBySig(uint256 _sig, Mode _mode) public view returns (VerifyingKey memory vk) { - if (!tallyVkSet[_mode][_sig]) revert TallyVkNotSet(); + if (!tallyVkSet[_mode][_sig]) revert VkNotSet(); vk = tallyVks[_mode][_sig]; } @@ -342,22 +394,41 @@ contract VkRegistry is Ownable(msg.sender), DomainObjs, SnarkCommon, IVkRegistry vk = getTallyVkBySig(sig, _mode); } - /// @notice Get the poll verifying key by signature + /// @notice Get the poll joining verifying key by signature /// @param _sig The signature /// @return vk The verifying key - function getPollVkBySig(uint256 _sig) public view returns (VerifyingKey memory vk) { - if (!pollVkSet[_sig]) revert PollVkNotSet(); + function getPollJoiningVkBySig(uint256 _sig) public view returns (VerifyingKey memory vk) { + if (!pollJoiningVkSet[_sig]) revert VkNotSet(); + + vk = pollJoiningVks[_sig]; + } + + /// @notice Get the poll joined verifying key by signature + /// @param _sig The signature + /// @return vk The verifying key + function getPollJoinedVkBySig(uint256 _sig) public view returns (VerifyingKey memory vk) { + if (!pollJoinedVkSet[_sig]) revert VkNotSet(); + + vk = pollJoinedVks[_sig]; + } + + /// @inheritdoc IVkRegistry + function getPollJoiningVk( + uint256 _stateTreeDepth, + uint256 _voteOptionTreeDepth + ) public view returns (VerifyingKey memory vk) { + uint256 sig = genPollJoiningVkSig(_stateTreeDepth, _voteOptionTreeDepth); - vk = pollVks[_sig]; + vk = getPollJoiningVkBySig(sig); } /// @inheritdoc IVkRegistry - function getPollVk( + function getPollJoinedVk( uint256 _stateTreeDepth, uint256 _voteOptionTreeDepth ) public view returns (VerifyingKey memory vk) { - uint256 sig = genPollVkSig(_stateTreeDepth, _voteOptionTreeDepth); + uint256 sig = genPollJoinedVkSig(_stateTreeDepth, _voteOptionTreeDepth); - vk = getPollVkBySig(sig); + vk = getPollJoinedVkBySig(sig); } } diff --git a/packages/contracts/contracts/interfaces/IVkRegistry.sol b/packages/contracts/contracts/interfaces/IVkRegistry.sol index 4c7a87cb83..c26657caf4 100644 --- a/packages/contracts/contracts/interfaces/IVkRegistry.sol +++ b/packages/contracts/contracts/interfaces/IVkRegistry.sol @@ -33,11 +33,20 @@ interface IVkRegistry { DomainObjs.Mode _mode ) external view returns (SnarkCommon.VerifyingKey memory); - /// @notice Get the poll verifying key + /// @notice Get the poll joining verifying key /// @param _stateTreeDepth The state tree depth /// @param _voteOptionTreeDepth The vote option tree depth /// @return The verifying key - function getPollVk( + function getPollJoiningVk( + uint256 _stateTreeDepth, + uint256 _voteOptionTreeDepth + ) external view returns (SnarkCommon.VerifyingKey memory); + + /// @notice Get the poll joined verifying key + /// @param _stateTreeDepth The state tree depth + /// @param _voteOptionTreeDepth The vote option tree depth + /// @return The verifying key + function getPollJoinedVk( uint256 _stateTreeDepth, uint256 _voteOptionTreeDepth ) external view returns (SnarkCommon.VerifyingKey memory); diff --git a/packages/contracts/deploy-config-example.json b/packages/contracts/deploy-config-example.json index a049ded54b..ce09bc24c5 100644 --- a/packages/contracts/deploy-config-example.json +++ b/packages/contracts/deploy-config-example.json @@ -56,9 +56,13 @@ "processWasm": "../cli/zkeys/ProcessMessagesNonQv_10-20-2_test/ProcessMessagesNonQv_10-20-2_test_js/ProcessMessagesNonQv_10-20-2_test.wasm", "tallyWasm": "../cli/zkeys/TallyVotesNonQv_10-1-2_test/TallyVotesNonQv_10-1-2_test_js/TallyVotesNonQv_10-1-2_test.wasm" }, - "pollZkey": { + "pollJoiningZkey": { "zkey": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test.0.zkey", "wasm": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test_js/PollJoining_10_test.wasm" + }, + "pollJoinedZkey": { + "zkey": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test.0.zkey", + "wasm": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test_js/PollJoined_10_test.wasm" } } }, @@ -127,9 +131,13 @@ "processWasm": "../cli/zkeys/ProcessMessagesNonQv_10-20-2_test/ProcessMessagesNonQv_10-20-2_test_js/ProcessMessagesNonQv_10-20-2_test.wasm", "tallyWasm": "../cli/zkeys/TallyVotesNonQv_10-1-2_test/TallyVotesNonQv_10-1-2_test_js/TallyVotesNonQv_10-1-2_test.wasm" }, - "pollZkey": { + "pollJoiningZkey": { "zkey": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test.0.zkey", "wasm": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test_js/PollJoining_10_test.wasm" + }, + "pollJoinedZkey": { + "zkey": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test.0.zkey", + "wasm": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test_js/PollJoined_10_test.wasm" } } }, @@ -199,9 +207,13 @@ "processWasm": "../cli/zkeys/ProcessMessagesNonQv_6-9-2-3/ProcessMessagesNonQv_6-9-2-3_js/ProcessMessagesNonQv_6-9-2-3.wasm", "tallyWasm": "../cli/zkeys/TallyVotesNonQv_6-2-3/TallyVotesNonQv_6-2-3_js/TallyVotesNonQv_6-2-3.wasm" }, - "pollZkey": { + "pollJoiningZkey": { "zkey": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test.0.zkey", "wasm": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test_js/PollJoining_10_test.wasm" + }, + "pollJoinedZkey": { + "zkey": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test.0.zkey", + "wasm": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test_js/PollJoined_10_test.wasm" } } }, @@ -271,9 +283,13 @@ "processWasm": "../cli/zkeys/ProcessMessagesNonQv_10-20-2_test/ProcessMessagesNonQv_10-20-2_test_js/ProcessMessagesNonQv_10-20-2_test.wasm", "tallyWasm": "../cli/zkeys/TallyVotesNonQv_10-1-2_test/TallyVotesNonQv_10-1-2_test_js/TallyVotesNonQv_10-1-2_test.wasm" }, - "pollZkey": { + "pollJoiningZkey": { "zkey": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test.0.zkey", "wasm": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test_js/PollJoining_10_test.wasm" + }, + "pollJoinedZkey": { + "zkey": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test.0.zkey", + "wasm": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test_js/PollJoined_10_test.wasm" } } }, @@ -343,9 +359,13 @@ "processWasm": "../cli/zkeys/ProcessMessagesNonQv_10-20-2_test/ProcessMessagesNonQv_10-20-2_test_js/ProcessMessagesNonQv_10-20-2_test.wasm", "tallyWasm": "../cli/zkeys/TallyVotesNonQv_10-1-2_test/TallyVotesNonQv_10-1-2_test_js/TallyVotesNonQv_10-1-2_test.wasm" }, - "pollZkey": { + "pollJoiningZkey": { "zkey": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test.0.zkey", "wasm": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test_js/PollJoining_10_test.wasm" + }, + "pollJoinedZkey": { + "zkey": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test.0.zkey", + "wasm": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test_js/PollJoined_10_test.wasm" } } }, @@ -415,9 +435,13 @@ "processWasm": "../cli/zkeys/ProcessMessagesNonQv_10-20-2_test/ProcessMessagesNonQv_10-20-2_test_js/ProcessMessagesNonQv_10-20-2_test.wasm", "tallyWasm": "../cli/zkeys/TallyVotesNonQv_10-1-2_test/TallyVotesNonQv_10-1-2_test_js/TallyVotesNonQv_10-1-2_test.wasm" }, - "pollZkey": { + "pollJoiningZkey": { "zkey": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test.0.zkey", "wasm": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test_js/PollJoining_10_test.wasm" + }, + "pollJoinedZkey": { + "zkey": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test.0.zkey", + "wasm": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test_js/PollJoined_10_test.wasm" } } }, @@ -492,9 +516,13 @@ "processWasm": "../cli/zkeys/ProcessMessagesNonQv_10-20-2_test/ProcessMessagesNonQv_10-20-2_test_js/ProcessMessagesNonQv_10-20-2_test.wasm", "tallyWasm": "../cli/zkeys/TallyVotesNonQv_10-1-2_test/TallyVotesNonQv_10-1-2_test_js/TallyVotesNonQv_10-1-2_test.wasm" }, - "pollZkey": { + "pollJoiningZkey": { "zkey": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test.0.zkey", "wasm": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test_js/PollJoining_10_test.wasm" + }, + "pollJoinedZkey": { + "zkey": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test.0.zkey", + "wasm": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test_js/PollJoined_10_test.wasm" } } }, @@ -569,9 +597,13 @@ "processWasm": "../cli/zkeys/ProcessMessagesNonQv_10-20-2_test/ProcessMessagesNonQv_10-20-2_test_js/ProcessMessagesNonQv_10-20-2_test.wasm", "tallyWasm": "../cli/zkeys/TallyVotesNonQv_10-1-2_test/TallyVotesNonQv_10-1-2_test_js/TallyVotesNonQv_10-1-2_test.wasm" }, - "pollZkey": { + "pollJoiningZkey": { "zkey": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test.0.zkey", "wasm": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test_js/PollJoining_10_test.wasm" + }, + "pollJoinedZkey": { + "zkey": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test.0.zkey", + "wasm": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test_js/PollJoined_10_test.wasm" } } }, @@ -646,9 +678,13 @@ "processWasm": "../cli/zkeys/ProcessMessagesNonQv_10-20-2_test/ProcessMessagesNonQv_10-20-2_test_js/ProcessMessagesNonQv_10-20-2_test.wasm", "tallyWasm": "../cli/zkeys/TallyVotesNonQv_10-1-2_test/TallyVotesNonQv_10-1-2_test_js/TallyVotesNonQv_10-1-2_test.wasm" }, - "pollZkey": { + "pollJoiningZkey": { "zkey": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test.0.zkey", "wasm": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test_js/PollJoining_10_test.wasm" + }, + "pollJoinedZkey": { + "zkey": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test.0.zkey", + "wasm": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test_js/PollJoined_10_test.wasm" } } }, @@ -723,9 +759,13 @@ "processWasm": "../cli/zkeys/ProcessMessagesNonQv_10-20-2_test/ProcessMessagesNonQv_10-20-2_test_js/ProcessMessagesNonQv_10-20-2_test.wasm", "tallyWasm": "../cli/zkeys/TallyVotesNonQv_10-1-2_test/TallyVotesNonQv_10-1-2_test_js/TallyVotesNonQv_10-1-2_test.wasm" }, - "pollZkey": { + "pollJoiningZkey": { "zkey": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test.0.zkey", "wasm": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test_js/PollJoining_10_test.wasm" + }, + "pollJoinedZkey": { + "zkey": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test.0.zkey", + "wasm": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test_js/PollJoined_10_test.wasm" } } }, @@ -800,9 +840,13 @@ "processWasm": "../cli/zkeys/ProcessMessagesNonQv_10-20-2_test/ProcessMessagesNonQv_10-20-2_test_js/ProcessMessagesNonQv_10-20-2_test.wasm", "tallyWasm": "../cli/zkeys/TallyVotesNonQv_10-1-2_test/TallyVotesNonQv_10-1-2_test_js/TallyVotesNonQv_10-1-2_test.wasm" }, - "pollZkey": { + "pollJoiningZkey": { "zkey": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test.0.zkey", "wasm": "../cli/zkeys/PollJoining_10_test/PollJoining_10_test_js/PollJoining_10_test.wasm" + }, + "pollJoinedZkey": { + "zkey": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test.0.zkey", + "wasm": "../cli/zkeys/PollJoined_10_test/PollJoined_10_test_js/PollJoined_10_test.wasm" } } }, diff --git a/packages/contracts/tasks/deploy/maci/08-vkRegistry.ts b/packages/contracts/tasks/deploy/maci/08-vkRegistry.ts index 4cb67f966c..b7194d45a0 100644 --- a/packages/contracts/tasks/deploy/maci/08-vkRegistry.ts +++ b/packages/contracts/tasks/deploy/maci/08-vkRegistry.ts @@ -33,9 +33,13 @@ deployment.deployTask(EDeploySteps.VkRegistry, "Deploy Vk Registry and set keys" const intStateTreeDepth = deployment.getDeployConfigField(EContracts.VkRegistry, "intStateTreeDepth"); const messageBatchSize = deployment.getDeployConfigField(EContracts.VkRegistry, "messageBatchSize"); const voteOptionTreeDepth = deployment.getDeployConfigField(EContracts.VkRegistry, "voteOptionTreeDepth"); - const pollJoiningTestZkeyPath = deployment.getDeployConfigField( + const pollJoiningZkeyPath = deployment.getDeployConfigField( EContracts.VkRegistry, - "zkeys.pollZkey.zkey", + "zkeys.pollJoiningZkey.zkey", + ); + const pollJoinedZkeyPath = deployment.getDeployConfigField( + EContracts.VkRegistry, + "zkeys.pollJoinedZkey.zkey", ); const processMessagesZkeyPathQv = deployment.getDeployConfigField( EContracts.VkRegistry, @@ -64,16 +68,17 @@ deployment.deployTask(EDeploySteps.VkRegistry, "Deploy Vk Registry and set keys" throw new Error("Non-QV zkeys are not set"); } - if (!pollJoiningTestZkeyPath) { + if (!pollJoiningZkeyPath) { throw new Error("Poll zkeys are not set"); } - const [qvProcessVk, qvTallyVk, nonQvProcessVk, nonQvTallyQv, pollVk] = await Promise.all([ + const [qvProcessVk, qvTallyVk, nonQvProcessVk, nonQvTallyQv, pollJoiningVk, pollJoinedVk] = await Promise.all([ processMessagesZkeyPathQv && extractVk(processMessagesZkeyPathQv), tallyVotesZkeyPathQv && extractVk(tallyVotesZkeyPathQv), processMessagesZkeyPathNonQv && extractVk(processMessagesZkeyPathNonQv), tallyVotesZkeyPathNonQv && extractVk(tallyVotesZkeyPathNonQv), - pollJoiningTestZkeyPath && extractVk(pollJoiningTestZkeyPath), + pollJoiningZkeyPath && extractVk(pollJoiningZkeyPath), + pollJoinedZkeyPath && extractVk(pollJoinedZkeyPath), ]).then((vks) => vks.map( (vk: IVkObjectParams | "" | undefined) => @@ -86,7 +91,6 @@ deployment.deployTask(EDeploySteps.VkRegistry, "Deploy Vk Registry and set keys" signer: deployer, }); - const pollZkeys = pollVk as IVerifyingKeyStruct; const processZkeys = [qvProcessVk, nonQvProcessVk].filter(Boolean) as IVerifyingKeyStruct[]; const tallyZkeys = [qvTallyVk, nonQvTallyQv].filter(Boolean) as IVerifyingKeyStruct[]; const modes: EMode[] = []; @@ -106,7 +110,8 @@ deployment.deployTask(EDeploySteps.VkRegistry, "Deploy Vk Registry and set keys" voteOptionTreeDepth, messageBatchSize, modes, - pollZkeys, + pollJoiningVk as IVerifyingKeyStruct, + pollJoinedVk as IVerifyingKeyStruct, processZkeys, tallyZkeys, ) diff --git a/packages/contracts/tests/Poll.test.ts b/packages/contracts/tests/Poll.test.ts index 150793afc8..d810a077af 100644 --- a/packages/contracts/tests/Poll.test.ts +++ b/packages/contracts/tests/Poll.test.ts @@ -25,7 +25,8 @@ import { duration, initialVoiceCreditBalance, messageBatchSize, - testPollVk, + testPollJoinedVk, + testPollJoiningVk, testProcessVk, testTallyVk, treeDepths, @@ -113,10 +114,18 @@ describe("Poll", () => { maciState.polls.get(pollId)?.publishMessage(message, padKey); // set the verification keys on the vk smart contract - await vkRegistryContract.setPollVkKey( + await vkRegistryContract.setPollJoiningVkKey( STATE_TREE_DEPTH, treeDepths.voteOptionTreeDepth, - testPollVk.asContractParam() as IVerifyingKeyStruct, + testPollJoiningVk.asContractParam() as IVerifyingKeyStruct, + { gasLimit: 10000000 }, + ); + + // set the verification keys on the vk smart contract + await vkRegistryContract.setPollJoinedVkKey( + STATE_TREE_DEPTH, + treeDepths.voteOptionTreeDepth, + testPollJoinedVk.asContractParam() as IVerifyingKeyStruct, { gasLimit: 10000000 }, ); diff --git a/packages/contracts/tests/Tally.test.ts b/packages/contracts/tests/Tally.test.ts index 3dbdf5b5df..4d07abc680 100644 --- a/packages/contracts/tests/Tally.test.ts +++ b/packages/contracts/tests/Tally.test.ts @@ -28,7 +28,8 @@ import { duration, initialVoiceCreditBalance, messageBatchSize, - testPollVk, + testPollJoinedVk, + testPollJoiningVk, testProcessVk, testTallyVk, treeDepths, @@ -286,10 +287,17 @@ describe("TallyVotes", () => { // update the poll state poll.updatePoll(BigInt(maciState.pubKeys.length)); - await vkRegistryContract.setPollVkKey( + await vkRegistryContract.setPollJoiningVkKey( STATE_TREE_DEPTH, treeDepths.voteOptionTreeDepth, - testPollVk.asContractParam() as IVerifyingKeyStruct, + testPollJoiningVk.asContractParam() as IVerifyingKeyStruct, + { gasLimit: 10000000 }, + ); + + await vkRegistryContract.setPollJoinedVkKey( + STATE_TREE_DEPTH, + treeDepths.voteOptionTreeDepth, + testPollJoinedVk.asContractParam() as IVerifyingKeyStruct, { gasLimit: 10000000 }, ); @@ -596,10 +604,18 @@ describe("TallyVotes", () => { poll.updatePoll(BigInt(maciState.pubKeys.length)); // set the verification keys on the vk smart contract - await vkRegistryContract.setPollVkKey( + await vkRegistryContract.setPollJoiningVkKey( + STATE_TREE_DEPTH, + treeDepths.voteOptionTreeDepth, + testPollJoiningVk.asContractParam() as IVerifyingKeyStruct, + { gasLimit: 10000000 }, + ); + + // set the verification keys on the vk smart contract + await vkRegistryContract.setPollJoinedVkKey( STATE_TREE_DEPTH, treeDepths.voteOptionTreeDepth, - testPollVk.asContractParam() as IVerifyingKeyStruct, + testPollJoinedVk.asContractParam() as IVerifyingKeyStruct, { gasLimit: 10000000 }, ); diff --git a/packages/contracts/tests/VkRegistry.test.ts b/packages/contracts/tests/VkRegistry.test.ts index 63e2098e32..bd08716420 100644 --- a/packages/contracts/tests/VkRegistry.test.ts +++ b/packages/contracts/tests/VkRegistry.test.ts @@ -6,7 +6,8 @@ import { EMode } from "../ts/constants"; import { messageBatchSize, - testPollVk, + testPollJoinedVk, + testPollJoiningVk, testProcessVk, testProcessVkNonQv, testTallyVk, @@ -32,12 +33,12 @@ describe("VkRegistry", () => { }); }); - describe("setPollVkKey", () => { + describe("setPollJoiningVkKey", () => { it("should set the poll vk", async () => { - const tx = await vkRegistryContract.setPollVkKey( + const tx = await vkRegistryContract.setPollJoiningVkKey( stateTreeDepth + 1, treeDepths.voteOptionTreeDepth, - testPollVk.asContractParam() as IVerifyingKeyStruct, + testPollJoiningVk.asContractParam() as IVerifyingKeyStruct, { gasLimit: 1000000 }, ); const receipt = await tx.wait(); @@ -46,13 +47,37 @@ describe("VkRegistry", () => { it("should throw when trying to set another vk for the same params", async () => { await expect( - vkRegistryContract.setPollVkKey( + vkRegistryContract.setPollJoiningVkKey( stateTreeDepth + 1, treeDepths.voteOptionTreeDepth, - testPollVk.asContractParam() as IVerifyingKeyStruct, + testPollJoiningVk.asContractParam() as IVerifyingKeyStruct, { gasLimit: 1000000 }, ), - ).to.be.revertedWithCustomError(vkRegistryContract, "PollVkAlreadySet"); + ).to.be.revertedWithCustomError(vkRegistryContract, "VkAlreadySet"); + }); + }); + + describe("setPollJoinedVkKey", () => { + it("should set the poll vk", async () => { + const tx = await vkRegistryContract.setPollJoinedVkKey( + stateTreeDepth + 1, + treeDepths.voteOptionTreeDepth, + testPollJoinedVk.asContractParam() as IVerifyingKeyStruct, + { gasLimit: 1000000 }, + ); + const receipt = await tx.wait(); + expect(receipt?.status).to.eq(1); + }); + + it("should throw when trying to set another vk for the same params", async () => { + await expect( + vkRegistryContract.setPollJoinedVkKey( + stateTreeDepth + 1, + treeDepths.voteOptionTreeDepth, + testPollJoinedVk.asContractParam() as IVerifyingKeyStruct, + { gasLimit: 1000000 }, + ), + ).to.be.revertedWithCustomError(vkRegistryContract, "VkAlreadySet"); }); }); @@ -82,7 +107,7 @@ describe("VkRegistry", () => { testProcessVk.asContractParam() as IVerifyingKeyStruct, testTallyVk.asContractParam() as IVerifyingKeyStruct, ), - ).to.be.revertedWithCustomError(vkRegistryContract, "ProcessVkAlreadySet"); + ).to.be.revertedWithCustomError(vkRegistryContract, "VkAlreadySet"); }); it("should allow to set vks for different params", async () => { @@ -122,7 +147,8 @@ describe("VkRegistry", () => { treeDepths.voteOptionTreeDepth, messageBatchSize, [EMode.NON_QV], - testPollVk.asContractParam() as IVerifyingKeyStruct, + testPollJoiningVk.asContractParam() as IVerifyingKeyStruct, + testPollJoinedVk.asContractParam() as IVerifyingKeyStruct, [testProcessVkNonQv.asContractParam() as IVerifyingKeyStruct], [testTallyVkNonQv.asContractParam() as IVerifyingKeyStruct], ); @@ -139,7 +165,8 @@ describe("VkRegistry", () => { treeDepths.voteOptionTreeDepth, messageBatchSize, [EMode.QV], - testPollVk.asContractParam() as IVerifyingKeyStruct, + testPollJoiningVk.asContractParam() as IVerifyingKeyStruct, + testPollJoinedVk.asContractParam() as IVerifyingKeyStruct, [ testProcessVk.asContractParam() as IVerifyingKeyStruct, testProcessVkNonQv.asContractParam() as IVerifyingKeyStruct, @@ -201,11 +228,19 @@ describe("VkRegistry", () => { }); describe("genSignatures", () => { - describe("genPollVkSig", () => { + describe("genPollJoiningVkSig", () => { + it("should generate a valid signature", async () => { + const sig = await vkRegistryContract.genPollJoiningVkSig(stateTreeDepth, treeDepths.voteOptionTreeDepth); + const vk = await vkRegistryContract.getPollJoiningVkBySig(sig); + compareVks(testPollJoiningVk, vk); + }); + }); + + describe("genPollJoinedVkSig", () => { it("should generate a valid signature", async () => { - const sig = await vkRegistryContract.genPollVkSig(stateTreeDepth, treeDepths.voteOptionTreeDepth); - const vk = await vkRegistryContract.getPollVkBySig(sig); - compareVks(testPollVk, vk); + const sig = await vkRegistryContract.genPollJoinedVkSig(stateTreeDepth, treeDepths.voteOptionTreeDepth); + const vk = await vkRegistryContract.getPollJoinedVkBySig(sig); + compareVks(testPollJoinedVk, vk); }); }); diff --git a/packages/contracts/tests/constants.ts b/packages/contracts/tests/constants.ts index 7b543b9b24..e0cdd5ee94 100644 --- a/packages/contracts/tests/constants.ts +++ b/packages/contracts/tests/constants.ts @@ -18,7 +18,15 @@ export const MESSAGE_TREE_DEPTH = 2; export const MESSAGE_TREE_SUBDEPTH = 1; export const messageBatchSize = 20; -export const testPollVk = new VerifyingKey( +export const testPollJoiningVk = new VerifyingKey( + new G1Point(BigInt(0), BigInt(1)), + new G2Point([BigInt(2), BigInt(3)], [BigInt(4), BigInt(5)]), + new G2Point([BigInt(6), BigInt(7)], [BigInt(8), BigInt(9)]), + new G2Point([BigInt(10), BigInt(11)], [BigInt(12), BigInt(13)]), + [new G1Point(BigInt(14), BigInt(15)), new G1Point(BigInt(16), BigInt(17))], +); + +export const testPollJoinedVk = new VerifyingKey( new G1Point(BigInt(0), BigInt(1)), new G2Point([BigInt(2), BigInt(3)], [BigInt(4), BigInt(5)]), new G2Point([BigInt(6), BigInt(7)], [BigInt(8), BigInt(9)]), diff --git a/packages/core/ts/index.ts b/packages/core/ts/index.ts index 199ae1cefd..664eff2157 100644 --- a/packages/core/ts/index.ts +++ b/packages/core/ts/index.ts @@ -2,7 +2,7 @@ export { MaciState } from "./MaciState"; export { Poll } from "./Poll"; -export { genPollVkSig, genProcessVkSig, genTallyVkSig } from "./utils/utils"; +export { genPollJoiningVkSig, genPollJoinedVkSig, genProcessVkSig, genTallyVkSig } from "./utils/utils"; export type { IJoiningCircuitArgs, diff --git a/packages/core/ts/utils/utils.ts b/packages/core/ts/utils/utils.ts index e0fcaacdb0..30dfdaa0e4 100644 --- a/packages/core/ts/utils/utils.ts +++ b/packages/core/ts/utils/utils.ts @@ -1,16 +1,27 @@ /* eslint-disable no-bitwise */ /** - * This function generates the signature of a ProcessMessage Verifying Key(VK). - * This can be used to check if a ProcessMessages' circuit VK is registered + * This function generates the signature of a Poll Joining Verifying Key (VK). + * This can be used to check if a PollJoining' circuit VK is registered * in a smart contract that holds several VKs. * @param stateTreeDepth - The depth of the state tree. * @param voteOptionTreeDepth - The depth of the vote option tree. * @returns Returns a signature for querying if a verifying key with the given parameters is already registered in the contract. */ -export const genPollVkSig = (stateTreeDepth: number, voteOptionTreeDepth: number): bigint => +export const genPollJoiningVkSig = (stateTreeDepth: number, voteOptionTreeDepth: number): bigint => (BigInt(stateTreeDepth) << 64n) + BigInt(voteOptionTreeDepth); +/** + * This function generates the signature of a Poll Joined Verifying Key (VK). + * This can be used to check if a PollJoined' circuit VK is registered + * in a smart contract that holds several VKs. + * @param stateTreeDepth - The depth of the state tree. + * @param voteOptionTreeDepth - The depth of the vote option tree. + * @returns Returns a signature for querying if a verifying key with the given parameters is already registered in the contract. + */ +export const genPollJoinedVkSig = (stateTreeDepth: number, voteOptionTreeDepth: number): bigint => + (BigInt(stateTreeDepth) << 128n) + (BigInt(voteOptionTreeDepth) << 64n); + /** * This function generates the signature of a ProcessMessage Verifying Key(VK). * This can be used to check if a ProcessMessages' circuit VK is registered