@maci-protocol/circuits 0.0.0-ci.f9da2fc → 0.0.0-ci.fc91dc9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/LICENSE +1 -2
  2. package/build/ts/{genZkeys.d.ts → generateZkeys.d.ts} +1 -1
  3. package/build/ts/generateZkeys.d.ts.map +1 -0
  4. package/build/ts/{genZkeys.js → generateZkeys.js} +1 -1
  5. package/build/ts/generateZkeys.js.map +1 -0
  6. package/build/ts/types.d.ts +8 -8
  7. package/build/ts/types.d.ts.map +1 -1
  8. package/build/tsconfig.build.tsbuildinfo +1 -1
  9. package/circom/circuits.json +7 -7
  10. package/circom/coordinator/non-qv/processMessages.circom +98 -95
  11. package/circom/coordinator/non-qv/tallyVotes.circom +38 -32
  12. package/circom/coordinator/qv/processMessages.circom +99 -93
  13. package/circom/coordinator/qv/tallyVotes.circom +39 -37
  14. package/circom/utils/{calculateTotal.circom → CalculateTotal.circom} +2 -0
  15. package/circom/utils/{verifySignature.circom → EdDSAPoseidonVerifier.circom} +40 -66
  16. package/circom/utils/MessageHasher.circom +57 -0
  17. package/circom/utils/MessageToCommand.circom +107 -0
  18. package/circom/utils/PoseidonHasher.circom +29 -0
  19. package/circom/utils/{privToPubKey.circom → PrivateToPublicKey.circom} +11 -9
  20. package/circom/utils/VerifySignature.circom +39 -0
  21. package/circom/utils/non-qv/{messageValidator.circom → MessageValidator.circom} +13 -11
  22. package/circom/utils/non-qv/{stateLeafAndBallotTransformer.circom → StateLeafAndBallotTransformer.circom} +32 -32
  23. package/circom/utils/qv/{messageValidator.circom → MessageValidator.circom} +13 -11
  24. package/circom/utils/qv/{stateLeafAndBallotTransformer.circom → StateLeafAndBallotTransformer.circom} +32 -32
  25. package/circom/utils/trees/BinaryMerkleRoot.circom +62 -0
  26. package/circom/utils/trees/CheckRoot.circom +49 -0
  27. package/circom/utils/trees/LeafExists.circom +27 -0
  28. package/circom/utils/trees/MerklePathIndicesGenerator.circom +44 -0
  29. package/circom/utils/trees/MerkleTreeInclusionProof.circom +50 -0
  30. package/circom/utils/trees/incrementalQuinaryTree.circom +2 -2
  31. package/circom/voter/PollJoined.circom +43 -0
  32. package/circom/voter/PollJoining.circom +54 -0
  33. package/package.json +12 -11
  34. package/build/ts/genZkeys.d.ts.map +0 -1
  35. package/build/ts/genZkeys.js.map +0 -1
  36. package/circom/utils/hashers.circom +0 -78
  37. package/circom/utils/messageToCommand.circom +0 -78
  38. package/circom/utils/trees/incrementalMerkleTree.circom +0 -198
  39. package/circom/voter/poll.circom +0 -91
@@ -5,12 +5,17 @@ include "./mux1.circom";
5
5
  // zk-kit imports
6
6
  include "./safe-comparators.circom";
7
7
  // local imports
8
- include "../../utils/hashers.circom";
9
- include "../../utils/messageToCommand.circom";
10
- include "../../utils/privToPubKey.circom";
11
- include "../../utils/qv/stateLeafAndBallotTransformer.circom";
8
+ include "../../utils/PoseidonHasher.circom";
9
+ include "../../utils/MessageHasher.circom";
10
+ include "../../utils/MessageToCommand.circom";
11
+ include "../../utils/PrivateToPublicKey.circom";
12
+ include "../../utils/qv/StateLeafAndBallotTransformer.circom";
12
13
  include "../../utils/trees/incrementalQuinaryTree.circom";
13
- include "../../utils/trees/incrementalMerkleTree.circom";
14
+ include "../../utils/trees/MerkleTreeInclusionProof.circom";
15
+ include "../../utils/trees/LeafExists.circom";
16
+ include "../../utils/trees/CheckRoot.circom";
17
+ include "../../utils/trees/MerklePathIndicesGenerator.circom";
18
+ include "../../utils/trees/BinaryMerkleRoot.circom";
14
19
 
15
20
  /**
16
21
  * Proves the correctness of processing a batch of MACI messages.
@@ -30,31 +35,31 @@ template ProcessMessages(
30
35
  var VOTE_OPTION_TREE_ARITY = 5;
31
36
  // Default for binary trees.
32
37
  var STATE_TREE_ARITY = 2;
33
- var MSG_LENGTH = 10;
34
- var PACKED_CMD_LENGTH = 4;
38
+ var MESSAGE_LENGTH = 10;
39
+ var PACKED_COMMAND_LENGTH = 4;
35
40
  var STATE_LEAF_LENGTH = 3;
36
41
  var BALLOT_LENGTH = 2;
37
- var BALLOT_NONCE_IDX = 0;
38
- var BALLOT_VO_ROOT_IDX = 1;
39
- var STATE_LEAF_PUB_X_IDX = 0;
40
- var STATE_LEAF_PUB_Y_IDX = 1;
41
- var STATE_LEAF_VOICE_CREDIT_BALANCE_IDX = 2;
42
- var msgTreeZeroValue = 8370432830353022751713833565135785980866757267633941821328460903436894336785;
42
+ var BALLOT_NONCE_INDEX = 0;
43
+ var BALLOT_VOTE_OPTION_ROOT_INDEX = 1;
44
+ var STATE_LEAF_PUBLIC_X_INDEX = 0;
45
+ var STATE_LEAF_PUBLIC_Y_INDEX = 1;
46
+ var STATE_LEAF_VOICE_CREDIT_BALANCE_INDEX = 2;
47
+ var MESSAGE_TREE_ZERO_VALUE = 8370432830353022751713833565135785980866757267633941821328460903436894336785;
43
48
  // Number of options for this poll.
44
49
  var maxVoteOptions = VOTE_OPTION_TREE_ARITY ** voteOptionTreeDepth;
45
50
 
46
51
  // Number of users that have completed the sign up.
47
- signal input numSignUps;
52
+ signal input totalSignups;
48
53
  // Value of chainHash at beginning of batch
49
54
  signal input inputBatchHash;
50
55
  // Value of chainHash at end of batch
51
56
  signal input outputBatchHash;
52
57
  // The messages.
53
- signal input msgs[batchSize][MSG_LENGTH];
58
+ signal input messages[batchSize][MESSAGE_LENGTH];
54
59
  // The coordinator's private key.
55
- signal input coordPrivKey;
60
+ signal input coordinatorPrivateKey;
56
61
  // The ECDH public key per message.
57
- signal input encPubKeys[batchSize][2];
62
+ signal input encryptionPublicKeys[batchSize][2];
58
63
  // The current state root (before the processing).
59
64
  signal input currentStateRoot;
60
65
  // The actual tree depth (might be <= stateTreeDepth).
@@ -117,10 +122,10 @@ template ProcessMessages(
117
122
  var voteOptionsValid = LessEqThan(32)([voteOptions, VOTE_OPTION_TREE_ARITY ** voteOptionTreeDepth]);
118
123
  voteOptionsValid === 1;
119
124
 
120
- // Check numSignUps <= the max number of users (i.e., number of state leaves
125
+ // Check totalSignups <= the max number of users (i.e., number of state leaves
121
126
  // that can fit the state tree).
122
- var numSignUpsValid = LessEqThan(32)([numSignUps, STATE_TREE_ARITY ** stateTreeDepth]);
123
- numSignUpsValid === 1;
127
+ var totalSignupsValid = LessEqThan(32)([totalSignups, STATE_TREE_ARITY ** stateTreeDepth]);
128
+ totalSignupsValid === 1;
124
129
 
125
130
  // Hash each Message to check their existence in the Message tree.
126
131
  var computedMessageHashers[batchSize];
@@ -130,7 +135,7 @@ template ProcessMessages(
130
135
 
131
136
  for (var i = 0; i < batchSize; i++) {
132
137
  // calculate message hash
133
- computedMessageHashers[i] = MessageHasher()(msgs[i], encPubKeys[i]);
138
+ computedMessageHashers[i] = MessageHasher()(messages[i], encryptionPublicKeys[i]);
134
139
  // check if message is valid or not (if index of message is less than index of last valid message in batch)
135
140
  var batchStartIndexValid = SafeLessThan(32)([index + i, batchEndIndex]);
136
141
  // calculate chain hash if message is valid
@@ -154,38 +159,38 @@ template ProcessMessages(
154
159
  // Ensure that the coordinator's public key from the contract is correct
155
160
  // based on the given private key - that is, the prover knows the
156
161
  // coordinator's private key.
157
- var derivedPubKey[2] = PrivToPubKey()(coordPrivKey);
158
- var derivedPubKeyHash = PoseidonHasher(2)(derivedPubKey);
159
- derivedPubKeyHash === coordinatorPublicKeyHash;
162
+ var derivedPublicKey[2] = PrivateToPublicKey()(coordinatorPrivateKey);
163
+ var derivedPublicKeyHash = PoseidonHasher(2)(derivedPublicKey);
164
+ derivedPublicKeyHash === coordinatorPublicKeyHash;
160
165
 
161
166
  // Decrypt each Message into a Command.
162
167
  // The command i-th is composed by the following fields.
163
168
  // e.g., command 0 is made of commandsStateIndex[0],
164
- // commandsNewPubKey[0], ..., commandsPackedCommandOut[0]
169
+ // commandsNewPublicKey[0], ..., commandsPackedCommandOut[0]
165
170
  var computedCommandsStateIndex[batchSize];
166
- var computedCommandsNewPubKey[batchSize][2];
171
+ var computedCommandsNewPublicKey[batchSize][2];
167
172
  var computedCommandsVoteOptionIndex[batchSize];
168
173
  var computedCommandsNewVoteWeight[batchSize];
169
174
  var computedCommandsNonce[batchSize];
170
175
  var computedCommandsPollId[batchSize];
171
176
  var computedCommandsSalt[batchSize];
172
- var computedCommandsSigR8[batchSize][2];
173
- var computedCommandsSigS[batchSize];
174
- var computedCommandsPackedCommandOut[batchSize][PACKED_CMD_LENGTH];
177
+ var computedCommandsSignaturePoint[batchSize][2];
178
+ var computedCommandsSignatureScalar[batchSize];
179
+ var computedCommandsPackedCommandOut[batchSize][PACKED_COMMAND_LENGTH];
175
180
 
176
181
  for (var i = 0; i < batchSize; i++) {
177
182
  (
178
183
  computedCommandsStateIndex[i],
179
- computedCommandsNewPubKey[i],
184
+ computedCommandsNewPublicKey[i],
180
185
  computedCommandsVoteOptionIndex[i],
181
186
  computedCommandsNewVoteWeight[i],
182
187
  computedCommandsNonce[i],
183
188
  computedCommandsPollId[i],
184
189
  computedCommandsSalt[i],
185
- computedCommandsSigR8[i],
186
- computedCommandsSigS[i],
190
+ computedCommandsSignaturePoint[i],
191
+ computedCommandsSignatureScalar[i],
187
192
  computedCommandsPackedCommandOut[i]
188
- ) = MessageToCommand()(msgs[i], coordPrivKey, encPubKeys[i]);
193
+ ) = MessageToCommand()(messages[i], coordinatorPrivateKey, encryptionPublicKeys[i]);
189
194
  }
190
195
 
191
196
  // Process messages in reverse order.
@@ -218,7 +223,7 @@ template ProcessMessages(
218
223
  }
219
224
 
220
225
  (computedNewVoteStateRoot[i], computedNewVoteBallotRoot[i]) = ProcessOne(stateTreeDepth, voteOptionTreeDepth)(
221
- numSignUps,
226
+ totalSignups,
222
227
  stateRoots[i + 1],
223
228
  ballotRoots[i + 1],
224
229
  actualStateTreeDepth,
@@ -229,14 +234,14 @@ template ProcessMessages(
229
234
  currentVoteWeights[i],
230
235
  currentVoteWeightsPathElement,
231
236
  computedCommandsStateIndex[i],
232
- computedCommandsNewPubKey[i],
237
+ computedCommandsNewPublicKey[i],
233
238
  computedCommandsVoteOptionIndex[i],
234
239
  computedCommandsNewVoteWeight[i],
235
240
  computedCommandsNonce[i],
236
241
  computedCommandsPollId[i],
237
242
  computedCommandsSalt[i],
238
- computedCommandsSigR8[i],
239
- computedCommandsSigS[i],
243
+ computedCommandsSignaturePoint[i],
244
+ computedCommandsSignatureScalar[i],
240
245
  computedCommandsPackedCommandOut[i],
241
246
  voteOptions
242
247
  );
@@ -261,24 +266,24 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
261
266
  // Constants defining the structure and size of state and ballots.
262
267
  var STATE_LEAF_LENGTH = 3;
263
268
  var BALLOT_LENGTH = 2;
264
- var MSG_LENGTH = 10;
265
- var PACKED_CMD_LENGTH = 4;
269
+ var MESSAGE_LENGTH = 10;
270
+ var PACKED_COMMAND_LENGTH = 4;
266
271
  var VOTE_OPTION_TREE_ARITY = 5;
267
272
  var STATE_TREE_ARITY = 2;
268
- var BALLOT_NONCE_IDX = 0;
269
- // Ballot vote option (VO) root index.
270
- var BALLOT_VO_ROOT_IDX = 1;
273
+ var BALLOT_NONCE_INDEX = 0;
274
+ // Ballot vote option (vote option) root index.
275
+ var BALLOT_VOTE_OPTION_ROOT_INDEX = 1;
271
276
 
272
277
  // Indices for elements within a state leaf.
273
278
  // Public key.
274
- var STATE_LEAF_PUB_X_IDX = 0;
275
- var STATE_LEAF_PUB_Y_IDX = 1;
279
+ var STATE_LEAF_PUBLIC_X_INDEX = 0;
280
+ var STATE_LEAF_PUBLIC_Y_INDEX = 1;
276
281
  // Voice Credit balance.
277
- var STATE_LEAF_VOICE_CREDIT_BALANCE_IDX = 2;
278
- var N_BITS = 252;
282
+ var STATE_LEAF_VOICE_CREDIT_BALANCE_INDEX = 2;
283
+ var NUMBER_BITS = 252;
279
284
 
280
285
  // Number of users that have completed the sign up.
281
- signal input numSignUps;
286
+ signal input totalSignups;
282
287
  // The current value of the state tree root.
283
288
  signal input currentStateRoot;
284
289
  // The current value of the ballot tree root.
@@ -300,16 +305,16 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
300
305
  signal input currentVoteWeightsPathElements[voteOptionTreeDepth][VOTE_OPTION_TREE_ARITY - 1];
301
306
 
302
307
  // Inputs related to the command being processed.
303
- signal input cmdStateIndex;
304
- signal input cmdNewPubKey[2];
305
- signal input cmdVoteOptionIndex;
306
- signal input cmdNewVoteWeight;
307
- signal input cmdNonce;
308
- signal input cmdPollId;
309
- signal input cmdSalt;
310
- signal input cmdSigR8[2];
311
- signal input cmdSigS;
312
- signal input packedCmd[PACKED_CMD_LENGTH];
308
+ signal input commandStateIndex;
309
+ signal input commandPublicKey[2];
310
+ signal input commandVoteOptionIndex;
311
+ signal input commandNewVoteWeight;
312
+ signal input commandNonce;
313
+ signal input commandPollId;
314
+ signal input commandSalt;
315
+ signal input commandSignaturePoint[2];
316
+ signal input commandSignatureScalar;
317
+ signal input packedCommand[PACKED_COMMAND_LENGTH];
313
318
 
314
319
  // The number of valid vote options for the poll.
315
320
  signal input voteOptions;
@@ -320,37 +325,37 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
320
325
  // Intermediate signals.
321
326
  // currentVoteWeight * currentVoteWeight.
322
327
  signal currentVoteWeightSquare;
323
- // cmdNewVoteWeight * cmdNewVoteWeight.
324
- signal cmdNewVoteWeightSquare;
325
- // equal to newBallotVoRootMux (Mux1).
328
+ // commandNewVoteWeight * commandNewVoteWeight.
329
+ signal commandNewVoteWeightSquare;
330
+ // equal to newBallotVoteOptionRootMux (Mux1).
326
331
  signal newBallotVoRoot;
327
332
 
328
333
  // 1. Transform a state leaf and a ballot with a command.
329
334
  // The result is a new state leaf, a new ballot, and an isValid signal (0 or 1).
330
- var computedNewSlPubKey[2], computedNewBallotNonce, computedIsValid, computedIsStateLeafIndexValid, computedIsVoteOptionIndexValid;
331
- (computedNewSlPubKey, computedNewBallotNonce, computedIsValid, computedIsStateLeafIndexValid, computedIsVoteOptionIndexValid) = StateLeafAndBallotTransformer()(
332
- numSignUps,
335
+ var computedNewstateLeafPublicKey[2], computedNewBallotNonce, computedIsValid, computedIsStateLeafIndexValid, computedIsVoteOptionIndexValid;
336
+ (computedNewstateLeafPublicKey, computedNewBallotNonce, computedIsValid, computedIsStateLeafIndexValid, computedIsVoteOptionIndexValid) = StateLeafAndBallotTransformer()(
337
+ totalSignups,
333
338
  voteOptions,
334
- [stateLeaf[STATE_LEAF_PUB_X_IDX], stateLeaf[STATE_LEAF_PUB_Y_IDX]],
335
- stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_IDX],
336
- ballot[BALLOT_NONCE_IDX],
339
+ [stateLeaf[STATE_LEAF_PUBLIC_X_INDEX], stateLeaf[STATE_LEAF_PUBLIC_Y_INDEX]],
340
+ stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_INDEX],
341
+ ballot[BALLOT_NONCE_INDEX],
337
342
  currentVoteWeight,
338
- cmdStateIndex,
339
- cmdNewPubKey,
340
- cmdVoteOptionIndex,
341
- cmdNewVoteWeight,
342
- cmdNonce,
343
- cmdPollId,
344
- cmdSalt,
345
- cmdSigR8,
346
- cmdSigS,
347
- packedCmd
343
+ commandStateIndex,
344
+ commandPublicKey,
345
+ commandVoteOptionIndex,
346
+ commandNewVoteWeight,
347
+ commandNonce,
348
+ commandPollId,
349
+ commandSalt,
350
+ commandSignaturePoint,
351
+ commandSignatureScalar,
352
+ packedCommand
348
353
  );
349
354
 
350
355
  // 2. If computedIsStateLeafIndexValid is equal to zero, generate indices for leaf zero.
351
356
  // Otherwise, generate indices for command.stateIndex.
352
- var stateIndexMux = Mux1()([0, cmdStateIndex], computedIsStateLeafIndexValid);
353
- var computedStateLeafPathIndices[stateTreeDepth] = MerkleGeneratePathIndices(stateTreeDepth)(stateIndexMux);
357
+ var stateIndexMux = Mux1()([0, commandStateIndex], computedIsStateLeafIndexValid);
358
+ var computedStateLeafPathIndices[stateTreeDepth] = MerklePathIndicesGenerator(stateTreeDepth)(stateIndexMux);
354
359
 
355
360
  // 3. Verify that the original state leaf exists in the given state root.
356
361
  var stateLeafHash = PoseidonHasher(3)(stateLeaf);
@@ -365,8 +370,8 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
365
370
 
366
371
  // 4. Verify that the original ballot exists in the given ballot root.
367
372
  var computedBallot = PoseidonHasher(2)([
368
- ballot[BALLOT_NONCE_IDX],
369
- ballot[BALLOT_VO_ROOT_IDX]
373
+ ballot[BALLOT_NONCE_INDEX],
374
+ ballot[BALLOT_VOTE_OPTION_ROOT_INDEX]
370
375
  ]);
371
376
 
372
377
  var computedBallotQip = MerkleTreeInclusionProof(stateTreeDepth)(
@@ -378,12 +383,12 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
378
383
  computedBallotQip === currentBallotRoot;
379
384
 
380
385
  // 5. Verify that currentVoteWeight exists in the ballot's vote option root
381
- // at cmdVoteOptionIndex.
386
+ // at commandVoteOptionIndex.
382
387
  currentVoteWeightSquare <== currentVoteWeight * currentVoteWeight;
383
- cmdNewVoteWeightSquare <== cmdNewVoteWeight * cmdNewVoteWeight;
388
+ commandNewVoteWeightSquare <== commandNewVoteWeight * commandNewVoteWeight;
384
389
 
385
- var cmdVoteOptionIndexMux = Mux1()([0, cmdVoteOptionIndex], computedIsVoteOptionIndexValid);
386
- var computedCurrentVoteWeightPathIndices[voteOptionTreeDepth] = QuinGeneratePathIndices(voteOptionTreeDepth)(cmdVoteOptionIndexMux);
390
+ var commandVoteOptionIndexMux = Mux1()([0, commandVoteOptionIndex], computedIsVoteOptionIndexValid);
391
+ var computedCurrentVoteWeightPathIndices[voteOptionTreeDepth] = QuinGeneratePathIndices(voteOptionTreeDepth)(commandVoteOptionIndexMux);
387
392
 
388
393
  var computedCurrentVoteWeightQip = QuinTreeInclusionProof(voteOptionTreeDepth)(
389
394
  currentVoteWeight,
@@ -391,13 +396,13 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
391
396
  currentVoteWeightsPathElements
392
397
  );
393
398
 
394
- computedCurrentVoteWeightQip === ballot[BALLOT_VO_ROOT_IDX];
399
+ computedCurrentVoteWeightQip === ballot[BALLOT_VOTE_OPTION_ROOT_INDEX];
395
400
 
396
- var voteWeightMux = Mux1()([currentVoteWeight, cmdNewVoteWeight], computedIsValid);
401
+ var voteWeightMux = Mux1()([currentVoteWeight, commandNewVoteWeight], computedIsValid);
397
402
  var voiceCreditBalanceMux = Mux1()(
398
403
  [
399
- stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_IDX],
400
- stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_IDX] + currentVoteWeightSquare - cmdNewVoteWeightSquare
404
+ stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_INDEX],
405
+ stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_INDEX] + currentVoteWeightSquare - commandNewVoteWeightSquare
401
406
  ],
402
407
  computedIsValid
403
408
  );
@@ -410,17 +415,17 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
410
415
  );
411
416
 
412
417
  // The new vote option root in the ballot
413
- var newBallotVoRootMux = Mux1()(
414
- [ballot[BALLOT_VO_ROOT_IDX], computedNewVoteOptionTreeQip],
418
+ var newBallotVoteOptionRootMux = Mux1()(
419
+ [ballot[BALLOT_VOTE_OPTION_ROOT_INDEX], computedNewVoteOptionTreeQip],
415
420
  computedIsValid
416
421
  );
417
422
 
418
- newBallotVoRoot <== newBallotVoRootMux;
423
+ newBallotVoRoot <== newBallotVoteOptionRootMux;
419
424
 
420
425
  // 6. Generate a new state root.
421
426
  var computedNewStateLeafhash = PoseidonHasher(3)([
422
- computedNewSlPubKey[STATE_LEAF_PUB_X_IDX],
423
- computedNewSlPubKey[STATE_LEAF_PUB_Y_IDX],
427
+ computedNewstateLeafPublicKey[STATE_LEAF_PUBLIC_X_INDEX],
428
+ computedNewstateLeafPublicKey[STATE_LEAF_PUBLIC_Y_INDEX],
424
429
  voiceCreditBalanceMux
425
430
  ]);
426
431
 
@@ -443,3 +448,4 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
443
448
 
444
449
  newBallotRoot <== computedNewBallotQip;
445
450
  }
451
+
@@ -5,10 +5,12 @@ include "./comparators.circom";
5
5
  // zk-kit import
6
6
  include "./unpack-element.circom";
7
7
  // local imports
8
- include "../../utils/trees/incrementalMerkleTree.circom";
8
+ include "../../utils/trees/CheckRoot.circom";
9
+ include "../../utils/trees/MerklePathIndicesGenerator.circom";
10
+ include "../../utils/trees/LeafExists.circom";
9
11
  include "../../utils/trees/incrementalQuinaryTree.circom";
10
- include "../../utils/calculateTotal.circom";
11
- include "../../utils/hashers.circom";
12
+ include "../../utils/CalculateTotal.circom";
13
+ include "../../utils/PoseidonHasher.circom";
12
14
 
13
15
  /**
14
16
  * Processes batches of votes and verifies their validity in a Merkle tree structure.
@@ -33,16 +35,16 @@ template TallyVotes(
33
35
  // The number of ballots processed at once, determined by the depth of the intermediate state tree.
34
36
  var batchSize = BALLOT_TREE_ARITY ** intStateTreeDepth;
35
37
  // Number of voting options available, determined by the depth of the vote option tree.
36
- var numVoteOptions = TREE_ARITY ** voteOptionTreeDepth;
38
+ var totalVoteOptions = TREE_ARITY ** voteOptionTreeDepth;
37
39
 
38
40
  // Number of elements in each ballot.
39
41
  var BALLOT_LENGTH = 2;
40
42
  // Index for the nonce in the ballot array.
41
- var BALLOT_NONCE_IDX = 0;
43
+ var BALLOT_NONCE_INDEX = 0;
42
44
  // Index for the voting option root in the ballot array.
43
- var BALLOT_VO_ROOT_IDX = 1;
45
+ var BALLOT_VOTE_OPTION_ROOT_INDEX = 1;
44
46
  // Difference in tree depths, used in path calculations.
45
- var k = stateTreeDepth - intStateTreeDepth;
47
+ var STATE_INT_TREE_DEPTH_DIFFERENCE = stateTreeDepth - intStateTreeDepth;
46
48
 
47
49
  // Root of the state Merkle tree, representing the overall state before voting.
48
50
  signal input stateRoot;
@@ -59,13 +61,13 @@ template TallyVotes(
59
61
  // Start index of given batch
60
62
  signal input index;
61
63
  // Number of users that signup
62
- signal input numSignUps;
64
+ signal input totalSignups;
63
65
  // Ballots and their corresponding path elements for verification in the tree.
64
66
  signal input ballots[batchSize][BALLOT_LENGTH];
65
- signal input ballotPathElements[k][BALLOT_TREE_ARITY - 1];
66
- signal input votes[batchSize][numVoteOptions];
67
+ signal input ballotPathElements[STATE_INT_TREE_DEPTH_DIFFERENCE][BALLOT_TREE_ARITY - 1];
68
+ signal input votes[batchSize][totalVoteOptions];
67
69
  // Current results for each vote option.
68
- signal input currentResults[numVoteOptions];
70
+ signal input currentResults[totalVoteOptions];
69
71
  // Salt for the root of the current results.
70
72
  signal input currentResultsRootSalt;
71
73
  // Total voice credits spent so far.
@@ -73,7 +75,7 @@ template TallyVotes(
73
75
  // Salt for the total spent voice credits.
74
76
  signal input currentSpentVoiceCreditSubtotalSalt;
75
77
  // Spent voice credits per vote option.
76
- signal input currentPerVOSpentVoiceCredits[numVoteOptions];
78
+ signal input currentPerVOSpentVoiceCredits[totalVoteOptions];
77
79
  // Salt for the root of spent credits per option.
78
80
  signal input currentPerVOSpentVoiceCreditsRootSalt;
79
81
  // Salt for the root of the new results.
@@ -88,21 +90,21 @@ template TallyVotes(
88
90
  computedSbCommitment === sbCommitment;
89
91
 
90
92
  // Validates that the index is within the valid range of sign-ups.
91
- var numSignUpsValid = LessEqThan(50)([index, numSignUps]);
92
- numSignUpsValid === 1;
93
+ var totalSignupsValid = LessEqThan(50)([index, totalSignups]);
94
+ totalSignupsValid === 1;
93
95
 
94
96
  // Hashes each ballot for subroot generation, and checks the existence of the leaf in the Merkle tree.
95
97
  var computedBallotHashers[batchSize];
96
98
 
97
99
  for (var i = 0; i < batchSize; i++) {
98
- computedBallotHashers[i] = PoseidonHasher(2)([ballots[i][BALLOT_NONCE_IDX], ballots[i][BALLOT_VO_ROOT_IDX]]);
100
+ computedBallotHashers[i] = PoseidonHasher(2)([ballots[i][BALLOT_NONCE_INDEX], ballots[i][BALLOT_VOTE_OPTION_ROOT_INDEX]]);
99
101
  }
100
102
 
101
103
  var computedBallotSubroot = CheckRoot(intStateTreeDepth)(computedBallotHashers);
102
- var computedBallotPathIndices[k] = MerkleGeneratePathIndices(k)(index / batchSize);
104
+ var computedBallotPathIndices[STATE_INT_TREE_DEPTH_DIFFERENCE] = MerklePathIndicesGenerator(STATE_INT_TREE_DEPTH_DIFFERENCE)(index / batchSize);
103
105
 
104
106
  // Verifies each ballot's existence within the ballot tree.
105
- LeafExists(k)(
107
+ LeafExists(STATE_INT_TREE_DEPTH_DIFFERENCE)(
106
108
  computedBallotSubroot,
107
109
  ballotPathElements,
108
110
  computedBallotPathIndices,
@@ -113,7 +115,7 @@ template TallyVotes(
113
115
  var computedVoteTree[batchSize];
114
116
  for (var i = 0; i < batchSize; i++) {
115
117
  computedVoteTree[i] = QuinCheckRoot(voteOptionTreeDepth)(votes[i]);
116
- computedVoteTree[i] === ballots[i][BALLOT_VO_ROOT_IDX];
118
+ computedVoteTree[i] === ballots[i][BALLOT_VOTE_OPTION_ROOT_INDEX];
117
119
  }
118
120
 
119
121
  // Calculates new results and spent voice credits based on the current and incoming votes.
@@ -121,8 +123,8 @@ template TallyVotes(
121
123
  var computedIsZero = IsZero()(computedIsFirstBatch);
122
124
 
123
125
  // Tally the new results.
124
- var computedCalculateTotalResult[numVoteOptions];
125
- for (var i = 0; i < numVoteOptions; i++) {
126
+ var computedCalculateTotalResult[totalVoteOptions];
127
+ for (var i = 0; i < totalVoteOptions; i++) {
126
128
  var numsRC[batchSize + 1];
127
129
  numsRC[batchSize] = currentResults[i] * computedIsZero;
128
130
  for (var j = 0; j < batchSize; j++) {
@@ -133,20 +135,20 @@ template TallyVotes(
133
135
  }
134
136
 
135
137
  // Tally the new spent voice credit total.
136
- var numsSVC[batchSize * numVoteOptions + 1];
137
- numsSVC[batchSize * numVoteOptions] = currentSpentVoiceCreditSubtotal * computedIsZero;
138
+ var numsSVC[batchSize * totalVoteOptions + 1];
139
+ numsSVC[batchSize * totalVoteOptions] = currentSpentVoiceCreditSubtotal * computedIsZero;
138
140
  for (var i = 0; i < batchSize; i++) {
139
- for (var j = 0; j < numVoteOptions; j++) {
140
- numsSVC[i * numVoteOptions + j] = votes[i][j] * votes[i][j];
141
+ for (var j = 0; j < totalVoteOptions; j++) {
142
+ numsSVC[i * totalVoteOptions + j] = votes[i][j] * votes[i][j];
141
143
  }
142
144
  }
143
145
 
144
- var computedNewSpentVoiceCreditSubtotal = CalculateTotal(batchSize * numVoteOptions + 1)(numsSVC);
146
+ var computedNewSpentVoiceCreditSubtotal = CalculateTotal(batchSize * totalVoteOptions + 1)(numsSVC);
145
147
 
146
148
  // Tally the spent voice credits per vote option.
147
- var computedNewPerVOSpentVoiceCredits[numVoteOptions];
149
+ var computedNewPerVOSpentVoiceCredits[totalVoteOptions];
148
150
 
149
- for (var i = 0; i < numVoteOptions; i++) {
151
+ for (var i = 0; i < totalVoteOptions; i++) {
150
152
  var computedNumsSVC[batchSize + 1];
151
153
  computedNumsSVC[batchSize] = currentPerVOSpentVoiceCredits[i] * computedIsZero;
152
154
  for (var j = 0; j < batchSize; j++) {
@@ -185,7 +187,7 @@ template ResultCommitmentVerifier(voteOptionTreeDepth) {
185
187
  // Number of children per node in the tree, defining the tree's branching factor.
186
188
  var TREE_ARITY = 5;
187
189
  // Number of voting options available, determined by the depth of the vote option tree.
188
- var numVoteOptions = TREE_ARITY ** voteOptionTreeDepth;
190
+ var totalVoteOptions = TREE_ARITY ** voteOptionTreeDepth;
189
191
 
190
192
  // Equal to 1 if this is the first batch, otherwise 0.
191
193
  signal input isFirstBatch;
@@ -195,12 +197,12 @@ template ResultCommitmentVerifier(voteOptionTreeDepth) {
195
197
  signal input newTallyCommitment;
196
198
 
197
199
  // Current results for each vote option.
198
- signal input currentResults[numVoteOptions];
200
+ signal input currentResults[totalVoteOptions];
199
201
  // Salt for the root of the current results.
200
202
  signal input currentResultsRootSalt;
201
203
 
202
204
  // New results for each vote option.
203
- signal input newResults[numVoteOptions];
205
+ signal input newResults[totalVoteOptions];
204
206
  // Salt for the root of the new results.
205
207
  signal input newResultsRootSalt;
206
208
 
@@ -215,12 +217,12 @@ template ResultCommitmentVerifier(voteOptionTreeDepth) {
215
217
  signal input newSpentVoiceCreditSubtotalSalt;
216
218
 
217
219
  // Spent voice credits per vote option.
218
- signal input currentPerVOSpentVoiceCredits[numVoteOptions];
220
+ signal input currentPerVOSpentVoiceCredits[totalVoteOptions];
219
221
  // Salt for the root of spent credits per option.
220
222
  signal input currentPerVOSpentVoiceCreditsRootSalt;
221
223
 
222
224
  // New spent voice credits per vote option.
223
- signal input newPerVOSpentVoiceCredits[numVoteOptions];
225
+ signal input newPerVOSpentVoiceCredits[totalVoteOptions];
224
226
  // Salt for the root of new spent credits per option.
225
227
  signal input newPerVOSpentVoiceCreditsRootSalt;
226
228
 
@@ -249,11 +251,11 @@ template ResultCommitmentVerifier(voteOptionTreeDepth) {
249
251
  // computedIsZero.out is 0 if this is the first batch.
250
252
  var computedIsZero = IsZero()(isFirstBatch);
251
253
 
252
- // hz is 0 if this is the first batch, currentTallyCommitment should be 0 if this is the first batch.
253
- // hz is 1 if this is not the first batch, currentTallyCommitment should not be 0 if this is the first batch.
254
- signal hz;
255
- hz <== computedIsZero * computedCurrentTallyCommitment;
256
- hz === currentTallyCommitment;
254
+ // isFirstCommitment is 0 if this is the first batch, currentTallyCommitment should be 0 if this is the first batch.
255
+ // isFirstCommitment is 1 if this is not the first batch, currentTallyCommitment should not be 0 if this is the first batch.
256
+ signal isFirstCommitment;
257
+ isFirstCommitment <== computedIsZero * computedCurrentTallyCommitment;
258
+ isFirstCommitment === currentTallyCommitment;
257
259
 
258
260
  // Compute the root of the new results.
259
261
  var computedNewResultsRoot = QuinCheckRoot(voteOptionTreeDepth)(newResults);
@@ -8,7 +8,9 @@ pragma circom 2.0.0;
8
8
  * final output reflects the cumulative total of the inputs provided.
9
9
  */
10
10
  template CalculateTotal(n) {
11
+ // Array of values.
11
12
  signal input nums[n];
13
+ // Total sum.
12
14
  signal output sum;
13
15
 
14
16
  signal sums[n];