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