@inco/lightning 0.3.2 → 0.5.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.
Files changed (108) hide show
  1. package/README.md +2 -8
  2. package/manifest.yaml +24 -11
  3. package/package.json +2 -5
  4. package/src/DeployUtils.sol +113 -77
  5. package/src/IIncoLightning.sol +16 -9
  6. package/src/IncoLightning.sol +18 -9
  7. package/src/IncoVerifier.sol +47 -0
  8. package/src/Lib.alphanet.sol +14 -15
  9. package/src/Lib.demonet.sol +14 -15
  10. package/src/Lib.devnet.sol +14 -15
  11. package/src/Lib.sol +14 -15
  12. package/src/Lib.template.sol +15 -44
  13. package/src/Lib.testnet.sol +14 -15
  14. package/src/Types.sol +7 -0
  15. package/src/interfaces/IIncoLightning.sol +20 -0
  16. package/src/interfaces/IIncoVerifier.sol +24 -0
  17. package/src/interfaces/automata-interfaces/BELE.sol +20 -0
  18. package/src/interfaces/automata-interfaces/IAutomataEnclaveIdentityDao.sol +28 -0
  19. package/src/interfaces/automata-interfaces/IFmspcTcbDao.sol +10 -0
  20. package/src/interfaces/automata-interfaces/IPCCSRouter.sol +94 -0
  21. package/src/interfaces/automata-interfaces/IPCCSRouterExtended.sol +10 -0
  22. package/src/interfaces/automata-interfaces/IPcsDao.sol +18 -0
  23. package/src/interfaces/automata-interfaces/IQuoteVerifier.sol +34 -0
  24. package/src/interfaces/automata-interfaces/Types.sol +193 -0
  25. package/src/libs/incoLightning_alphanet_v0_297966649.sol +14 -15
  26. package/src/libs/incoLightning_demonet_v0_863421733.sol +14 -15
  27. package/src/libs/incoLightning_devnet_v0_340846814.sol +14 -15
  28. package/src/libs/incoLightning_testnet_v0_183408998.sol +14 -15
  29. package/src/libs/incoLightning_testnet_v1_938327937.sol +451 -0
  30. package/src/lightning-parts/AccessControl/AdvancedAccessControl.sol +133 -0
  31. package/src/lightning-parts/AccessControl/AdvancedAccessControl.types.sol +18 -0
  32. package/src/lightning-parts/AccessControl/BaseAccessControlList.sol +42 -3
  33. package/src/lightning-parts/AccessControl/interfaces/IAdvancedAccessControl.sol +25 -0
  34. package/src/lightning-parts/AccessControl/interfaces/IBaseAccessControlList.sol +24 -0
  35. package/src/lightning-parts/AccessControl/test/TestAdvancedAccessControl.t.sol +234 -0
  36. package/src/lightning-parts/AccessControl/test/TestBaseAccessControl.t.sol +16 -2
  37. package/src/lightning-parts/DecryptionAttester.sol +45 -0
  38. package/src/lightning-parts/DecryptionAttester.types.sol +7 -0
  39. package/src/lightning-parts/EncryptedInput.sol +10 -13
  40. package/src/lightning-parts/EncryptedOperations.sol +78 -28
  41. package/src/lightning-parts/TEELifecycle.sol +180 -88
  42. package/src/lightning-parts/TrivialEncryption.sol +9 -9
  43. package/src/lightning-parts/interfaces/IDecryptionAttester.sol +9 -0
  44. package/src/lightning-parts/interfaces/IEncryptedInput.sol +19 -0
  45. package/src/lightning-parts/interfaces/IEncryptedOperations.sol +31 -0
  46. package/src/lightning-parts/interfaces/ITEELifecycle.sol +26 -0
  47. package/src/lightning-parts/interfaces/ITrivialEncryption.sol +10 -0
  48. package/src/lightning-parts/primitives/EventCounter.sol +15 -3
  49. package/src/lightning-parts/primitives/HandleGeneration.sol +8 -3
  50. package/src/lightning-parts/primitives/HandleMetadata.sol +1 -1
  51. package/src/lightning-parts/primitives/LightningAddressGetter.sol +10 -0
  52. package/src/lightning-parts/primitives/SignatureVerifier.sol +2 -9
  53. package/src/lightning-parts/primitives/VerifierAddressGetter.sol +13 -0
  54. package/src/lightning-parts/primitives/{EventCounter.gen.sol → interfaces/IEventCounter.sol} +4 -2
  55. package/src/lightning-parts/primitives/interfaces/IHandleGeneration.sol +41 -0
  56. package/src/lightning-parts/primitives/interfaces/ISignatureVerifier.sol +9 -0
  57. package/src/lightning-parts/primitives/interfaces/IVerifierAddressGetter.sol +8 -0
  58. package/src/lightning-parts/test/HandleMetadata.t.sol +25 -6
  59. package/src/lightning-parts/test/TestDecryptionAttestationInSynchronousFlow.t.sol +78 -0
  60. package/src/periphery/SessionVerifier.sol +63 -0
  61. package/src/test/AddTwo.sol +20 -24
  62. package/src/test/FakeIncoInfra/FakeDecryptionAttester.sol +198 -0
  63. package/src/test/FakeIncoInfra/FakeIncoInfraBase.sol +0 -15
  64. package/src/test/FakeIncoInfra/FakeQuoteVerifier.sol +10 -6
  65. package/src/test/FakeIncoInfra/MockOpHandler.sol +0 -7
  66. package/src/test/FakeIncoInfra/MockRemoteAttestation.sol +19 -7
  67. package/src/test/FakeIncoInfra/getOpForSelector.sol +0 -3
  68. package/src/test/IncoTest.sol +12 -11
  69. package/src/test/TEELifecycle/TEELifecycleMockTest.t.sol +98 -77
  70. package/src/test/TestAddTwo.t.sol +16 -9
  71. package/src/test/TestFakeInfra.t.sol +10 -27
  72. package/src/test/TestUpgrade.t.sol +11 -4
  73. package/src/test/TestVersion.t.sol +0 -7
  74. package/src/version/IncoLightningConfig.sol +4 -3
  75. package/src/version/SessionVerifierConfig.sol +8 -0
  76. package/src/version/Version.sol +7 -9
  77. package/src/version/interfaces/IVersion.sol +8 -0
  78. package/src/DeployTEE.sol +0 -153
  79. package/src/IncoLightning.gen.sol +0 -15
  80. package/src/lightning-parts/AccessControl/BaseAccessControlList.gen.sol +0 -19
  81. package/src/lightning-parts/DecryptionHandler.gen.sol +0 -54
  82. package/src/lightning-parts/DecryptionHandler.sol +0 -307
  83. package/src/lightning-parts/DecryptionHandler.types.sol +0 -34
  84. package/src/lightning-parts/EncryptedInput.gen.sol +0 -16
  85. package/src/lightning-parts/EncryptedOperations.gen.sol +0 -59
  86. package/src/lightning-parts/TEELifecycle.gen.sol +0 -58
  87. package/src/lightning-parts/TrivialEncryption.gen.sol +0 -15
  88. package/src/lightning-parts/primitives/HandleGeneration.gen.sol +0 -19
  89. package/src/lightning-parts/primitives/HandleMetadata.gen.sol +0 -4
  90. package/src/lightning-parts/primitives/SignatureVerifier.gen.sol +0 -16
  91. package/src/test/FibonacciDecrypt.sol +0 -49
  92. package/src/test/TEELifecycle/TEELifecycleHWTest.t.sol +0 -119
  93. package/src/test/TEELifecycle/addnode_data/eoa.txt +0 -1
  94. package/src/test/TEELifecycle/addnode_data/quote.bin +0 -0
  95. package/src/test/TEELifecycle/bootstrap_data/ecies_pubkey.bin +0 -1
  96. package/src/test/TEELifecycle/bootstrap_data/eip712_signature.bin +0 -1
  97. package/src/test/TEELifecycle/bootstrap_data/eoa.txt +0 -1
  98. package/src/test/TEELifecycle/bootstrap_data/qe_identity +0 -1
  99. package/src/test/TEELifecycle/bootstrap_data/qe_identity_signature.bin +0 -1
  100. package/src/test/TEELifecycle/bootstrap_data/quote.bin +0 -0
  101. package/src/test/TEELifecycle/bootstrap_data/tcb_info +0 -1
  102. package/src/test/TEELifecycle/bootstrap_data/tcb_info_signature.bin +0 -1
  103. package/src/test/TEELifecycle/test_cert/AttestationReportSigningCA.crl +0 -0
  104. package/src/test/TEELifecycle/test_cert/Intel_SGX_Attestation_RootCA.cer +0 -0
  105. package/src/test/TEELifecycle/test_cert/Intel_SGX_PCK_CRL.crl +0 -0
  106. package/src/test/TEELifecycle/test_cert/Intel_SGX_PCK_PlatformCA.cer +0 -0
  107. package/src/test/TEELifecycle/test_cert/Intel_SGX_TCB_Signing.cer +0 -0
  108. package/src/version/Version.gen.sol +0 -14
@@ -0,0 +1,133 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {AllowanceVoucher, AllowanceProof} from "./AdvancedAccessControl.types.sol";
5
+ import {ALLOWANCE_GRANTED_MAGIC_VALUE} from "../../Types.sol";
6
+ import {EIP712Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol";
7
+ import {IAdvancedAccessControl, IVoucherEip712Checker} from "./interfaces/IAdvancedAccessControl.sol";
8
+ import {SharerNotAllowedForHandle} from "../../Types.sol";
9
+ import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
10
+ import {IBaseAccessControlList} from "./interfaces/IBaseAccessControlList.sol";
11
+ import {LightningAddressGetter} from "../primitives/LightningAddressGetter.sol";
12
+
13
+ abstract contract AdvancedAccessControlStorage {
14
+ struct AACStorage {
15
+ mapping(address => bytes32) activeVouchersSessionNonce; // initial session nonce is 0
16
+ }
17
+
18
+ bytes32 private constant AACStorageLocation =
19
+ keccak256("inco.storage.AdvancedAccessControl");
20
+
21
+ function getAACStorage() internal pure returns (AACStorage storage $) {
22
+ bytes32 loc = AACStorageLocation;
23
+ assembly {
24
+ $.slot := loc
25
+ }
26
+ }
27
+ }
28
+
29
+ abstract contract VoucherEip712Checker is IVoucherEip712Checker, EIP712Upgradeable {
30
+ bytes32 constant AllowanceVoucherStructHash =
31
+ keccak256(
32
+ "AllowanceVoucher(bytes32 sessionNonce,address verifyingContract,bytes4 callFunction,bytes sharerArgData)"
33
+ );
34
+
35
+ function allowanceVoucherDigest(
36
+ AllowanceVoucher memory voucher
37
+ ) public view returns (bytes32) {
38
+ return
39
+ _hashTypedDataV4(
40
+ keccak256(
41
+ abi.encode(
42
+ AllowanceVoucherStructHash,
43
+ voucher.sessionNonce,
44
+ voucher.verifyingContract,
45
+ voucher.callFunction,
46
+ keccak256(voucher.sharerArgData)
47
+ )
48
+ )
49
+ );
50
+ }
51
+ }
52
+
53
+ abstract contract AdvancedAccessControl is
54
+ IAdvancedAccessControl,
55
+ AdvancedAccessControlStorage,
56
+ VoucherEip712Checker,
57
+ LightningAddressGetter
58
+ {
59
+ using SignatureChecker for address;
60
+
61
+ error InvalidVoucherSignature(
62
+ address signer,
63
+ bytes32 digest,
64
+ bytes signature
65
+ );
66
+ error InvalidVoucherSessionNonce(
67
+ bytes32 providedSessionNonce,
68
+ bytes32 activeSessionNonce
69
+ );
70
+
71
+ /// @dev meant to for simulation, can't be a view function as it calls other contracts
72
+ /// @dev returns true if the account is allowed to access the handle, false or reverts otherwise
73
+ function isAllowedWithProof(
74
+ bytes32 handle,
75
+ address account,
76
+ AllowanceProof memory proof
77
+ ) public returns (bool) {
78
+ require(
79
+ IBaseAccessControlList(incoLightningAddress).isAllowed(handle, proof.sharer),
80
+ SharerNotAllowedForHandle(handle, proof.sharer)
81
+ );
82
+ bytes32 voucherDigest = allowanceVoucherDigest(proof.voucher);
83
+ require(
84
+ proof.sharer.isValidSignatureNow(
85
+ voucherDigest,
86
+ proof.voucherSignature
87
+ ),
88
+ InvalidVoucherSignature(
89
+ proof.sharer,
90
+ voucherDigest,
91
+ proof.voucherSignature
92
+ )
93
+ );
94
+ bytes32 sharerActiveVouchersSessionNonce = getActiveVouchersSessionNonce(
95
+ proof.sharer
96
+ );
97
+ require(
98
+ proof.voucher.sessionNonce == sharerActiveVouchersSessionNonce,
99
+ InvalidVoucherSessionNonce(
100
+ proof.voucher.sessionNonce,
101
+ sharerActiveVouchersSessionNonce
102
+ )
103
+ );
104
+ (bool success, bytes memory result) = proof
105
+ .voucher
106
+ .verifyingContract
107
+ .call(
108
+ abi.encodeWithSelector(
109
+ proof.voucher.callFunction,
110
+ handle,
111
+ account,
112
+ proof.voucher.sharerArgData,
113
+ proof.requesterArgData
114
+ )
115
+ );
116
+ return (success &&
117
+ result.length >= 32 &&
118
+ abi.decode(result, (bytes32)) == ALLOWANCE_GRANTED_MAGIC_VALUE);
119
+ }
120
+
121
+ function getActiveVouchersSessionNonce(
122
+ address account
123
+ ) public view returns (bytes32) {
124
+ return getAACStorage().activeVouchersSessionNonce[account];
125
+ }
126
+
127
+ /// @notice invalidates all previously signed vouchers
128
+ function updateActiveVouchersSessionNonce() external {
129
+ getAACStorage().activeVouchersSessionNonce[msg.sender] = keccak256(
130
+ abi.encodePacked(msg.sender, block.prevrandao)
131
+ );
132
+ }
133
+ }
@@ -0,0 +1,18 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ // can be for arbitrary handles to arbitrary accounts
5
+ // signed by the account sharing its read access
6
+ struct AllowanceVoucher {
7
+ bytes32 sessionNonce;
8
+ address verifyingContract;
9
+ bytes4 callFunction;
10
+ bytes sharerArgData;
11
+ }
12
+
13
+ struct AllowanceProof {
14
+ address sharer;
15
+ AllowanceVoucher voucher;
16
+ bytes voucherSignature;
17
+ bytes requesterArgData;
18
+ }
@@ -2,11 +2,14 @@
2
2
  pragma solidity ^0.8;
3
3
 
4
4
  import {SenderNotAllowedForHandle} from "../../Types.sol";
5
- import {IBaseAccessControlListGen} from "./BaseAccessControlList.gen.sol";
5
+ import {IBaseAccessControlList} from "./interfaces/IBaseAccessControlList.sol";
6
+ import {VerifierAddressGetter} from "../primitives/VerifierAddressGetter.sol";
7
+ import {AllowanceProof} from "../AccessControl/AdvancedAccessControl.types.sol";
6
8
 
7
9
  contract AccessControlListStorage {
8
10
  struct ACLStorage {
9
11
  mapping(bytes32 handle => mapping(address account => bool isAllowed)) persistedAllowedPairs;
12
+ mapping(bytes32 handle => bool isAllowed) persistedAllowedForDecryption;
10
13
  }
11
14
 
12
15
  bytes32 private constant ACLStorageLocation = keccak256("inco.storage.ACL");
@@ -20,7 +23,13 @@ contract AccessControlListStorage {
20
23
  }
21
24
 
22
25
  // todo should add allowance events ?
23
- contract BaseAccessControlList is IBaseAccessControlListGen, AccessControlListStorage {
26
+ abstract contract BaseAccessControlList is IBaseAccessControlList, AccessControlListStorage, VerifierAddressGetter {
27
+ error ProofVerificationFailed(
28
+ address verifyingContract,
29
+ bytes4 callFunction,
30
+ bytes argData
31
+ );
32
+
24
33
  /// @dev persistent
25
34
  function allow(bytes32 handle, address account) public {
26
35
  require(
@@ -30,6 +39,16 @@ contract BaseAccessControlList is IBaseAccessControlListGen, AccessControlListSt
30
39
  allowInternal(handle, account);
31
40
  }
32
41
 
42
+ /// @dev Permanently allows public decryption/reencryption access to anyone for the given handle.
43
+ function reveal(bytes32 handle) public {
44
+ require(
45
+ isAllowed(handle, msg.sender),
46
+ SenderNotAllowedForHandle(handle, msg.sender)
47
+ );
48
+ ACLStorage storage $ = getACLStorage();
49
+ $.persistedAllowedForDecryption[handle] = true;
50
+ }
51
+
33
52
  /// @dev persistent
34
53
  function allowInternal(bytes32 handle, address account) internal {
35
54
  ACLStorage storage $ = getACLStorage();
@@ -87,6 +106,18 @@ contract BaseAccessControlList is IBaseAccessControlListGen, AccessControlListSt
87
106
  }
88
107
  }
89
108
 
109
+ function claimHandle(bytes32 handle, AllowanceProof memory proof) public {
110
+ require(
111
+ incoVerifier.isAllowedWithProof(handle, msg.sender, proof),
112
+ ProofVerificationFailed(
113
+ proof.voucher.verifyingContract,
114
+ proof.voucher.callFunction,
115
+ proof.voucher.sharerArgData
116
+ )
117
+ );
118
+ allowInternal(handle, msg.sender);
119
+ }
120
+
90
121
  function persistAllowed(
91
122
  bytes32 handle,
92
123
  address account
@@ -101,6 +132,14 @@ contract BaseAccessControlList is IBaseAccessControlListGen, AccessControlListSt
101
132
  ) public view returns (bool) {
102
133
  return
103
134
  allowedTransient(handle, account) ||
104
- persistAllowed(handle, account);
135
+ persistAllowed(handle, account) ||
136
+ isRevealed(handle);
137
+ }
138
+
139
+ function isRevealed(
140
+ bytes32 handle
141
+ ) public view returns (bool) {
142
+ ACLStorage storage $ = getACLStorage();
143
+ return $.persistedAllowedForDecryption[handle];
105
144
  }
106
145
  }
@@ -0,0 +1,25 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {
5
+ AllowanceProof,
6
+ AllowanceVoucher
7
+ } from "../AdvancedAccessControl.types.sol";
8
+
9
+ interface IVoucherEip712Checker {
10
+ function allowanceVoucherDigest(
11
+ AllowanceVoucher memory voucher
12
+ ) external view returns (bytes32);
13
+ }
14
+
15
+ interface IAdvancedAccessControl is IVoucherEip712Checker {
16
+ function isAllowedWithProof(
17
+ bytes32 handle,
18
+ address account,
19
+ AllowanceProof memory proof
20
+ ) external returns (bool);
21
+ function getActiveVouchersSessionNonce(
22
+ address account
23
+ ) external view returns (bytes32);
24
+ function updateActiveVouchersSessionNonce() external;
25
+ }
@@ -0,0 +1,24 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {IVerifierAddressGetter} from "../../primitives/interfaces/IVerifierAddressGetter.sol";
5
+ import {AllowanceProof} from "../AdvancedAccessControl.types.sol";
6
+
7
+ interface IBaseAccessControlList is IVerifierAddressGetter {
8
+ function allow(bytes32 handle, address account) external;
9
+ function allowTransient(bytes32 handle, address account) external;
10
+ function allowedTransient(
11
+ bytes32 handle,
12
+ address account
13
+ ) external view returns (bool);
14
+ function cleanTransientStorage() external;
15
+ function persistAllowed(
16
+ bytes32 handle,
17
+ address account
18
+ ) external view returns (bool);
19
+ function isAllowed(
20
+ bytes32 handle,
21
+ address account
22
+ ) external view returns (bool);
23
+ function claimHandle(bytes32 handle, AllowanceProof memory proof) external;
24
+ }
@@ -0,0 +1,234 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {IncoTest} from "../../../test/IncoTest.sol";
5
+ import {SessionVerifier, Session} from "../../../periphery/SessionVerifier.sol";
6
+ import {AllowanceVoucher, AllowanceProof} from "../AdvancedAccessControl.sol";
7
+ import {euint256} from "../../../Types.sol";
8
+ import {e, inco} from "../../../Lib.sol";
9
+ import {AdvancedAccessControl} from "../AdvancedAccessControl.sol";
10
+ import {ALLOWANCE_GRANTED_MAGIC_VALUE} from "../../../Types.sol";
11
+ import {IIncoVerifier} from "../../../interfaces/IIncoVerifier.sol";
12
+
13
+ contract SomeContractWithConfidentialData {
14
+ using e for bytes;
15
+ using e for euint256;
16
+
17
+ euint256 public secret;
18
+
19
+ function saveAPersonalSecret(bytes memory ciphertext) public {
20
+ secret = ciphertext.newEuint256(msg.sender);
21
+ secret.allow(msg.sender);
22
+ }
23
+ }
24
+
25
+ contract SomeVerifier {
26
+ struct SharerArg {
27
+ bytes32 handleShared;
28
+ address allowedAccount;
29
+ }
30
+
31
+ struct RequesterArg {
32
+ bytes2 mustBeBeef;
33
+ }
34
+
35
+ function someCheck(
36
+ bytes32 handle,
37
+ address account,
38
+ bytes memory sharerArgData,
39
+ bytes memory requesterArgData
40
+ ) public pure returns (bytes32) {
41
+ SharerArg memory sharerArg = abi.decode(sharerArgData, (SharerArg));
42
+ RequesterArg memory requesterArg = abi.decode(
43
+ requesterArgData,
44
+ (RequesterArg)
45
+ );
46
+ if (
47
+ requesterArg.mustBeBeef == bytes2(0xbeef) &&
48
+ sharerArg.handleShared == handle &&
49
+ sharerArg.allowedAccount == account
50
+ ) {
51
+ return ALLOWANCE_GRANTED_MAGIC_VALUE;
52
+ }
53
+ return bytes32(0);
54
+ }
55
+ }
56
+
57
+ contract DoesNotVerifyAnything {
58
+ function someCheck(
59
+ bytes32 /* handle */,
60
+ address /* account */,
61
+ bytes memory /* sharerArgData */,
62
+ bytes memory /* requesterArgData */
63
+ ) public pure returns (bytes32) {
64
+ return ALLOWANCE_GRANTED_MAGIC_VALUE;
65
+ }
66
+ }
67
+
68
+ contract TestAdvancedAccessControl is IncoTest {
69
+ SomeContractWithConfidentialData someContract;
70
+ bytes32 secretHandle;
71
+ IIncoVerifier incoVerifier;
72
+
73
+ function setUp() public override {
74
+ super.setUp();
75
+ someContract = new SomeContractWithConfidentialData();
76
+ bytes memory secretCt = fakePrepareEuint256Ciphertext(42);
77
+ vm.prank(alice);
78
+ someContract.saveAPersonalSecret(secretCt);
79
+ secretHandle = euint256.unwrap(someContract.secret());
80
+ incoVerifier = inco.incoVerifier();
81
+ }
82
+
83
+ function testAdvancedSharingWithSession() public {
84
+ SessionVerifier sessionVerifier = new SessionVerifier("");
85
+ assertFalse(
86
+ inco.isAllowed(secretHandle, bob),
87
+ "bob should't be allowed on secret yet"
88
+ );
89
+ assertTrue(
90
+ inco.isAllowed(secretHandle, alice),
91
+ "alice should be allowed on secret"
92
+ );
93
+ AllowanceVoucher memory aliceSessionVoucherForBob = AllowanceVoucher({
94
+ sessionNonce: bytes32(0),
95
+ verifyingContract: address(sessionVerifier),
96
+ callFunction: SessionVerifier.canUseSession.selector,
97
+ sharerArgData: abi.encode(
98
+ Session({decrypter: bob, expiresAt: block.timestamp + 1 days})
99
+ )
100
+ });
101
+ AllowanceProof memory bobsProof = getBobsProof(
102
+ aliceSessionVoucherForBob
103
+ );
104
+ assertTrue(
105
+ incoVerifier.isAllowedWithProof(secretHandle, bob, bobsProof),
106
+ "bob should be allowed on secret with proof"
107
+ );
108
+ vm.prank(bob);
109
+ inco.claimHandle(secretHandle, bobsProof);
110
+ assertTrue(
111
+ inco.persistAllowed(secretHandle, bob),
112
+ "bob should have claimed persistent allowance on secret"
113
+ );
114
+ }
115
+
116
+ function testVoucherSessionIdCheck() public {
117
+ DoesNotVerifyAnything verifier = new DoesNotVerifyAnything();
118
+ AllowanceVoucher memory voucher = AllowanceVoucher({
119
+ sessionNonce: bytes32(0),
120
+ verifyingContract: address(verifier),
121
+ callFunction: verifier.someCheck.selector,
122
+ sharerArgData: ""
123
+ });
124
+ AllowanceProof memory bobsFirstProof = getBobsProof(voucher);
125
+ assertTrue(
126
+ incoVerifier.isAllowedWithProof(secretHandle, bob, bobsFirstProof),
127
+ "the initial vouchers session nonce should be 0"
128
+ );
129
+ bytes32 madeUpNonce = bytes32(bytes4(0xdeadbeef));
130
+ voucher = AllowanceVoucher({
131
+ sessionNonce: madeUpNonce,
132
+ verifyingContract: address(verifier),
133
+ callFunction: verifier.someCheck.selector,
134
+ sharerArgData: ""
135
+ });
136
+ AllowanceProof memory invalidBobProof = getBobsProof(voucher);
137
+ // the session nonce should be checked by inco
138
+ vm.expectRevert(
139
+ abi.encodeWithSelector(
140
+ AdvancedAccessControl.InvalidVoucherSessionNonce.selector,
141
+ madeUpNonce,
142
+ bytes32(0)
143
+ )
144
+ );
145
+ incoVerifier.isAllowedWithProof(secretHandle, bob, invalidBobProof);
146
+ vm.prank(alice);
147
+ incoVerifier.updateActiveVouchersSessionNonce();
148
+ bytes32 alicesNewNonce = incoVerifier.getActiveVouchersSessionNonce(
149
+ alice
150
+ );
151
+ // previously valid voucher should now be invalid
152
+ vm.expectRevert(
153
+ abi.encodeWithSelector(
154
+ AdvancedAccessControl.InvalidVoucherSessionNonce.selector,
155
+ bytes32(0),
156
+ alicesNewNonce
157
+ )
158
+ );
159
+ incoVerifier.isAllowedWithProof(secretHandle, bob, bobsFirstProof);
160
+ voucher = AllowanceVoucher({
161
+ sessionNonce: alicesNewNonce,
162
+ verifyingContract: address(verifier),
163
+ callFunction: verifier.someCheck.selector,
164
+ sharerArgData: ""
165
+ });
166
+ AllowanceProof memory bobsSecondProof = getBobsProof(voucher);
167
+ assertTrue(
168
+ incoVerifier.isAllowedWithProof(secretHandle, bob, bobsSecondProof),
169
+ "the voucher should signed with the new nonce should be valid"
170
+ );
171
+ }
172
+
173
+ function testSessionVerifierAreCorrectlyCalledAsCheckers() public {
174
+ SomeVerifier verifier = new SomeVerifier();
175
+ AllowanceVoucher memory voucher = AllowanceVoucher({
176
+ sessionNonce: bytes32(0),
177
+ verifyingContract: address(verifier),
178
+ callFunction: verifier.someCheck.selector,
179
+ sharerArgData: abi.encode(
180
+ SomeVerifier.SharerArg({
181
+ handleShared: secretHandle,
182
+ allowedAccount: bob
183
+ })
184
+ )
185
+ });
186
+ AllowanceProof memory bobsProof = AllowanceProof({
187
+ sharer: alice,
188
+ voucher: voucher,
189
+ voucherSignature: getAliceSig(voucher),
190
+ requesterArgData: abi.encode(
191
+ SomeVerifier.RequesterArg({mustBeBeef: bytes2(0xbeef)})
192
+ )
193
+ });
194
+ assertTrue(
195
+ incoVerifier.isAllowedWithProof(secretHandle, bob, bobsProof),
196
+ "bob should be allowed on secret with proof"
197
+ );
198
+ bobsProof = AllowanceProof({
199
+ sharer: alice,
200
+ voucher: voucher,
201
+ voucherSignature: getAliceSig(voucher),
202
+ requesterArgData: abi.encode(
203
+ SomeVerifier.RequesterArg({mustBeBeef: bytes2(0xbebe)})
204
+ )
205
+ });
206
+ assertFalse(
207
+ incoVerifier.isAllowedWithProof(secretHandle, bob, bobsProof),
208
+ "all parameters should be checked"
209
+ );
210
+ }
211
+
212
+ function getBobsProof(
213
+ AllowanceVoucher memory alicesVoucher
214
+ ) private view returns (AllowanceProof memory) {
215
+ bytes memory voucherSignature = getAliceSig(alicesVoucher);
216
+ return
217
+ AllowanceProof({
218
+ sharer: alice,
219
+ voucher: alicesVoucher,
220
+ voucherSignature: voucherSignature,
221
+ requesterArgData: ""
222
+ });
223
+ }
224
+
225
+ function getAliceSig(
226
+ AllowanceVoucher memory voucher
227
+ ) private view returns (bytes memory) {
228
+ return
229
+ getSignatureForDigest(
230
+ incoVerifier.allowanceVoucherDigest(voucher),
231
+ alicePrivKey
232
+ );
233
+ }
234
+ }
@@ -1,12 +1,26 @@
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 {VerifierAddressGetter} from "../../primitives/VerifierAddressGetter.sol";
6
+ import {euint256, inco} from "../../../Lib.sol";
7
+ import {IncoTest} from "../../../test/IncoTest.sol";
8
+
9
+ contract TestBaseAccessControl is BaseAccessControlList, IncoTest {
10
+ constructor() VerifierAddressGetter(address(0)) {}
6
11
 
7
- contract TestBaseAccessControl is BaseAccessControlList, TestUtils {
8
12
  function testHandleZeroIsDisallowed() public view {
9
13
  bytes32 handle = bytes32(0);
10
14
  assert(!isAllowed(handle, alice));
11
15
  }
16
+
17
+ function testReveal() public {
18
+ euint256 secret = inco.asEuint256(1337);
19
+ assert(inco.isAllowed(euint256.unwrap(secret), address(this)));
20
+ assert(!inco.isAllowed(euint256.unwrap(secret), alice));
21
+
22
+ inco.reveal(euint256.unwrap(secret));
23
+ assert(inco.isAllowed(euint256.unwrap(secret), address(this)));
24
+ assert(inco.isAllowed(euint256.unwrap(secret), alice));
25
+ }
12
26
  }
@@ -0,0 +1,45 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {DecryptionAttestation} from "./DecryptionAttester.types.sol";
5
+ import {EIP712Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol";
6
+ import {SignatureVerifier} from "./primitives/SignatureVerifier.sol";
7
+ import {IDecryptionAttester} from "./interfaces/IDecryptionAttester.sol";
8
+
9
+ // todo pre charging transient decrypted values leads to a superior DevX
10
+
11
+ // todo #1032 add DecryptionAttester to IncoVerifier, will include signature verifier as well and fix #874
12
+ abstract contract DecryptionAttester is
13
+ IDecryptionAttester,
14
+ SignatureVerifier,
15
+ EIP712Upgradeable
16
+ {
17
+ bytes32 constant DecryptionAttestationStructHash =
18
+ keccak256("DecryptionAttestation(bytes32 handle,bytes32 value)");
19
+
20
+ function decryptionAttestationDigest(
21
+ DecryptionAttestation memory decryption
22
+ ) public view returns (bytes32) {
23
+ return
24
+ _hashTypedDataV4(
25
+ keccak256(
26
+ abi.encode(
27
+ DecryptionAttestationStructHash,
28
+ decryption.handle,
29
+ decryption.value
30
+ )
31
+ )
32
+ );
33
+ }
34
+
35
+ function isValidDecryptionAttestation(
36
+ DecryptionAttestation memory decryption,
37
+ bytes memory signature
38
+ ) public view returns (bool) {
39
+ return
40
+ isValidSignature(
41
+ decryptionAttestationDigest(decryption),
42
+ signature
43
+ );
44
+ }
45
+ }
@@ -0,0 +1,7 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ struct DecryptionAttestation {
5
+ bytes32 handle;
6
+ bytes32 value; // encoded bool or uint256 // todo switch this to bytes
7
+ }
@@ -4,17 +4,16 @@ 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";
8
- import {IEncryptedInputGen} from "./EncryptedInput.gen.sol";
7
+ import {euint256, ebool, eaddress, ETypes} from "../Types.sol";
8
+ import {IEncryptedInput} from "./interfaces/IEncryptedInput.sol";
9
9
  import {HandleAlreadyExists} from "../Errors.sol";
10
10
 
11
11
  abstract contract EncryptedInput is
12
- IEncryptedInputGen,
12
+ IEncryptedInput,
13
13
  BaseAccessControlList,
14
14
  EventCounter,
15
15
  HandleGeneration
16
16
  {
17
-
18
17
  event NewInput(
19
18
  bytes32 indexed result,
20
19
  address indexed contractAddress,
@@ -42,7 +41,10 @@ abstract contract EncryptedInput is
42
41
  bytes memory ciphertext,
43
42
  address user
44
43
  ) external returns (eaddress newValue) {
45
- return eaddress.wrap(newInput(ciphertext, user, ETypes.AddressOrUint160OrBytes20));
44
+ return
45
+ eaddress.wrap(
46
+ newInput(ciphertext, user, ETypes.AddressOrUint160OrBytes20)
47
+ );
46
48
  }
47
49
 
48
50
  function newInput(
@@ -57,13 +59,8 @@ abstract contract EncryptedInput is
57
59
  // We allow to user since this is harmless and it is convenient to use the allow mapping to track existing
58
60
  allowInternal(newHandle, user);
59
61
  allowTransientInternal(newHandle, msg.sender);
60
- emit NewInput(
61
- newHandle,
62
- msg.sender,
63
- user,
64
- inputType,
65
- ciphertext,
66
- getNewEventId()
67
- );
62
+ uint256 id = getNextEventId();
63
+ emit NewInput(newHandle, msg.sender, user, inputType, ciphertext, id);
64
+ setDigest(abi.encodePacked(newHandle, id));
68
65
  }
69
66
  }