@iexec-nox/nox-protocol-contracts 0.1.0-beta.4 → 0.1.0-beta.6
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 +1 -2
- package/contracts/interfaces/INoxCompute.sol +228 -70
- package/contracts/sdk/Nox.sol +146 -114
- package/contracts/shared/TypeUtils.sol +2 -16
- package/package.json +11 -11
- package/contracts/interfaces/IACL.sol +0 -109
- package/contracts/interfaces/IErrors.sol +0 -14
package/README.md
CHANGED
|
@@ -4,9 +4,8 @@ Smart contracts for the Nox protocol, including on-chain access control for encr
|
|
|
4
4
|
|
|
5
5
|
## What’s inside
|
|
6
6
|
|
|
7
|
-
- `IACL`: access control list for encrypted handles (admins, viewers, public decryption flags).
|
|
8
7
|
- `INoxCompute`: TEE compute entry point (handle validation, plaintext → encrypted conversion, arithmetic ops).
|
|
9
|
-
- `Nox` SDK library: convenience wrapper for app contracts that call `NoxCompute
|
|
8
|
+
- `Nox` SDK library: convenience wrapper for app contracts that call `NoxCompute`.
|
|
10
9
|
|
|
11
10
|
## Requirements
|
|
12
11
|
|
|
@@ -1,18 +1,31 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
pragma solidity ^0.8.0;
|
|
3
3
|
|
|
4
|
-
import {IErrors} from "./IErrors.sol";
|
|
5
|
-
import {IACL} from "./IACL.sol";
|
|
6
4
|
import {TEEType} from "../shared/TypeUtils.sol";
|
|
7
5
|
|
|
8
6
|
/**
|
|
9
7
|
* @title INoxCompute
|
|
10
8
|
* @notice Interface for the Nox compute contract powered by TEE.
|
|
11
9
|
*/
|
|
12
|
-
interface INoxCompute
|
|
10
|
+
interface INoxCompute {
|
|
11
|
+
/// Error thrown when account address is zero
|
|
12
|
+
error InvalidZeroAddress();
|
|
13
|
+
/// Error thrown when bytes parameter is empty
|
|
14
|
+
error InvalidEmptyBytes();
|
|
15
|
+
/// Error thrown when sender doesn't have access to the handle
|
|
16
|
+
error UnauthorizedSender(address sender);
|
|
17
|
+
/// Error thrown when an account is not allowed to use a handle
|
|
18
|
+
error NotAllowed(bytes32 handle, address account);
|
|
13
19
|
error InvalidProof(bytes proof, string reason);
|
|
20
|
+
error UnsupportedType();
|
|
14
21
|
error IncompatibleTypes();
|
|
15
22
|
|
|
23
|
+
/// Emitted when admin role is granted
|
|
24
|
+
event Allowed(address indexed sender, address indexed account, bytes32 indexed handle);
|
|
25
|
+
/// Emitted when viewer role is granted
|
|
26
|
+
event ViewerAdded(address indexed sender, address indexed viewer, bytes32 indexed handle);
|
|
27
|
+
/// Emitted when a handle is marked as publicly decryptable
|
|
28
|
+
event MarkedAsPubliclyDecryptable(address indexed sender, bytes32 indexed handle);
|
|
16
29
|
event KmsPublicKeyUpdated(bytes newKmsPublicKey);
|
|
17
30
|
event GatewayUpdated(address indexed newGateway);
|
|
18
31
|
event ProofExpirationDurationUpdated(uint256 newDuration);
|
|
@@ -97,6 +110,20 @@ interface INoxCompute is IErrors {
|
|
|
97
110
|
bytes32 success,
|
|
98
111
|
bytes32 result
|
|
99
112
|
);
|
|
113
|
+
event SafeMul(
|
|
114
|
+
address indexed caller,
|
|
115
|
+
bytes32 leftHandOperand,
|
|
116
|
+
bytes32 rightHandOperand,
|
|
117
|
+
bytes32 success,
|
|
118
|
+
bytes32 result
|
|
119
|
+
);
|
|
120
|
+
event SafeDiv(
|
|
121
|
+
address indexed caller,
|
|
122
|
+
bytes32 numerator,
|
|
123
|
+
bytes32 denominator,
|
|
124
|
+
bytes32 success,
|
|
125
|
+
bytes32 result
|
|
126
|
+
);
|
|
100
127
|
event Select(
|
|
101
128
|
address indexed caller,
|
|
102
129
|
bytes32 condition,
|
|
@@ -140,6 +167,8 @@ interface INoxCompute is IErrors {
|
|
|
140
167
|
Div,
|
|
141
168
|
SafeAdd,
|
|
142
169
|
SafeSub,
|
|
170
|
+
SafeMul,
|
|
171
|
+
SafeDiv,
|
|
143
172
|
Select,
|
|
144
173
|
Eq,
|
|
145
174
|
Ne,
|
|
@@ -152,19 +181,83 @@ interface INoxCompute is IErrors {
|
|
|
152
181
|
Burn
|
|
153
182
|
}
|
|
154
183
|
|
|
184
|
+
// ------------- ACL functions -------------
|
|
185
|
+
|
|
155
186
|
/**
|
|
156
|
-
*
|
|
157
|
-
* @
|
|
187
|
+
* Grant admin role to another address for a specific handle
|
|
188
|
+
* @dev Caller must have access (transient OR persistent) to the handle
|
|
189
|
+
* @param handle The handle identifier
|
|
190
|
+
* @param account The address to grant admin role
|
|
158
191
|
*/
|
|
159
|
-
function
|
|
192
|
+
function allow(bytes32 handle, address account) external;
|
|
160
193
|
|
|
161
|
-
|
|
194
|
+
/**
|
|
195
|
+
* Allows the use of `handle` by address `account` for this transaction.
|
|
196
|
+
* @param handle Handle.
|
|
197
|
+
* @param account Address of the account.
|
|
198
|
+
*/
|
|
199
|
+
function allowTransient(bytes32 handle, address account) external;
|
|
162
200
|
|
|
163
201
|
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
202
|
+
* Removes all transient authorizations. This is useful for integration with Account Abstraction
|
|
203
|
+
* when bundling several UserOps calling the NoxCompute.
|
|
204
|
+
* @dev Can be called by anyone (typically by AA bundlers between UserOps).
|
|
166
205
|
*/
|
|
167
|
-
function
|
|
206
|
+
function cleanTransientStorage() external;
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Returns whether the account is allowed to use the `handle`, either due to
|
|
210
|
+
* allowTransient() or allow().
|
|
211
|
+
* @param handle Handle.
|
|
212
|
+
* @param account Address of the account.
|
|
213
|
+
* @return Whether the account can access the handle (persistent or transient).
|
|
214
|
+
*/
|
|
215
|
+
function isAllowed(bytes32 handle, address account) external view returns (bool);
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Checks whether the account is allowed to use all provided handles.
|
|
219
|
+
* Reverts with NotAllowed if any handle is not allowed.
|
|
220
|
+
* @param account Address of the account.
|
|
221
|
+
* @param handles Array of handles to check.
|
|
222
|
+
*/
|
|
223
|
+
function validateAllowedForAll(address account, bytes32[] calldata handles) external view;
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Add a viewer for a specific handle
|
|
227
|
+
* @dev Only an admin can add a viewer. The viewer address cannot be address(0).
|
|
228
|
+
* @param handle The handle identifier
|
|
229
|
+
* @param viewer The address to grant viewer role
|
|
230
|
+
*/
|
|
231
|
+
function addViewer(bytes32 handle, address viewer) external;
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Returns whether the account can view the handle.
|
|
235
|
+
* @dev Returns true if any of the following conditions are met:
|
|
236
|
+
* - The handle is publicly decryptable
|
|
237
|
+
* - The account was added as a viewer via `addViewer`
|
|
238
|
+
* - The account has persistent access (is allowed) on the handle
|
|
239
|
+
* @param handle Handle.
|
|
240
|
+
* @param viewer Address of the viewer.
|
|
241
|
+
* @return Whether the account can view the handle.
|
|
242
|
+
*/
|
|
243
|
+
function isViewer(bytes32 handle, address viewer) external view returns (bool);
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Mark a handle as publicly decryptable.
|
|
247
|
+
* @dev The caller must be allowed to use the handle.
|
|
248
|
+
* If not, the function reverts.
|
|
249
|
+
* @param handle Handle to mark as publicly decryptable.
|
|
250
|
+
*/
|
|
251
|
+
function allowPublicDecryption(bytes32 handle) external;
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Checks whether a handle is publicly decryptable.
|
|
255
|
+
* @param handle Handle.
|
|
256
|
+
* @return Whether the handle is publicly decryptable.
|
|
257
|
+
*/
|
|
258
|
+
function isPubliclyDecryptable(bytes32 handle) external view returns (bool);
|
|
259
|
+
|
|
260
|
+
// ------------- Compute functions -------------
|
|
168
261
|
|
|
169
262
|
/**
|
|
170
263
|
* @notice Converts a plaintext value into an encrypted value
|
|
@@ -175,7 +268,21 @@ interface INoxCompute is IErrors {
|
|
|
175
268
|
function plaintextToEncrypted(bytes32 value, TEEType teeType) external returns (bytes32);
|
|
176
269
|
|
|
177
270
|
/**
|
|
178
|
-
* @notice
|
|
271
|
+
* @notice Validates a handle proof for a given owner and type.
|
|
272
|
+
* @param handle handle to validate
|
|
273
|
+
* @param owner owner of the provided handle
|
|
274
|
+
* @param proof proof data
|
|
275
|
+
* @param teeType expected handle type
|
|
276
|
+
*/
|
|
277
|
+
function validateProof(
|
|
278
|
+
bytes32 handle,
|
|
279
|
+
address owner,
|
|
280
|
+
bytes calldata proof,
|
|
281
|
+
TEEType teeType
|
|
282
|
+
) external;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* @notice Performs an addition between two encrypted values without overflow check.
|
|
179
286
|
* @param leftHandOperand Left-hand side operand handle
|
|
180
287
|
* @param rightHandOperand Right-hand side operand handle
|
|
181
288
|
* @return result Result handle
|
|
@@ -186,7 +293,7 @@ interface INoxCompute is IErrors {
|
|
|
186
293
|
) external returns (bytes32 result);
|
|
187
294
|
|
|
188
295
|
/**
|
|
189
|
-
* @notice Performs a subtraction between two encrypted values without
|
|
296
|
+
* @notice Performs a subtraction between two encrypted values without underflow check.
|
|
190
297
|
* @param leftHandOperand Left-hand side operand handle
|
|
191
298
|
* @param rightHandOperand Right-hand side operand handle
|
|
192
299
|
* @return result Result handle
|
|
@@ -197,7 +304,21 @@ interface INoxCompute is IErrors {
|
|
|
197
304
|
) external returns (bytes32 result);
|
|
198
305
|
|
|
199
306
|
/**
|
|
200
|
-
* @notice Performs a
|
|
307
|
+
* @notice Performs a multiplication between two encrypted values without overflow check.
|
|
308
|
+
* @param leftHandOperand Left-hand side operand handle
|
|
309
|
+
* @param rightHandOperand Right-hand side operand handle
|
|
310
|
+
* @return result Result handle
|
|
311
|
+
*/
|
|
312
|
+
function mul(
|
|
313
|
+
bytes32 leftHandOperand,
|
|
314
|
+
bytes32 rightHandOperand
|
|
315
|
+
) external returns (bytes32 result);
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* @notice Performs a division between two encrypted values without safety checks.
|
|
319
|
+
* In the case of a division by zero, the result will be as follows:
|
|
320
|
+
* - For unsigned integers uintN: encrypted MAX_UintN (i.e., 2^N - 1)
|
|
321
|
+
* - For signed integers intN: encrypted MAX_IntN (i.e., 2^(N-1) - 1)
|
|
201
322
|
* @param numerator Value to be divided
|
|
202
323
|
* @param denominator Value to divide by
|
|
203
324
|
* @return result Result handle
|
|
@@ -205,15 +326,77 @@ interface INoxCompute is IErrors {
|
|
|
205
326
|
function div(bytes32 numerator, bytes32 denominator) external returns (bytes32 result);
|
|
206
327
|
|
|
207
328
|
/**
|
|
208
|
-
* @notice Performs
|
|
329
|
+
* @notice Performs an addition between two encrypted values with overflow check.
|
|
330
|
+
* If the operation succeeds, the value of the success handle will be an encrypted
|
|
331
|
+
* `true` and the result handle's value will be the encrypted sum.
|
|
332
|
+
* If the operation fails (e.g., due to overflow), the success handle will contain
|
|
333
|
+
* an encrypted `false` and the result handle will contain an encrypted `0`.
|
|
334
|
+
* @param leftHandOperand Left-hand side operand handle
|
|
335
|
+
* @param rightHandOperand Right-hand side operand handle
|
|
336
|
+
* @return success Whether the operation was successful
|
|
337
|
+
* @return result Result handle
|
|
338
|
+
*/
|
|
339
|
+
function safeAdd(
|
|
340
|
+
bytes32 leftHandOperand,
|
|
341
|
+
bytes32 rightHandOperand
|
|
342
|
+
) external returns (bytes32 success, bytes32 result);
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* @notice Performs a subtraction between two encrypted values with underflow check.
|
|
346
|
+
* If the operation succeeds, the value of the success handle will be an encrypted
|
|
347
|
+
* `true` and the result handle's value will be the encrypted difference.
|
|
348
|
+
* If the operation fails (e.g., due to underflow), the success handle will contain
|
|
349
|
+
* an encrypted `false` and the result handle will contain an encrypted `0`.
|
|
209
350
|
* @param leftHandOperand Left-hand side operand handle
|
|
210
351
|
* @param rightHandOperand Right-hand side operand handle
|
|
352
|
+
* @return success Whether the operation was successful
|
|
211
353
|
* @return result Result handle
|
|
212
354
|
*/
|
|
213
|
-
function
|
|
355
|
+
function safeSub(
|
|
214
356
|
bytes32 leftHandOperand,
|
|
215
357
|
bytes32 rightHandOperand
|
|
216
|
-
) external returns (bytes32 result);
|
|
358
|
+
) external returns (bytes32 success, bytes32 result);
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* @notice Performs a multiplication between two encrypted values with overflow check.
|
|
362
|
+
* If the operation succeeds, the value of the success handle will be an encrypted
|
|
363
|
+
* `true` and the result handle's value will be the encrypted product.
|
|
364
|
+
* If the operation fails (e.g., due to overflow), the success handle will contain
|
|
365
|
+
* an encrypted `false` and the result handle will contain an encrypted `0`.
|
|
366
|
+
* @param leftHandOperand Left-hand side operand handle
|
|
367
|
+
* @param rightHandOperand Right-hand side operand handle
|
|
368
|
+
* @return success Whether the operation was successful
|
|
369
|
+
* @return result Result handle
|
|
370
|
+
*/
|
|
371
|
+
function safeMul(
|
|
372
|
+
bytes32 leftHandOperand,
|
|
373
|
+
bytes32 rightHandOperand
|
|
374
|
+
) external returns (bytes32 success, bytes32 result);
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* @notice Performs a division between two encrypted values with division-by-zero check.
|
|
378
|
+
* If the operation succeeds, the value of the success handle will be an encrypted
|
|
379
|
+
* `true` and the result handle's value will be the encrypted quotient.
|
|
380
|
+
* If the operation fails (e.g., due to division by zero), the success handle will contain
|
|
381
|
+
* an encrypted `false` and the result handle will contain an encrypted `0`.
|
|
382
|
+
* @param numerator Value to be divided
|
|
383
|
+
* @param denominator Value to divide by
|
|
384
|
+
* @return success Whether the operation was successful
|
|
385
|
+
* @return result Result handle
|
|
386
|
+
*/
|
|
387
|
+
function safeDiv(
|
|
388
|
+
bytes32 numerator,
|
|
389
|
+
bytes32 denominator
|
|
390
|
+
) external returns (bytes32 success, bytes32 result);
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* @notice Selects between two encrypted values based on a condition
|
|
394
|
+
* @param condition Condition handle
|
|
395
|
+
* @param ifTrue Value handle if condition is true
|
|
396
|
+
* @param ifFalse Value handle if condition is false
|
|
397
|
+
* @return result Selected value handle
|
|
398
|
+
*/
|
|
399
|
+
function select(bytes32 condition, bytes32 ifTrue, bytes32 ifFalse) external returns (bytes32);
|
|
217
400
|
|
|
218
401
|
/**
|
|
219
402
|
* @notice Checks equality between two encrypted values
|
|
@@ -281,45 +464,12 @@ interface INoxCompute is IErrors {
|
|
|
281
464
|
bytes32 rightHandOperand
|
|
282
465
|
) external returns (bytes32 result);
|
|
283
466
|
|
|
284
|
-
// TODO for all safe operations, determine which cyphertexte linked to the new handle to return
|
|
285
|
-
// as result in case of failure.
|
|
286
|
-
/**
|
|
287
|
-
* @notice Performs an addition between two encrypted values with safety checks.
|
|
288
|
-
* The operation fails in the case of overflows.
|
|
289
|
-
* @param leftHandOperand Left-hand side operand handle
|
|
290
|
-
* @param rightHandOperand Right-hand side operand handle
|
|
291
|
-
* @return success Whether the operation was successful
|
|
292
|
-
* @return result Result handle
|
|
293
|
-
*/
|
|
294
|
-
function safeAdd(
|
|
295
|
-
bytes32 leftHandOperand,
|
|
296
|
-
bytes32 rightHandOperand
|
|
297
|
-
) external returns (bytes32 success, bytes32 result);
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* @notice Performs a subtraction between two encrypted values with safety checks.
|
|
301
|
-
* The operation fails in the case of underflow.
|
|
302
|
-
* @param leftHandOperand Left-hand side operand handle
|
|
303
|
-
* @param rightHandOperand Right-hand side operand handle
|
|
304
|
-
* @return success Whether the operation was successful
|
|
305
|
-
* @return result Result handle
|
|
306
|
-
*/
|
|
307
|
-
function safeSub(
|
|
308
|
-
bytes32 leftHandOperand,
|
|
309
|
-
bytes32 rightHandOperand
|
|
310
|
-
) external returns (bytes32 success, bytes32 result);
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* @notice Selects between two encrypted values based on a condition
|
|
314
|
-
* @param condition Condition handle
|
|
315
|
-
* @param ifTrue Value handle if condition is true
|
|
316
|
-
* @param ifFalse Value handle if condition is false
|
|
317
|
-
* @return result Selected value handle
|
|
318
|
-
*/
|
|
319
|
-
function select(bytes32 condition, bytes32 ifTrue, bytes32 ifFalse) external returns (bytes32);
|
|
320
|
-
|
|
321
467
|
/**
|
|
322
468
|
* @notice Computes a confidential transfer between two balances.
|
|
469
|
+
* The transfer will succeed if the sender has sufficient balance and fail otherwise.
|
|
470
|
+
* If the transfer fails, the success handle will contain an encrypted `false`, the
|
|
471
|
+
* newBalanceFrom and newBalanceTo handles will contain the same values as the input
|
|
472
|
+
* balanceFrom and balanceTo handles.
|
|
323
473
|
* @param balanceFrom Sender's current balance handle
|
|
324
474
|
* @param balanceTo Recipient's current balance handle
|
|
325
475
|
* @param amount Amount handle to transfer
|
|
@@ -335,6 +485,9 @@ interface INoxCompute is IErrors {
|
|
|
335
485
|
|
|
336
486
|
/**
|
|
337
487
|
* @notice Computes a confidential mint operation.
|
|
488
|
+
* If the minting operation fails (e.g., due to overflow), the success handle will
|
|
489
|
+
* contain an encrypted `false` and the newBalanceTo and newTotalSupply handles will
|
|
490
|
+
* contain the same values as the input balanceTo and totalSupply handles.
|
|
338
491
|
* @param balanceTo Recipient's current balance handle
|
|
339
492
|
* @param amount Amount handle to mint
|
|
340
493
|
* @param totalSupply Current total supply handle
|
|
@@ -350,6 +503,9 @@ interface INoxCompute is IErrors {
|
|
|
350
503
|
|
|
351
504
|
/**
|
|
352
505
|
* @notice Computes a confidential burn operation.
|
|
506
|
+
* If the burn operation fails (e.g., due to underflow), the success handle will
|
|
507
|
+
* contain an encrypted `false` and the newBalanceFrom and newTotalSupply handles will
|
|
508
|
+
* contain the same values as the input balanceFrom and totalSupply handles.
|
|
353
509
|
* @param balanceFrom Sender's current balance handle
|
|
354
510
|
* @param amount Amount handle to burn
|
|
355
511
|
* @param totalSupply Current total supply handle
|
|
@@ -363,25 +519,27 @@ interface INoxCompute is IErrors {
|
|
|
363
519
|
bytes32 totalSupply
|
|
364
520
|
) external returns (bytes32 success, bytes32 newBalanceFrom, bytes32 newTotalSupply);
|
|
365
521
|
|
|
366
|
-
|
|
367
|
-
bytes32 handle,
|
|
368
|
-
address owner,
|
|
369
|
-
bytes calldata proof,
|
|
370
|
-
TEEType teeType
|
|
371
|
-
) external;
|
|
522
|
+
// ------------- Admin functions -------------
|
|
372
523
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
function
|
|
524
|
+
/**
|
|
525
|
+
* @notice Sets the KMS public key used for ECIES encryption.
|
|
526
|
+
* @param newKmsPublicKey The compressed SEC1 secp256k1 public key (33 bytes)
|
|
527
|
+
*/
|
|
528
|
+
function setKmsPublicKey(bytes calldata newKmsPublicKey) external;
|
|
378
529
|
|
|
379
|
-
|
|
380
|
-
|
|
530
|
+
/**
|
|
531
|
+
* @notice Sets the gateway address in the contract's config.
|
|
532
|
+
* @param gatewayAddress The address of the gateway
|
|
533
|
+
*/
|
|
534
|
+
function setGateway(address gatewayAddress) external;
|
|
381
535
|
|
|
382
|
-
|
|
383
|
-
|
|
536
|
+
/**
|
|
537
|
+
* @notice Sets the proof expiration duration.
|
|
538
|
+
* @param newDuration The new expiration duration in seconds
|
|
539
|
+
*/
|
|
540
|
+
function setProofExpirationDuration(uint256 newDuration) external;
|
|
384
541
|
|
|
385
|
-
|
|
386
|
-
function
|
|
542
|
+
function kmsPublicKey() external view returns (bytes memory);
|
|
543
|
+
function gateway() external view returns (address);
|
|
544
|
+
function proofExpirationDuration() external view returns (uint256);
|
|
387
545
|
}
|