@maci-protocol/circuits 0.0.0-ci.4c6d4e8 → 0.0.0-ci.52ce07e
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.
- package/LICENSE +1 -2
- package/build/ts/{genZkeys.d.ts → generateZkeys.d.ts} +1 -1
- package/build/ts/generateZkeys.d.ts.map +1 -0
- package/build/ts/{genZkeys.js → generateZkeys.js} +1 -1
- package/build/ts/generateZkeys.js.map +1 -0
- package/build/ts/types.d.ts +11 -11
- package/build/ts/types.d.ts.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/circom/circuits.json +23 -7
- package/circom/coordinator/full/MessageProcessor.circom +253 -0
- package/circom/coordinator/full/SingleMessageProcessor.circom +204 -0
- package/circom/coordinator/non-qv/processMessages.circom +110 -112
- package/circom/coordinator/non-qv/tallyVotes.circom +49 -46
- package/circom/coordinator/qv/processMessages.circom +111 -110
- package/circom/coordinator/qv/tallyVotes.circom +63 -63
- package/circom/utils/{calculateTotal.circom → CalculateTotal.circom} +8 -6
- package/circom/utils/{verifySignature.circom → EdDSAPoseidonVerifier.circom} +40 -66
- package/circom/utils/MessageHasher.circom +57 -0
- package/circom/utils/MessageToCommand.circom +107 -0
- package/circom/utils/PoseidonHasher.circom +29 -0
- package/circom/utils/{privToPubKey.circom → PrivateToPublicKey.circom} +12 -10
- package/circom/utils/VerifySignature.circom +39 -0
- package/circom/utils/full/MessageValidator.circom +91 -0
- package/circom/utils/full/StateLeafAndBallotTransformer.circom +122 -0
- package/circom/utils/non-qv/{messageValidator.circom → MessageValidator.circom} +17 -15
- package/circom/utils/non-qv/{stateLeafAndBallotTransformer.circom → StateLeafAndBallotTransformer.circom} +36 -36
- package/circom/utils/qv/{messageValidator.circom → MessageValidator.circom} +17 -15
- package/circom/utils/qv/{stateLeafAndBallotTransformer.circom → StateLeafAndBallotTransformer.circom} +36 -36
- package/circom/utils/trees/BinaryMerkleRoot.circom +11 -3
- package/circom/utils/trees/CheckRoot.circom +18 -14
- package/circom/utils/trees/LeafExists.circom +3 -3
- package/circom/utils/trees/{MerkleGeneratePathIndices.circom → MerklePathIndicesGenerator.circom} +11 -7
- package/circom/utils/trees/MerkleTreeInclusionProof.circom +10 -9
- package/circom/utils/trees/QuinaryCheckRoot.circom +54 -0
- package/circom/utils/trees/QuinaryGeneratePathIndices.circom +44 -0
- package/circom/utils/trees/QuinaryLeafExists.circom +30 -0
- package/circom/utils/trees/QuinarySelector.circom +42 -0
- package/circom/utils/trees/QuinaryTreeInclusionProof.circom +55 -0
- package/circom/utils/trees/Splicer.circom +76 -0
- package/circom/voter/PollJoined.circom +43 -0
- package/circom/voter/PollJoining.circom +54 -0
- package/package.json +15 -12
- package/build/ts/genZkeys.d.ts.map +0 -1
- package/build/ts/genZkeys.js.map +0 -1
- package/circom/utils/hashers.circom +0 -78
- package/circom/utils/messageToCommand.circom +0 -78
- package/circom/utils/trees/incrementalQuinaryTree.circom +0 -287
- package/circom/voter/poll.circom +0 -92
|
@@ -5,16 +5,17 @@ include "./mux1.circom";
|
|
|
5
5
|
// zk-kit imports
|
|
6
6
|
include "./safe-comparators.circom";
|
|
7
7
|
// local imports
|
|
8
|
-
include "../../utils/
|
|
9
|
-
include "../../utils/
|
|
10
|
-
include "../../utils/
|
|
11
|
-
include "../../utils/
|
|
12
|
-
include "../../utils/
|
|
13
|
-
|
|
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";
|
|
13
|
+
include "../../utils/trees/QuinaryTreeInclusionProof.circom";
|
|
14
|
+
include "../../utils/trees/QuinaryGeneratePathIndices.circom";
|
|
14
15
|
include "../../utils/trees/MerkleTreeInclusionProof.circom";
|
|
15
16
|
include "../../utils/trees/LeafExists.circom";
|
|
16
17
|
include "../../utils/trees/CheckRoot.circom";
|
|
17
|
-
include "../../utils/trees/
|
|
18
|
+
include "../../utils/trees/MerklePathIndicesGenerator.circom";
|
|
18
19
|
include "../../utils/trees/BinaryMerkleRoot.circom";
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -35,31 +36,31 @@ template ProcessMessages(
|
|
|
35
36
|
var VOTE_OPTION_TREE_ARITY = 5;
|
|
36
37
|
// Default for binary trees.
|
|
37
38
|
var STATE_TREE_ARITY = 2;
|
|
38
|
-
var
|
|
39
|
-
var
|
|
39
|
+
var MESSAGE_LENGTH = 10;
|
|
40
|
+
var PACKED_COMMAND_LENGTH = 4;
|
|
40
41
|
var STATE_LEAF_LENGTH = 3;
|
|
41
42
|
var BALLOT_LENGTH = 2;
|
|
42
|
-
var
|
|
43
|
-
var
|
|
44
|
-
var
|
|
45
|
-
var
|
|
46
|
-
var
|
|
47
|
-
var
|
|
43
|
+
var BALLOT_NONCE_INDEX = 0;
|
|
44
|
+
var BALLOT_VOTE_OPTION_ROOT_INDEX = 1;
|
|
45
|
+
var STATE_LEAF_PUBLIC_X_INDEX = 0;
|
|
46
|
+
var STATE_LEAF_PUBLIC_Y_INDEX = 1;
|
|
47
|
+
var STATE_LEAF_VOICE_CREDIT_BALANCE_INDEX = 2;
|
|
48
|
+
var MESSAGE_TREE_ZERO_VALUE = 8370432830353022751713833565135785980866757267633941821328460903436894336785;
|
|
48
49
|
// Number of options for this poll.
|
|
49
50
|
var maxVoteOptions = VOTE_OPTION_TREE_ARITY ** voteOptionTreeDepth;
|
|
50
51
|
|
|
51
52
|
// Number of users that have completed the sign up.
|
|
52
|
-
signal input
|
|
53
|
+
signal input totalSignups;
|
|
53
54
|
// Value of chainHash at beginning of batch
|
|
54
55
|
signal input inputBatchHash;
|
|
55
56
|
// Value of chainHash at end of batch
|
|
56
57
|
signal input outputBatchHash;
|
|
57
58
|
// The messages.
|
|
58
|
-
signal input
|
|
59
|
+
signal input messages[batchSize][MESSAGE_LENGTH];
|
|
59
60
|
// The coordinator's private key.
|
|
60
|
-
signal input
|
|
61
|
+
signal input coordinatorPrivateKey;
|
|
61
62
|
// The ECDH public key per message.
|
|
62
|
-
signal input
|
|
63
|
+
signal input encryptionPublicKeys[batchSize][2];
|
|
63
64
|
// The current state root (before the processing).
|
|
64
65
|
signal input currentStateRoot;
|
|
65
66
|
// The actual tree depth (might be <= stateTreeDepth).
|
|
@@ -122,10 +123,10 @@ template ProcessMessages(
|
|
|
122
123
|
var voteOptionsValid = LessEqThan(32)([voteOptions, VOTE_OPTION_TREE_ARITY ** voteOptionTreeDepth]);
|
|
123
124
|
voteOptionsValid === 1;
|
|
124
125
|
|
|
125
|
-
// Check
|
|
126
|
+
// Check totalSignups <= the max number of users (i.e., number of state leaves
|
|
126
127
|
// that can fit the state tree).
|
|
127
|
-
var
|
|
128
|
-
|
|
128
|
+
var totalSignupsValid = LessEqThan(32)([totalSignups, STATE_TREE_ARITY ** stateTreeDepth]);
|
|
129
|
+
totalSignupsValid === 1;
|
|
129
130
|
|
|
130
131
|
// Hash each Message to check their existence in the Message tree.
|
|
131
132
|
var computedMessageHashers[batchSize];
|
|
@@ -135,7 +136,7 @@ template ProcessMessages(
|
|
|
135
136
|
|
|
136
137
|
for (var i = 0; i < batchSize; i++) {
|
|
137
138
|
// calculate message hash
|
|
138
|
-
computedMessageHashers[i] = MessageHasher()(
|
|
139
|
+
computedMessageHashers[i] = MessageHasher()(messages[i], encryptionPublicKeys[i]);
|
|
139
140
|
// check if message is valid or not (if index of message is less than index of last valid message in batch)
|
|
140
141
|
var batchStartIndexValid = SafeLessThan(32)([index + i, batchEndIndex]);
|
|
141
142
|
// calculate chain hash if message is valid
|
|
@@ -159,38 +160,38 @@ template ProcessMessages(
|
|
|
159
160
|
// Ensure that the coordinator's public key from the contract is correct
|
|
160
161
|
// based on the given private key - that is, the prover knows the
|
|
161
162
|
// coordinator's private key.
|
|
162
|
-
var
|
|
163
|
-
var
|
|
164
|
-
|
|
163
|
+
var derivedPublicKey[2] = PrivateToPublicKey()(coordinatorPrivateKey);
|
|
164
|
+
var derivedPublicKeyHash = PoseidonHasher(2)(derivedPublicKey);
|
|
165
|
+
derivedPublicKeyHash === coordinatorPublicKeyHash;
|
|
165
166
|
|
|
166
167
|
// Decrypt each Message into a Command.
|
|
167
168
|
// The command i-th is composed by the following fields.
|
|
168
169
|
// e.g., command 0 is made of commandsStateIndex[0],
|
|
169
|
-
//
|
|
170
|
+
// commandsNewPublicKey[0], ..., commandsPackedCommandOut[0]
|
|
170
171
|
var computedCommandsStateIndex[batchSize];
|
|
171
|
-
var
|
|
172
|
+
var computedCommandsNewPublicKey[batchSize][2];
|
|
172
173
|
var computedCommandsVoteOptionIndex[batchSize];
|
|
173
174
|
var computedCommandsNewVoteWeight[batchSize];
|
|
174
175
|
var computedCommandsNonce[batchSize];
|
|
175
176
|
var computedCommandsPollId[batchSize];
|
|
176
177
|
var computedCommandsSalt[batchSize];
|
|
177
|
-
var
|
|
178
|
-
var
|
|
179
|
-
var computedCommandsPackedCommandOut[batchSize][
|
|
178
|
+
var computedCommandsSignaturePoint[batchSize][2];
|
|
179
|
+
var computedCommandsSignatureScalar[batchSize];
|
|
180
|
+
var computedCommandsPackedCommandOut[batchSize][PACKED_COMMAND_LENGTH];
|
|
180
181
|
|
|
181
182
|
for (var i = 0; i < batchSize; i++) {
|
|
182
183
|
(
|
|
183
184
|
computedCommandsStateIndex[i],
|
|
184
|
-
|
|
185
|
+
computedCommandsNewPublicKey[i],
|
|
185
186
|
computedCommandsVoteOptionIndex[i],
|
|
186
187
|
computedCommandsNewVoteWeight[i],
|
|
187
188
|
computedCommandsNonce[i],
|
|
188
189
|
computedCommandsPollId[i],
|
|
189
190
|
computedCommandsSalt[i],
|
|
190
|
-
|
|
191
|
-
|
|
191
|
+
computedCommandsSignaturePoint[i],
|
|
192
|
+
computedCommandsSignatureScalar[i],
|
|
192
193
|
computedCommandsPackedCommandOut[i]
|
|
193
|
-
) = MessageToCommand()(
|
|
194
|
+
) = MessageToCommand()(messages[i], coordinatorPrivateKey, encryptionPublicKeys[i]);
|
|
194
195
|
}
|
|
195
196
|
|
|
196
197
|
// Process messages in reverse order.
|
|
@@ -205,43 +206,43 @@ template ProcessMessages(
|
|
|
205
206
|
// Start from batchSize and decrement for process in reverse order.
|
|
206
207
|
for (var i = batchSize - 1; i >= 0; i--) {
|
|
207
208
|
// Process as vote type message.
|
|
208
|
-
var
|
|
209
|
-
var
|
|
210
|
-
var
|
|
209
|
+
var computedCurrentStateLeavesPathElements[stateTreeDepth][STATE_TREE_ARITY - 1];
|
|
210
|
+
var computedCurrentBallotPathElements[stateTreeDepth][STATE_TREE_ARITY - 1];
|
|
211
|
+
var computedCurrentVoteWeightsPathElements[voteOptionTreeDepth][VOTE_OPTION_TREE_ARITY - 1];
|
|
211
212
|
|
|
212
213
|
for (var j = 0; j < stateTreeDepth; j++) {
|
|
213
214
|
for (var k = 0; k < STATE_TREE_ARITY - 1; k++) {
|
|
214
|
-
|
|
215
|
-
|
|
215
|
+
computedCurrentStateLeavesPathElements[j][k] = currentStateLeavesPathElements[i][j][k];
|
|
216
|
+
computedCurrentBallotPathElements[j][k] = currentBallotsPathElements[i][j][k];
|
|
216
217
|
}
|
|
217
218
|
}
|
|
218
219
|
|
|
219
220
|
for (var j = 0; j < voteOptionTreeDepth; j++) {
|
|
220
221
|
for (var k = 0; k < VOTE_OPTION_TREE_ARITY - 1; k++) {
|
|
221
|
-
|
|
222
|
+
computedCurrentVoteWeightsPathElements[j][k] = currentVoteWeightsPathElements[i][j][k];
|
|
222
223
|
}
|
|
223
224
|
}
|
|
224
225
|
|
|
225
226
|
(computedNewVoteStateRoot[i], computedNewVoteBallotRoot[i]) = ProcessOne(stateTreeDepth, voteOptionTreeDepth)(
|
|
226
|
-
|
|
227
|
+
totalSignups,
|
|
227
228
|
stateRoots[i + 1],
|
|
228
229
|
ballotRoots[i + 1],
|
|
229
230
|
actualStateTreeDepth,
|
|
230
231
|
currentStateLeaves[i],
|
|
231
|
-
|
|
232
|
+
computedCurrentStateLeavesPathElements,
|
|
232
233
|
currentBallots[i],
|
|
233
|
-
|
|
234
|
+
computedCurrentBallotPathElements,
|
|
234
235
|
currentVoteWeights[i],
|
|
235
|
-
|
|
236
|
+
computedCurrentVoteWeightsPathElements,
|
|
236
237
|
computedCommandsStateIndex[i],
|
|
237
|
-
|
|
238
|
+
computedCommandsNewPublicKey[i],
|
|
238
239
|
computedCommandsVoteOptionIndex[i],
|
|
239
240
|
computedCommandsNewVoteWeight[i],
|
|
240
241
|
computedCommandsNonce[i],
|
|
241
242
|
computedCommandsPollId[i],
|
|
242
243
|
computedCommandsSalt[i],
|
|
243
|
-
|
|
244
|
-
|
|
244
|
+
computedCommandsSignaturePoint[i],
|
|
245
|
+
computedCommandsSignatureScalar[i],
|
|
245
246
|
computedCommandsPackedCommandOut[i],
|
|
246
247
|
voteOptions
|
|
247
248
|
);
|
|
@@ -266,24 +267,24 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
|
|
|
266
267
|
// Constants defining the structure and size of state and ballots.
|
|
267
268
|
var STATE_LEAF_LENGTH = 3;
|
|
268
269
|
var BALLOT_LENGTH = 2;
|
|
269
|
-
var
|
|
270
|
-
var
|
|
270
|
+
var MESSAGE_LENGTH = 10;
|
|
271
|
+
var PACKED_COMMAND_LENGTH = 4;
|
|
271
272
|
var VOTE_OPTION_TREE_ARITY = 5;
|
|
272
273
|
var STATE_TREE_ARITY = 2;
|
|
273
|
-
var
|
|
274
|
-
// Ballot vote option (
|
|
275
|
-
var
|
|
274
|
+
var BALLOT_NONCE_INDEX = 0;
|
|
275
|
+
// Ballot vote option (vote option) root index.
|
|
276
|
+
var BALLOT_VOTE_OPTION_ROOT_INDEX = 1;
|
|
276
277
|
|
|
277
278
|
// Indices for elements within a state leaf.
|
|
278
279
|
// Public key.
|
|
279
|
-
var
|
|
280
|
-
var
|
|
280
|
+
var STATE_LEAF_PUBLIC_X_INDEX = 0;
|
|
281
|
+
var STATE_LEAF_PUBLIC_Y_INDEX = 1;
|
|
281
282
|
// Voice Credit balance.
|
|
282
|
-
var
|
|
283
|
-
var
|
|
283
|
+
var STATE_LEAF_VOICE_CREDIT_BALANCE_INDEX = 2;
|
|
284
|
+
var NUMBER_BITS = 252;
|
|
284
285
|
|
|
285
286
|
// Number of users that have completed the sign up.
|
|
286
|
-
signal input
|
|
287
|
+
signal input totalSignups;
|
|
287
288
|
// The current value of the state tree root.
|
|
288
289
|
signal input currentStateRoot;
|
|
289
290
|
// The current value of the ballot tree root.
|
|
@@ -305,16 +306,16 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
|
|
|
305
306
|
signal input currentVoteWeightsPathElements[voteOptionTreeDepth][VOTE_OPTION_TREE_ARITY - 1];
|
|
306
307
|
|
|
307
308
|
// Inputs related to the command being processed.
|
|
308
|
-
signal input
|
|
309
|
-
signal input
|
|
310
|
-
signal input
|
|
311
|
-
signal input
|
|
312
|
-
signal input
|
|
313
|
-
signal input
|
|
314
|
-
signal input
|
|
315
|
-
signal input
|
|
316
|
-
signal input
|
|
317
|
-
signal input
|
|
309
|
+
signal input commandStateIndex;
|
|
310
|
+
signal input commandPublicKey[2];
|
|
311
|
+
signal input commandVoteOptionIndex;
|
|
312
|
+
signal input commandNewVoteWeight;
|
|
313
|
+
signal input commandNonce;
|
|
314
|
+
signal input commandPollId;
|
|
315
|
+
signal input commandSalt;
|
|
316
|
+
signal input commandSignaturePoint[2];
|
|
317
|
+
signal input commandSignatureScalar;
|
|
318
|
+
signal input packedCommand[PACKED_COMMAND_LENGTH];
|
|
318
319
|
|
|
319
320
|
// The number of valid vote options for the poll.
|
|
320
321
|
signal input voteOptions;
|
|
@@ -325,37 +326,37 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
|
|
|
325
326
|
// Intermediate signals.
|
|
326
327
|
// currentVoteWeight * currentVoteWeight.
|
|
327
328
|
signal currentVoteWeightSquare;
|
|
328
|
-
//
|
|
329
|
-
signal
|
|
330
|
-
// equal to
|
|
331
|
-
signal
|
|
329
|
+
// commandNewVoteWeight * commandNewVoteWeight.
|
|
330
|
+
signal commandNewVoteWeightSquare;
|
|
331
|
+
// equal to newBallotVoteOptionRootMux (Mux1).
|
|
332
|
+
signal newBallotVoteOptionRoot;
|
|
332
333
|
|
|
333
334
|
// 1. Transform a state leaf and a ballot with a command.
|
|
334
335
|
// The result is a new state leaf, a new ballot, and an isValid signal (0 or 1).
|
|
335
|
-
var
|
|
336
|
-
(
|
|
337
|
-
|
|
336
|
+
var computedNewStateLeafPublicKey[2], computedNewBallotNonce, computedIsValid, computedIsStateLeafIndexValid, computedIsVoteOptionIndexValid;
|
|
337
|
+
(computedNewStateLeafPublicKey, computedNewBallotNonce, computedIsValid, computedIsStateLeafIndexValid, computedIsVoteOptionIndexValid) = StateLeafAndBallotTransformer()(
|
|
338
|
+
totalSignups,
|
|
338
339
|
voteOptions,
|
|
339
|
-
[stateLeaf[
|
|
340
|
-
stateLeaf[
|
|
341
|
-
ballot[
|
|
340
|
+
[stateLeaf[STATE_LEAF_PUBLIC_X_INDEX], stateLeaf[STATE_LEAF_PUBLIC_Y_INDEX]],
|
|
341
|
+
stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_INDEX],
|
|
342
|
+
ballot[BALLOT_NONCE_INDEX],
|
|
342
343
|
currentVoteWeight,
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
344
|
+
commandStateIndex,
|
|
345
|
+
commandPublicKey,
|
|
346
|
+
commandVoteOptionIndex,
|
|
347
|
+
commandNewVoteWeight,
|
|
348
|
+
commandNonce,
|
|
349
|
+
commandPollId,
|
|
350
|
+
commandSalt,
|
|
351
|
+
commandSignaturePoint,
|
|
352
|
+
commandSignatureScalar,
|
|
353
|
+
packedCommand
|
|
353
354
|
);
|
|
354
355
|
|
|
355
356
|
// 2. If computedIsStateLeafIndexValid is equal to zero, generate indices for leaf zero.
|
|
356
357
|
// Otherwise, generate indices for command.stateIndex.
|
|
357
|
-
var stateIndexMux = Mux1()([0,
|
|
358
|
-
var computedStateLeafPathIndices[stateTreeDepth] =
|
|
358
|
+
var stateIndexMux = Mux1()([0, commandStateIndex], computedIsStateLeafIndexValid);
|
|
359
|
+
var computedStateLeafPathIndices[stateTreeDepth] = MerklePathIndicesGenerator(stateTreeDepth)(stateIndexMux);
|
|
359
360
|
|
|
360
361
|
// 3. Verify that the original state leaf exists in the given state root.
|
|
361
362
|
var stateLeafHash = PoseidonHasher(3)(stateLeaf);
|
|
@@ -370,8 +371,8 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
|
|
|
370
371
|
|
|
371
372
|
// 4. Verify that the original ballot exists in the given ballot root.
|
|
372
373
|
var computedBallot = PoseidonHasher(2)([
|
|
373
|
-
ballot[
|
|
374
|
-
ballot[
|
|
374
|
+
ballot[BALLOT_NONCE_INDEX],
|
|
375
|
+
ballot[BALLOT_VOTE_OPTION_ROOT_INDEX]
|
|
375
376
|
]);
|
|
376
377
|
|
|
377
378
|
var computedBallotQip = MerkleTreeInclusionProof(stateTreeDepth)(
|
|
@@ -383,54 +384,54 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
|
|
|
383
384
|
computedBallotQip === currentBallotRoot;
|
|
384
385
|
|
|
385
386
|
// 5. Verify that currentVoteWeight exists in the ballot's vote option root
|
|
386
|
-
// at
|
|
387
|
+
// at commandVoteOptionIndex.
|
|
387
388
|
currentVoteWeightSquare <== currentVoteWeight * currentVoteWeight;
|
|
388
|
-
|
|
389
|
+
commandNewVoteWeightSquare <== commandNewVoteWeight * commandNewVoteWeight;
|
|
389
390
|
|
|
390
|
-
var
|
|
391
|
-
var computedCurrentVoteWeightPathIndices[voteOptionTreeDepth] =
|
|
391
|
+
var commandVoteOptionIndexMux = Mux1()([0, commandVoteOptionIndex], computedIsVoteOptionIndexValid);
|
|
392
|
+
var computedCurrentVoteWeightPathIndices[voteOptionTreeDepth] = QuinaryGeneratePathIndices(voteOptionTreeDepth)(commandVoteOptionIndexMux);
|
|
392
393
|
|
|
393
|
-
var computedCurrentVoteWeightQip =
|
|
394
|
+
var computedCurrentVoteWeightQip = QuinaryTreeInclusionProof(voteOptionTreeDepth)(
|
|
394
395
|
currentVoteWeight,
|
|
395
396
|
computedCurrentVoteWeightPathIndices,
|
|
396
397
|
currentVoteWeightsPathElements
|
|
397
398
|
);
|
|
398
399
|
|
|
399
|
-
computedCurrentVoteWeightQip === ballot[
|
|
400
|
+
computedCurrentVoteWeightQip === ballot[BALLOT_VOTE_OPTION_ROOT_INDEX];
|
|
400
401
|
|
|
401
|
-
var voteWeightMux = Mux1()([currentVoteWeight,
|
|
402
|
+
var voteWeightMux = Mux1()([currentVoteWeight, commandNewVoteWeight], computedIsValid);
|
|
402
403
|
var voiceCreditBalanceMux = Mux1()(
|
|
403
404
|
[
|
|
404
|
-
stateLeaf[
|
|
405
|
-
stateLeaf[
|
|
405
|
+
stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_INDEX],
|
|
406
|
+
stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_INDEX] + currentVoteWeightSquare - commandNewVoteWeightSquare
|
|
406
407
|
],
|
|
407
408
|
computedIsValid
|
|
408
409
|
);
|
|
409
410
|
|
|
410
411
|
// 5.1. Update the ballot's vote option root with the new vote weight.
|
|
411
|
-
var computedNewVoteOptionTreeQip =
|
|
412
|
+
var computedNewVoteOptionTreeQip = QuinaryTreeInclusionProof(voteOptionTreeDepth)(
|
|
412
413
|
voteWeightMux,
|
|
413
414
|
computedCurrentVoteWeightPathIndices,
|
|
414
415
|
currentVoteWeightsPathElements
|
|
415
416
|
);
|
|
416
417
|
|
|
417
418
|
// The new vote option root in the ballot
|
|
418
|
-
var
|
|
419
|
-
[ballot[
|
|
419
|
+
var newBallotVoteOptionRootMux = Mux1()(
|
|
420
|
+
[ballot[BALLOT_VOTE_OPTION_ROOT_INDEX], computedNewVoteOptionTreeQip],
|
|
420
421
|
computedIsValid
|
|
421
422
|
);
|
|
422
423
|
|
|
423
|
-
|
|
424
|
+
newBallotVoteOptionRoot <== newBallotVoteOptionRootMux;
|
|
424
425
|
|
|
425
426
|
// 6. Generate a new state root.
|
|
426
|
-
var
|
|
427
|
-
|
|
428
|
-
|
|
427
|
+
var computedNewStateLeafHash = PoseidonHasher(3)([
|
|
428
|
+
computedNewStateLeafPublicKey[STATE_LEAF_PUBLIC_X_INDEX],
|
|
429
|
+
computedNewStateLeafPublicKey[STATE_LEAF_PUBLIC_Y_INDEX],
|
|
429
430
|
voiceCreditBalanceMux
|
|
430
431
|
]);
|
|
431
432
|
|
|
432
433
|
var computedNewStateLeafQip = BinaryMerkleRoot(stateTreeDepth)(
|
|
433
|
-
|
|
434
|
+
computedNewStateLeafHash,
|
|
434
435
|
actualStateTreeDepth,
|
|
435
436
|
computedStateLeafPathIndices,
|
|
436
437
|
stateLeafPathElements
|
|
@@ -439,7 +440,7 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
|
|
|
439
440
|
newStateRoot <== computedNewStateLeafQip;
|
|
440
441
|
|
|
441
442
|
// 7. Generate a new ballot root.
|
|
442
|
-
var computedNewBallot = PoseidonHasher(2)([computedNewBallotNonce,
|
|
443
|
+
var computedNewBallot = PoseidonHasher(2)([computedNewBallotNonce, newBallotVoteOptionRoot]);
|
|
443
444
|
var computedNewBallotQip = MerkleTreeInclusionProof(stateTreeDepth)(
|
|
444
445
|
computedNewBallot,
|
|
445
446
|
computedStateLeafPathIndices,
|