From d7d033b5aee8a897f64b0a995d6399d8e00b1822 Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Sun, 25 Feb 2024 09:29:08 +0200 Subject: [PATCH] fix: fix typos --- circuits/circom/processMessages.circom | 4 +-- circuits/circom/processMessagesNonQv.circom | 4 +-- .../stateLeafAndBallotTransformer.circom | 2 +- .../stateLeafAndBallotTransformerNonQv.circom | 2 +- .../circom/trees/incrementalQuinTree.circom | 2 +- circuits/ts/__tests__/CeremonyParams.test.ts | 2 +- circuits/ts/__tests__/Ecdh.test.ts | 2 +- circuits/ts/__tests__/TallyVotes.test.ts | 4 +-- cli/tests/utils.ts | 2 +- cli/ts/commands/airdrop.ts | 4 +-- cli/ts/commands/deployPoll.ts | 2 +- cli/ts/utils/defaults.ts | 2 +- contracts/contracts/trees/AccQueue.sol | 2 +- contracts/tasks/deploy/index.ts | 2 +- contracts/tasks/helpers/types.ts | 2 +- contracts/tests/AccQueue.test.ts | 2 +- contracts/ts/types.ts | 2 +- contracts/ts/utils.ts | 2 +- core/ts/__tests__/Poll.test.ts | 2 +- crypto/README.md | 2 +- crypto/ts/__tests__/IMT.test.ts | 2 +- crypto/ts/hashing.ts | 2 +- crypto/ts/quinTree.ts | 2 +- domainobjs/ts/__tests__/stateLeaf.test.ts | 2 +- website/blog/2021-10-12-maci-v1.md | 4 +-- website/blog/2023-01-18-maci-v1.1.1.md | 6 ++-- website/src/scripts/setupTypedoc.ts | 2 +- .../version-v0.x/introduction.md | 4 +-- .../versioned_docs/version-v1.x/contracts.md | 2 +- .../versioned_docs/version-v1.x/key-change.md | 4 +-- website/versioned_docs/version-v1.x/spec.md | 28 +++++++++---------- .../version-v1.x/testing-in-detail.md | 4 +-- 32 files changed, 55 insertions(+), 55 deletions(-) diff --git a/circuits/circom/processMessages.circom b/circuits/circom/processMessages.circom index 8858a42f4a..6b1c9c3e22 100644 --- a/circuits/circom/processMessages.circom +++ b/circuits/circom/processMessages.circom @@ -84,7 +84,7 @@ template ProcessMessages( // The index of the last message leaf in the batch to process, exclusive. // This value may be less than batchStartIndex + batchSize if this batch is - // the last batch and the total number of mesages is not a multiple of the + // the last batch and the total number of messages is not a multiple of the // batch size. signal batchEndIndex; @@ -544,7 +544,7 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) { // ----------------------------------------------------------------------- // 2. If msgType = 0 and isValid is 0, generate indices for leaf 0 - // Otherwise, generate indices for commmand.stateIndex or topupStateIndex depending on msgType + // Otherwise, generate indices for command.stateIndex or topupStateIndex depending on msgType signal indexByType; signal tmpIndex1; signal tmpIndex2; diff --git a/circuits/circom/processMessagesNonQv.circom b/circuits/circom/processMessagesNonQv.circom index 190a0c1fdf..7f484e1892 100644 --- a/circuits/circom/processMessagesNonQv.circom +++ b/circuits/circom/processMessagesNonQv.circom @@ -85,7 +85,7 @@ template ProcessMessagesNonQv( // The index of the last message leaf in the batch to process, exclusive. // This value may be less than batchStartIndex + batchSize if this batch is - // the last batch and the total number of mesages is not a multiple of the + // the last batch and the total number of messages is not a multiple of the // batch size. signal batchEndIndex; @@ -457,7 +457,7 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) { // ----------------------------------------------------------------------- // 2. If msgType = 0 and isValid is 0, generate indices for leaf 0 - // Otherwise, generate indices for commmand.stateIndex or topupStateIndex depending on msgType + // Otherwise, generate indices for command.stateIndex or topupStateIndex depending on msgType signal indexByType; signal tmpIndex1; signal tmpIndex2; diff --git a/circuits/circom/stateLeafAndBallotTransformer.circom b/circuits/circom/stateLeafAndBallotTransformer.circom index 79dde80d33..afaf536346 100644 --- a/circuits/circom/stateLeafAndBallotTransformer.circom +++ b/circuits/circom/stateLeafAndBallotTransformer.circom @@ -21,7 +21,7 @@ template StateLeafAndBallotTransformer() { signal input slPubKey[2]; // the current voice credit balance of the signed up user signal input slVoiceCreditBalance; - // the signup timestmap + // the signup timestamp signal input slTimestamp; // when the poll ends signal input pollEndTimestamp; diff --git a/circuits/circom/stateLeafAndBallotTransformerNonQv.circom b/circuits/circom/stateLeafAndBallotTransformerNonQv.circom index 0055c84a14..8fb900a007 100644 --- a/circuits/circom/stateLeafAndBallotTransformerNonQv.circom +++ b/circuits/circom/stateLeafAndBallotTransformerNonQv.circom @@ -21,7 +21,7 @@ template StateLeafAndBallotTransformerNonQv() { signal input slPubKey[2]; // the current voice credit balance of the signed up user signal input slVoiceCreditBalance; - // the signup timestmap + // the signup timestamp signal input slTimestamp; // when the poll ends signal input pollEndTimestamp; diff --git a/circuits/circom/trees/incrementalQuinTree.circom b/circuits/circom/trees/incrementalQuinTree.circom index 434cf9f7ad..9b3251626a 100644 --- a/circuits/circom/trees/incrementalQuinTree.circom +++ b/circuits/circom/trees/incrementalQuinTree.circom @@ -10,7 +10,7 @@ include "./checkRoot.circom"; include "../hasherPoseidon.circom"; include "../utils.circom"; -// This file contains circuits for quintary Merkle tree verifcation. +// This file contains circuits for quintary Merkle tree verification. // It assumes that each node contains 5 leaves, as we use the PoseidonT6 // circuit to hash leaves, which supports up to 5 input elements. diff --git a/circuits/ts/__tests__/CeremonyParams.test.ts b/circuits/ts/__tests__/CeremonyParams.test.ts index 12ae5f4c8a..373071a87c 100644 --- a/circuits/ts/__tests__/CeremonyParams.test.ts +++ b/circuits/ts/__tests__/CeremonyParams.test.ts @@ -334,7 +334,7 @@ describe("Ceremony param tests", () => { await testCircuit.expectConstraintPass(witness); }); - it("should produce the correct result if the inital tally is not zero", async () => { + it("should produce the correct result if the initial tally is not zero", async () => { const generatedInputs = poll.tallyVotes() as unknown as ITallyVotesInputs; // Start the tally from non-zero value diff --git a/circuits/ts/__tests__/Ecdh.test.ts b/circuits/ts/__tests__/Ecdh.test.ts index 3baa883900..a8b0dda20e 100644 --- a/circuits/ts/__tests__/Ecdh.test.ts +++ b/circuits/ts/__tests__/Ecdh.test.ts @@ -40,7 +40,7 @@ describe("Public key derivation circuit", () => { pubKey: keypair2.pubKey.asCircuitInputs() as unknown as bigint[], }; - // calculate first time witness and check contraints + // calculate first time witness and check constraints const witness = await circuit.calculateWitness(circuitInputs); await circuit.expectConstraintPass(witness); diff --git a/circuits/ts/__tests__/TallyVotes.test.ts b/circuits/ts/__tests__/TallyVotes.test.ts index d141691ef3..ca9afe3305 100644 --- a/circuits/ts/__tests__/TallyVotes.test.ts +++ b/circuits/ts/__tests__/TallyVotes.test.ts @@ -133,7 +133,7 @@ describe("TallyVotes circuit", function test() { await circuit.expectConstraintPass(witness); }); - it("should produce the correct result if the inital tally is not zero", async () => { + it("should produce the correct result if the initial tally is not zero", async () => { const generatedInputs = poll.tallyVotes() as unknown as ITallyVotesInputs; // Start the tally from non-zero value @@ -220,7 +220,7 @@ describe("TallyVotes circuit", function test() { await circuitNonQv.expectConstraintPass(witness); }); - it("should produce the correct result if the inital tally is not zero", async () => { + it("should produce the correct result if the initial tally is not zero", async () => { const generatedInputs = poll.tallyVotesNonQv() as unknown as ITallyVotesInputs; // Start the tally from non-zero value diff --git a/cli/tests/utils.ts b/cli/tests/utils.ts index 7a9caf9b20..707420f9a0 100644 --- a/cli/tests/utils.ts +++ b/cli/tests/utils.ts @@ -20,7 +20,7 @@ export const cleanVanilla = (): void => { /** * Test utility to clean up the proofs directory - * adn the subsidy.json file + * and the subsidy.json file */ export const cleanSubsidy = (): void => { cleanVanilla(); diff --git a/cli/ts/commands/airdrop.ts b/cli/ts/commands/airdrop.ts index a83062579f..67ce7d3e5c 100644 --- a/cli/ts/commands/airdrop.ts +++ b/cli/ts/commands/airdrop.ts @@ -4,7 +4,7 @@ import { type AirdropArgs, logError, logGreen, success, readContractAddress, con /** * Utility that can be used to get - * topup credits aidropped + * topup credits airdropped * to the coordinator * @param AirdropArgs - The arguments for the airdrop command */ @@ -23,7 +23,7 @@ export const airdrop = async ({ const topupCredit = readContractAddress("TopupCredit", network?.name); // we want to ensure that we have either the address stored - // or that it was passed as a paramter + // or that it was passed as a parameter if (!topupCredit && !contractAddress) { logError("Please provide an ERC20 contract address"); } diff --git a/cli/ts/commands/deployPoll.ts b/cli/ts/commands/deployPoll.ts index bb3158b029..bfbae295af 100644 --- a/cli/ts/commands/deployPoll.ts +++ b/cli/ts/commands/deployPoll.ts @@ -159,7 +159,7 @@ export const deployPoll = async ({ logGreen(quiet, info(`Subsidy contract: ${subsidyContractAddress}`)); storeContractAddress(`Subsidy-${pollId.toString()}`, subsidyContractAddress, network?.name); } - // store the addresss + // store the address storeContractAddress(`MessageProcessor-${pollId.toString()}`, messageProcessorContractAddress, network?.name); storeContractAddress(`Tally-${pollId.toString()}`, tallyContractAddress, network?.name); storeContractAddress(`Poll-${pollId.toString()}`, pollAddr, network?.name); diff --git a/cli/ts/utils/defaults.ts b/cli/ts/utils/defaults.ts index c2ee94404a..e61037ac52 100644 --- a/cli/ts/utils/defaults.ts +++ b/cli/ts/utils/defaults.ts @@ -6,7 +6,7 @@ export const DEFAULT_ETH_SK = "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5 export const DEFAULT_INITIAL_VOICE_CREDITS = 99; // the default signup gatekeeper data export const DEFAULT_SG_DATA = "0x0000000000000000000000000000000000000000000000000000000000000000"; -// the defualt initial voice credit proxy data +// the default initial voice credit proxy data export const DEFAULT_IVCP_DATA = "0x0000000000000000000000000000000000000000000000000000000000000000"; // the default number of operations to queue in the state root queue export const DEFAULT_SR_QUEUE_OPS = 4; diff --git a/contracts/contracts/trees/AccQueue.sol b/contracts/contracts/trees/AccQueue.sol index 462a176ec1..7e1f6fe2a9 100644 --- a/contracts/contracts/trees/AccQueue.sol +++ b/contracts/contracts/trees/AccQueue.sol @@ -285,7 +285,7 @@ abstract contract AccQueue is Ownable, Hasher { // There must be subtrees to merge if (numLeaves == 0) revert NothingToMerge(); - // Fill any empty leaves in the current subtree with zeros ony if the + // Fill any empty leaves in the current subtree with zeros only if the // current subtree is not full if (numLeaves % subTreeCapacity != 0) { fill(); diff --git a/contracts/tasks/deploy/index.ts b/contracts/tasks/deploy/index.ts index 71be91f7c5..63d76bd6d8 100644 --- a/contracts/tasks/deploy/index.ts +++ b/contracts/tasks/deploy/index.ts @@ -2,7 +2,7 @@ import fs from "fs"; import path from "path"; /** - * The same as individual imports but doesn't require to add new import line everytime + * The same as individual imports but doesn't require to add new import line every time */ ["maci", "poll"].forEach((folder) => { const tasksPath = path.resolve(__dirname, folder); diff --git a/contracts/tasks/helpers/types.ts b/contracts/tasks/helpers/types.ts index 9931cd0efd..66c1f117ce 100644 --- a/contracts/tasks/helpers/types.ts +++ b/contracts/tasks/helpers/types.ts @@ -532,7 +532,7 @@ export interface IVerifyFullArgs { } /** - * Interface that represents verification subtaks arguments + * Interface that represents verification subtask arguments * This is extracted from hardhat etherscan plugin */ export interface IVerificationSubtaskArgs { diff --git a/contracts/tests/AccQueue.test.ts b/contracts/tests/AccQueue.test.ts index 2fca1592c1..69d2ae673a 100644 --- a/contracts/tests/AccQueue.test.ts +++ b/contracts/tests/AccQueue.test.ts @@ -243,7 +243,7 @@ describe("AccQueues", () => { ); }); - it("Merging without enqueing new data should not change the root", async () => { + it("Merging without enqueuing new data should not change the root", async () => { const MAIN_DEPTH = 5; const r = await deployTestAccQueues("AccQueueBinary0", SUB_DEPTH, HASH_LENGTH, ZERO); diff --git a/contracts/ts/types.ts b/contracts/ts/types.ts index 4bf861b24c..b0fe921df3 100644 --- a/contracts/ts/types.ts +++ b/contracts/ts/types.ts @@ -86,7 +86,7 @@ export interface IDeployedTestContracts { } /** - * An interface that representes an action that should + * An interface that represents an action that should * be applied to a MaciState and its Polls within the * genMaciState function. */ diff --git a/contracts/ts/utils.ts b/contracts/ts/utils.ts index 75e5b49cf6..359c9b2a90 100644 --- a/contracts/ts/utils.ts +++ b/contracts/ts/utils.ts @@ -33,7 +33,7 @@ export const sleep = async (ms: number): Promise => { }; /** - * The comparision function for Actions based on block number and transaction + * The comparison function for Actions based on block number and transaction * index. * @param actions - the array of actions to sort * @returns the sorted array of actions diff --git a/core/ts/__tests__/Poll.test.ts b/core/ts/__tests__/Poll.test.ts index 02908f50c2..629b4783b5 100644 --- a/core/ts/__tests__/Poll.test.ts +++ b/core/ts/__tests__/Poll.test.ts @@ -278,7 +278,7 @@ describe("Poll", function test() { poll.currentMessageBatchIndex = undefined; }); - it("shuold throw if the state has not been copied prior to calling processMessages", () => { + it("should throw if the state has not been copied prior to calling processMessages", () => { const tmpPoll = maciState.deployPoll( BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, diff --git a/crypto/README.md b/crypto/README.md index 91fd971a84..90af7b8ee2 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -8,7 +8,7 @@ employs. ## AccQueue -AccQueue is an implementation of an Accumulator Queue. This is used to manage a queue of elements in merkle-tree like structure. This TypeScript class conforms with the smart contract impemented in _maci-contracts_ - AccQueue.sol. +AccQueue is an implementation of an Accumulator Queue. This is used to manage a queue of elements in merkle-tree like structure. This TypeScript class conforms with the smart contract implemented in _maci-contracts_ - AccQueue.sol. The main tree is divided into subtrees to allow for easier management. Each of the subtrees has its own root and leaves, with the depth being defined by the _subDepth_ property of the AccQueue class. When a new leaf is "enqued", this is actually added to the current subtree. If this is full, we calculate the root of the subtree and store it, while the new leaf is added to the next subtree. diff --git a/crypto/ts/__tests__/IMT.test.ts b/crypto/ts/__tests__/IMT.test.ts index 89428f6ff8..00b1f3ed1b 100644 --- a/crypto/ts/__tests__/IMT.test.ts +++ b/crypto/ts/__tests__/IMT.test.ts @@ -53,7 +53,7 @@ describe("IMT comparison", () => { }); describe("genSubrootProof", () => { - it("should geneate a valid proof for a subtree", () => { + it("should generate a valid proof for a subtree", () => { const mt1 = new IncrementalQuinTree(5, 0n, 5, hash5); for (let i = 0; i < 100; i += 1) { diff --git a/crypto/ts/hashing.ts b/crypto/ts/hashing.ts index e695cf61e2..140a0453dd 100644 --- a/crypto/ts/hashing.ts +++ b/crypto/ts/hashing.ts @@ -59,7 +59,7 @@ export const poseidonT4 = (inputs: bigint[]): bigint => { /** * Hash up to 4 elements * @param inputs The elements to hash - * @retuns the hash of the elements + * @returns the hash of the elements */ export const poseidonT5 = (inputs: bigint[]): bigint => { assert(inputs.length === 4); diff --git a/crypto/ts/quinTree.ts b/crypto/ts/quinTree.ts index 9004138e9d..e429453071 100644 --- a/crypto/ts/quinTree.ts +++ b/crypto/ts/quinTree.ts @@ -216,7 +216,7 @@ export class IncrementalQuinTree { /** * Verify a proof * @param proof The proof to verify - * @returns Wether the proof is valid + * @returns Whether the proof is valid */ verifyProof = (proof: IMerkleProof): boolean => { const { pathElements, leaf, root, pathIndices } = proof; diff --git a/domainobjs/ts/__tests__/stateLeaf.test.ts b/domainobjs/ts/__tests__/stateLeaf.test.ts index 826b6e8250..6c8e2add74 100644 --- a/domainobjs/ts/__tests__/stateLeaf.test.ts +++ b/domainobjs/ts/__tests__/stateLeaf.test.ts @@ -86,7 +86,7 @@ describe("stateLeaf", () => { }); describe("toJSON", () => { - it("should produce an object with the correct properities", () => { + it("should produce an object with the correct properties", () => { const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); const json = stateLeaf.toJSON(); diff --git a/website/blog/2021-10-12-maci-v1.md b/website/blog/2021-10-12-maci-v1.md index 92e6a41083..4c896e91f6 100644 --- a/website/blog/2021-10-12-maci-v1.md +++ b/website/blog/2021-10-12-maci-v1.md @@ -47,7 +47,7 @@ Finally, in early 2021 we were very fortunate to bring on Cory Dickson to the te It is very difficult for naive voting systems, particularly those which are integrated into smart contract platforms, to prevent collusion. For instance, if a simple Ethereum transaction represents a vote, a briber can easily examine its calldata, tell how its sender voted, and reward or punish them accordingly. -More broadly, collusion resistance is particulary important for cryptoeconomic systems. Vitalik Buterin describes the motivations behind MACI in On Collusion. He argues that systems that use cryptoeconomic incentive mechanisms to align participants’ behaviour can be vulnerable to collusion attacks, such as bribery. In another post, he elaborates: +More broadly, collusion resistance is particularly important for cryptoeconomic systems. Vitalik Buterin describes the motivations behind MACI in On Collusion. He argues that systems that use cryptoeconomic incentive mechanisms to align participants’ behaviour can be vulnerable to collusion attacks, such as bribery. In another post, he elaborates: if you can prove how you voted, selling your vote becomes very easy. Provability of votes would also enable forms of coercion where the coercer demands to see some kind of proof of voting for their preferred candidate. @@ -61,7 +61,7 @@ Finally, MACI is important because as crypto communities are increasingly adopti ## What’s new? -In this release, we rearchitected MACI’s smart contracts to allow for greater flexiblity and separation of concerns. In particular, we support multiple polls within a single instance of MACI. This allows the coordinator to run and tally many elections either subsequently or concurrently. +In this release, we rearchitected MACI’s smart contracts to allow for greater flexibility and separation of concerns. In particular, we support multiple polls within a single instance of MACI. This allows the coordinator to run and tally many elections either subsequently or concurrently. We’ve kept the ability for developers to provide their own set of logic to gate-keep signups. For instance, application developers can write custom logic that only allows addresses which own a certain token to sign up once to MACI in order to participate in polls. diff --git a/website/blog/2023-01-18-maci-v1.1.1.md b/website/blog/2023-01-18-maci-v1.1.1.md index f4c4035e21..06a444adf8 100644 --- a/website/blog/2023-01-18-maci-v1.1.1.md +++ b/website/blog/2023-01-18-maci-v1.1.1.md @@ -58,7 +58,7 @@ All of these issues have been successfully resolved, on top of fixing minor issu ### Top Up Credit -Rather than requring a user to sign up multiple times, it is now possible to top up voice credits by sending a top up message on the Poll contract. Withdrawals are not enabled as this would allow a malicious user to bribe others offline to transfer their keys. +Rather than requiring a user to sign up multiple times, it is now possible to top up voice credits by sending a top up message on the Poll contract. Withdrawals are not enabled as this would allow a malicious user to bribe others offline to transfer their keys. Now, the Poll contract will hold all the funds deposited from users for the current poll. At the end of a poll, the coordinator can transfer the funds to a hardcoded address which can be used to fund public goods. @@ -74,7 +74,7 @@ Pairwise subsidy is a new way to reduce collusion in quadratic funding applicati In this [post](https://ethresear.ch/t/pairwise-coordination-subsidies-a-new-quadratic-funding-design/5553), Vitalik introduced this kind of collusion and also proposed a protocol to penalize this behavior. As a generalized solution, the more correlation between contributions, the smaller subsidy should be allocated to this project, as this reduces the risk of collusion between contributors. It should be noted that this solution assumes that an identity system is in place to prevent the same entity from registering with two different identities. -Please refer to this [post](https://hackmd.io/@chaosma/H1_9xmT2K) for a more detailed explaination of the implementation. +Please refer to this [post](https://hackmd.io/@chaosma/H1_9xmT2K) for a more detailed explanation of the implementation. Finally, please note that currently it is not possible to generate the `zkeys` for the subsidy circuit with with the `vote options` parameter larger than $5^2$. This issue is documented [here](https://github.com/privacy-scaling-explorations/maci/issues/584) and the team will focus on finding a solution to be able to support larger vote options. @@ -82,7 +82,7 @@ Finally, please note that currently it is not possible to generate the `zkeys` f MACI now includes a sample [coordinator service](https://github.com/privacy-scaling-explorations/maci/tree/v1.1.1/server). -There are two roles in the cordinator service: admin (i.e. MACI coordinator) and user (i.e. a voter). The admin's responsibility is to ensure that the code remains updated and that the backend services are live. The user can then simply send HTTP requests to the backend server to interact with MACI, for instance, by signing up and publishing a message on chain. +There are two roles in the coordinator service: admin (i.e. MACI coordinator) and user (i.e. a voter). The admin's responsibility is to ensure that the code remains updated and that the backend services are live. The user can then simply send HTTP requests to the backend server to interact with MACI, for instance, by signing up and publishing a message on chain. The coordinator service has been wrapped into two docker instances: one for the backend server to accept user requests; one for the Mongodb service to store all necessary information on the current state such as smart contract addresses, zero knowledge proof keys and so on. diff --git a/website/src/scripts/setupTypedoc.ts b/website/src/scripts/setupTypedoc.ts index 059d01937e..6f08d8c35d 100644 --- a/website/src/scripts/setupTypedoc.ts +++ b/website/src/scripts/setupTypedoc.ts @@ -6,7 +6,7 @@ import { copyDirectory, fitFormat, generateSidebarString, insertIndexPage } from const TYPEDOC_DIR = path.resolve(__dirname, "../../typedoc"); /** - * A function that remove the auto-genrated navigator + * A function that remove the auto-generated navigator * and the title at the top of the page, * meanwhile adding sidebar configurations above the content. * @param file - the file being updated diff --git a/website/versioned_docs/version-v0.x/introduction.md b/website/versioned_docs/version-v0.x/introduction.md index b7420863c2..2bc8536038 100644 --- a/website/versioned_docs/version-v0.x/introduction.md +++ b/website/versioned_docs/version-v0.x/introduction.md @@ -31,7 +31,7 @@ Even if Alice reveals the cleartext of her vote to Bob, she just needs to not sh ## Technical process -Refer to the [Glossary](#Glossary) for defintions of terms. +Refer to the [Glossary](#Glossary) for definitions of terms. 1. The coordinator deploys the MACI contract to an Ethereum blockchain and starts the sign-up period. The same transaction that deploys the contract also stores the value of an empty vote option tree. 2. To sign up, each user creates an EdDSA keypair and invokes the contract's `signUp()` function. Alternatively, there is a mechanism where some contract function checks if the user owns a particular ERC721 token and adds them to the whitelist. It in turn generates a new leaf to the state tree and updates the state tree root. @@ -48,7 +48,7 @@ Refer to the [Glossary](#Glossary) for defintions of terms. - Otherwise, the user should use the most current public key they have registered. - - Submit the the message, as well as the epheremal public key in the clear to the contract using its `publishMessage()` function, which hashes the command and inserts it into the message tree. + - Submit the the message, as well as the ephemeral public key in the clear to the contract using its `publishMessage()` function, which hashes the command and inserts it into the message tree. 5. The coordinator processes all the commands after the voting period ends. diff --git a/website/versioned_docs/version-v1.x/contracts.md b/website/versioned_docs/version-v1.x/contracts.md index 365475abd0..c4b35a27b4 100644 --- a/website/versioned_docs/version-v1.x/contracts.md +++ b/website/versioned_docs/version-v1.x/contracts.md @@ -338,7 +338,7 @@ struct MaxValues { } ``` -These are stored separately to avoid a stack overlow error during compilation of the contracts using them. +These are stored separately to avoid a stack overflow error during compilation of the contracts using them. ## AccQueue diff --git a/website/versioned_docs/version-v1.x/key-change.md b/website/versioned_docs/version-v1.x/key-change.md index b5aec91393..4a81356454 100644 --- a/website/versioned_docs/version-v1.x/key-change.md +++ b/website/versioned_docs/version-v1.x/key-change.md @@ -9,11 +9,11 @@ sidebar_position: 16 MACI's voters are identified by their MACI public key. Together with their private key, they can sign and submit messages to live Polls. -As MACI's main property is to provide collusion resistence in digital voting applications, it is important to have a mechanism for a user to change their voting key, should this become compromised, or they wish to revoke past actions. +As MACI's main property is to provide collusion resistance in digital voting applications, it is important to have a mechanism for a user to change their voting key, should this become compromised, or they wish to revoke past actions. ## How MACI messages are processed -In order to understand how key changing currenctly works in MACI, we need to understand how messages are processed. +In order to understand how key changing currently works in MACI, we need to understand how messages are processed. After a poll ends, the coordinator processes messages off chain in reverse order. To improve efficiency, messages are processed in batches, and correctness is proved for each batch using a zk-SNARK circuit. diff --git a/website/versioned_docs/version-v1.x/spec.md b/website/versioned_docs/version-v1.x/spec.md index d2b77a327e..47bd59d0fd 100644 --- a/website/versioned_docs/version-v1.x/spec.md +++ b/website/versioned_docs/version-v1.x/spec.md @@ -108,7 +108,7 @@ The algorithm to do so is as such: #### 1.4. Public key generation -A public key is a point on the Baby Jubjub curve. It is determistically derived from a private key $s$, the procedure to do so is almost identical to [RFC8032](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.5). +A public key is a point on the Baby Jubjub curve. It is deterministically derived from a private key $s$, the procedure to do so is almost identical to [RFC8032](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.5). 1. Format the private key [1.3] 2. Multiply $G$ by 8 and multiply the resulting point by the formatted private key to derive the public key $A$: @@ -246,7 +246,7 @@ Effectively, four out of five times it is invoked, an enqueue operation _may or ##### 1.10.2. Merging subroots -Before computing the main Merkle root, it is necessary to compute the `smallSRTroot` (the smallest subroot tree root). This is the Merkle root of a tree which is small enough to fit all the subroots, it uses a similar mechanisim to enqueuing leaves [1.10.2]. +Before computing the main Merkle root, it is necessary to compute the `smallSRTroot` (the smallest subroot tree root). This is the Merkle root of a tree which is small enough to fit all the subroots, it uses a similar mechanism to enqueuing leaves [1.10.2]. The `AccQueue.sol` contract provides the `mergeSubRoots(uint256 _numSrQueueOps)` function which allows the coordinator to specify the number of queue operations to execute. The entire tree may be merged in a single transaction, or it may not. Multiple calls to `mergeSubRoots` may be required due to the block gas limit. @@ -274,7 +274,7 @@ A verifying key is used to validate a zk-SNARK proof. Each unique permutation of ### 2.2. Private key -A private key $k$ represents a particpant's ability to broadcast or decrypt messages under an unique identity and generation of a shared key [1.9], it translates to a scalar point on the Baby Jubjub ellpitical curve. To avoid confusion with Ethereum's ECDSA encryption, MACI requires serialisation bound with the prefix `macisk.` +A private key $k$ represents a participant's ability to broadcast or decrypt messages under an unique identity and generation of a shared key [1.9], it translates to a scalar point on the Baby Jubjub elliptical curve. To avoid confusion with Ethereum's ECDSA encryption, MACI requires serialisation bound with the prefix `macisk.` #### 2.2.1. Serialisation @@ -298,7 +298,7 @@ A public key $p$ represents a users identity derived from $k$ and therefore is a #### 2.3.1. Serialisation -To get a serialised public key from public key coordinates, the variable $u$ is defined as public key's y-cordinate, a 32 bit buffer $v$ is created and iterated over each uninitialised byte to: +To get a serialised public key from public key coordinates, the variable $u$ is defined as public key's y-coordinate, a 32 bit buffer $v$ is created and iterated over each uninitialised byte to: 1. assign the result of a bitwise [`AND (&)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND) operation between values $u$ and $255$ to byte $n$ 2. shift $u$ right by 8 bits ([`>>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Right_shift)) @@ -312,7 +312,7 @@ To reverse the effects of serialisation and return the unpacked public key, we m 1. shift $u$ left by the result of $8$ multiplied by $n$ bits ([`<<`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Left_shift)) 2. assign $y$ the result of addition between $y$ and $u$ -The result $y$ is the public key's y-cordinate, to then compute the x-cordinate we must look at the equation for the twisted Edwards elliptic curve (as defined in [`EIP-2494`](https://eips.ethereum.org/EIPS/eip-2494)): +The result $y$ is the public key's y-coordinate, to then compute the x-coordinate we must look at the equation for the twisted Edwards elliptic curve (as defined in [`EIP-2494`](https://eips.ethereum.org/EIPS/eip-2494)): $ax^2 + y^2 = 1 + dx^2y^2$ @@ -334,7 +334,7 @@ A command represents an action that a user may take. Such as casting a vote in a | $cm_{p_{x}}$ | Public key x-coordinate | 253 | If no change is necessary this parameter should reflect the current public key's x-coordinate | | $cm_{p_{y}}$ | Public key y-coordinate | 253 | If no change is necessary this parameter should reflect the current public key's y-coordinate | | $cm_{i_{v}}$ | Vote option index | 50 | Option state leaf index of preference to assign the vote for | -| $cm_w$ | Voting weight | 50 | Voice credit balance allocation, this is an arbitary value dependent on a user's available credits | +| $cm_w$ | Voting weight | 50 | Voice credit balance allocation, this is an arbitrary value dependent on a user's available credits| | $cm_n$ | Nonce | 50 | State leaf's index of actions committed plus one | | $cm_{id}$ | Poll id | 50 | The poll's identifier to cast in regard to | | $cm_s$ | Salt | 253 | An entropy value to inhibit brute force attacks | @@ -369,7 +369,7 @@ To decrypt a message using $k_s$ is expressed as $[p, R8[0], R8[1], cm_s]$ = $\mathsf{poseidonDecrypt}(M, k_s[0], k_s[1], cm_n, 7)$ -To unpack $p$ to it's original five parameters, it must be seperated into 50 bit values from the parent 250 bit value. To extract 50 bits at byte $n$, we: +To unpack $p$ to it's original five parameters, it must be separated into 50 bit values from the parent 250 bit value. To extract 50 bits at byte $n$, we: 1. initialise 50 bits 2. shift left by $n$ bits @@ -454,7 +454,7 @@ MACI provides collusion-resistance assuming that: That said, even if the coordinator is dishonest, they can neither tamper nor censor with its execution. -In MACI, the contents of a vote can only be decrypted by the coordinator. Moreover, the validity of a vote cannot be proven, as participants can revoke past actions through key-changes. Therefore, inhibiting the adversary in validating the fufilliment of such agreements. +In MACI, the contents of a vote can only be decrypted by the coordinator. Moreover, the validity of a vote cannot be proven, as participants can revoke past actions through key-changes. Therefore, inhibiting the adversary in validating the fulfillment of such agreements. To clarify how this works, consider the following situation between Alice and Eve involving a vote option A: @@ -463,7 +463,7 @@ To clarify how this works, consider the following situation between Alice and Ev 3. Alice casts a message for option A, in which she simultaneously: - Votes in opposition of A - Changes her keypair through submitting a new public key -4. Eve is uncertain whether Alice has voted for her preference due to the secrecy of the message, regardless she assumes confirmation upon recieving the transaction hash +4. Eve is uncertain whether Alice has voted for her preference due to the secrecy of the message, regardless she assumes confirmation upon receiving the transaction hash 5. Alice broadcasts a message from the new keypair registered in step 3 and casts a vote in support of poll A in turn, voiding her initial vote in opposition Eve is doubtful whether her request was actually satisfied and is unaware to Alice casting a new vote to void the first, she decides not compensate Alice because of the uncertainty surrounding her compliance. @@ -499,7 +499,7 @@ Each leaf within the ballot trees stores a participants vote within a poll, it s #### The message tree (per poll) -Each leaf within the message tree correlates to a command cast from participants within a poll, it too like the state tree has a default nothing-up-my-sleeve value at leaf zero. Except it is a Keccak256 hash of the string `"Maci"` moduluo the SNARK field size $p$ [1.1]. +Each leaf within the message tree correlates to a command cast from participants within a poll, it too like the state tree has a default nothing-up-my-sleeve value at leaf zero. Except it is a Keccak256 hash of the string `"Maci"` modulo the SNARK field size $p$ [1.1]. ### 3.7. System flow @@ -509,7 +509,7 @@ Registration is initiated through fulfilling the requirements specified in the g #### When a user publishes a message -Publishing messages requires users to encrypt a command using a shared key generated using ECDH [1.10] and submiting the ciphertext through the `publishMessage()` function. The message is then queued for processing by the co-ordinator once published. +Publishing messages requires users to encrypt a command using a shared key generated using ECDH [1.10] and submitting the ciphertext through the `publishMessage()` function. The message is then queued for processing by the co-ordinator once published. #### When the coordinator merges the state queue @@ -517,7 +517,7 @@ To subsidise gas costs for users, registration does not require the state root t Which first requires the merging of subroots [1.10.1], this creates the shortest possible tree that contains all the state leaves. Which may or may not require multiple transactions (in the form of batches) due to the restriction of the block gas limit. Once all the subroots have been computed they are merged [1.10.2] to compute the state root at its full depth. -After merging, the state-ballot commitment hash `currentSbCommitment` is initialised, which is a $\mathsf{poseidon_{3}}$ represenation of the state's Merkle root, the ballot's Merkle root and a salt. At initialisation the Merkle roots are equal to the trees at full depth. +After merging, the state-ballot commitment hash `currentSbCommitment` is initialised, which is a $\mathsf{poseidon_{3}}$ representation of the state's Merkle root, the ballot's Merkle root and a salt. At initialisation the Merkle roots are equal to the trees at full depth. #### When the coordinator merges the message queue @@ -525,7 +525,7 @@ The process of merging queues are the same in both the message and state trees. #### When the coordinator processes the messages -As large zk-SNARK circuits take up a lot of disk space and require a large amount of resources to compile, it is not feasible to prove the correctness of message processing for all messages in a single proof. Rather, we process messages in batches. With each batch of messages at a particular index, the coordinator proves, using a zk-SNARK proof, intermediate `currentSbCommitment` values for subroots at a relative depth. The authencity of this statement is confirmed using the registry's processing verifying key. The outcome of processing all batches, which must occur in consecutive order, is the same as if all the messages were processed in one go. +As large zk-SNARK circuits take up a lot of disk space and require a large amount of resources to compile, it is not feasible to prove the correctness of message processing for all messages in a single proof. Rather, we process messages in batches. With each batch of messages at a particular index, the coordinator proves, using a zk-SNARK proof, intermediate `currentSbCommitment` values for subroots at a relative depth. The authenticity of this statement is confirmed using the registry's processing verifying key. The outcome of processing all batches, which must occur in consecutive order, is the same as if all the messages were processed in one go. #### When the coordinator tallies the votes @@ -609,7 +609,7 @@ The integration tests and shell scripts in the `cli` directory provide examples | `isTallyVkSet(uint256 _sig)` | Non-applicable | Query whether a signature valid for tallying votes | | `genProcessVkSig(uint256 _stateTreeDepth, uint256 _messageTreeDepth, uint256 _voteOptionTreeDepth, uint256 _messageBatchSize)` | Non-applicable | Generate a signature (used for verifying key mapping lookups) for message processing by compressing parameters into a singular value | | `genTallyVkSig(uint256 _stateTreeDepth, uint256 _intStateTreeDepth, uint256 _voteOptionTreeDepth)` | Non-appicable | Generate a signature (used for verifying key mapping lookups) for vote tallying by compressing parameters into a singular value | -| `setVerifyingKeys( uint256 _stateTreeDepth, uint256 _intStateTreeDepth, uint256 _messageTreeDepth, uint256 _voteOptionTreeDepth, uint256 _messageBatchSize, VerifyingKey memory _processVk, VerifyingKey memory _tallyVk)` | Coordinator only | Intialise verifying keys for processing and tallying to the contract alongside specifying each tree depth | +| `setVerifyingKeys( uint256 _stateTreeDepth, uint256 _intStateTreeDepth, uint256 _messageTreeDepth, uint256 _voteOptionTreeDepth, uint256 _messageBatchSize, VerifyingKey memory _processVk, VerifyingKey memory _tallyVk)` | Coordinator only | Initialise verifying keys for processing and tallying to the contract alongside specifying each tree depth | | `hasProcessVk(uint256 _stateTreeDepth, uint256 _messageTreeDepth, uint256 _voteOptionTreeDepth, uint256 _messageBatchSize)` | Non-applicable | Query whether the signature of the parameters is valid for message processing | | `getProcessVkBySig(uint256 _sig)` | Non-applicable | Query a processing verifying key by providing a valid signature | | `getProcessVk(uint256 _stateTreeDepth, uint256 _messageTreeDepth, uint256 _voteOptionTreeDepth, uint256 _messageBatchSize)` | Non-applicable | Query a processing verifying key by providing parameters to generate a valid signature | diff --git a/website/versioned_docs/version-v1.x/testing-in-detail.md b/website/versioned_docs/version-v1.x/testing-in-detail.md index 42e18d1587..ff79c54791 100644 --- a/website/versioned_docs/version-v1.x/testing-in-detail.md +++ b/website/versioned_docs/version-v1.x/testing-in-detail.md @@ -90,7 +90,7 @@ Let's look at the fields in detail: - `expectedTotalSpentVoiceCredits`: the expected total spent voice credits - `subsidy`: an object that contains the subsidy details. If you do not provide any subsidy details, the default will be used: `enabled = false`, `expectedSubsidy = []`. If you do provide subsidy details, you must provide both fields. -As an example, let's try to implement a test given the following criterias: +As an example, let's try to implement a test given the following criteria: 1. We want 10 users to signup 2. We want each user to publish a different vote @@ -179,7 +179,7 @@ The core package contains a number of tests that are used to verify that the cor These tests interact with the crypto and dombinobjs packages, where mock data comes from. Their main goal is to ensure that the core functions work as expected, and that the state is as expected after a series of operations. -Currently, there is a blend of e2e and unit tests, where e2e tests are used to verify that the entire MACI local processing works as expcted (users signup, publish votes, messages are processed and finally these votes are tallied). Unit tests on the other hand are used to verify that the core functions work as expected, such as `processMessage` and `tallyVotes`. You will find them in separate files, with e2e being [here](https://github.com/privacy-scaling-explorations/maci/blob/dev/core/ts/__tests__/e2e.test.ts) and unit tests in the other files. +Currently, there is a blend of e2e and unit tests, where e2e tests are used to verify that the entire MACI local processing works as expected (users signup, publish votes, messages are processed and finally these votes are tallied). Unit tests on the other hand are used to verify that the core functions work as expected, such as `processMessage` and `tallyVotes`. You will find them in separate files, with e2e being [here](https://github.com/privacy-scaling-explorations/maci/blob/dev/core/ts/__tests__/e2e.test.ts) and unit tests in the other files. ### Domainobjs/Crypto tests