@openzeppelin/compact-contracts 0.3.0-alpha.2 → 0.4.0-alpha.1
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 +10 -4
- package/access/AccessControl.compact +2 -2
- package/access/Ownable.compact +2 -2
- package/access/ShieldedAccessControl.compact +2 -2
- package/access/ZOwnablePK.compact +2 -2
- package/crypto/EcdhMask.compact +5 -5
- package/crypto/Ecdsa.compact +111 -0
- package/crypto/ElGamal.compact +33 -66
- package/multisig/EcdsaSignerManager.compact +229 -0
- package/multisig/ForwarderPrivate.compact +2 -2
- package/multisig/ForwarderShielded.compact +2 -2
- package/multisig/ForwarderUnshielded.compact +2 -2
- package/multisig/ProposalManager.compact +2 -2
- package/multisig/ShieldedTreasury.compact +2 -2
- package/multisig/ShieldedTreasuryStateless.compact +2 -2
- package/multisig/Signer.compact +2 -2
- package/multisig/UnshieldedTreasury.compact +2 -2
- package/multisig/presets/ShieldedMultiSig.compact +2 -2
- package/multisig/presets/ShieldedMultiSigV2.compact +72 -127
- package/multisig/presets/ShieldedMultiSigV3.compact +81 -138
- package/multisig/presets/forwarder/ForwarderPrivate.compact +2 -2
- package/multisig/presets/forwarder/ForwarderShielded.compact +2 -2
- package/multisig/presets/forwarder/ForwarderUnshielded.compact +2 -2
- package/package.json +22 -20
- package/security/Allowlist.compact +2 -2
- package/security/Blocklist.compact +2 -2
- package/security/Initializable.compact +2 -2
- package/security/Pausable.compact +2 -2
- package/token/ConfidentialFungibleToken.compact +9 -9
- package/token/FungibleToken.compact +2 -2
- package/token/MultiToken.compact +2 -2
- package/token/NativeShieldedToken.compact +2 -2
- package/token/NativeShieldedTokenCore.compact +2 -2
- package/token/NativeShieldedTokenFamily.compact +2 -2
- package/token/NonFungibleToken.compact +2 -2
- package/token/extensions/ConfidentialFungibleTokenPublicSupply.compact +2 -2
- package/token/extensions/NativeShieldedTokenDerivedNonce.compact +2 -2
- package/token/extensions/NativeShieldedTokenFamilyPublicSupply.compact +1 -1
- package/token/extensions/NativeShieldedTokenPublicSupply.compact +1 -1
- package/token/extensions/NativeShieldedTokenPublicSupplyCore.compact +1 -1
- package/utils/Utils.compact +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.0
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (multisig/presets/ShieldedMultiSigV3.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @title ShieldedMultiSigV3
|
|
@@ -33,47 +33,26 @@ pragma language_version >= 0.23.0;
|
|
|
33
33
|
* hash prevent signatures for one operation type from being replayed as
|
|
34
34
|
* the other.
|
|
35
35
|
*
|
|
36
|
-
* @notice
|
|
37
|
-
* `
|
|
38
|
-
*
|
|
36
|
+
* @notice Threshold authorization is enforced with secp256k1 ECDSA
|
|
37
|
+
* (`secp256k1EcdsaVerifyLowS`) over `persistentHash` digests, via
|
|
38
|
+
* `EcdsaSignerManager`, so a high-s signature is rejected. The approval
|
|
39
|
+
* vectors are fixed at `Vector<2, ...>`, so this contract is 2-of-3 only.
|
|
40
|
+
*
|
|
41
|
+
* TODO: switch every digest to `keccak256` to match the custodian's HSM
|
|
42
|
+
* signing format (#827).
|
|
39
43
|
*/
|
|
40
44
|
|
|
41
45
|
import CompactStandardLibrary;
|
|
42
46
|
|
|
43
|
-
import "../
|
|
47
|
+
import "../EcdsaSignerManager" prefix EcdsaSignerManager_;
|
|
44
48
|
import "../../utils/Utils" prefix Utils_;
|
|
45
49
|
// For testing
|
|
46
50
|
export { ZswapCoinPublicKey };
|
|
47
51
|
|
|
48
|
-
// ─── Types ──────────────────────────────────────────────────────
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* @description Accumulator for fold-based signature verification.
|
|
52
|
-
* Threads the valid count, previous commitment (for duplicate
|
|
53
|
-
* detection), and message hash through each iteration.
|
|
54
|
-
*/
|
|
55
|
-
struct VerificationState {
|
|
56
|
-
validCount: Uint<8>,
|
|
57
|
-
prevCommitment: Bytes<32>,
|
|
58
|
-
msgHash: Bytes<32>
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* @description Input to persistentHash for computing signer commitments.
|
|
63
|
-
* Combines the ECDSA public key with an instance-specific salt and
|
|
64
|
-
* domain separator to produce a unique, unlinkable commitment.
|
|
65
|
-
*/
|
|
66
|
-
struct SignerCommitmentInput {
|
|
67
|
-
pk: Bytes<64>,
|
|
68
|
-
salt: Bytes<32>,
|
|
69
|
-
domain: Bytes<32>
|
|
70
|
-
}
|
|
71
|
-
|
|
72
52
|
// ─── State ──────────────────────────────────────────────────────
|
|
73
53
|
|
|
74
54
|
export ledger _counter: Counter;
|
|
75
55
|
export ledger _coinNonce: Bytes<32>;
|
|
76
|
-
export ledger _instanceSalt: Bytes<32>;
|
|
77
56
|
export sealed ledger _tokenDomain: Bytes<32>;
|
|
78
57
|
|
|
79
58
|
// ─── Constructor ────────────────────────────────────────────────
|
|
@@ -82,9 +61,9 @@ export sealed ledger _tokenDomain: Bytes<32>;
|
|
|
82
61
|
* @description Deploys the contract with 3 signer commitments and
|
|
83
62
|
* a threshold of 2.
|
|
84
63
|
*
|
|
85
|
-
* Each commitment is
|
|
86
|
-
*
|
|
87
|
-
*
|
|
64
|
+
* Each commitment is `persistentHash(pkX, pkY, instanceSalt,
|
|
65
|
+
* "multisig:signer:")`. Use the exported `_calculateSignerId` circuit to
|
|
66
|
+
* derive them consistently with in-circuit verification.
|
|
88
67
|
*
|
|
89
68
|
* `tokenDomain` is used with `kernel.self()` to derive the token color
|
|
90
69
|
* via `tokenType(_tokenDomain, kernel.self())`. Only coins of this color
|
|
@@ -109,10 +88,9 @@ constructor(
|
|
|
109
88
|
tokenDomain: Bytes<32>,
|
|
110
89
|
signerCommitments: Vector<3, Bytes<32>>,
|
|
111
90
|
) {
|
|
112
|
-
_instanceSalt = disclose(instanceSalt);
|
|
113
91
|
_coinNonce = disclose(initCoinNonce);
|
|
114
92
|
_tokenDomain = disclose(tokenDomain);
|
|
115
|
-
|
|
93
|
+
EcdsaSignerManager_initialize<3>(instanceSalt, signerCommitments, 2);
|
|
116
94
|
}
|
|
117
95
|
|
|
118
96
|
// ─── Mint ───────────────────────────────────────────────────────
|
|
@@ -136,9 +114,7 @@ constructor(
|
|
|
136
114
|
* after the counter has been incremented, binding each mint's nonce to a
|
|
137
115
|
* distinct counter value.
|
|
138
116
|
*
|
|
139
|
-
* @
|
|
140
|
-
* with `ecdsaVerify` once the Compact ECDSA and Keccak primitives are
|
|
141
|
-
* available, to match the custodian's HSM signing format.
|
|
117
|
+
* @circuitInfo k=17, rows=84506
|
|
142
118
|
*
|
|
143
119
|
* Requirements:
|
|
144
120
|
*
|
|
@@ -149,14 +125,14 @@ constructor(
|
|
|
149
125
|
*
|
|
150
126
|
* @param {Uint<64>} amount - The token amount to mint.
|
|
151
127
|
* @param {Either<ZswapCoinPublicKey, ContractAddress>} recipient - The address to receive the minted tokens.
|
|
152
|
-
* @param {Vector<2,
|
|
153
|
-
* @param {Vector<2,
|
|
128
|
+
* @param {Vector<2, Secp256k1Point>} pubkeys - Public keys of approving signers.
|
|
129
|
+
* @param {Vector<2, Secp256k1EcdsaSignature>} signatures - ECDSA signatures over the mint hash.
|
|
154
130
|
*/
|
|
155
131
|
export circuit mint(
|
|
156
132
|
amount: Uint<64>,
|
|
157
133
|
recipient: Either<ZswapCoinPublicKey, ContractAddress>,
|
|
158
|
-
pubkeys: Vector<2,
|
|
159
|
-
signatures: Vector<2,
|
|
134
|
+
pubkeys: Vector<2, Secp256k1Point>,
|
|
135
|
+
signatures: Vector<2, Secp256k1EcdsaSignature>
|
|
160
136
|
): [] {
|
|
161
137
|
const opNonce = _counter;
|
|
162
138
|
_counter.increment(1);
|
|
@@ -173,16 +149,7 @@ export circuit mint(
|
|
|
173
149
|
amount as Bytes<32>
|
|
174
150
|
]);
|
|
175
151
|
|
|
176
|
-
|
|
177
|
-
validCount: 0 as Uint<8>,
|
|
178
|
-
prevCommitment: pad(32, ""),
|
|
179
|
-
msgHash: msgHash
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
const finalState = fold(verifySignature, initialState, pubkeys, signatures);
|
|
183
|
-
// Thresh check not needed as it will always be 2
|
|
184
|
-
// Leaving it as defense-in-depth
|
|
185
|
-
Signer_assertThresholdMet(finalState.validCount);
|
|
152
|
+
EcdsaSignerManager_assertApprovals(msgHash, pubkeys, signatures);
|
|
186
153
|
|
|
187
154
|
_coinNonce = evolveNonce(_counter, _coinNonce);
|
|
188
155
|
mintShieldedToken(_tokenDomain, disclose(amount), _coinNonce, disclose(canonRecipient));
|
|
@@ -211,9 +178,7 @@ export circuit mint(
|
|
|
211
178
|
* The "multisig:burn:" domain prefix ensures burn signatures cannot be replayed
|
|
212
179
|
* as mint operations for the same parameters.
|
|
213
180
|
*
|
|
214
|
-
* @
|
|
215
|
-
* with `ecdsaVerify` once the Compact ECDSA and Keccak primitives are
|
|
216
|
-
* available, to match the custodian's HSM signing format.
|
|
181
|
+
* @circuitInfo k=17, rows=92170
|
|
217
182
|
*
|
|
218
183
|
* Requirements:
|
|
219
184
|
*
|
|
@@ -226,14 +191,14 @@ export circuit mint(
|
|
|
226
191
|
*
|
|
227
192
|
* @param {QualifiedShieldedCoinInfo} coin - The coin to burn (from operator's UTXO pool).
|
|
228
193
|
* @param {Uint<64>} amount - The token amount to burn.
|
|
229
|
-
* @param {Vector<2,
|
|
230
|
-
* @param {Vector<2,
|
|
194
|
+
* @param {Vector<2, Secp256k1Point>} pubkeys - Public keys of approving signers.
|
|
195
|
+
* @param {Vector<2, Secp256k1EcdsaSignature>} signatures - ECDSA signatures over the burn hash.
|
|
231
196
|
*/
|
|
232
197
|
export circuit burn(
|
|
233
198
|
coin: QualifiedShieldedCoinInfo,
|
|
234
199
|
amount: Uint<64>,
|
|
235
|
-
pubkeys: Vector<2,
|
|
236
|
-
signatures: Vector<2,
|
|
200
|
+
pubkeys: Vector<2, Secp256k1Point>,
|
|
201
|
+
signatures: Vector<2, Secp256k1EcdsaSignature>
|
|
237
202
|
): [] {
|
|
238
203
|
const opNonce = _counter;
|
|
239
204
|
_counter.increment(1);
|
|
@@ -245,16 +210,7 @@ export circuit burn(
|
|
|
245
210
|
amount as Bytes<32>
|
|
246
211
|
]);
|
|
247
212
|
|
|
248
|
-
|
|
249
|
-
validCount: 0 as Uint<8>,
|
|
250
|
-
prevCommitment: pad(32, ""),
|
|
251
|
-
msgHash: msgHash
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
const finalState = fold(verifySignature, initialState, pubkeys, signatures);
|
|
255
|
-
// Thresh check not needed as it will always be 2
|
|
256
|
-
// Leaving it as defense-in-depth
|
|
257
|
-
Signer_assertThresholdMet(finalState.validCount);
|
|
213
|
+
EcdsaSignerManager_assertApprovals(msgHash, pubkeys, signatures);
|
|
258
214
|
|
|
259
215
|
assert(coin.color == tokenType(_tokenDomain, kernel.self()), "Multisig: coin not from this contract");
|
|
260
216
|
assert(coin.value >= amount, "Multisig: insufficient coin value");
|
|
@@ -262,107 +218,94 @@ export circuit burn(
|
|
|
262
218
|
sendShielded(disclose(coin), shieldedBurnAddress(), disclose(amount));
|
|
263
219
|
}
|
|
264
220
|
|
|
265
|
-
// ───
|
|
221
|
+
// ─── Commitments ────────────────────────────────────────────────
|
|
266
222
|
|
|
267
223
|
/**
|
|
268
|
-
* @description
|
|
269
|
-
*
|
|
270
|
-
* Computes the signer's commitment from their public key and the instance
|
|
271
|
-
* salt, checks for duplicates against the previous commitment, verifies
|
|
272
|
-
* registry membership, and validates the ECDSA signature.
|
|
224
|
+
* @description Computes a signer commitment from a secp256k1 public key,
|
|
225
|
+
* as `persistentHash(pkX, pkY, salt, "multisig:signer:")`.
|
|
273
226
|
*
|
|
274
|
-
*
|
|
275
|
-
* supports only a fixed 2-of-3 configuration. Supporting more signatures
|
|
276
|
-
* (e.g. 3-of-N) requires a separate variant with a larger vector and a
|
|
277
|
-
* different duplicate-detection mechanism (sorted commitments or bitmap).
|
|
227
|
+
* Pure, so the deployer can derive constructor commitments off-chain.
|
|
278
228
|
*
|
|
279
|
-
*
|
|
280
|
-
* @param {Bytes<64>} pubkey - The signer's ECDSA public key.
|
|
281
|
-
* @param {Bytes<64>} signature - The signer's signature over msgHash.
|
|
282
|
-
* @returns {VerificationState} Updated accumulator.
|
|
283
|
-
*/
|
|
284
|
-
circuit verifySignature(
|
|
285
|
-
state: VerificationState,
|
|
286
|
-
pubkey: Bytes<64>,
|
|
287
|
-
signature: Bytes<64>
|
|
288
|
-
): VerificationState {
|
|
289
|
-
const commitment = _calculateSignerId(pubkey, _instanceSalt);
|
|
290
|
-
|
|
291
|
-
// Duplicate detection — sufficient for 2 signers only
|
|
292
|
-
assert(commitment != state.prevCommitment, "Multisig: duplicate signer");
|
|
293
|
-
|
|
294
|
-
Signer_assertSigner(commitment);
|
|
295
|
-
|
|
296
|
-
// TODO: Replace with ecdsaVerify + keccak256 when primitives are available
|
|
297
|
-
assert(stubVerifySignature(pubkey, state.msgHash, signature), "Multisig: invalid signature");
|
|
298
|
-
|
|
299
|
-
return VerificationState {
|
|
300
|
-
validCount: state.validCount + 1 as Uint<8>,
|
|
301
|
-
prevCommitment: commitment,
|
|
302
|
-
msgHash: state.msgHash
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* @description Computes a signer commitment from an ECDSA public key.
|
|
308
|
-
*
|
|
309
|
-
* The commitment is persistentHash(pk, salt, domain) where:
|
|
310
|
-
* - pk: the signer's ECDSA public key (64 bytes)
|
|
311
|
-
* - salt: instance-specific random value (prevents cross-contract correlation)
|
|
312
|
-
* - domain: "multisig:signer:" (domain separation)
|
|
229
|
+
* Requirements:
|
|
313
230
|
*
|
|
314
|
-
*
|
|
315
|
-
* commitments for the constructor.
|
|
231
|
+
* - `pk` must not be the secp256k1 identity point, which has no coordinates.
|
|
316
232
|
*
|
|
317
|
-
* @param {
|
|
233
|
+
* @param {Secp256k1Point} pk - The secp256k1 public key.
|
|
318
234
|
* @param {Bytes<32>} salt - The instance salt.
|
|
319
235
|
* @returns {Bytes<32>} The signer commitment.
|
|
320
236
|
*/
|
|
321
237
|
export pure circuit _calculateSignerId(
|
|
322
|
-
pk:
|
|
238
|
+
pk: Secp256k1Point,
|
|
323
239
|
salt: Bytes<32>
|
|
324
240
|
): Bytes<32> {
|
|
325
|
-
return
|
|
326
|
-
pk: pk,
|
|
327
|
-
salt: salt,
|
|
328
|
-
domain: pad(32, "multisig:signer:")
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* @description Stub for ECDSA signature verification.
|
|
334
|
-
* Always returns true. MUST be replaced before any non-test deployment.
|
|
335
|
-
*/
|
|
336
|
-
circuit stubVerifySignature(
|
|
337
|
-
pubkey: Bytes<64>,
|
|
338
|
-
msgHash: Bytes<32>,
|
|
339
|
-
signature: Bytes<64>
|
|
340
|
-
): Boolean {
|
|
341
|
-
return true;
|
|
241
|
+
return EcdsaSignerManager_calculateSignerId(pk, salt);
|
|
342
242
|
}
|
|
343
243
|
|
|
344
244
|
// ─── View ───────────────────────────────────────────────────────
|
|
345
245
|
|
|
246
|
+
/**
|
|
247
|
+
* @description Returns the counter the next mint or burn digest will bind to.
|
|
248
|
+
*
|
|
249
|
+
* @circuitInfo k=6, rows=34
|
|
250
|
+
*
|
|
251
|
+
* @returns {Uint<64>} The current counter.
|
|
252
|
+
*/
|
|
346
253
|
export circuit getNonce(): Uint<64> {
|
|
347
254
|
return _counter;
|
|
348
255
|
}
|
|
349
256
|
|
|
257
|
+
/**
|
|
258
|
+
* @description Returns the domain separator this contract's token type derives from.
|
|
259
|
+
*
|
|
260
|
+
* @circuitInfo k=6, rows=57
|
|
261
|
+
*
|
|
262
|
+
* @returns {Bytes<32>} The token domain.
|
|
263
|
+
*/
|
|
350
264
|
export circuit getTokenDomain(): Bytes<32> {
|
|
351
265
|
return _tokenDomain;
|
|
352
266
|
}
|
|
353
267
|
|
|
268
|
+
/**
|
|
269
|
+
* @description Returns this contract's token type.
|
|
270
|
+
*
|
|
271
|
+
* @circuitInfo k=13, rows=3836
|
|
272
|
+
*
|
|
273
|
+
* @returns {Bytes<32>} The token type.
|
|
274
|
+
*/
|
|
354
275
|
export circuit getTokenType(): Bytes<32> {
|
|
355
276
|
return tokenType(_tokenDomain, kernel.self());
|
|
356
277
|
}
|
|
357
278
|
|
|
279
|
+
/**
|
|
280
|
+
* @description Returns the number of registered signers.
|
|
281
|
+
*
|
|
282
|
+
* @circuitInfo k=6, rows=34
|
|
283
|
+
*
|
|
284
|
+
* @returns {Uint<8>} The signer count.
|
|
285
|
+
*/
|
|
358
286
|
export circuit getSignerCount(): Uint<8> {
|
|
359
|
-
return
|
|
287
|
+
return EcdsaSignerManager_getSignerCount();
|
|
360
288
|
}
|
|
361
289
|
|
|
290
|
+
/**
|
|
291
|
+
* @description Returns the approval threshold.
|
|
292
|
+
*
|
|
293
|
+
* @circuitInfo k=6, rows=34
|
|
294
|
+
*
|
|
295
|
+
* @returns {Uint<8>} The threshold.
|
|
296
|
+
*/
|
|
362
297
|
export circuit getThreshold(): Uint<8> {
|
|
363
|
-
return
|
|
298
|
+
return EcdsaSignerManager_getThreshold();
|
|
364
299
|
}
|
|
365
300
|
|
|
301
|
+
/**
|
|
302
|
+
* @description Returns whether the given commitment is a registered signer.
|
|
303
|
+
*
|
|
304
|
+
* @circuitInfo k=8, rows=129
|
|
305
|
+
*
|
|
306
|
+
* @param {Bytes<32>} commitment - The signer commitment to check.
|
|
307
|
+
* @returns {Boolean} True if registered.
|
|
308
|
+
*/
|
|
366
309
|
export circuit isSigner(commitment: Bytes<32>): Boolean {
|
|
367
|
-
return
|
|
310
|
+
return EcdsaSignerManager_isSigner(commitment);
|
|
368
311
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (multisig/presets/forwarder/ForwarderPrivate.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @title ForwarderPrivate
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (multisig/presets/forwarder/ForwarderShielded.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @title ForwarderShielded
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (multisig/presets/forwarder/ForwarderUnshielded.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @title ForwarderUnshielded
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openzeppelin/compact-contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0-alpha.1",
|
|
4
4
|
"description": "OpenZeppelin Compact contract library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openzeppelin",
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
"compile": "compact-compiler --exclude '*/archive/*'",
|
|
28
28
|
"compile:access": "compact-compiler --dir access",
|
|
29
29
|
"compile:archive": "compact-compiler --dir archive",
|
|
30
|
-
"compile:crypto": "compact-compiler --dir crypto",
|
|
31
|
-
"compile:multisig": "compact-compiler --dir multisig",
|
|
30
|
+
"compile:crypto": "compact-compiler --dir crypto --feature-zkir-v3",
|
|
31
|
+
"compile:multisig": "compact-compiler --dir multisig --feature-zkir-v3",
|
|
32
32
|
"compile:security": "compact-compiler --dir security",
|
|
33
33
|
"compile:token": "compact-compiler --dir token",
|
|
34
34
|
"compile:utils": "compact-compiler --dir utils",
|
|
35
|
-
"compile:integration": "
|
|
35
|
+
"compile:integration": "compact-compiler --src test/integration/_mocks",
|
|
36
36
|
"build": "compact-builder --hierarchical --out dist --clean-dist --exclude '*/archive/*' --exclude 'Mock*' --exclude '*.mock.compact' --copy package.json --copy ../README.md && find dist -type d -empty -delete",
|
|
37
37
|
"test": "vitest run --project unit",
|
|
38
38
|
"test:coverage": "vitest run --project unit --coverage",
|
|
@@ -46,24 +46,26 @@
|
|
|
46
46
|
"node": ">=22"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@openzeppelin/compact-cli": "^0.0.
|
|
49
|
+
"@openzeppelin/compact-cli": "^0.0.3"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@midnight-ntwrk/compact-js": "2.5.
|
|
53
|
-
"@midnight-ntwrk/compact-runtime": "0.
|
|
54
|
-
"@midnight-ntwrk/
|
|
55
|
-
"@midnight-ntwrk/midnight-js-
|
|
56
|
-
"@midnight-ntwrk/midnight-js-
|
|
57
|
-
"@midnight-ntwrk/midnight-js-
|
|
58
|
-
"@midnight-ntwrk/midnight-js-
|
|
59
|
-
"@midnight-ntwrk/midnight-js-
|
|
60
|
-
"@midnight-ntwrk/midnight-js-
|
|
61
|
-
"@midnight-ntwrk/
|
|
62
|
-
"@
|
|
63
|
-
"@
|
|
64
|
-
"@
|
|
65
|
-
"@
|
|
66
|
-
"@
|
|
52
|
+
"@midnight-ntwrk/compact-js": "2.5.5-rc.8",
|
|
53
|
+
"@midnight-ntwrk/compact-runtime": "0.19.0",
|
|
54
|
+
"@midnight-ntwrk/midnight-js-contracts": "5.0.0-beta.7",
|
|
55
|
+
"@midnight-ntwrk/midnight-js-http-client-proof-provider": "5.0.0-beta.7",
|
|
56
|
+
"@midnight-ntwrk/midnight-js-indexer-public-data-provider": "5.0.0-beta.7",
|
|
57
|
+
"@midnight-ntwrk/midnight-js-network-id": "5.0.0-beta.7",
|
|
58
|
+
"@midnight-ntwrk/midnight-js-node-zk-config-provider": "5.0.0-beta.7",
|
|
59
|
+
"@midnight-ntwrk/midnight-js-protocol": "5.0.0-beta.7",
|
|
60
|
+
"@midnight-ntwrk/midnight-js-types": "5.0.0-beta.7",
|
|
61
|
+
"@midnight-ntwrk/testkit-js": "5.0.0-beta.7",
|
|
62
|
+
"@midnightntwrk/ledger-v9": "1.0.0-rc.3",
|
|
63
|
+
"@midnightntwrk/wallet-sdk-address-format": "4.0.0-beta.2",
|
|
64
|
+
"@noble/curves": "^2.2.0",
|
|
65
|
+
"@openzeppelin/compact-simulator": "^0.4.0",
|
|
66
|
+
"@tsconfig/node24": "^24.0.5",
|
|
67
|
+
"@types/node": "26.4.0",
|
|
68
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
67
69
|
"fast-check": "^4.9.0",
|
|
68
70
|
"ts-node": "^10.9.2",
|
|
69
71
|
"typescript": "^6.0.3",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (security/Allowlist.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module Allowlist
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (security/Blocklist.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module Blocklist
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (security/Initializable.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module Initializable
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (security/Pausable.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module Pausable
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (token/ConfidentialFungibleToken.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module ConfidentialFungibleToken
|
|
@@ -131,7 +131,7 @@ pragma language_version >= 0.23.0;
|
|
|
131
131
|
* Midnight runtime enforcing two curve invariants this module does NOT re-check:
|
|
132
132
|
* every JubjubPoint reaching a curve op is cofactor-cleared into the prime-order
|
|
133
133
|
* subgroup (so off-curve, low-order, or mixed-order points make the circuit
|
|
134
|
-
* unsatisfiable), and
|
|
134
|
+
* unsatisfiable), and a scalar >= the subgroup order is rejected. These are
|
|
135
135
|
* regression-pinned with adversarial inputs in
|
|
136
136
|
* `crypto/test/CurveRuntimeInvariants.test.ts`, which fails loudly if a future
|
|
137
137
|
* runtime stops enforcing them. That is behavioral verification of the shipped
|
|
@@ -653,9 +653,9 @@ module ConfidentialFungibleToken {
|
|
|
653
653
|
const seed = wit_RandomnessSeed();
|
|
654
654
|
|
|
655
655
|
// Randomness must be a VALID Jubjub scalar. `transientHash`'s raw Field output
|
|
656
|
-
// can exceed the Jubjub scalar-field order
|
|
657
|
-
//
|
|
658
|
-
//
|
|
656
|
+
// can exceed the Jubjub scalar-field order, so each scalar is derived via
|
|
657
|
+
// `degradeToTransient(persistentHash(...))`, which truncates into the scalar
|
|
658
|
+
// field. The per-recipient count, folded into a
|
|
659
659
|
// Bytes<32> nonce, keeps each credit's randomness unique even if the seed
|
|
660
660
|
// repeats (essential for the memo OTP). This inlines the tag + expansion into
|
|
661
661
|
// a single hash per scalar. The residual persistentHash cost is poseidon-gated
|
|
@@ -669,10 +669,10 @@ module ConfidentialFungibleToken {
|
|
|
669
669
|
const countHash = persistentHash<Field>(count);
|
|
670
670
|
const rBalance = degradeToTransient(
|
|
671
671
|
persistentHash<Vector<4, Bytes<32>>>([seed, pad(32, "credit_balance"), account, countHash])
|
|
672
|
-
);
|
|
672
|
+
) as JubjubScalar;
|
|
673
673
|
const e = degradeToTransient(
|
|
674
674
|
persistentHash<Vector<4, Bytes<32>>>([seed, pad(32, "credit_memo"), account, countHash])
|
|
675
|
-
);
|
|
675
|
+
) as JubjubScalar;
|
|
676
676
|
|
|
677
677
|
// Credit lands in the recipient's PENDING pool (not spendable), so incoming
|
|
678
678
|
// value never churns their spendable ciphertext; they sweep it when ready.
|
|
@@ -1167,7 +1167,7 @@ module ConfidentialFungibleToken {
|
|
|
1167
1167
|
// never decrypted. Use an on-curve identity point (never a `default`,
|
|
1168
1168
|
// which is off-curve).
|
|
1169
1169
|
ownerMemo: EcdhMask_Ciphertext {
|
|
1170
|
-
ephemeralPk: ecMulGenerator(0 as
|
|
1170
|
+
ephemeralPk: ecMulGenerator(0 as JubjubScalar),
|
|
1171
1171
|
ct: 0 as Field
|
|
1172
1172
|
}
|
|
1173
1173
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (token/FungibleToken.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module FungibleToken
|
package/token/MultiToken.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.1 (token/MultiToken.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module MultiToken
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (token/NativeShieldedToken.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module NativeShieldedToken
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (token/NativeShieldedTokenCore.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module NativeShieldedTokenCore
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (token/NativeShieldedTokenFamily.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module NativeShieldedTokenFamily
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (token/NonFungibleToken.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module NonFungibleToken
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (token/extensions/ConfidentialFungibleTokenPublicSupply.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module ConfidentialFungibleTokenPublicSupply
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.1 (token/extensions/NativeShieldedTokenDerivedNonce.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module NativeShieldedTokenDerivedNonce
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
// OpenZeppelin Compact Contracts v0.2.0 (token/extensions/NativeShieldedTokenFamilyPublicSupply.compact)
|
|
3
3
|
|
|
4
|
-
pragma language_version >= 0.
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module NativeShieldedTokenFamilyPublicSupply
|