@openzeppelin/compact-contracts 0.3.0-rc.1 → 0.4.0-alpha.2
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 +14 -4
- package/access/AccessControl.compact +14 -14
- package/access/Ownable.compact +16 -10
- package/access/ShieldedAccessControl.compact +26 -2
- package/access/ZOwnablePK.compact +9 -9
- package/crypto/EcdhMask.compact +5 -5
- package/crypto/Ecdsa.compact +111 -0
- package/crypto/Eip712.compact +168 -0
- package/crypto/ElGamal.compact +33 -107
- package/multisig/EcdsaSignerManager.compact +246 -0
- package/multisig/ForwarderPrivate.compact +12 -6
- package/multisig/ForwarderShielded.compact +3 -3
- package/multisig/ForwarderUnshielded.compact +3 -3
- package/multisig/ProposalManager.compact +195 -23
- package/multisig/ShieldedTreasury.compact +29 -2
- package/multisig/ShieldedTreasuryStateless.compact +2 -2
- package/multisig/Signer.compact +28 -80
- package/multisig/UnshieldedTreasury.compact +10 -2
- package/multisig/{presets/forwarder/ForwarderPrivate.compact → examples/ForwarderPrivateExample.compact} +4 -4
- package/multisig/{presets/forwarder/ForwarderShielded.compact → examples/ForwarderShieldedExample.compact} +4 -4
- package/multisig/{presets/forwarder/ForwarderUnshielded.compact → examples/ForwarderUnshieldedExample.compact} +4 -4
- package/multisig/examples/NativeShieldedTokenIssuerExample.compact +143 -0
- package/multisig/examples/ShieldedMultiSigV2Example.compact +77 -0
- package/multisig/presets/NativeShieldedTokenIssuer.compact +542 -0
- package/multisig/presets/ShieldedMultiSigV2.compact +267 -259
- package/package.json +31 -25
- package/security/Allowlist.compact +6 -6
- package/security/Blocklist.compact +6 -6
- package/security/Initializable.compact +9 -5
- package/security/Pausable.compact +11 -7
- package/token/ConfidentialFungibleToken.compact +143 -270
- package/token/FungibleToken.compact +36 -22
- package/token/MultiToken.compact +16 -16
- package/token/NativeShieldedToken.compact +17 -66
- package/token/NativeShieldedTokenCore.compact +26 -48
- package/token/NativeShieldedTokenFamily.compact +17 -67
- package/token/NonFungibleToken.compact +40 -79
- package/token/extensions/ConfidentialFungibleTokenPublicSupply.compact +12 -7
- package/token/extensions/NativeShieldedTokenDerivedNonce.compact +3 -3
- package/token/extensions/NativeShieldedTokenFamilyPublicSupply.compact +8 -8
- package/token/extensions/NativeShieldedTokenPublicSupply.compact +8 -8
- package/token/extensions/NativeShieldedTokenPublicSupplyCore.compact +6 -6
- package/utils/EvmAbi.compact +134 -0
- package/utils/Utils.compact +2 -12
- package/multisig/presets/ShieldedMultiSig.compact +0 -227
- package/multisig/presets/ShieldedMultiSigV3.compact +0 -368
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[](https://docs.midnight.network/relnotes/compact/)
|
|
2
2
|
[](CODE_OF_CONDUCT.md)
|
|
3
3
|
|
|
4
4
|
This project is built on the Midnight Network.
|
|
@@ -37,8 +37,8 @@ Follow Midnight's [Compact Developer Tools installation guide](https://docs.midn
|
|
|
37
37
|
```bash
|
|
38
38
|
$ compact compile --version
|
|
39
39
|
|
|
40
|
-
Compactc version: 0.
|
|
41
|
-
0.
|
|
40
|
+
Compactc version: 0.34.0
|
|
41
|
+
0.34.0
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
### Installation
|
|
@@ -64,7 +64,7 @@ Import the modules through `./node_modules/@openzeppelin/compact-contracts/...`.
|
|
|
64
64
|
```typescript
|
|
65
65
|
// MyContract.compact
|
|
66
66
|
|
|
67
|
-
pragma language_version >= 0.
|
|
67
|
+
pragma language_version >= 0.26.0;
|
|
68
68
|
|
|
69
69
|
import CompactStandardLibrary;
|
|
70
70
|
import "./node_modules/@openzeppelin/compact-contracts/access/Ownable"
|
|
@@ -189,6 +189,16 @@ Compiling 14 circuits:
|
|
|
189
189
|
Overall progress [====================] 14/14
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
+
ZKIR v3: the library targets ZKIR v2, the compiler 0.34.0 default.
|
|
193
|
+
Pass `--feature-zkir-v3` only when the contract reaches a module that needs it:
|
|
194
|
+
the secp256k1-based `crypto/Ecdsa` and `multisig/EcdsaSignerManager`,
|
|
195
|
+
or the `keccak256`-based `crypto/Eip712`.
|
|
196
|
+
`multisig/presets/ShieldedMultiSigV2`, `multisig/presets/NativeShieldedTokenIssuer`
|
|
197
|
+
and the `multisig/examples/` contracts reach both.
|
|
198
|
+
`utils/EvmAbi` needs no `keccak256` of its own and compiles on either backend.
|
|
199
|
+
Compiling the other modules under v3 currently hits upstream blockers,
|
|
200
|
+
listed under [Known issues](CHANGELOG.md#known-issues).
|
|
201
|
+
|
|
192
202
|
## Development
|
|
193
203
|
|
|
194
204
|
OpenZeppelin Contracts for Compact exists thanks to its contributors.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.2 (access/AccessControl.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module AccessControl
|
|
@@ -168,7 +168,7 @@ module AccessControl {
|
|
|
168
168
|
/**
|
|
169
169
|
* @description Returns `true` if `account` has been granted `roleId`.
|
|
170
170
|
*
|
|
171
|
-
* @
|
|
171
|
+
* @constraints k=10, rows=1017
|
|
172
172
|
*
|
|
173
173
|
* @param {Bytes<32>} roleId - The role identifier.
|
|
174
174
|
* @param {Either<Bytes<32>, ContractAddress>} account - The account to query.
|
|
@@ -206,7 +206,7 @@ module AccessControl {
|
|
|
206
206
|
* In the case of an external (non-contract) caller, the caller’s identity is
|
|
207
207
|
* derived from the `wit_AccessControlSK` witness as `persistentHash(secretKey)`.
|
|
208
208
|
*
|
|
209
|
-
* @
|
|
209
|
+
* @constraints k=13, rows=2660
|
|
210
210
|
*
|
|
211
211
|
* Requirements:
|
|
212
212
|
*
|
|
@@ -225,7 +225,7 @@ module AccessControl {
|
|
|
225
225
|
/**
|
|
226
226
|
* @description Reverts if `account` is missing `roleId`.
|
|
227
227
|
*
|
|
228
|
-
* @
|
|
228
|
+
* @constraints k=10, rows=997
|
|
229
229
|
*
|
|
230
230
|
* Requirements:
|
|
231
231
|
*
|
|
@@ -248,7 +248,7 @@ module AccessControl {
|
|
|
248
248
|
*
|
|
249
249
|
* To change a role's admin use {_setRoleAdmin}.
|
|
250
250
|
*
|
|
251
|
-
* @
|
|
251
|
+
* @constraints k=9, rows=371
|
|
252
252
|
*
|
|
253
253
|
* @param {Bytes<32>} roleId - The role identifier.
|
|
254
254
|
* @return {Bytes<32>} roleAdmin - The admin role that controls `roleId`.
|
|
@@ -263,7 +263,7 @@ module AccessControl {
|
|
|
263
263
|
/**
|
|
264
264
|
* @description Grants `roleId` to `account`.
|
|
265
265
|
*
|
|
266
|
-
* @
|
|
266
|
+
* @constraints k=13, rows=3527
|
|
267
267
|
*
|
|
268
268
|
* Requirements:
|
|
269
269
|
*
|
|
@@ -285,7 +285,7 @@ module AccessControl {
|
|
|
285
285
|
/**
|
|
286
286
|
* @description Revokes `roleId` from `account`.
|
|
287
287
|
*
|
|
288
|
-
* @
|
|
288
|
+
* @constraints k=13, rows=3457
|
|
289
289
|
*
|
|
290
290
|
* Requirements:
|
|
291
291
|
*
|
|
@@ -314,7 +314,7 @@ module AccessControl {
|
|
|
314
314
|
* `persistentHash(secretKey)`. The `callerConfirmation` parameter must match
|
|
315
315
|
* the caller's computed account identifier to prevent accidental renunciation.
|
|
316
316
|
*
|
|
317
|
-
* @
|
|
317
|
+
* @constraints k=13, rows=3313
|
|
318
318
|
*
|
|
319
319
|
* Requirements:
|
|
320
320
|
*
|
|
@@ -339,7 +339,7 @@ module AccessControl {
|
|
|
339
339
|
/**
|
|
340
340
|
* @description Sets `adminRole` as `roleId`'s admin role.
|
|
341
341
|
*
|
|
342
|
-
* @
|
|
342
|
+
* @constraints k=10, rows=579
|
|
343
343
|
*
|
|
344
344
|
* @param {Bytes<32>} roleId - The role identifier.
|
|
345
345
|
* @param {Bytes<32>} adminRole - The admin role identifier.
|
|
@@ -353,7 +353,7 @@ module AccessControl {
|
|
|
353
353
|
* @description Attempts to grant `roleId` to `account` and returns a boolean indicating if `roleId` was granted.
|
|
354
354
|
* Internal circuit without access restriction.
|
|
355
355
|
*
|
|
356
|
-
* @
|
|
356
|
+
* @constraints k=11, rows=1141
|
|
357
357
|
*
|
|
358
358
|
* Requirements:
|
|
359
359
|
*
|
|
@@ -376,7 +376,7 @@ module AccessControl {
|
|
|
376
376
|
* @description Attempts to grant `roleId` to `account` and returns a boolean indicating if `roleId` was granted.
|
|
377
377
|
* Internal circuit without access restriction. It does NOT check if the role is granted to a ContractAddress.
|
|
378
378
|
*
|
|
379
|
-
* @
|
|
379
|
+
* @constraints k=11, rows=1140
|
|
380
380
|
*
|
|
381
381
|
* @notice External smart contracts cannot call the access control contract at this time, so granting a role to a ContractAddress may
|
|
382
382
|
* render a circuit permanently inaccessible.
|
|
@@ -409,7 +409,7 @@ module AccessControl {
|
|
|
409
409
|
* @description Attempts to revoke `roleId` from `account` and returns a boolean indicating if `roleId` was revoked.
|
|
410
410
|
* Internal circuit without access restriction.
|
|
411
411
|
*
|
|
412
|
-
* @
|
|
412
|
+
* @constraints k=11, rows=1071
|
|
413
413
|
*
|
|
414
414
|
* @param {Bytes<32>} roleId - The role identifier.
|
|
415
415
|
* @param {Either<Bytes<32>, ContractAddress>} account - A Bytes<32> or ContractAddress.
|
|
@@ -437,7 +437,7 @@ module AccessControl {
|
|
|
437
437
|
*
|
|
438
438
|
* The result is a 32-byte commitment that uniquely identifies the caller.
|
|
439
439
|
*
|
|
440
|
-
* @
|
|
440
|
+
* @constraints k=13, rows=2294
|
|
441
441
|
*
|
|
442
442
|
* @returns {Bytes<32>} accountId - The computed account identifier.
|
|
443
443
|
*/
|
package/access/Ownable.compact
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.2 (access/Ownable.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module Ownable
|
|
@@ -94,6 +94,12 @@ module Ownable {
|
|
|
94
94
|
*/
|
|
95
95
|
export ledger _isInitialized: Boolean;
|
|
96
96
|
|
|
97
|
+
/**
|
|
98
|
+
* @description The current owner, canonicalized on write. A `left` holds an
|
|
99
|
+
* account identifier, stored as supplied and never checked against the secret
|
|
100
|
+
* key it should derive from; a `right` holds a contract address. The zero
|
|
101
|
+
* value means ownership has been renounced.
|
|
102
|
+
*/
|
|
97
103
|
export ledger _owner: Either<Bytes<32>, ContractAddress>;
|
|
98
104
|
|
|
99
105
|
/**
|
|
@@ -111,7 +117,7 @@ module Ownable {
|
|
|
111
117
|
* @description Initializes the contract by setting the `initialOwner`.
|
|
112
118
|
* This must be called in the contract's constructor.
|
|
113
119
|
*
|
|
114
|
-
* @
|
|
120
|
+
* @constraints k=10, rows=626
|
|
115
121
|
*
|
|
116
122
|
* Requirements:
|
|
117
123
|
*
|
|
@@ -158,7 +164,7 @@ module Ownable {
|
|
|
158
164
|
/**
|
|
159
165
|
* @description Returns the current contract owner.
|
|
160
166
|
*
|
|
161
|
-
* @
|
|
167
|
+
* @constraints k=7, rows=74
|
|
162
168
|
*
|
|
163
169
|
* Requirements:
|
|
164
170
|
*
|
|
@@ -178,7 +184,7 @@ module Ownable {
|
|
|
178
184
|
* interactions are supported in Compact.
|
|
179
185
|
* This restriction prevents permanently disabling access to a circuit.
|
|
180
186
|
*
|
|
181
|
-
* @
|
|
187
|
+
* @constraints k=13, rows=2947
|
|
182
188
|
*
|
|
183
189
|
* Requirements:
|
|
184
190
|
*
|
|
@@ -205,7 +211,7 @@ module Ownable {
|
|
|
205
211
|
* Ownership privileges sent to a contract address may become uncallable.
|
|
206
212
|
* Once contract-to-contract calls are supported, this circuit may be deprecated.
|
|
207
213
|
*
|
|
208
|
-
* @
|
|
214
|
+
* @constraints k=13, rows=2944
|
|
209
215
|
*
|
|
210
216
|
* Requirements:
|
|
211
217
|
*
|
|
@@ -228,7 +234,7 @@ module Ownable {
|
|
|
228
234
|
* It will not be possible to call `assertOnlyOwner` circuits anymore.
|
|
229
235
|
* Can only be called by the current owner.
|
|
230
236
|
*
|
|
231
|
-
* @
|
|
237
|
+
* @constraints k=13, rows=2353
|
|
232
238
|
*
|
|
233
239
|
* Requirements:
|
|
234
240
|
*
|
|
@@ -256,7 +262,7 @@ module Ownable {
|
|
|
256
262
|
* In the case of an external (non-contract) caller, the caller’s identity is
|
|
257
263
|
* derived from the `wit_OwnableSK` witness as `persistentHash(secretKey)`.
|
|
258
264
|
*
|
|
259
|
-
* @
|
|
265
|
+
* @constraints k=13, rows=2349
|
|
260
266
|
*
|
|
261
267
|
* Requirements:
|
|
262
268
|
*
|
|
@@ -282,7 +288,7 @@ module Ownable {
|
|
|
282
288
|
* interactions are supported in Compact.
|
|
283
289
|
* This restriction prevents circuits from being inadvertently locked in contracts.
|
|
284
290
|
*
|
|
285
|
-
* @
|
|
291
|
+
* @constraints k=10, rows=598
|
|
286
292
|
*
|
|
287
293
|
* Requirements:
|
|
288
294
|
*
|
|
@@ -307,7 +313,7 @@ module Ownable {
|
|
|
307
313
|
* Ownership privileges sent to a contract address may become uncallable.
|
|
308
314
|
* Once contract-to-contract calls are supported, this circuit may be deprecated.
|
|
309
315
|
*
|
|
310
|
-
* @
|
|
316
|
+
* @constraints k=10, rows=595
|
|
311
317
|
*
|
|
312
318
|
* Requirements:
|
|
313
319
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.2 (access/ShieldedAccessControl.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module ShieldedAccessControl
|
|
@@ -199,6 +199,10 @@ module ShieldedAccessControl {
|
|
|
199
199
|
/**
|
|
200
200
|
* @ledger _adminRoles
|
|
201
201
|
* @description Mapping from a role identifier to an admin role identifier.
|
|
202
|
+
* @type {RoleIdentifier} role - The role being administered.
|
|
203
|
+
* @type {RoleIdentifier} adminRole - The role permitted to grant and revoke it.
|
|
204
|
+
* @type {Map<role, adminRole>}
|
|
205
|
+
* @type {Map<RoleIdentifier, RoleIdentifier>} _adminRoles
|
|
202
206
|
*/
|
|
203
207
|
export ledger _adminRoles: Map<RoleIdentifier, RoleIdentifier>;
|
|
204
208
|
|
|
@@ -311,6 +315,8 @@ module ShieldedAccessControl {
|
|
|
311
315
|
/**
|
|
312
316
|
* @description Reverts if caller cannot provide a valid proof of ownership for `role`.
|
|
313
317
|
*
|
|
318
|
+
* @constraints k=15, rows=16997
|
|
319
|
+
*
|
|
314
320
|
* Requirements:
|
|
315
321
|
*
|
|
316
322
|
* - caller must prove ownership of `role`.
|
|
@@ -337,6 +343,8 @@ module ShieldedAccessControl {
|
|
|
337
343
|
* caller if the proving environment supplies an invalid Merkle path. This circuit will never return true for an
|
|
338
344
|
* unauthorized caller.
|
|
339
345
|
*
|
|
346
|
+
* @constraints k=15, rows=16997
|
|
347
|
+
*
|
|
340
348
|
* Requirements:
|
|
341
349
|
*
|
|
342
350
|
* - caller must not provide valid Merkle tree path for a different `(role, accountId)` pairing.
|
|
@@ -392,6 +400,8 @@ module ShieldedAccessControl {
|
|
|
392
400
|
* limited Merkle tree storage slots. Once revoked, a role cannot be re-granted to the same `accountId`. A new
|
|
393
401
|
* `accountId` must be generated to be re-authorized for a revoked `role`.
|
|
394
402
|
*
|
|
403
|
+
* @constraints k=15, rows=28995
|
|
404
|
+
*
|
|
395
405
|
* Requirements:
|
|
396
406
|
*
|
|
397
407
|
* - caller must prove they're an admin for `role`.
|
|
@@ -434,6 +444,8 @@ module ShieldedAccessControl {
|
|
|
434
444
|
* but are otherwise benign. A single nullifier invalidates all duplicate commitments.
|
|
435
445
|
* Implementing contracts are responsible for mitigating tree exhaustion risk.
|
|
436
446
|
*
|
|
447
|
+
* @constraints k=14, rows=12250
|
|
448
|
+
*
|
|
437
449
|
* Requirements:
|
|
438
450
|
*
|
|
439
451
|
* - The `(role, accountId)` pairing must not be already revoked.
|
|
@@ -466,6 +478,8 @@ module ShieldedAccessControl {
|
|
|
466
478
|
* @warning Outside observers may be able to use timing and pattern analysis to weaken pseudonymity
|
|
467
479
|
* guarantees if renounceRole is used in tandem with other on-chain actions.
|
|
468
480
|
*
|
|
481
|
+
* @constraints k=14, rows=14440
|
|
482
|
+
*
|
|
469
483
|
* Requirements:
|
|
470
484
|
*
|
|
471
485
|
* - The caller must provide a valid `accountId` for the role.
|
|
@@ -497,6 +511,8 @@ module ShieldedAccessControl {
|
|
|
497
511
|
* `role`. At this time, proofs of non-membership on values in the Merkle tree LDT are not possible
|
|
498
512
|
* so a `(role, accountId)` pairing that does not exist can still be revoked.
|
|
499
513
|
*
|
|
514
|
+
* @constraints k=15, rows=27005
|
|
515
|
+
*
|
|
500
516
|
* Requirements:
|
|
501
517
|
*
|
|
502
518
|
* - caller must prove they're an admin for `role`.
|
|
@@ -533,6 +549,8 @@ module ShieldedAccessControl {
|
|
|
533
549
|
* @warning Exposing this circuit directly in an implementing contract would allow anyone to revoke
|
|
534
550
|
* roles without authorization. It must be wrapped with appropriate access control.
|
|
535
551
|
*
|
|
552
|
+
* @constraints k=14, rows=10260
|
|
553
|
+
*
|
|
536
554
|
* Requirements:
|
|
537
555
|
*
|
|
538
556
|
* - The `(role, accountId)` pairing must not be already revoked.
|
|
@@ -599,6 +617,8 @@ module ShieldedAccessControl {
|
|
|
599
617
|
*
|
|
600
618
|
* To change a role's admin use {_setRoleAdmin}.
|
|
601
619
|
*
|
|
620
|
+
* @constraints k=9, rows=374
|
|
621
|
+
*
|
|
602
622
|
* Disclosures:
|
|
603
623
|
*
|
|
604
624
|
* - A role identifier.
|
|
@@ -621,6 +641,8 @@ module ShieldedAccessControl {
|
|
|
621
641
|
* @warning Exposing this circuit directly in an implementing contract would allow anyone to assign
|
|
622
642
|
* arbitrary admin roles without authorization. It must be wrapped with appropriate access control.
|
|
623
643
|
*
|
|
644
|
+
* @constraints k=10, rows=581
|
|
645
|
+
*
|
|
624
646
|
* Disclosures:
|
|
625
647
|
*
|
|
626
648
|
* - The role identifier
|
|
@@ -707,6 +729,8 @@ module ShieldedAccessControl {
|
|
|
707
729
|
* - `commitmentDomain`: Domain separator `"ShieldedAccessControl:commitment"` (padded to 32 bytes) to prevent
|
|
708
730
|
* hash collisions when extending the module or using similar commitment schemes.
|
|
709
731
|
*
|
|
732
|
+
* @constraints k=13, rows=6404
|
|
733
|
+
*
|
|
710
734
|
* @param {RoleIdentifier} role - The role identifier.
|
|
711
735
|
* @param {AccountIdentifier} accountId - The unique identifier of the account.
|
|
712
736
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.2 (access/ZOwnablePK.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module ZOwnablePK
|
|
@@ -99,7 +99,7 @@ module ZOwnablePK {
|
|
|
99
99
|
* @warning The `ownerId` must be calculated prior to contract deployment using the SHA256 hashing algorithm.
|
|
100
100
|
* Using any other algorithm will result in a permanent loss of contract access.
|
|
101
101
|
*
|
|
102
|
-
* @
|
|
102
|
+
* @constraints k=14, rows=14933
|
|
103
103
|
*
|
|
104
104
|
* Requirements:
|
|
105
105
|
*
|
|
@@ -150,7 +150,7 @@ module ZOwnablePK {
|
|
|
150
150
|
* @description Returns the current commitment representing the contract owner.
|
|
151
151
|
* The full commitment is: `SHA256(SHA256(pk, nonce), instanceSalt, counter, domain)`.
|
|
152
152
|
*
|
|
153
|
-
* @
|
|
153
|
+
* @constraints k=6, rows=48
|
|
154
154
|
*
|
|
155
155
|
* Requirements:
|
|
156
156
|
*
|
|
@@ -167,7 +167,7 @@ module ZOwnablePK {
|
|
|
167
167
|
* @description Transfers ownership to `newOwnerId`.
|
|
168
168
|
* `newOwnerId` must be precalculated and given to the current owner off chain.
|
|
169
169
|
*
|
|
170
|
-
* @
|
|
170
|
+
* @constraints k=15, rows=17023
|
|
171
171
|
*
|
|
172
172
|
* Requirements:
|
|
173
173
|
*
|
|
@@ -191,7 +191,7 @@ module ZOwnablePK {
|
|
|
191
191
|
* It will not be possible to call `assertOnlyOwner` circuits anymore.
|
|
192
192
|
* Can only be called by the current owner.
|
|
193
193
|
*
|
|
194
|
-
* @
|
|
194
|
+
* @constraints k=14, rows=10579
|
|
195
195
|
*
|
|
196
196
|
* Requirements:
|
|
197
197
|
*
|
|
@@ -212,7 +212,7 @@ module ZOwnablePK {
|
|
|
212
212
|
* the stored owner commitment.
|
|
213
213
|
* Use this to only allow the owner to call specific circuits.
|
|
214
214
|
*
|
|
215
|
-
* @
|
|
215
|
+
* @constraints k=14, rows=10577
|
|
216
216
|
*
|
|
217
217
|
* Requirements:
|
|
218
218
|
*
|
|
@@ -257,7 +257,7 @@ module ZOwnablePK {
|
|
|
257
257
|
* - `domain`: Domain separator `"ZOwnablePK:shield:"` (padded to 32 bytes) to prevent
|
|
258
258
|
* hash collisions when extending the module or using similar commitment schemes.
|
|
259
259
|
*
|
|
260
|
-
* @
|
|
260
|
+
* @constraints k=13, rows=6544
|
|
261
261
|
*
|
|
262
262
|
* Requirements:
|
|
263
263
|
*
|
|
@@ -320,7 +320,7 @@ module ZOwnablePK {
|
|
|
320
320
|
* @description Transfers ownership to owner id `newOwnerId` without
|
|
321
321
|
* enforcing permission checks on the caller.
|
|
322
322
|
*
|
|
323
|
-
* @
|
|
323
|
+
* @constraints k=13, rows=6460
|
|
324
324
|
*
|
|
325
325
|
* Requirements:
|
|
326
326
|
*
|
package/crypto/EcdhMask.compact
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.2 (crypto/EcdhMask.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module EcdhMask
|
|
@@ -142,10 +142,10 @@ module EcdhMask {
|
|
|
142
142
|
export pure circuit encrypt(
|
|
143
143
|
recipientPk: JubjubPoint,
|
|
144
144
|
value: Uint<128>,
|
|
145
|
-
e:
|
|
145
|
+
e: JubjubScalar,
|
|
146
146
|
domain: Bytes<32>
|
|
147
147
|
): Ciphertext {
|
|
148
|
-
const identity = ecMulGenerator(0 as
|
|
148
|
+
const identity = ecMulGenerator(0 as JubjubScalar);
|
|
149
149
|
assert(recipientPk != identity, "EcdhMask: identity pk");
|
|
150
150
|
const ephemeralPk = ecMulGenerator(e);
|
|
151
151
|
// Guard the ephemeral POINT, not the scalar: `ephemeralPk == identity`
|
|
@@ -169,7 +169,7 @@ module EcdhMask {
|
|
|
169
169
|
* @return The recovered value as a `Field` (equal to the original `value`,
|
|
170
170
|
* which is `< 2^128`).
|
|
171
171
|
*/
|
|
172
|
-
export pure circuit decrypt(ciphertext: Ciphertext, ekScalar:
|
|
172
|
+
export pure circuit decrypt(ciphertext: Ciphertext, ekScalar: JubjubScalar, domain: Bytes<32>): Field {
|
|
173
173
|
const sShared = ecMul(ciphertext.ephemeralPk, ekScalar);
|
|
174
174
|
const mask = kdf(sShared, domain);
|
|
175
175
|
return ciphertext.ct - mask;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.2 (crypto/Ecdsa.compact)
|
|
3
|
+
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module Ecdsa
|
|
8
|
+
* @description The low-s rule for secp256k1 ECDSA signatures.
|
|
9
|
+
*
|
|
10
|
+
* `secp256k1EcdsaVerify` accepts both `(r, s)` and `(r, n - s)`, so every valid
|
|
11
|
+
* signature has a second valid encoding that anyone can derive without the
|
|
12
|
+
* signing key. Its own documentation leaves the low-s constraint to the caller.
|
|
13
|
+
* This module is that constraint: reject `s > n / 2` and each signature has one
|
|
14
|
+
* encoding, which is what replay sets, nullifiers, and signature-derived
|
|
15
|
+
* identifiers rely on.
|
|
16
|
+
*/
|
|
17
|
+
module Ecdsa {
|
|
18
|
+
import CompactStandardLibrary;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @description Returns whether `s` is canonical, i.e. `s <= n / 2` where `n`
|
|
22
|
+
* is the secp256k1 group order.
|
|
23
|
+
*
|
|
24
|
+
* @constraints k=13, rows=5125 (zkir-v3)
|
|
25
|
+
*
|
|
26
|
+
* @param {Secp256k1Scalar} s - The `s` component of a signature.
|
|
27
|
+
* @returns {Boolean} True if `s` is in the low half.
|
|
28
|
+
*/
|
|
29
|
+
export pure circuit isLowS(s: Secp256k1Scalar): Boolean {
|
|
30
|
+
const sBytes = (s as Bytes<32>) as Vector<32, Uint<8>>;
|
|
31
|
+
return fold(compareByteLe, true, sBytes, SECP256K1_HALF_ORDER_LE());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @description Fold callback over one little-endian byte pair. A differing
|
|
36
|
+
* pair overrides the running result, so the accumulator ends up holding the
|
|
37
|
+
* comparison at the most significant byte where `s` and `n / 2` differ. All
|
|
38
|
+
* pairs equal leaves the seed untouched, which is what makes the comparison
|
|
39
|
+
* inclusive.
|
|
40
|
+
*
|
|
41
|
+
* @param {Boolean} isLow - Result from the less significant bytes.
|
|
42
|
+
* @param {Uint<8>} sByte - Byte of `s`.
|
|
43
|
+
* @param {Uint<8>} halfByte - Byte of `n / 2`.
|
|
44
|
+
* @returns {Boolean} Updated result.
|
|
45
|
+
*/
|
|
46
|
+
pure circuit compareByteLe(
|
|
47
|
+
isLow: Boolean,
|
|
48
|
+
sByte: Uint<8>,
|
|
49
|
+
halfByte: Uint<8>
|
|
50
|
+
): Boolean {
|
|
51
|
+
return sByte == halfByte ? isLow : sByte < halfByte;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @description `n / 2` as little-endian bytes, matching the byte order of
|
|
56
|
+
* `Secp256k1Scalar as Bytes<32>`.
|
|
57
|
+
*
|
|
58
|
+
* @returns {Vector<32, Uint<8>>} The bytes of `n / 2`, least significant first.
|
|
59
|
+
*/
|
|
60
|
+
pure circuit SECP256K1_HALF_ORDER_LE(): Vector<32, Uint<8>> {
|
|
61
|
+
// 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0
|
|
62
|
+
return [
|
|
63
|
+
160, 32, 27, 104, 70, 47, 233, 223,
|
|
64
|
+
29, 80, 164, 87, 115, 110, 87, 93,
|
|
65
|
+
255, 255, 255, 255, 255, 255, 255, 255,
|
|
66
|
+
255, 255, 255, 255, 255, 255, 255, 127
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ─── Verification ───────────────────────────────────────────────────────────
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @description Rejects a signature in the high half.
|
|
74
|
+
*
|
|
75
|
+
* @constraints k=13, rows=5156 (zkir-v3)
|
|
76
|
+
*
|
|
77
|
+
* Requirements:
|
|
78
|
+
*
|
|
79
|
+
* - `sig.s` must satisfy `s <= n / 2`.
|
|
80
|
+
*
|
|
81
|
+
* @param {Secp256k1EcdsaSignature} sig - The signature to check.
|
|
82
|
+
* @returns {[]} Empty tuple.
|
|
83
|
+
*/
|
|
84
|
+
export pure circuit assertLowS(sig: Secp256k1EcdsaSignature): [] {
|
|
85
|
+
assert(isLowS(sig.s), "Ecdsa: high-s signature");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @description Verifies `sig` over `msgHash` under `pk`, accepting only the
|
|
90
|
+
* low-s encoding. Reports the result instead of asserting, so a caller can
|
|
91
|
+
* fold it into a count or a threshold.
|
|
92
|
+
*
|
|
93
|
+
* @constraints k=16, rows=34056 (zkir-v3)
|
|
94
|
+
*
|
|
95
|
+
* @param {Bytes<32>} msgHash - The digest that was signed.
|
|
96
|
+
* @param {Secp256k1EcdsaSignature} sig - The signature over `msgHash`.
|
|
97
|
+
* @param {Secp256k1Point} pk - The signer's public key.
|
|
98
|
+
* @returns {Boolean} True if the signature is valid and canonical.
|
|
99
|
+
*/
|
|
100
|
+
export pure circuit secp256k1EcdsaVerifyLowS(
|
|
101
|
+
msgHash: Bytes<32>,
|
|
102
|
+
sig: Secp256k1EcdsaSignature,
|
|
103
|
+
pk: Secp256k1Point
|
|
104
|
+
): Boolean {
|
|
105
|
+
// TODO: inline into the return once a guarded stdlib verify compiles.
|
|
106
|
+
// Short-circuiting `&&` puts it behind a guard, which trips an internal
|
|
107
|
+
// error in the compiler's missing-guard-workarounds pass.
|
|
108
|
+
const verified = secp256k1EcdsaVerify(msgHash, sig, pk);
|
|
109
|
+
return isLowS(sig.s) && verified;
|
|
110
|
+
}
|
|
111
|
+
}
|