Skip to content

Commit

Permalink
refactor(topup): remove the topup feature
Browse files Browse the repository at this point in the history
remove the topup feature until a more appropriate design is proposed. Currently the feature is not
used in production and adds unnecessary complexity to the code. A re-design is necessary to make it
an effective feature.

BREAKING CHANGE: No more topups
  • Loading branch information
ctrlc03 committed May 4, 2024
1 parent 553995a commit d3cab94
Show file tree
Hide file tree
Showing 56 changed files with 250 additions and 1,477 deletions.
51 changes: 9 additions & 42 deletions circuits/circom/core/non-qv/processMessages.circom
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ include "../../utils/hashers.circom";
include "../../utils/messageToCommand.circom";
include "../../utils/privToPubKey.circom";
include "../../utils/processMessagesInputHasher.circom";
include "../../utils/processTopup.circom";
include "../../utils/non-qv/stateLeafAndBallotTransformer.circom";
include "../../trees/incrementalMerkleTree.circom";
include "../../trees/incrementalQuinaryTree.circom";

/**
Expand All @@ -36,7 +36,7 @@ include "../../trees/incrementalQuinaryTree.circom";
// Default for Binary trees.
var STATE_TREE_ARITY = 2;
var batchSize = MESSAGE_TREE_ARITY ** msgBatchDepth;
var MSG_LENGTH = 11;
var MSG_LENGTH = 10;
var PACKED_CMD_LENGTH = 4;
var STATE_LEAF_LENGTH = 4;
var BALLOT_LENGTH = 2;
Expand Down Expand Up @@ -292,7 +292,6 @@ include "../../trees/incrementalQuinaryTree.circom";
}

(computedNewVoteStateRoot[i], computedNewVoteBallotRoot[i]) = ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth)(
msgs[i][0],
numSignUps,
maxVoteOptions,
pollEndTimestamp,
Expand All @@ -306,7 +305,6 @@ include "../../trees/incrementalQuinaryTree.circom";
currentVoteWeights[i],
currentVoteWeightsPathElement,
computedCommandsStateIndex[i],
msgs[i][1],
computedCommandsNewPubKey[i],
computedCommandsVoteOptionIndex[i],
computedCommandsNewVoteWeight[i],
Expand All @@ -318,27 +316,8 @@ include "../../trees/incrementalQuinaryTree.circom";
computedCommandsPackedCommandOut[i]
);

// Process as topup type message.
computedNewTopupStateRoot[i] = ProcessTopup(stateTreeDepth)(
msgs[i][0],
msgs[i][1],
msgs[i][2],
numSignUps,
actualStateTreeDepth,
currentStateLeaves[i],
currentStateLeavesPathElement
);

// Pick the correct result by Message type.
tmpStateRoot1[i] <== computedNewVoteStateRoot[i] * (2 - msgs[i][0]);
tmpStateRoot2[i] <== computedNewTopupStateRoot[i] * (msgs[i][0] - 1);

tmpBallotRoot1[i] <== computedNewVoteBallotRoot[i] * (2 - msgs[i][0]);
tmpBallotRoot2[i] <== ballotRoots[i + 1] * (msgs[i][0] - 1);

stateRoots[i] <== tmpStateRoot1[i] + tmpStateRoot2[i];

ballotRoots[i] <== tmpBallotRoot1[i] + tmpBallotRoot2[i];
stateRoots[i] <== computedNewVoteStateRoot[i];
ballotRoots[i] <== computedNewVoteBallotRoot[i];
}

var computedNewSbCommitment = PoseidonHasher(3)([stateRoots[0], ballotRoots[0], newSbSalt]);
Expand All @@ -357,7 +336,7 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {
// Constants defining the structure and size of state and ballots.
var STATE_LEAF_LENGTH = 4;
var BALLOT_LENGTH = 2;
var MSG_LENGTH = 11;
var MSG_LENGTH = 10;
var PACKED_CMD_LENGTH = 4;
var MESSAGE_TREE_ARITY = 5;
var STATE_TREE_ARITY = 2;
Expand All @@ -376,7 +355,6 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {
var N_BITS = 252;

// Inputs representing the message and the current state.
signal input msgType;
signal input numSignUps;
signal input maxVoteOptions;
signal input pollEndTimestamp;
Expand All @@ -403,7 +381,6 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {

// Inputs related to the command being processed.
signal input cmdStateIndex;
signal input topupStateIndex;
signal input cmdNewPubKey[2];
signal input cmdVoteOptionIndex;
signal input cmdNewVoteWeight;
Expand All @@ -418,12 +395,6 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {
signal output newBallotRoot;

// Intermediate signals.
// cmdStateIndex * (2 - msgType).
signal tmpIndex1;
// topupStateIndex * (msgType - 1).
signal tmpIndex2;
// sum of tmpIndex1 + tmpIndex2.
signal indexByType;
// currentVoteWeight * currentVoteWeight.
signal b;
// cmdNewVoteWeight * cmdNewVoteWeight.
Expand Down Expand Up @@ -455,14 +426,10 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {
packedCmd
);

// 2. If msgType and isValid are equal to zero, generate indices for leaf zero.
// Otherwise, generate indices for commmand.stateIndex or topupStateIndex depending on msgType.
tmpIndex1 <== cmdStateIndex * (2 - msgType);
tmpIndex2 <== topupStateIndex * (msgType - 1);
indexByType <== tmpIndex1 + tmpIndex2;

var stateLeafIndexValid = SafeLessThan(N_BITS)([indexByType, numSignUps]);
var stateIndexMux = Mux1()([0, indexByType], stateLeafIndexValid);
// 2. If isValid is equal to zero, generate indices for leaf zero.
// Otherwise, generate indices for commmand.stateIndex.
var stateLeafIndexValid = SafeLessThan(N_BITS)([cmdStateIndex, numSignUps]);
var stateIndexMux = Mux1()([0, cmdStateIndex], stateLeafIndexValid);
var computedStateLeafPathIndices[stateTreeDepth] = MerkleGeneratePathIndices(stateTreeDepth)(stateIndexMux);

// 3. Verify that the original state leaf exists in the given state root.
Expand Down
54 changes: 8 additions & 46 deletions circuits/circom/core/qv/processMessages.circom
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ include "../../utils/hashers.circom";
include "../../utils/messageToCommand.circom";
include "../../utils/privToPubKey.circom";
include "../../utils/processMessagesInputHasher.circom";
include "../../utils/processTopup.circom";
include "../../utils/qv/stateLeafAndBallotTransformer.circom";
include "../../trees/incrementalQuinaryTree.circom";
include "../../trees/incrementalMerkleTree.circom";
Expand Down Expand Up @@ -37,7 +36,7 @@ template ProcessMessages(
// Default for binary trees.
var STATE_TREE_ARITY = 2;
var batchSize = MESSAGE_TREE_ARITY ** msgBatchDepth;
var MSG_LENGTH = 11;
var MSG_LENGTH = 10;
var PACKED_CMD_LENGTH = 4;
var STATE_LEAF_LENGTH = 4;
var BALLOT_LENGTH = 2;
Expand Down Expand Up @@ -123,10 +122,6 @@ template ProcessMessages(
// signals (for processing purposes).
signal stateRoots[batchSize + 1];
signal ballotRoots[batchSize + 1];
signal tmpStateRoot1[batchSize];
signal tmpStateRoot2[batchSize];
signal tmpBallotRoot1[batchSize];
signal tmpBallotRoot2[batchSize];

// Must verify the current sb commitment.
var computedCurrentSbCommitment = PoseidonHasher(3)([currentStateRoot, currentBallotRoot, currentSbSalt]);
Expand Down Expand Up @@ -292,7 +287,6 @@ template ProcessMessages(
}

(computedNewVoteStateRoot[i], computedNewVoteBallotRoot[i]) = ProcessOne(stateTreeDepth, voteOptionTreeDepth)(
msgs[i][0],
numSignUps,
maxVoteOptions,
pollEndTimestamp,
Expand All @@ -306,7 +300,6 @@ template ProcessMessages(
currentVoteWeights[i],
currentVoteWeightsPathElement,
computedCommandsStateIndex[i],
msgs[i][1],
computedCommandsNewPubKey[i],
computedCommandsVoteOptionIndex[i],
computedCommandsNewVoteWeight[i],
Expand All @@ -318,27 +311,8 @@ template ProcessMessages(
computedCommandsPackedCommandOut[i]
);

// Process as topup type message.
computedNewTopupStateRoot[i] = ProcessTopup(stateTreeDepth)(
msgs[i][0],
msgs[i][1],
msgs[i][2],
numSignUps,
actualStateTreeDepth,
currentStateLeaves[i],
currentStateLeavesPathElement
);

// Pick the correct result by Message type.
tmpStateRoot1[i] <== computedNewVoteStateRoot[i] * (2 - msgs[i][0]);
tmpStateRoot2[i] <== computedNewTopupStateRoot[i] * (msgs[i][0] - 1);

tmpBallotRoot1[i] <== computedNewVoteBallotRoot[i] * (2 - msgs[i][0]);
tmpBallotRoot2[i] <== ballotRoots[i + 1] * (msgs[i][0] - 1);

stateRoots[i] <== tmpStateRoot1[i] + tmpStateRoot2[i];

ballotRoots[i] <== tmpBallotRoot1[i] + tmpBallotRoot2[i];
stateRoots[i] <== computedNewVoteStateRoot[i];
ballotRoots[i] <== computedNewVoteBallotRoot[i];
}

var computedNewSbCommitment = PoseidonHasher(3)([stateRoots[0], ballotRoots[0], newSbSalt]);
Expand All @@ -357,7 +331,7 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
// Constants defining the structure and size of state and ballots.
var STATE_LEAF_LENGTH = 4;
var BALLOT_LENGTH = 2;
var MSG_LENGTH = 11;
var MSG_LENGTH = 10;
var PACKED_CMD_LENGTH = 4;
var MESSAGE_TREE_ARITY = 5;
var STATE_TREE_ARITY = 2;
Expand All @@ -376,7 +350,6 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
var N_BITS = 252;

// Inputs representing the message and the current state.
signal input msgType;
signal input numSignUps;
signal input maxVoteOptions;
signal input pollEndTimestamp;
Expand All @@ -403,7 +376,6 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {

// Inputs related to the command being processed.
signal input cmdStateIndex;
signal input topupStateIndex;
signal input cmdNewPubKey[2];
signal input cmdVoteOptionIndex;
signal input cmdNewVoteWeight;
Expand All @@ -418,12 +390,6 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
signal output newBallotRoot;

// Intermediate signals.
// cmdStateIndex * (2 - msgType).
signal tmpIndex1;
// topupStateIndex * (msgType - 1).
signal tmpIndex2;
// sum of tmpIndex1 + tmpIndex2.
signal indexByType;
// currentVoteWeight * currentVoteWeight.
signal b;
// cmdNewVoteWeight * cmdNewVoteWeight.
Expand Down Expand Up @@ -455,14 +421,10 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
packedCmd
);

// 2. If msgType and isValid are equal to zero, generate indices for leaf zero.
// Otherwise, generate indices for commmand.stateIndex or topupStateIndex depending on msgType.
tmpIndex1 <== cmdStateIndex * (2 - msgType);
tmpIndex2 <== topupStateIndex * (msgType - 1);
indexByType <== tmpIndex1 + tmpIndex2;

var stateLeafIndexValid = SafeLessThan(N_BITS)([indexByType, numSignUps]);
var stateIndexMux = Mux1()([0, indexByType], stateLeafIndexValid);
// 2. If isValid is equal to zero, generate indices for leaf zero.
// Otherwise, generate indices for commmand.stateIndex.
var stateLeafIndexValid = SafeLessThan(N_BITS)([cmdStateIndex, numSignUps]);
var stateIndexMux = Mux1()([0, cmdStateIndex], stateLeafIndexValid);
var computedStateLeafPathIndices[stateTreeDepth] = MerkleGeneratePathIndices(stateTreeDepth)(stateIndexMux);

// 3. Verify that the original state leaf exists in the given state root.
Expand Down
22 changes: 10 additions & 12 deletions circuits/circom/utils/hashers.circom
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,21 @@ template PoseidonHasher(n) {

/**
* Hashes a MACI message and the public key used for message encryption.
* This template processes 11 message inputs and a 2-element public key
* This template processes 10 message inputs and a 2-element public key
* combining them using the Poseidon hash function. The hashing process involves two stages:
* 1. hashing message parts in groups of five and,
* 2. hashing the grouped results alongside the first message input and
* the encryption public key to produce a final hash output.
*/
template MessageHasher() {
// 11 inputs are the MACI message.
signal input in[11];
// The MACI message is composed of 10 parts.
signal input in[10];
// the public key used to encrypt the message.
signal input encPubKey[2];
// we output an hash.
signal output hash;

// Hasher5(
// in[0]
// Hasher4(
// Hasher5_1(in[1], in[2], in[3], in[4], in[5]),
// Hasher5_2(in[6], in[7], in[8], in[9], in[10])
// in[11],
Expand All @@ -94,24 +93,23 @@ template MessageHasher() {

var computedHasher5_1;
computedHasher5_1 = PoseidonHasher(5)([
in[0],
in[1],
in[2],
in[3],
in[4],
in[5]
in[4]
]);

var computedHasher5_2;
computedHasher5_2 = PoseidonHasher(5)([
in[6],
in[5],
in[6],
in[7],
in[8],
in[9],
in[10]
in[9]
]);

hash <== PoseidonHasher(5)([
in[0],
hash <== PoseidonHasher(4)([
computedHasher5_1,
computedHasher5_2,
encPubKey[0],
Expand Down
10 changes: 5 additions & 5 deletions circuits/circom/utils/messageToCommand.circom
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ template MessageToCommand() {
var UNPACKED_CMD_LENGTH = 8;
var UNPACK_ELEM_LENGTH = 5;
var DECRYPTED_LENGTH = 9;
var MESSAGE_PARTS = 11;
var MESSAGE_PARTS = 10;

// The message is an array of 11 parts.
// The message is an array of 10 parts.
signal input message[MESSAGE_PARTS];
signal input encPrivKey;
signal input encPubKey[2];
Expand All @@ -48,9 +48,9 @@ template MessageToCommand() {
var computedDecryptor[DECRYPTED_LENGTH] = PoseidonDecryptWithoutCheck(MSG_LENGTH)(
[
// nb. the first one is the msg type => skip.
message[1], message[2], message[3], message[4],
message[5], message[6], message[7], message[8],
message[9], message[10]
message[0], message[1], message[2], message[3],
message[4], message[5], message[6], message[7],
message[8], message[9]
],
0,
computedEcdh
Expand Down
Loading

0 comments on commit d3cab94

Please sign in to comment.