Skip to content

Commit

Permalink
Merge branch 'dev' into feat/subgraph
Browse files Browse the repository at this point in the history
  • Loading branch information
hangleang authored Feb 21, 2024
2 parents 1199951 + d35c154 commit 368e4be
Show file tree
Hide file tree
Showing 48 changed files with 1,589 additions and 595 deletions.
7 changes: 3 additions & 4 deletions circuits/circom/messageValidator.circom
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ template MessageValidator() {
signal input stateTreeIndex;
// how many signups we have in the state tree
signal input numSignUps;
// we check that the state tree index is <= than the number of signups
// we check that the state tree index is < than the number of signups
// as first validation
// it is <= because the state tree index is 1-based
// it is < because the state tree index is 0-based
// 0 is for blank state leaf then 1 for the first actual user
// which is where the numSignUps starts
component validStateLeafIndex = SafeLessEqThan(252);
component validStateLeafIndex = SafeLessThan(252);
validStateLeafIndex.in[0] <== stateTreeIndex;
validStateLeafIndex.in[1] <== numSignUps;

Expand Down
7 changes: 3 additions & 4 deletions circuits/circom/messageValidatorNonQv.circom
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ template MessageValidatorNonQv() {
signal input stateTreeIndex;
// how many signups we have in the state tree
signal input numSignUps;
// we check that the state tree index is <= than the number of signups
// we check that the state tree index is < than the number of signups
// as first validation
// it is <= because the state tree index is 1-based
// it is < because the state tree index is 0-based
// 0 is for blank state leaf then 1 for the first actual user
// which is where the numSignUps starts
component validStateLeafIndex = SafeLessEqThan(252);
component validStateLeafIndex = SafeLessThan(252);
validStateLeafIndex.in[0] <== stateTreeIndex;
validStateLeafIndex.in[1] <== numSignUps;

Expand Down
49 changes: 38 additions & 11 deletions circuits/circom/processMessages.circom
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ template ProcessMessages(
var STATE_LEAF_PUB_Y_IDX = 1;
var STATE_LEAF_VOICE_CREDIT_BALANCE_IDX = 2;
var STATE_LEAF_TIMESTAMP_IDX = 3;

var N_BITS = 252;

// Note that we sha256 hash some values from the contract, pass in the hash
// as a public input, and pass in said values as private inputs. This saves
Expand Down Expand Up @@ -277,6 +279,7 @@ template ProcessMessages(
component processors[batchSize];
// topup type processor
component processors2[batchSize];

for (var i = batchSize - 1; i >= 0; i --) {
// process it as vote type message
processors[i] = ProcessOne(stateTreeDepth, voteOptionTreeDepth);
Expand Down Expand Up @@ -349,6 +352,7 @@ template ProcessMessages(
<== currentStateLeavesPathElements[i][j][k];
}
}

// pick the correct result by msg type
tmpStateRoot1[i] <== processors[i].newStateRoot * (2 - msgs[i][0]);
tmpStateRoot2[i] <== processors2[i].newStateRoot * (msgs[i][0] - 1);
Expand Down Expand Up @@ -378,6 +382,8 @@ template ProcessTopup(stateTreeDepth) {
var STATE_LEAF_VOICE_CREDIT_BALANCE_IDX = 2;
var STATE_LEAF_TIMESTAMP_IDX = 3;

var N_BITS = 252;

signal input msgType;
signal input stateTreeIndex;
signal input amount;
Expand All @@ -395,9 +401,9 @@ template ProcessTopup(stateTreeDepth) {
// msgType of topup command is 2
amt <== amount * (msgType - 1);
index <== stateTreeIndex * (msgType - 1);
component validCreditBalance = LessEqThan(252);
component validCreditBalance = LessEqThan(N_BITS);
// check stateIndex, if invalid index, set index and amount to zero
component validStateLeafIndex = LessEqThan(252);
component validStateLeafIndex = LessEqThan(N_BITS);
validStateLeafIndex.in[0] <== index;
validStateLeafIndex.in[1] <== numSignUps;

Expand Down Expand Up @@ -462,6 +468,8 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
var STATE_LEAF_VOICE_CREDIT_BALANCE_IDX = 2;
var STATE_LEAF_TIMESTAMP_IDX = 3;

var N_BITS = 252;

signal input msgType;
signal input numSignUps;
signal input maxVoteOptions;
Expand Down Expand Up @@ -526,22 +534,34 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {

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

component stateIndexMux = Mux1();
stateIndexMux.s <== transformer.isValid + msgType - 1;
stateIndexMux.c[0] <== 0;
stateIndexMux.c[1] <== indexByType;
// we can validate if the state index is within the numSignups
// if not, we use 0
// this is because decryption of an invalid message
// might result in random packed vals
component validStateLeafIndex = SafeLessThan(N_BITS);
validStateLeafIndex.in[0] <== indexByType;
validStateLeafIndex.in[1] <== numSignUps;

component stateLeafPathIndices = QuinGeneratePathIndices(stateTreeDepth);
stateLeafPathIndices.in <== stateIndexMux.out;
// use a mux to pick the correct index
component indexMux = Mux1();
indexMux.s <== validStateLeafIndex.out;
indexMux.c[0] <== 0;
indexMux.c[1] <== indexByType;

// @note that we expect a coordinator to send the state leaf corresponding to a message
// which specifies a valid state index. If this is not the case, the
// proof will fail to generate.
component stateLeafPathIndices = QuinGeneratePathIndices(stateTreeDepth);
stateLeafPathIndices.in <== indexMux.out;

// -----------------------------------------------------------------------
// 3. Verify that the original state leaf exists in the given state root
component stateLeafQip = QuinTreeInclusionProof(stateTreeDepth);
Expand Down Expand Up @@ -572,6 +592,7 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
ballotQip.path_elements[i][j] <== ballotPathElements[i][j];
}
}

ballotQip.root === currentBallotRoot;

// -----------------------------------------------------------------------
Expand All @@ -583,7 +604,7 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
b <== currentVoteWeight * currentVoteWeight;
c <== cmdNewVoteWeight * cmdNewVoteWeight;

component enoughVoiceCredits = SafeGreaterEqThan(252);
component enoughVoiceCredits = SafeGreaterEqThan(N_BITS);
enoughVoiceCredits.in[0] <== stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_IDX] + b;
enoughVoiceCredits.in[1] <== c;

Expand All @@ -592,8 +613,14 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
isMessageValid.in[0] <== bothValid;
isMessageValid.in[1] <== transformer.isValid + enoughVoiceCredits.out;

// check that the vote option index is < maxVoteOptions (0-indexed)
component validVoteOptionIndex = SafeLessThan(N_BITS);
validVoteOptionIndex.in[0] <== cmdVoteOptionIndex;
validVoteOptionIndex.in[1] <== maxVoteOptions;

// @note pick the correct vote option index based on whether the index is < max vote options
component cmdVoteOptionIndexMux = Mux1();
cmdVoteOptionIndexMux.s <== isMessageValid.out;
cmdVoteOptionIndexMux.s <== validVoteOptionIndex.out;
cmdVoteOptionIndexMux.c[0] <== 0;
cmdVoteOptionIndexMux.c[1] <== cmdVoteOptionIndex;

Expand Down
38 changes: 30 additions & 8 deletions circuits/circom/processMessagesNonQv.circom
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ template ProcessMessagesNonQv(
var STATE_LEAF_PUB_Y_IDX = 1;
var STATE_LEAF_VOICE_CREDIT_BALANCE_IDX = 2;
var STATE_LEAF_TIMESTAMP_IDX = 3;

var N_BITS = 252;

// Note that we sha256 hash some values from the contract, pass in the hash
// as a public input, and pass in said values as private inputs. This saves
Expand Down Expand Up @@ -389,6 +391,8 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {
var STATE_LEAF_VOICE_CREDIT_BALANCE_IDX = 2;
var STATE_LEAF_TIMESTAMP_IDX = 3;

var N_BITS = 252;

signal input msgType;
signal input numSignUps;
signal input maxVoteOptions;
Expand Down Expand Up @@ -461,13 +465,25 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {
tmpIndex2 <== topupStateIndex * (msgType - 1);
indexByType <== tmpIndex1 + tmpIndex2;

component stateIndexMux = Mux1();
stateIndexMux.s <== transformer.isValid + msgType - 1;
stateIndexMux.c[0] <== 0;
stateIndexMux.c[1] <== indexByType;

// we can validate if the state index is within the numSignups
// if not, we use 0
// this is because decryption of an invalid message
// might result in random packed vals
component validStateLeafIndex = SafeLessThan(N_BITS);
validStateLeafIndex.in[0] <== indexByType;
validStateLeafIndex.in[1] <== numSignUps;

// use a mux to pick the correct index
component indexMux = Mux1();
indexMux.s <== validStateLeafIndex.out;
indexMux.c[0] <== 0;
indexMux.c[1] <== indexByType;

// @note that we expect a coordinator to send the state leaf corresponding to a message
// which specifies a valid state index. If this is not the case, the
// proof will fail to generate.
component stateLeafPathIndices = QuinGeneratePathIndices(stateTreeDepth);
stateLeafPathIndices.in <== stateIndexMux.out;
stateLeafPathIndices.in <== indexMux.out;

// -----------------------------------------------------------------------
// 3. Verify that the original state leaf exists in the given state root
Expand Down Expand Up @@ -510,7 +526,7 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {
b <== currentVoteWeight;
c <== cmdNewVoteWeight;

component enoughVoiceCredits = SafeGreaterEqThan(252);
component enoughVoiceCredits = SafeGreaterEqThan(N_BITS);
enoughVoiceCredits.in[0] <== stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_IDX] + b;
enoughVoiceCredits.in[1] <== c;

Expand All @@ -519,8 +535,14 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {
isMessageValid.in[0] <== bothValid;
isMessageValid.in[1] <== transformer.isValid + enoughVoiceCredits.out;

// check that the vote option index is < maxVoteOptions (0-indexed)
component validVoteOptionIndex = SafeLessThan(N_BITS);
validVoteOptionIndex.in[0] <== cmdVoteOptionIndex;
validVoteOptionIndex.in[1] <== maxVoteOptions;

// @note pick the correct vote option index based on whether the index is < max vote options
component cmdVoteOptionIndexMux = Mux1();
cmdVoteOptionIndexMux.s <== isMessageValid.out;
cmdVoteOptionIndexMux.s <== validVoteOptionIndex.out;
cmdVoteOptionIndexMux.c[0] <== 0;
cmdVoteOptionIndexMux.c[1] <== cmdVoteOptionIndex;

Expand Down
2 changes: 1 addition & 1 deletion circuits/circom/stateLeafAndBallotTransformer.circom
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ template StateLeafAndBallotTransformer() {
messageValidator.voteWeight <== cmdNewVoteWeight;

// if the message is valid then we swap out the public key
// we have to do this in two Mux one for pucKey[0]
// we have to do this in two Mux one for pubKey[0]
// and one for pubKey[1]
component newSlPubKey0Mux = Mux1();
newSlPubKey0Mux.s <== messageValidator.isValid;
Expand Down
2 changes: 1 addition & 1 deletion circuits/circom/stateLeafAndBallotTransformerNonQv.circom
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ template StateLeafAndBallotTransformerNonQv() {
messageValidator.voteWeight <== cmdNewVoteWeight;

// if the message is valid then we swap out the public key
// we have to do this in two Mux one for pucKey[0]
// we have to do this in two Mux one for pubKey[0]
// and one for pubKey[1]
component newSlPubKey0Mux = Mux1();
newSlPubKey0Mux.s <== messageValidator.isValid;
Expand Down
4 changes: 2 additions & 2 deletions circuits/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
},
"dependencies": {
"@zk-kit/circuits": "^0.3.0",
"circomkit": "^0.0.22",
"circomkit": "^0.0.24",
"circomlib": "^2.0.5",
"maci-core": "^1.1.2",
"maci-crypto": "^1.1.2",
Expand All @@ -50,7 +50,7 @@
"@types/chai": "^4.3.11",
"@types/chai-as-promised": "^7.1.8",
"@types/mocha": "^10.0.6",
"@types/node": "^20.11.17",
"@types/node": "^20.11.19",
"chai": "^4.3.10",
"chai-as-promised": "^7.1.1",
"mocha": "^10.3.0",
Expand Down
Loading

0 comments on commit 368e4be

Please sign in to comment.