@semaphore-protocol/contracts 3.1.0 → 3.2.0

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/README.md CHANGED
@@ -34,7 +34,7 @@
34
34
  🔎 Issues
35
35
  </a>
36
36
  <span>&nbsp;&nbsp;|&nbsp;&nbsp;</span>
37
- <a href="https://discord.gg/6mSdGHnstH">
37
+ <a href="https://semaphore.appliedzkp.org/discord">
38
38
  🗣️ Chat &amp; Support
39
39
  </a>
40
40
  </h4>
@@ -111,6 +111,9 @@ If you want to deploy your contract in a specific network you can set up the `DE
111
111
 
112
112
  ```bash
113
113
  yarn deploy:semaphore --network goerli
114
+ yarn deploy:semaphore --network sepolia
115
+ yarn deploy:semaphore --network mumbai
116
+ yarn deploy:semaphore --network optimism-goerli
114
117
  yarn deploy:semaphore --network arbitrum
115
118
  ```
116
119
 
package/base/Pairing.sol CHANGED
@@ -9,7 +9,7 @@
9
9
  pragma solidity ^0.8.4;
10
10
 
11
11
  library Pairing {
12
- error Semaphore__InvalidProof();
12
+ error InvalidProof();
13
13
 
14
14
  // The prime q in the base field F_q for G1
15
15
  uint256 constant BASE_MODULUS = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
@@ -56,7 +56,7 @@ library Pairing {
56
56
 
57
57
  // Validate input or revert
58
58
  if (p.X >= BASE_MODULUS || p.Y >= BASE_MODULUS) {
59
- revert Semaphore__InvalidProof();
59
+ revert InvalidProof();
60
60
  }
61
61
 
62
62
  // We know p.Y > 0 and p.Y < BASE_MODULUS.
@@ -82,7 +82,7 @@ library Pairing {
82
82
  }
83
83
 
84
84
  if (!success) {
85
- revert Semaphore__InvalidProof();
85
+ revert InvalidProof();
86
86
  }
87
87
  }
88
88
 
@@ -92,7 +92,7 @@ library Pairing {
92
92
  // By EIP-196 the values p.X and p.Y are verified to less than the BASE_MODULUS and
93
93
  // form a valid point on the curve. But the scalar is not verified, so we do that explicitelly.
94
94
  if (s >= SCALAR_MODULUS) {
95
- revert Semaphore__InvalidProof();
95
+ revert InvalidProof();
96
96
  }
97
97
 
98
98
  uint256[3] memory input;
@@ -109,7 +109,7 @@ library Pairing {
109
109
  }
110
110
 
111
111
  if (!success) {
112
- revert Semaphore__InvalidProof();
112
+ revert InvalidProof();
113
113
  }
114
114
  }
115
115
 
@@ -120,7 +120,7 @@ library Pairing {
120
120
  // By EIP-197 all input is verified to be less than the BASE_MODULUS and form elements in their
121
121
  // respective groups of the right order.
122
122
  if (p1.length != p2.length) {
123
- revert Semaphore__InvalidProof();
123
+ revert InvalidProof();
124
124
  }
125
125
 
126
126
  uint256 elements = p1.length;
@@ -145,7 +145,7 @@ library Pairing {
145
145
  }
146
146
 
147
147
  if (!success || out[0] != 1) {
148
- revert Semaphore__InvalidProof();
148
+ revert InvalidProof();
149
149
  }
150
150
  }
151
151
  }
package/package.json CHANGED
@@ -1,35 +1,35 @@
1
1
  {
2
- "name": "@semaphore-protocol/contracts",
3
- "version": "3.1.0",
4
- "description": "Semaphore contracts to manage groups and broadcast anonymous signals.",
5
- "license": "MIT",
6
- "files": [
7
- "**/*.sol"
8
- ],
9
- "keywords": [
10
- "blockchain",
11
- "ethereum",
12
- "hardhat",
13
- "smart-contracts",
14
- "semaphore",
15
- "identity",
16
- "solidity",
17
- "zero-knowledge",
18
- "zk-snarks",
19
- "zero-knowledge-proofs",
20
- "circom",
21
- "proof-of-membership"
22
- ],
23
- "repository": "https://github.com/semaphore-protocol/semaphore",
24
- "homepage": "https://github.com/semaphore-protocol/semaphore/tree/main/packages/contracts",
25
- "bugs": {
26
- "url": "https://github.com/semaphore-protocol/semaphore.git/issues"
27
- },
28
- "publishConfig": {
29
- "access": "public"
30
- },
31
- "dependencies": {
32
- "@openzeppelin/contracts": "4.7.3",
33
- "@zk-kit/incremental-merkle-tree.sol": "1.3.3"
34
- }
35
- }
2
+ "name": "@semaphore-protocol/contracts",
3
+ "version": "3.2.0",
4
+ "description": "Semaphore contracts to manage groups and broadcast anonymous signals.",
5
+ "license": "MIT",
6
+ "files": [
7
+ "**/*.sol"
8
+ ],
9
+ "keywords": [
10
+ "blockchain",
11
+ "ethereum",
12
+ "hardhat",
13
+ "smart-contracts",
14
+ "semaphore",
15
+ "identity",
16
+ "solidity",
17
+ "zero-knowledge",
18
+ "zk-snarks",
19
+ "zero-knowledge-proofs",
20
+ "circom",
21
+ "proof-of-membership"
22
+ ],
23
+ "repository": "https://github.com/semaphore-protocol/semaphore",
24
+ "homepage": "https://github.com/semaphore-protocol/semaphore/tree/main/packages/contracts",
25
+ "bugs": {
26
+ "url": "https://github.com/semaphore-protocol/semaphore.git/issues"
27
+ },
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "dependencies": {
32
+ "@openzeppelin/contracts": "4.7.3",
33
+ "@zk-kit/incremental-merkle-tree.sol": "1.3.3"
34
+ }
35
+ }
package/Semaphore.sol DELETED
@@ -1,193 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity 0.8.4;
3
-
4
- import "./interfaces/ISemaphore.sol";
5
- import "./interfaces/ISemaphoreVerifier.sol";
6
- import "./base/SemaphoreGroups.sol";
7
-
8
- /// @title Semaphore
9
- /// @dev This contract uses the Semaphore base contracts to provide a complete service
10
- /// to allow admins to create and manage groups and their members to generate Semaphore proofs
11
- /// and verify them. Group admins can add, update or remove group members, and can be
12
- /// an Ethereum account or a smart contract. This contract also assigns each new Merkle tree
13
- /// generated with a new root a duration (or an expiry) within which the proofs generated with that root
14
- /// can be validated.
15
- contract Semaphore is ISemaphore, SemaphoreGroups {
16
- ISemaphoreVerifier public verifier;
17
-
18
- /// @dev Gets a group id and returns the group parameters.
19
- mapping(uint256 => Group) public groups;
20
-
21
- /// @dev Checks if the group admin is the transaction sender.
22
- /// @param groupId: Id of the group.
23
- modifier onlyGroupAdmin(uint256 groupId) {
24
- if (groups[groupId].admin != _msgSender()) {
25
- revert Semaphore__CallerIsNotTheGroupAdmin();
26
- }
27
- _;
28
- }
29
-
30
- /// @dev Checks if there is a verifier for the given tree depth.
31
- /// @param merkleTreeDepth: Depth of the tree.
32
- modifier onlySupportedMerkleTreeDepth(uint256 merkleTreeDepth) {
33
- if (merkleTreeDepth < 16 || merkleTreeDepth > 32) {
34
- revert Semaphore__MerkleTreeDepthIsNotSupported();
35
- }
36
- _;
37
- }
38
-
39
- /// @dev Initializes the Semaphore verifier used to verify the user's ZK proofs.
40
- /// @param _verifier: Semaphore verifier address.
41
- constructor(ISemaphoreVerifier _verifier) {
42
- verifier = _verifier;
43
- }
44
-
45
- /// @dev See {ISemaphore-createGroup}.
46
- function createGroup(
47
- uint256 groupId,
48
- uint256 merkleTreeDepth,
49
- address admin
50
- ) external override onlySupportedMerkleTreeDepth(merkleTreeDepth) {
51
- _createGroup(groupId, merkleTreeDepth);
52
-
53
- groups[groupId].admin = admin;
54
- groups[groupId].merkleTreeDuration = 1 hours;
55
-
56
- emit GroupAdminUpdated(groupId, address(0), admin);
57
- }
58
-
59
- /// @dev See {ISemaphore-createGroup}.
60
- function createGroup(
61
- uint256 groupId,
62
- uint256 merkleTreeDepth,
63
- address admin,
64
- uint256 merkleTreeDuration
65
- ) external override onlySupportedMerkleTreeDepth(merkleTreeDepth) {
66
- _createGroup(groupId, merkleTreeDepth);
67
-
68
- groups[groupId].admin = admin;
69
- groups[groupId].merkleTreeDuration = merkleTreeDuration;
70
-
71
- emit GroupAdminUpdated(groupId, address(0), admin);
72
- }
73
-
74
- /// @dev See {ISemaphore-updateGroupAdmin}.
75
- function updateGroupAdmin(uint256 groupId, address newAdmin) external override onlyGroupAdmin(groupId) {
76
- groups[groupId].admin = newAdmin;
77
-
78
- emit GroupAdminUpdated(groupId, _msgSender(), newAdmin);
79
- }
80
-
81
- /// @dev See {ISemaphore-updateGroupMerkleTreeDuration}.
82
- function updateGroupMerkleTreeDuration(uint256 groupId, uint256 newMerkleTreeDuration)
83
- external
84
- override
85
- onlyGroupAdmin(groupId)
86
- {
87
- uint256 oldMerkleTreeDuration = groups[groupId].merkleTreeDuration;
88
-
89
- groups[groupId].merkleTreeDuration = newMerkleTreeDuration;
90
-
91
- emit GroupMerkleTreeDurationUpdated(groupId, oldMerkleTreeDuration, newMerkleTreeDuration);
92
- }
93
-
94
- /// @dev See {ISemaphore-addMember}.
95
- function addMember(uint256 groupId, uint256 identityCommitment) external override onlyGroupAdmin(groupId) {
96
- _addMember(groupId, identityCommitment);
97
-
98
- uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);
99
-
100
- groups[groupId].merkleRootCreationDates[merkleTreeRoot] = block.timestamp;
101
- }
102
-
103
- /// @dev See {ISemaphore-addMembers}.
104
- function addMembers(uint256 groupId, uint256[] calldata identityCommitments)
105
- external
106
- override
107
- onlyGroupAdmin(groupId)
108
- {
109
- for (uint256 i = 0; i < identityCommitments.length; ) {
110
- _addMember(groupId, identityCommitments[i]);
111
-
112
- unchecked {
113
- ++i;
114
- }
115
- }
116
-
117
- uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);
118
-
119
- groups[groupId].merkleRootCreationDates[merkleTreeRoot] = block.timestamp;
120
- }
121
-
122
- /// @dev See {ISemaphore-updateMember}.
123
- function updateMember(
124
- uint256 groupId,
125
- uint256 identityCommitment,
126
- uint256 newIdentityCommitment,
127
- uint256[] calldata proofSiblings,
128
- uint8[] calldata proofPathIndices
129
- ) external override onlyGroupAdmin(groupId) {
130
- _updateMember(groupId, identityCommitment, newIdentityCommitment, proofSiblings, proofPathIndices);
131
-
132
- uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);
133
-
134
- groups[groupId].merkleRootCreationDates[merkleTreeRoot] = block.timestamp;
135
- }
136
-
137
- /// @dev See {ISemaphore-removeMember}.
138
- function removeMember(
139
- uint256 groupId,
140
- uint256 identityCommitment,
141
- uint256[] calldata proofSiblings,
142
- uint8[] calldata proofPathIndices
143
- ) external override onlyGroupAdmin(groupId) {
144
- _removeMember(groupId, identityCommitment, proofSiblings, proofPathIndices);
145
-
146
- uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);
147
-
148
- groups[groupId].merkleRootCreationDates[merkleTreeRoot] = block.timestamp;
149
- }
150
-
151
- /// @dev See {ISemaphore-verifyProof}.
152
- function verifyProof(
153
- uint256 groupId,
154
- uint256 merkleTreeRoot,
155
- uint256 signal,
156
- uint256 nullifierHash,
157
- uint256 externalNullifier,
158
- uint256[8] calldata proof
159
- ) external override {
160
- uint256 merkleTreeDepth = getMerkleTreeDepth(groupId);
161
-
162
- if (merkleTreeDepth == 0) {
163
- revert Semaphore__GroupDoesNotExist();
164
- }
165
-
166
- uint256 currentMerkleTreeRoot = getMerkleTreeRoot(groupId);
167
-
168
- // A proof could have used an old Merkle tree root.
169
- // https://github.com/semaphore-protocol/semaphore/issues/98
170
- if (merkleTreeRoot != currentMerkleTreeRoot) {
171
- uint256 merkleRootCreationDate = groups[groupId].merkleRootCreationDates[merkleTreeRoot];
172
- uint256 merkleTreeDuration = groups[groupId].merkleTreeDuration;
173
-
174
- if (merkleRootCreationDate == 0) {
175
- revert Semaphore__MerkleTreeRootIsNotPartOfTheGroup();
176
- }
177
-
178
- if (block.timestamp > merkleRootCreationDate + merkleTreeDuration) {
179
- revert Semaphore__MerkleTreeRootIsExpired();
180
- }
181
- }
182
-
183
- if (groups[groupId].nullifierHashes[nullifierHash]) {
184
- revert Semaphore__YouAreUsingTheSameNillifierTwice();
185
- }
186
-
187
- verifier.verifyProof(merkleTreeRoot, nullifierHash, signal, externalNullifier, proof, merkleTreeDepth);
188
-
189
- groups[groupId].nullifierHashes[nullifierHash] = true;
190
-
191
- emit ProofVerified(groupId, merkleTreeRoot, nullifierHash, externalNullifier, signal);
192
- }
193
- }