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