@maci-protocol/circuits 0.0.0-ci.d0dddbc → 0.0.0-ci.d231815
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/build/ts/types.d.ts +2 -2
- package/build/ts/types.d.ts.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/circom/coordinator/full/MessageProcessor.circom +5 -13
- package/circom/coordinator/full/SingleMessageProcessor.circom +3 -4
- package/circom/coordinator/non-qv/MessageProcessor.circom +5 -13
- package/circom/coordinator/non-qv/SingleMessageProcessor.circom +10 -13
- package/circom/coordinator/non-qv/VoteTally.circom +1 -2
- package/circom/coordinator/qv/MessageProcessor.circom +5 -13
- package/circom/coordinator/qv/SingleMessageProcessor.circom +10 -14
- package/circom/coordinator/qv/VoteTally.circom +1 -2
- package/circom/coordinator/qv/VoteTallyWithIndividualCounts.circom +226 -0
- package/circom/utils/EdDSAPoseidonVerifier.circom +8 -3
- package/circom/utils/IsOnCurve.circom +40 -0
- package/circom/utils/full/StateLeafAndBallotTransformer.circom +5 -0
- package/circom/utils/non-qv/StateLeafAndBallotTransformer.circom +5 -0
- package/circom/utils/qv/StateLeafAndBallotTransformer.circom +5 -0
- package/circom/utils/trees/BinaryMerkleRoot.circom +5 -2
- package/circom/voter/PollJoined.circom +3 -3
- package/circom/voter/PollJoining.circom +3 -3
- package/package.json +16 -15
- package/circom/utils/trees/MerklePathIndicesGenerator.circom +0 -44
|
@@ -9,6 +9,7 @@ include "./escalarmulany.circom";
|
|
|
9
9
|
include "./escalarmulfix.circom";
|
|
10
10
|
// local imports
|
|
11
11
|
include "./PoseidonHasher.circom";
|
|
12
|
+
include "./IsOnCurve.circom";
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Variant of the EdDSAPoseidonVerifier template from circomlib
|
|
@@ -37,9 +38,13 @@ template EdDSAPoseidonVerifier() {
|
|
|
37
38
|
// Output signal for the validity of the signature.
|
|
38
39
|
signal output isValid;
|
|
39
40
|
|
|
41
|
+
// Verify the public key and signature point are on the BabyJubJub curve.
|
|
42
|
+
var computedIsPkOnCurve = IsOnCurve()(publicKeyX, publicKeyY);
|
|
43
|
+
var computedIsSpOnCurve = IsOnCurve()(signaturePointX, signaturePointY);
|
|
44
|
+
|
|
40
45
|
// Ensure signatureScalar<Subgroup Order.
|
|
41
46
|
// convert the signature scalar signatureScalar into its binary representation.
|
|
42
|
-
var computedNum2Bits[254] =
|
|
47
|
+
var computedNum2Bits[254] = Num2Bits_strict()(signatureScalar);
|
|
43
48
|
|
|
44
49
|
var computedCompConstantIn[254] = computedNum2Bits;
|
|
45
50
|
computedCompConstantIn[253] = 0;
|
|
@@ -82,10 +87,10 @@ template EdDSAPoseidonVerifier() {
|
|
|
82
87
|
// Components to handle edge cases and ensure that all conditions
|
|
83
88
|
// for a valid signature are met, including the
|
|
84
89
|
// public key not being zero and other integrity checks.
|
|
85
|
-
var computedIsAxZero = IsZero()(
|
|
90
|
+
var computedIsAxZero = IsZero()(computedDouble3XOut);
|
|
86
91
|
var computedIsAxEqual = IsEqual()([computedIsAxZero, 0]);
|
|
87
92
|
var computedIsCcZero = IsZero()(computedCompConstant);
|
|
88
|
-
var computedIsValid = IsEqual()([computedIsLeftRightValid + computedIsAxEqual + computedIsCcZero,
|
|
93
|
+
var computedIsValid = IsEqual()([computedIsLeftRightValid + computedIsAxEqual + computedIsCcZero + computedIsPkOnCurve + computedIsSpOnCurve, 5]);
|
|
89
94
|
|
|
90
95
|
isValid <== computedIsValid;
|
|
91
96
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
pragma circom 2.0.0;
|
|
2
|
+
|
|
3
|
+
// zk-kit imports
|
|
4
|
+
include "./comparators.circom";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Returns 0 or 1 depending on if the point is on the BabyJubJub curve or not. The point is on the
|
|
8
|
+
* BabyJubJub curve if the following equation is true: a*x^2 + y^2 == 1 + d*x^2*y^2
|
|
9
|
+
* This template is identical to the BabyCheck template from circomlib, but it returns 0 or 1
|
|
10
|
+
* instead of having a hard constraint.
|
|
11
|
+
* Based on: https://github.com/iden3/circomlib/blob/master/circuits/babyjub.circom
|
|
12
|
+
*/
|
|
13
|
+
template IsOnCurve() {
|
|
14
|
+
// x coordinate of the point on the BabyJubJub curve.
|
|
15
|
+
signal input x;
|
|
16
|
+
// y coordinate of the point on the BabyJubJub curve.
|
|
17
|
+
signal input y;
|
|
18
|
+
// True when the point (x, y) satisfies the BabyJubJub curve equation.
|
|
19
|
+
signal output isValid;
|
|
20
|
+
|
|
21
|
+
// x^2 and y^2 intermediate values.
|
|
22
|
+
signal x2;
|
|
23
|
+
signal y2;
|
|
24
|
+
// x^2 * y^2 intermediate value.
|
|
25
|
+
signal x2y2;
|
|
26
|
+
|
|
27
|
+
// BabyJubJub curve parameters.
|
|
28
|
+
var a = 168700;
|
|
29
|
+
var d = 168696;
|
|
30
|
+
|
|
31
|
+
// Compute x^2 and y^2.
|
|
32
|
+
x2 <== x * x;
|
|
33
|
+
y2 <== y * y;
|
|
34
|
+
|
|
35
|
+
// Compute x^2 * y^2.
|
|
36
|
+
x2y2 <== x2 * y2;
|
|
37
|
+
|
|
38
|
+
// Check if a*x^2 + y^2 == 1 + d*x^2*y^2.
|
|
39
|
+
isValid <== IsEqual()([a * x2 + y2, 1 + d * x2y2]);
|
|
40
|
+
}
|
|
@@ -119,4 +119,9 @@ template StateLeafAndBallotTransformerFull() {
|
|
|
119
119
|
isValid <== computedIsValid;
|
|
120
120
|
isStateLeafIndexValid <== computedIsStateLeafIndexValid;
|
|
121
121
|
isVoteOptionIndexValid <== computedIsVoteOptionIndexValid;
|
|
122
|
+
|
|
123
|
+
// Constrain commandPollId and commandSalt using dummy squares.
|
|
124
|
+
// This binds the proof to a specific poll and salt.
|
|
125
|
+
signal commandPollIdSquare <== commandPollId * commandPollId;
|
|
126
|
+
signal commandSaltSquared <== commandSalt * commandSalt;
|
|
122
127
|
}
|
|
@@ -102,4 +102,9 @@ template StateLeafAndBallotTransformerNonQv() {
|
|
|
102
102
|
isValid <== computedIsValid;
|
|
103
103
|
isStateLeafIndexValid <== computedIsStateLeafIndexValid;
|
|
104
104
|
isVoteOptionIndexValid <== computedIsVoteOptionIndexValid;
|
|
105
|
+
|
|
106
|
+
// Constrain commandPollId and commandSalt using dummy squares.
|
|
107
|
+
// This binds the proof to a specific poll and salt.
|
|
108
|
+
signal commandPollIdSquare <== commandPollId * commandPollId;
|
|
109
|
+
signal commandSaltSquared <== commandSalt * commandSalt;
|
|
105
110
|
}
|
|
@@ -102,4 +102,9 @@ template StateLeafAndBallotTransformer() {
|
|
|
102
102
|
isValid <== computedIsValid;
|
|
103
103
|
isStateLeafIndexValid <== computedIsStateLeafIndexValid;
|
|
104
104
|
isVoteOptionIndexValid <== computedIsVoteOptionIndexValid;
|
|
105
|
+
|
|
106
|
+
// Constrain commandPollId and commandSalt using dummy squares.
|
|
107
|
+
// This binds the proof to a specific poll and salt.
|
|
108
|
+
signal commandPollIdSquare <== commandPollId * commandPollId;
|
|
109
|
+
signal commandSaltSquared <== commandSalt * commandSalt;
|
|
105
110
|
}
|
|
@@ -25,14 +25,17 @@ template BinaryMerkleRoot(MAX_DEPTH) {
|
|
|
25
25
|
signal input leaf;
|
|
26
26
|
// The depth of the Merkle tree.
|
|
27
27
|
signal input depth;
|
|
28
|
-
// The
|
|
29
|
-
signal input
|
|
28
|
+
// The index of the leaf node in the Merkle tree.
|
|
29
|
+
signal input index;
|
|
30
30
|
// The sibling nodes of the leaf node in the Merkle tree.
|
|
31
31
|
signal input siblings[MAX_DEPTH][1];
|
|
32
32
|
|
|
33
33
|
// The output of the Merkle tree root.
|
|
34
34
|
signal output out;
|
|
35
35
|
|
|
36
|
+
// The indices of the leaf node in the Merkle tree.
|
|
37
|
+
signal indices[MAX_DEPTH] <== Num2Bits(MAX_DEPTH)(index);
|
|
38
|
+
|
|
36
39
|
signal nodes[MAX_DEPTH + 1];
|
|
37
40
|
nodes[0] <== leaf;
|
|
38
41
|
|
|
@@ -19,8 +19,8 @@ template PollJoined(stateTreeDepth) {
|
|
|
19
19
|
signal input voiceCreditsBalance;
|
|
20
20
|
// Path elements
|
|
21
21
|
signal input pathElements[stateTreeDepth][STATE_TREE_ARITY - 1];
|
|
22
|
-
//
|
|
23
|
-
signal input
|
|
22
|
+
// Index
|
|
23
|
+
signal input index;
|
|
24
24
|
// Poll State tree root which proves the user is joined
|
|
25
25
|
signal input stateRoot;
|
|
26
26
|
// The actual tree depth (might be <= stateTreeDepth) Used in BinaryMerkleRoot
|
|
@@ -35,7 +35,7 @@ template PollJoined(stateTreeDepth) {
|
|
|
35
35
|
var calculatedRoot = BinaryMerkleRoot(stateTreeDepth)(
|
|
36
36
|
stateLeaf,
|
|
37
37
|
actualStateTreeDepth,
|
|
38
|
-
|
|
38
|
+
index,
|
|
39
39
|
pathElements
|
|
40
40
|
);
|
|
41
41
|
|
|
@@ -18,8 +18,8 @@ template PollJoining(stateTreeDepth) {
|
|
|
18
18
|
signal input pollPublicKey[2];
|
|
19
19
|
// Siblings
|
|
20
20
|
signal input siblings[stateTreeDepth][STATE_TREE_ARITY - 1];
|
|
21
|
-
//
|
|
22
|
-
signal input
|
|
21
|
+
// Index
|
|
22
|
+
signal input index;
|
|
23
23
|
// User's hashed private key
|
|
24
24
|
signal input nullifier;
|
|
25
25
|
// MACI State tree root which proves the user is signed up
|
|
@@ -46,7 +46,7 @@ template PollJoining(stateTreeDepth) {
|
|
|
46
46
|
var calculatedRoot = BinaryMerkleRoot(stateTreeDepth)(
|
|
47
47
|
publicKeyHash,
|
|
48
48
|
actualStateTreeDepth,
|
|
49
|
-
|
|
49
|
+
index,
|
|
50
50
|
siblings
|
|
51
51
|
);
|
|
52
52
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maci-protocol/circuits",
|
|
3
|
-
"version": "0.0.0-ci.
|
|
3
|
+
"version": "0.0.0-ci.d231815",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "zk-SNARK circuits for MACI",
|
|
6
6
|
"main": "build/ts/index.js",
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
"test:verifySignature": "pnpm run mocha-test ts/__tests__/VerifySignature.test.ts",
|
|
39
39
|
"test:privateToPublicKey": "pnpm run mocha-test ts/__tests__/PrivateToPublicKey.test.ts",
|
|
40
40
|
"test:calculateTotal": "pnpm run mocha-test ts/__tests__/CalculateTotal.test.ts",
|
|
41
|
-
"test:
|
|
41
|
+
"test:messageProcessorFull": "pnpm run mocha-test ts/__tests__/MessageProcessorFull.test.ts",
|
|
42
|
+
"test:isOnCurve": "pnpm run mocha-test ts/__tests__/IsOnCurve.test.ts",
|
|
42
43
|
"test:voteTally": "pnpm run mocha-test ts/__tests__/VoteTally.test.ts",
|
|
43
44
|
"test:ceremonyParams": "pnpm run mocha-test ts/__tests__/CeremonyParams.test.ts",
|
|
44
45
|
"test:incrementalQuinaryTree": "pnpm run mocha-test ts/__tests__/IncrementalQuinaryTree.test.ts",
|
|
@@ -46,29 +47,29 @@
|
|
|
46
47
|
"test:pollJoined": "pnpm run mocha-test ts/__tests__/PollJoined.test.ts"
|
|
47
48
|
},
|
|
48
49
|
"dependencies": {
|
|
49
|
-
"@maci-protocol/core": "0.0.0-ci.
|
|
50
|
-
"@maci-protocol/crypto": "0.0.0-ci.
|
|
51
|
-
"@maci-protocol/domainobjs": "0.0.0-ci.
|
|
52
|
-
"@maci-protocol/sdk": "0.0.0-ci.
|
|
50
|
+
"@maci-protocol/core": "0.0.0-ci.d231815",
|
|
51
|
+
"@maci-protocol/crypto": "0.0.0-ci.d231815",
|
|
52
|
+
"@maci-protocol/domainobjs": "0.0.0-ci.d231815",
|
|
53
|
+
"@maci-protocol/sdk": "0.0.0-ci.d231815",
|
|
53
54
|
"@zk-kit/circuits": "^0.4.0",
|
|
54
|
-
"circomkit": "^0.3.
|
|
55
|
+
"circomkit": "^0.3.4",
|
|
55
56
|
"circomlib": "^2.0.5"
|
|
56
57
|
},
|
|
57
58
|
"devDependencies": {
|
|
58
59
|
"@types/chai": "^4.3.11",
|
|
59
|
-
"@types/chai-as-promised": "^
|
|
60
|
+
"@types/chai-as-promised": "^8.0.2",
|
|
60
61
|
"@types/mocha": "^10.0.10",
|
|
61
|
-
"@types/node": "^24.0
|
|
62
|
+
"@types/node": "^24.11.0",
|
|
62
63
|
"@types/snarkjs": "^0.7.9",
|
|
63
64
|
"@zk-kit/baby-jubjub": "^1.0.3",
|
|
64
65
|
"chai": "^4.3.10",
|
|
65
|
-
"chai-as-promised": "^
|
|
66
|
-
"fast-check": "^4.
|
|
67
|
-
"glob": "^
|
|
68
|
-
"mocha": "^11.
|
|
66
|
+
"chai-as-promised": "^8.0.1",
|
|
67
|
+
"fast-check": "^4.2.0",
|
|
68
|
+
"glob": "^12.0.0",
|
|
69
|
+
"mocha": "^11.7.2",
|
|
69
70
|
"ts-mocha": "^11.1.0",
|
|
70
71
|
"ts-node": "^10.9.1",
|
|
71
|
-
"typescript": "^5.
|
|
72
|
+
"typescript": "^5.9.2"
|
|
72
73
|
},
|
|
73
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "271bc779ccbd8510ae0fcbc43063aacffe39d4d9"
|
|
74
75
|
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
pragma circom 2.0.0;
|
|
2
|
-
|
|
3
|
-
// zk-kit imports
|
|
4
|
-
include "./safe-comparators.circom";
|
|
5
|
-
// local import
|
|
6
|
-
include "../CalculateTotal.circom";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Calculates the path indices required for Merkle proof verifications.
|
|
10
|
-
* Given a node index within an IMT and the total tree levels, it outputs the path indices leading to that node.
|
|
11
|
-
* The template handles the modulo and division operations to break down the tree index into its constituent path indices.
|
|
12
|
-
*/
|
|
13
|
-
template MerklePathIndicesGenerator(levels) {
|
|
14
|
-
// The base used for the modulo and division operations, set to 2 for binary trees.
|
|
15
|
-
var BASE = 2;
|
|
16
|
-
|
|
17
|
-
// The total sum of the path indices.
|
|
18
|
-
signal input indices;
|
|
19
|
-
|
|
20
|
-
// The generated path indices.
|
|
21
|
-
signal output out[levels];
|
|
22
|
-
|
|
23
|
-
var computedIndices = indices;
|
|
24
|
-
var computedResults[levels];
|
|
25
|
-
|
|
26
|
-
for (var i = 0; i < levels; i++) {
|
|
27
|
-
// circom's best practices suggests to avoid using <-- unless you
|
|
28
|
-
// are aware of what's going on. This is the only way to do modulo operation.
|
|
29
|
-
out[i] <-- computedIndices % BASE;
|
|
30
|
-
computedIndices = computedIndices \ BASE;
|
|
31
|
-
|
|
32
|
-
// Check that each output element is less than the base.
|
|
33
|
-
var computedIsOutputElementLessThanBase = SafeLessThan(3)([out[i], BASE]);
|
|
34
|
-
computedIsOutputElementLessThanBase === 1;
|
|
35
|
-
|
|
36
|
-
// Re-compute the total sum.
|
|
37
|
-
computedResults[i] = out[i] * (BASE ** i);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Check that the total sum matches the index.
|
|
41
|
-
var computedCalculateTotal = CalculateTotal(levels)(computedResults);
|
|
42
|
-
|
|
43
|
-
computedCalculateTotal === indices;
|
|
44
|
-
}
|