@inco/lightning 0.3.2 → 0.4.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
@@ -60,14 +60,6 @@ With a nod to the future we provide the `make release` target which performs a s
60
60
  1. PR to main
61
61
  2. Manually grab hash from dockerhub which is also `git describe --tags --always --dirty`
62
62
 
63
- ## Update denver multi-chain testnet
64
-
65
- 1. Copy docker tag into [Pulumi.multichain.yaml](../../infraco/pkg/denver/Pulumi.multichain.yaml)
66
- 2. Consider whether to cobber `requestConter.txt` and `lastBlock.txt` depending on the type of update:
67
- - If updating a covalidator to an existing contract use `--no-clobber`
68
- - If updating a covalidator to a new contract omit `--no-clobber`
69
- 3. Run `pulumi up`
70
-
71
63
  ## Manifest file
72
64
 
73
65
  [`manifest.yaml`](./manifest.yaml) is a file that tracks Inco Lightning smart contract releases (versioned instances of the executor contract) and deployments (actual instances of the contract on particular chains). The release names correspond to the names of the [solidity libs](./src/libs) that are libraries that statically link to the correct executor for the corresponding release.
package/manifest.yaml CHANGED
@@ -140,8 +140,8 @@ incoLightning_devnet_v0_340846814:
140
140
  salt: "0x8202d2d747784cb7d48868e44c42c4bf162a70bc00b001d6742fded0dd599ede"
141
141
  deployments:
142
142
  - name: incoLightningPreview_0_2_1__340846814
143
- chainId: "4801"
144
- chainName: World Chain Sepolia
143
+ chainId: "9746"
144
+ chainName: Plasma Testnet
145
145
  version:
146
146
  major: 0
147
147
  minor: 2
@@ -149,11 +149,11 @@ incoLightning_devnet_v0_340846814:
149
149
  shortSalt: "340846814"
150
150
  decryptSigner: "0x138AcbDC1FA02b955949d8Da09E546Ea7748710f"
151
151
  eciesPublicKey: "0x038a582d29083c2f3fefe024bf4dd9ab913ab8973716977da5f01106e0b84095b1"
152
- blockNumber: "17365942"
153
- deployDate: 2025-08-15T17:35:15.208Z
154
- commit: v0.2.17-35-g8cca6b4e-dirty
152
+ blockNumber: "1718868"
153
+ deployDate: 2025-09-10T15:20:25.654Z
154
+ commit: v6-7-gf96f358e-dirty
155
155
  active: true
156
- - name: incoLightningPreview_0_2_1__340846814
156
+ - name: incoLightning_0_2_1__340846814
157
157
  chainId: "9746"
158
158
  chainName: Plasma Testnet
159
159
  version:
@@ -162,11 +162,24 @@ incoLightning_devnet_v0_340846814:
162
162
  patch: 1
163
163
  shortSalt: "340846814"
164
164
  decryptSigner: "0x138AcbDC1FA02b955949d8Da09E546Ea7748710f"
165
- eciesPublicKey: "0x048a582d29083c2f3fefe024bf4dd9ab913ab8973716977da5f01106e0b8\
166
- 4095b1e647a9e377175fcb66bda05087c93b05e1fd53a704d0914bb23a0b2a69e9f235"
167
- blockNumber: "3339121"
168
- deployDate: 2025-08-07T12:14:56.788Z
169
- commit: v0.2.17-28-gfd11c1aa-dirty
165
+ eciesPublicKey: "0x038a582d29083c2f3fefe024bf4dd9ab913ab8973716977da5f01106e0b84095b1"
166
+ blockNumber: "1717229"
167
+ deployDate: 2025-09-10T14:53:07.218Z
168
+ commit: v6-7-gf96f358e-dirty
169
+ active: true
170
+ - name: incoLightningPreview_0_2_1__340846814
171
+ chainId: "4801"
172
+ chainName: World Chain Sepolia
173
+ version:
174
+ major: 0
175
+ minor: 2
176
+ patch: 1
177
+ shortSalt: "340846814"
178
+ decryptSigner: "0x138AcbDC1FA02b955949d8Da09E546Ea7748710f"
179
+ eciesPublicKey: "0x038a582d29083c2f3fefe024bf4dd9ab913ab8973716977da5f01106e0b84095b1"
180
+ blockNumber: "17365942"
181
+ deployDate: 2025-08-15T17:35:15.208Z
182
+ commit: v0.2.17-35-g8cca6b4e-dirty
170
183
  active: true
171
184
  - name: incoLightning_0_2_0__340846814
172
185
  chainId: "84532"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inco/lightning",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "repository": "https://github.com/Inco-fhevm/inco-monorepo",
5
5
  "files": [
6
6
  "src/",
@@ -410,6 +410,18 @@ library e {
410
410
  inco.allow(eaddress.unwrap(a), to);
411
411
  }
412
412
 
413
+ function reveal(euint256 a) internal {
414
+ inco.reveal(euint256.unwrap(a));
415
+ }
416
+
417
+ function reveal(ebool a) internal {
418
+ inco.reveal(ebool.unwrap(a));
419
+ }
420
+
421
+ function reveal(eaddress a) internal {
422
+ inco.reveal(eaddress.unwrap(a));
423
+ }
424
+
413
425
  function allowThis(euint256 a) internal {
414
426
  allow(a, address(this));
415
427
  }
@@ -410,6 +410,18 @@ library e {
410
410
  inco.allow(eaddress.unwrap(a), to);
411
411
  }
412
412
 
413
+ function reveal(euint256 a) internal {
414
+ inco.reveal(euint256.unwrap(a));
415
+ }
416
+
417
+ function reveal(ebool a) internal {
418
+ inco.reveal(ebool.unwrap(a));
419
+ }
420
+
421
+ function reveal(eaddress a) internal {
422
+ inco.reveal(eaddress.unwrap(a));
423
+ }
424
+
413
425
  function allowThis(euint256 a) internal {
414
426
  allow(a, address(this));
415
427
  }
@@ -410,6 +410,18 @@ library e {
410
410
  inco.allow(eaddress.unwrap(a), to);
411
411
  }
412
412
 
413
+ function reveal(euint256 a) internal {
414
+ inco.reveal(euint256.unwrap(a));
415
+ }
416
+
417
+ function reveal(ebool a) internal {
418
+ inco.reveal(ebool.unwrap(a));
419
+ }
420
+
421
+ function reveal(eaddress a) internal {
422
+ inco.reveal(eaddress.unwrap(a));
423
+ }
424
+
413
425
  function allowThis(euint256 a) internal {
414
426
  allow(a, address(this));
415
427
  }
package/src/Lib.sol CHANGED
@@ -410,6 +410,18 @@ library e {
410
410
  inco.allow(eaddress.unwrap(a), to);
411
411
  }
412
412
 
413
+ function reveal(euint256 a) internal {
414
+ inco.reveal(euint256.unwrap(a));
415
+ }
416
+
417
+ function reveal(ebool a) internal {
418
+ inco.reveal(ebool.unwrap(a));
419
+ }
420
+
421
+ function reveal(eaddress a) internal {
422
+ inco.reveal(eaddress.unwrap(a));
423
+ }
424
+
413
425
  function allowThis(euint256 a) internal {
414
426
  allow(a, address(this));
415
427
  }
@@ -444,6 +444,18 @@ library e {
444
444
  inco.allow(eaddress.unwrap(a), to);
445
445
  }
446
446
 
447
+ function reveal(euint256 a) internal {
448
+ inco.reveal(euint256.unwrap(a));
449
+ }
450
+
451
+ function reveal(ebool a) internal {
452
+ inco.reveal(ebool.unwrap(a));
453
+ }
454
+
455
+ function reveal(eaddress a) internal {
456
+ inco.reveal(eaddress.unwrap(a));
457
+ }
458
+
447
459
  function allowThis(euint256 a) internal {
448
460
  allow(a, address(this));
449
461
  }
@@ -410,6 +410,18 @@ library e {
410
410
  inco.allow(eaddress.unwrap(a), to);
411
411
  }
412
412
 
413
+ function reveal(euint256 a) internal {
414
+ inco.reveal(euint256.unwrap(a));
415
+ }
416
+
417
+ function reveal(ebool a) internal {
418
+ inco.reveal(ebool.unwrap(a));
419
+ }
420
+
421
+ function reveal(eaddress a) internal {
422
+ inco.reveal(eaddress.unwrap(a));
423
+ }
424
+
413
425
  function allowThis(euint256 a) internal {
414
426
  allow(a, address(this));
415
427
  }
@@ -410,6 +410,18 @@ library e {
410
410
  inco.allow(eaddress.unwrap(a), to);
411
411
  }
412
412
 
413
+ function reveal(euint256 a) internal {
414
+ inco.reveal(euint256.unwrap(a));
415
+ }
416
+
417
+ function reveal(ebool a) internal {
418
+ inco.reveal(ebool.unwrap(a));
419
+ }
420
+
421
+ function reveal(eaddress a) internal {
422
+ inco.reveal(eaddress.unwrap(a));
423
+ }
424
+
413
425
  function allowThis(euint256 a) internal {
414
426
  allow(a, address(this));
415
427
  }
@@ -410,6 +410,18 @@ library e {
410
410
  inco.allow(eaddress.unwrap(a), to);
411
411
  }
412
412
 
413
+ function reveal(euint256 a) internal {
414
+ inco.reveal(euint256.unwrap(a));
415
+ }
416
+
417
+ function reveal(ebool a) internal {
418
+ inco.reveal(ebool.unwrap(a));
419
+ }
420
+
421
+ function reveal(eaddress a) internal {
422
+ inco.reveal(eaddress.unwrap(a));
423
+ }
424
+
413
425
  function allowThis(euint256 a) internal {
414
426
  allow(a, address(this));
415
427
  }
@@ -410,6 +410,18 @@ library e {
410
410
  inco.allow(eaddress.unwrap(a), to);
411
411
  }
412
412
 
413
+ function reveal(euint256 a) internal {
414
+ inco.reveal(euint256.unwrap(a));
415
+ }
416
+
417
+ function reveal(ebool a) internal {
418
+ inco.reveal(ebool.unwrap(a));
419
+ }
420
+
421
+ function reveal(eaddress a) internal {
422
+ inco.reveal(eaddress.unwrap(a));
423
+ }
424
+
413
425
  function allowThis(euint256 a) internal {
414
426
  allow(a, address(this));
415
427
  }
@@ -410,6 +410,18 @@ library e {
410
410
  inco.allow(eaddress.unwrap(a), to);
411
411
  }
412
412
 
413
+ function reveal(euint256 a) internal {
414
+ inco.reveal(euint256.unwrap(a));
415
+ }
416
+
417
+ function reveal(ebool a) internal {
418
+ inco.reveal(ebool.unwrap(a));
419
+ }
420
+
421
+ function reveal(eaddress a) internal {
422
+ inco.reveal(eaddress.unwrap(a));
423
+ }
424
+
413
425
  function allowThis(euint256 a) internal {
414
426
  allow(a, address(this));
415
427
  }
@@ -7,6 +7,9 @@ interface IBaseAccessControlListGen {
7
7
  /// @dev persistent
8
8
  function allow(bytes32 handle, address account) external;
9
9
 
10
+ /// @dev Permanently allows public decryption/reencryption access to anyone for the given handle.
11
+ function reveal(bytes32 handle) external;
12
+
10
13
  function allowTransient(bytes32 handle, address account) external;
11
14
 
12
15
  function allowedTransient(bytes32 handle, address account) external view returns (bool);
@@ -16,4 +19,6 @@ interface IBaseAccessControlListGen {
16
19
  function persistAllowed(bytes32 handle, address account) external view returns (bool);
17
20
 
18
21
  function isAllowed(bytes32 handle, address account) external view returns (bool);
22
+
23
+ function isRevealed(bytes32 handle) external view returns (bool);
19
24
  }
@@ -7,6 +7,7 @@ import {IBaseAccessControlListGen} from "./BaseAccessControlList.gen.sol";
7
7
  contract AccessControlListStorage {
8
8
  struct ACLStorage {
9
9
  mapping(bytes32 handle => mapping(address account => bool isAllowed)) persistedAllowedPairs;
10
+ mapping(bytes32 handle => bool isAllowed) persistedAllowedForDecryption;
10
11
  }
11
12
 
12
13
  bytes32 private constant ACLStorageLocation = keccak256("inco.storage.ACL");
@@ -30,6 +31,16 @@ contract BaseAccessControlList is IBaseAccessControlListGen, AccessControlListSt
30
31
  allowInternal(handle, account);
31
32
  }
32
33
 
34
+ /// @dev Permanently allows public decryption/reencryption access to anyone for the given handle.
35
+ function reveal(bytes32 handle) public {
36
+ require(
37
+ isAllowed(handle, msg.sender),
38
+ SenderNotAllowedForHandle(handle, msg.sender)
39
+ );
40
+ ACLStorage storage $ = getACLStorage();
41
+ $.persistedAllowedForDecryption[handle] = true;
42
+ }
43
+
33
44
  /// @dev persistent
34
45
  function allowInternal(bytes32 handle, address account) internal {
35
46
  ACLStorage storage $ = getACLStorage();
@@ -101,6 +112,14 @@ contract BaseAccessControlList is IBaseAccessControlListGen, AccessControlListSt
101
112
  ) public view returns (bool) {
102
113
  return
103
114
  allowedTransient(handle, account) ||
104
- persistAllowed(handle, account);
115
+ persistAllowed(handle, account) ||
116
+ isRevealed(handle);
117
+ }
118
+
119
+ function isRevealed(
120
+ bytes32 handle
121
+ ) public view returns (bool) {
122
+ ACLStorage storage $ = getACLStorage();
123
+ return $.persistedAllowedForDecryption[handle];
105
124
  }
106
125
  }
@@ -1,12 +1,25 @@
1
1
  // SPDX-License-Identifier: No License
2
2
  pragma solidity ^0.8;
3
3
 
4
- import {TestUtils} from "@inco/shared/src/TestUtils.sol";
5
4
  import {BaseAccessControlList} from "../BaseAccessControlList.sol";
5
+ import {inco, e, euint256} from "@inco/lightning/src/Lib.sol";
6
+ import {IncoTest} from "@inco/lightning/src/test/IncoTest.sol";
7
+
8
+ contract TestBaseAccessControl is BaseAccessControlList, IncoTest {
9
+ using e for euint256;
6
10
 
7
- contract TestBaseAccessControl is BaseAccessControlList, TestUtils {
8
11
  function testHandleZeroIsDisallowed() public view {
9
12
  bytes32 handle = bytes32(0);
10
13
  assert(!isAllowed(handle, alice));
11
14
  }
15
+
16
+ function testReveal() public {
17
+ euint256 secret = inco.asEuint256(1337);
18
+ assert(inco.isAllowed(euint256.unwrap(secret), address(this)));
19
+ assert(!inco.isAllowed(euint256.unwrap(secret), alice));
20
+
21
+ inco.reveal(euint256.unwrap(secret));
22
+ assert(inco.isAllowed(euint256.unwrap(secret), address(this)));
23
+ assert(inco.isAllowed(euint256.unwrap(secret), alice));
24
+ }
12
25
  }
@@ -4,7 +4,7 @@ pragma solidity ^0.8;
4
4
  import { BaseAccessControlList } from "./AccessControl/BaseAccessControlList.sol";
5
5
  import { EventCounter } from "./primitives/EventCounter.sol";
6
6
  import { HandleGeneration } from "./primitives/HandleGeneration.sol";
7
- import { euint256, ebool, eaddress, ETypes, EVM_HOST_CHAIN_PREFIX, HANDLE_VERSION, HANDLE_INDEX } from "../Types.sol";
7
+ import { euint256, ebool, eaddress, EOps, ETypes, EVM_HOST_CHAIN_PREFIX, HANDLE_VERSION, HANDLE_INDEX } from "../Types.sol";
8
8
  import { HandleAlreadyExists } from "../Errors.sol";
9
9
 
10
10
  interface IEncryptedInputGen {
@@ -4,7 +4,7 @@ pragma solidity ^0.8;
4
4
  import {BaseAccessControlList} from "./AccessControl/BaseAccessControlList.sol";
5
5
  import {EventCounter} from "./primitives/EventCounter.sol";
6
6
  import {HandleGeneration} from "./primitives/HandleGeneration.sol";
7
- import {euint256, ebool, eaddress, ETypes, EVM_HOST_CHAIN_PREFIX, HANDLE_VERSION, HANDLE_INDEX} from "../Types.sol";
7
+ import {euint256, ebool, eaddress, EOps, ETypes, EVM_HOST_CHAIN_PREFIX, HANDLE_VERSION, HANDLE_INDEX} from "../Types.sol";
8
8
  import {IEncryptedInputGen} from "./EncryptedInput.gen.sol";
9
9
  import {HandleAlreadyExists} from "../Errors.sol";
10
10
 
@@ -57,13 +57,15 @@ abstract contract EncryptedInput is
57
57
  // We allow to user since this is harmless and it is convenient to use the allow mapping to track existing
58
58
  allowInternal(newHandle, user);
59
59
  allowTransientInternal(newHandle, msg.sender);
60
+ uint256 id = getNextEventId();
60
61
  emit NewInput(
61
62
  newHandle,
62
63
  msg.sender,
63
64
  user,
64
65
  inputType,
65
66
  ciphertext,
66
- getNewEventId()
67
+ id
67
68
  );
69
+ setDigest(abi.encodePacked(newHandle, id));
68
70
  }
69
71
  }
@@ -248,7 +248,9 @@ abstract contract EncryptedOperations is
248
248
  euint256.unwrap(rhs)
249
249
  )
250
250
  );
251
- emit EAdd(lhs, rhs, result, getNewEventId());
251
+ uint256 id = getNextEventId();
252
+ emit EAdd(lhs, rhs, result, id);
253
+ setDigest(abi.encodePacked(result, id));
252
254
  }
253
255
 
254
256
  function eSub(
@@ -263,7 +265,9 @@ abstract contract EncryptedOperations is
263
265
  euint256.unwrap(rhs)
264
266
  )
265
267
  );
266
- emit ESub(lhs, rhs, result, getNewEventId());
268
+ uint256 id = getNextEventId();
269
+ emit ESub(lhs, rhs, result, id);
270
+ setDigest(abi.encodePacked(result, id));
267
271
  }
268
272
 
269
273
  function eMul(
@@ -278,8 +282,10 @@ abstract contract EncryptedOperations is
278
282
  euint256.unwrap(rhs)
279
283
  )
280
284
  );
281
- emit EMul(lhs, rhs, result, getNewEventId());
282
- }
285
+ uint256 id = getNextEventId();
286
+ emit EMul(lhs, rhs, result, id);
287
+ setDigest(abi.encodePacked(result, id));
288
+ }
283
289
 
284
290
  function eDiv(
285
291
  euint256 lhs,
@@ -293,7 +299,9 @@ abstract contract EncryptedOperations is
293
299
  euint256.unwrap(rhs)
294
300
  )
295
301
  );
296
- emit EDiv(lhs, rhs, result, getNewEventId());
302
+ uint256 id = getNextEventId();
303
+ emit EDiv(lhs, rhs, result, id);
304
+ setDigest(abi.encodePacked(result, id));
297
305
  }
298
306
 
299
307
  function eRem(
@@ -308,7 +316,9 @@ abstract contract EncryptedOperations is
308
316
  euint256.unwrap(rhs)
309
317
  )
310
318
  );
311
- emit ERem(lhs, rhs, result, getNewEventId());
319
+ uint256 id = getNextEventId();
320
+ emit ERem(lhs, rhs, result, id);
321
+ setDigest(abi.encodePacked(result, id));
312
322
  }
313
323
 
314
324
  function eBitAnd(
@@ -321,7 +331,9 @@ abstract contract EncryptedOperations is
321
331
  checkInput(rhs, typeToBitMask(rhsType));
322
332
  require(lhsType == rhsType, UnexpectedType(lhsType, typeToBitMask(rhsType)));
323
333
  result = createResultHandle(EOps.BitAnd, lhsType, lhs, rhs);
324
- emit EBitAnd(lhs, rhs, result, getNewEventId());
334
+ uint256 id = getNextEventId();
335
+ emit EBitAnd(lhs, rhs, result, id);
336
+ setDigest(abi.encodePacked(result, id));
325
337
  }
326
338
 
327
339
  function eBitOr(
@@ -334,7 +346,9 @@ abstract contract EncryptedOperations is
334
346
  checkInput(rhs, typeToBitMask(rhsType));
335
347
  require(lhsType == rhsType, UnexpectedType(lhsType, typeToBitMask(rhsType)));
336
348
  result = createResultHandle(EOps.BitOr, lhsType, lhs, rhs);
337
- emit EBitOr(lhs, rhs, result, getNewEventId());
349
+ uint256 id = getNextEventId();
350
+ emit EBitOr(lhs, rhs, result, id);
351
+ setDigest(abi.encodePacked(result, id));
338
352
  }
339
353
 
340
354
  function eBitXor(
@@ -347,7 +361,9 @@ abstract contract EncryptedOperations is
347
361
  checkInput(rhs, typeToBitMask(rhsType));
348
362
  require(lhsType == rhsType, UnexpectedType(lhsType, typeToBitMask(rhsType)));
349
363
  result = createResultHandle(EOps.BitXor, lhsType, lhs, rhs);
350
- emit EBitXor(lhs, rhs, result, getNewEventId());
364
+ uint256 id = getNextEventId();
365
+ emit EBitXor(lhs, rhs, result, id);
366
+ setDigest(abi.encodePacked(result, id));
351
367
  }
352
368
 
353
369
  function eShl(
@@ -362,7 +378,9 @@ abstract contract EncryptedOperations is
362
378
  euint256.unwrap(rhs)
363
379
  )
364
380
  );
365
- emit EShl(lhs, rhs, result, getNewEventId());
381
+ uint256 id = getNextEventId();
382
+ emit EShl(lhs, rhs, result, id);
383
+ setDigest(abi.encodePacked(result, id));
366
384
  }
367
385
 
368
386
  function eShr(
@@ -377,7 +395,9 @@ abstract contract EncryptedOperations is
377
395
  euint256.unwrap(rhs)
378
396
  )
379
397
  );
380
- emit EShr(lhs, rhs, result, getNewEventId());
398
+ uint256 id = getNextEventId();
399
+ emit EShr(lhs, rhs, result, id);
400
+ setDigest(abi.encodePacked(result, id));
381
401
  }
382
402
 
383
403
  function eRotl(
@@ -392,7 +412,9 @@ abstract contract EncryptedOperations is
392
412
  euint256.unwrap(rhs)
393
413
  )
394
414
  );
395
- emit ERotl(lhs, rhs, result, getNewEventId());
415
+ uint256 id = getNextEventId();
416
+ emit ERotl(lhs, rhs, result, id);
417
+ setDigest(abi.encodePacked(result, id));
396
418
  }
397
419
 
398
420
  function eRotr(
@@ -407,7 +429,9 @@ abstract contract EncryptedOperations is
407
429
  euint256.unwrap(rhs)
408
430
  )
409
431
  );
410
- emit ERotr(lhs, rhs, result, getNewEventId());
432
+ uint256 id = getNextEventId();
433
+ emit ERotr(lhs, rhs, result, id);
434
+ setDigest(abi.encodePacked(result, id));
411
435
  }
412
436
 
413
437
  function eEq(
@@ -425,7 +449,9 @@ abstract contract EncryptedOperations is
425
449
  rhs
426
450
  )
427
451
  );
428
- emit EEq(lhs, rhs, result, getNewEventId());
452
+ uint256 id = getNextEventId();
453
+ emit EEq(lhs, rhs, result, id);
454
+ setDigest(abi.encodePacked(result, id));
429
455
  }
430
456
 
431
457
  function eNe(
@@ -443,7 +469,9 @@ abstract contract EncryptedOperations is
443
469
  rhs
444
470
  )
445
471
  );
446
- emit ENe(lhs, rhs, result, getNewEventId());
472
+ uint256 id = getNextEventId();
473
+ emit ENe(lhs, rhs, result, id);
474
+ setDigest(abi.encodePacked(result, id));
447
475
  }
448
476
 
449
477
  function eGe(
@@ -458,7 +486,9 @@ abstract contract EncryptedOperations is
458
486
  euint256.unwrap(rhs)
459
487
  )
460
488
  );
461
- emit EGe(lhs, rhs, result, getNewEventId());
489
+ uint256 id = getNextEventId();
490
+ emit EGe(lhs, rhs, result, id);
491
+ setDigest(abi.encodePacked(result, id));
462
492
  }
463
493
 
464
494
  function eGt(
@@ -473,7 +503,9 @@ abstract contract EncryptedOperations is
473
503
  euint256.unwrap(rhs)
474
504
  )
475
505
  );
476
- emit EGt(lhs, rhs, result, getNewEventId());
506
+ uint256 id = getNextEventId();
507
+ emit EGt(lhs, rhs, result, id);
508
+ setDigest(abi.encodePacked(result, id));
477
509
  }
478
510
 
479
511
  function eLe(
@@ -488,7 +520,9 @@ abstract contract EncryptedOperations is
488
520
  euint256.unwrap(rhs)
489
521
  )
490
522
  );
491
- emit ELe(lhs, rhs, result, getNewEventId());
523
+ uint256 id = getNextEventId();
524
+ emit ELe(lhs, rhs, result, id);
525
+ setDigest(abi.encodePacked(result, id));
492
526
  }
493
527
 
494
528
  function eLt(
@@ -503,7 +537,9 @@ abstract contract EncryptedOperations is
503
537
  euint256.unwrap(rhs)
504
538
  )
505
539
  );
506
- emit ELt(lhs, rhs, result, getNewEventId());
540
+ uint256 id = getNextEventId();
541
+ emit ELt(lhs, rhs, result, id);
542
+ setDigest(abi.encodePacked(result, id));
507
543
  }
508
544
 
509
545
  function eMin(
@@ -518,7 +554,9 @@ abstract contract EncryptedOperations is
518
554
  euint256.unwrap(rhs)
519
555
  )
520
556
  );
521
- emit EMin(lhs, rhs, result, getNewEventId());
557
+ uint256 id = getNextEventId();
558
+ emit EMin(lhs, rhs, result, id);
559
+ setDigest(abi.encodePacked(result, id));
522
560
  }
523
561
 
524
562
  function eMax(
@@ -533,7 +571,9 @@ abstract contract EncryptedOperations is
533
571
  euint256.unwrap(rhs)
534
572
  )
535
573
  );
536
- emit EMax(lhs, rhs, result, getNewEventId());
574
+ uint256 id = getNextEventId();
575
+ emit EMax(lhs, rhs, result, id);
576
+ setDigest(abi.encodePacked(result, id));
537
577
  }
538
578
 
539
579
  function eNot(ebool operand) external returns (ebool result) {
@@ -541,7 +581,9 @@ abstract contract EncryptedOperations is
541
581
  result = ebool.wrap(
542
582
  createResultHandle(EOps.Not, ETypes.Bool, ebool.unwrap(operand))
543
583
  );
544
- emit ENot(operand, result, getNewEventId());
584
+ uint256 id = getNextEventId();
585
+ emit ENot(operand, result, id);
586
+ setDigest(abi.encodePacked(result, id));
545
587
  }
546
588
 
547
589
  function eCast(
@@ -551,7 +593,9 @@ abstract contract EncryptedOperations is
551
593
  bytes32 baseHandle = keccak256(abi.encodePacked(EOps.Cast, ct, toType));
552
594
  result = embedTypeVersion(baseHandle, toType);
553
595
  allowTransientInternal(result, msg.sender);
554
- emit ECast(ct, uint8(toType), result, getNewEventId());
596
+ uint256 id = getNextEventId();
597
+ emit ECast(ct, uint8(toType), result, id);
598
+ setDigest(abi.encodePacked(result, id));
555
599
  }
556
600
 
557
601
  function eRand(
@@ -568,7 +612,9 @@ abstract contract EncryptedOperations is
568
612
  //NOTE: We pass the incremented randCounter which is incremented using postfix increment above.
569
613
  // Due to postfix returning the value before incrementing, the emitted randCounter will be larger by one than the number used to build the handle.
570
614
  // So for security and replayability reasons, we always use the incremented randCounter when seeding on the covalidator side, which is fine for as long as we're consistent.
571
- emit ERand(randCounter, randType, result, getNewEventId());
615
+ uint256 id = getNextEventId();
616
+ emit ERand(randCounter, randType, result, id);
617
+ setDigest(abi.encodePacked(result, id));
572
618
  }
573
619
 
574
620
  function eRandBounded(
@@ -588,7 +634,9 @@ abstract contract EncryptedOperations is
588
634
  //NOTE: We pass the incremented randCounter which is incremented using postfix increment above.
589
635
  // Due to postfix returning the value before incrementing, the emitted randCounter will be larger by one than the number used to build the handle.
590
636
  // So for security and replayability reasons, we always use the incremented randCounter when seeding on the covalidator side, which is fine for as long as we're consistent.
591
- emit ERandBounded(randCounter, randType, upperBound, result, getNewEventId());
637
+ uint256 id = getNextEventId();
638
+ emit ERandBounded(randCounter, randType, upperBound, result, id);
639
+ setDigest(abi.encodePacked(result, id));
592
640
  }
593
641
 
594
642
  // todo add support in testing framework
@@ -608,7 +656,9 @@ abstract contract EncryptedOperations is
608
656
  );
609
657
  result = embedTypeVersion(baseHandle, returnType);
610
658
  allowTransientInternal(result, msg.sender);
611
- emit EIfThenElse(control, ifTrue, ifFalse, result, getNewEventId());
659
+ uint256 id = getNextEventId();
660
+ emit EIfThenElse(control, ifTrue, ifFalse, result, id);
661
+ setDigest(abi.encodePacked(result, id));
612
662
  }
613
663
 
614
664
  function checkEIfThenElseInputs(
@@ -2,7 +2,7 @@
2
2
  pragma solidity ^0.8;
3
3
 
4
4
  import { EventCounter } from "./primitives/EventCounter.sol";
5
- import { euint256, ebool, eaddress, ETypes } from "../Types.sol";
5
+ import { euint256, ebool, eaddress, EOps, ETypes } from "../Types.sol";
6
6
  import { BaseAccessControlList } from "./AccessControl/BaseAccessControlList.sol";
7
7
  import { HandleGeneration } from "./primitives/HandleGeneration.sol";
8
8
 
@@ -2,7 +2,7 @@
2
2
  pragma solidity ^0.8;
3
3
 
4
4
  import {EventCounter} from "./primitives/EventCounter.sol";
5
- import {euint256, ebool, eaddress, ETypes} from "../Types.sol";
5
+ import {euint256, ebool, eaddress, EOps, ETypes} from "../Types.sol";
6
6
  import {BaseAccessControlList} from "./AccessControl/BaseAccessControlList.sol";
7
7
  import {HandleGeneration} from "./primitives/HandleGeneration.sol";
8
8
  import {ITrivialEncryptionGen} from "./TrivialEncryption.gen.sol";
@@ -40,11 +40,13 @@ abstract contract TrivialEncryption is
40
40
  ) internal returns (bytes32 newHandle) {
41
41
  newHandle = getTrivialEncryptHandle(plainTextBytes, handleType);
42
42
  allowTransientInternal(newHandle, msg.sender);
43
+ uint256 id = getNextEventId();
43
44
  emit TrivialEncrypt(
44
45
  newHandle,
45
46
  plainTextBytes,
46
47
  handleType,
47
- getNewEventId()
48
+ id
48
49
  );
50
+ setDigest(abi.encodePacked(newHandle, id));
49
51
  }
50
52
  }
@@ -2,5 +2,7 @@
2
2
  pragma solidity ^0.8;
3
3
 
4
4
  interface IEventCounterGen {
5
+ function getNextEventId() external view returns (uint256);
6
+
5
7
  function getEventCounter() external view returns (uint256);
6
8
  }
@@ -5,6 +5,7 @@ import {IEventCounterGen} from "./EventCounter.gen.sol";
5
5
 
6
6
  contract EventCounterStorage {
7
7
  struct Storage {
8
+ // TODO: change type to bytes32 when we rename away from "counter".
8
9
  uint256 eventCounter;
9
10
  }
10
11
 
@@ -28,7 +29,18 @@ contract EventCounter is IEventCounterGen, EventCounterStorage {
28
29
  newEventId = getEventCounterStorage().eventCounter++;
29
30
  }
30
31
 
31
- function getEventCounter() external view returns (uint256) {
32
+ function setDigest(bytes memory serialization) internal {
33
+ getEventCounterStorage().eventCounter = uint256(keccak256(serialization));
34
+ }
35
+
36
+ // @notice Gives the next event ID value to use.
37
+ function getNextEventId() public view returns (uint256) {
32
38
  return getEventCounterStorage().eventCounter;
33
39
  }
40
+
41
+ // @notice Gives the current value of the event counter.
42
+ // @dev DEPRECATED: use getNextEventId() instead.
43
+ function getEventCounter() public view returns (uint256) {
44
+ return getNextEventId();
45
+ }
34
46
  }
@@ -24,20 +24,31 @@ contract AddTwo {
24
24
  return inco.eAdd(a, inco.asEuint256(two));
25
25
  }
26
26
 
27
+ // To generate a different handle with the same result, instead of adding 2 we add 1 + 1
28
+ function addTwoAlt(euint256 a) external returns (euint256) {
29
+ uint256 one = 1;
30
+ return inco.eAdd(a, inco.eAdd(inco.asEuint256(one), inco.asEuint256(one)));
31
+ }
32
+
27
33
  function addTwoEOA(
28
34
  bytes memory uint256EInput
29
- ) external returns (uint256, euint256) {
35
+ ) external returns (uint256, euint256, euint256) {
30
36
  euint256 value = inco.newEuint256(uint256EInput, msg.sender);
31
37
  euint256 result = this.addTwo(value);
32
38
  inco.allow(euint256.unwrap(result), address(this));
33
39
  inco.allow(euint256.unwrap(result), msg.sender);
40
+
41
+ // Used to test attested reveal functionality. Note that msg.sender is not allowed, instead we call .reveal() that gives permission to anyone.
42
+ euint256 resultRevealed = this.addTwoAlt(value);
43
+ inco.reveal(euint256.unwrap(resultRevealed));
44
+
34
45
  uint256 requestId = inco.requestDecryption(
35
46
  this.callback.selector,
36
47
  block.timestamp + 2 hours,
37
48
  euint256.unwrap(result),
38
49
  ""
39
50
  );
40
- return (requestId, result);
51
+ return (requestId, result, resultRevealed);
41
52
  }
42
53
 
43
54
  function callback(