@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.
- package/README.md +2 -8
- package/manifest.yaml +24 -11
- package/package.json +2 -5
- package/src/DeployUtils.sol +113 -77
- package/src/IIncoLightning.sol +16 -9
- package/src/IncoLightning.sol +18 -9
- package/src/IncoVerifier.sol +47 -0
- package/src/Lib.alphanet.sol +14 -15
- package/src/Lib.demonet.sol +14 -15
- package/src/Lib.devnet.sol +14 -15
- package/src/Lib.sol +14 -15
- package/src/Lib.template.sol +15 -44
- package/src/Lib.testnet.sol +14 -15
- package/src/Types.sol +7 -0
- package/src/interfaces/IIncoLightning.sol +20 -0
- package/src/interfaces/IIncoVerifier.sol +24 -0
- package/src/interfaces/automata-interfaces/BELE.sol +20 -0
- package/src/interfaces/automata-interfaces/IAutomataEnclaveIdentityDao.sol +28 -0
- package/src/interfaces/automata-interfaces/IFmspcTcbDao.sol +10 -0
- package/src/interfaces/automata-interfaces/IPCCSRouter.sol +94 -0
- package/src/interfaces/automata-interfaces/IPCCSRouterExtended.sol +10 -0
- package/src/interfaces/automata-interfaces/IPcsDao.sol +18 -0
- package/src/interfaces/automata-interfaces/IQuoteVerifier.sol +34 -0
- package/src/interfaces/automata-interfaces/Types.sol +193 -0
- package/src/libs/incoLightning_alphanet_v0_297966649.sol +14 -15
- package/src/libs/incoLightning_demonet_v0_863421733.sol +14 -15
- package/src/libs/incoLightning_devnet_v0_340846814.sol +14 -15
- package/src/libs/incoLightning_testnet_v0_183408998.sol +14 -15
- package/src/libs/incoLightning_testnet_v1_938327937.sol +451 -0
- package/src/lightning-parts/AccessControl/AdvancedAccessControl.sol +133 -0
- package/src/lightning-parts/AccessControl/AdvancedAccessControl.types.sol +18 -0
- package/src/lightning-parts/AccessControl/BaseAccessControlList.sol +42 -3
- package/src/lightning-parts/AccessControl/interfaces/IAdvancedAccessControl.sol +25 -0
- package/src/lightning-parts/AccessControl/interfaces/IBaseAccessControlList.sol +24 -0
- package/src/lightning-parts/AccessControl/test/TestAdvancedAccessControl.t.sol +234 -0
- package/src/lightning-parts/AccessControl/test/TestBaseAccessControl.t.sol +16 -2
- package/src/lightning-parts/DecryptionAttester.sol +45 -0
- package/src/lightning-parts/DecryptionAttester.types.sol +7 -0
- package/src/lightning-parts/EncryptedInput.sol +10 -13
- package/src/lightning-parts/EncryptedOperations.sol +78 -28
- package/src/lightning-parts/TEELifecycle.sol +180 -88
- package/src/lightning-parts/TrivialEncryption.sol +9 -9
- package/src/lightning-parts/interfaces/IDecryptionAttester.sol +9 -0
- package/src/lightning-parts/interfaces/IEncryptedInput.sol +19 -0
- package/src/lightning-parts/interfaces/IEncryptedOperations.sol +31 -0
- package/src/lightning-parts/interfaces/ITEELifecycle.sol +26 -0
- package/src/lightning-parts/interfaces/ITrivialEncryption.sol +10 -0
- package/src/lightning-parts/primitives/EventCounter.sol +15 -3
- package/src/lightning-parts/primitives/HandleGeneration.sol +8 -3
- package/src/lightning-parts/primitives/HandleMetadata.sol +1 -1
- package/src/lightning-parts/primitives/LightningAddressGetter.sol +10 -0
- package/src/lightning-parts/primitives/SignatureVerifier.sol +2 -9
- package/src/lightning-parts/primitives/VerifierAddressGetter.sol +13 -0
- package/src/lightning-parts/primitives/{EventCounter.gen.sol → interfaces/IEventCounter.sol} +4 -2
- package/src/lightning-parts/primitives/interfaces/IHandleGeneration.sol +41 -0
- package/src/lightning-parts/primitives/interfaces/ISignatureVerifier.sol +9 -0
- package/src/lightning-parts/primitives/interfaces/IVerifierAddressGetter.sol +8 -0
- package/src/lightning-parts/test/HandleMetadata.t.sol +25 -6
- package/src/lightning-parts/test/TestDecryptionAttestationInSynchronousFlow.t.sol +78 -0
- package/src/periphery/SessionVerifier.sol +63 -0
- package/src/test/AddTwo.sol +20 -24
- package/src/test/FakeIncoInfra/FakeDecryptionAttester.sol +198 -0
- package/src/test/FakeIncoInfra/FakeIncoInfraBase.sol +0 -15
- package/src/test/FakeIncoInfra/FakeQuoteVerifier.sol +10 -6
- package/src/test/FakeIncoInfra/MockOpHandler.sol +0 -7
- package/src/test/FakeIncoInfra/MockRemoteAttestation.sol +19 -7
- package/src/test/FakeIncoInfra/getOpForSelector.sol +0 -3
- package/src/test/IncoTest.sol +12 -11
- package/src/test/TEELifecycle/TEELifecycleMockTest.t.sol +98 -77
- package/src/test/TestAddTwo.t.sol +16 -9
- package/src/test/TestFakeInfra.t.sol +10 -27
- package/src/test/TestUpgrade.t.sol +11 -4
- package/src/test/TestVersion.t.sol +0 -7
- package/src/version/IncoLightningConfig.sol +4 -3
- package/src/version/SessionVerifierConfig.sol +8 -0
- package/src/version/Version.sol +7 -9
- package/src/version/interfaces/IVersion.sol +8 -0
- package/src/DeployTEE.sol +0 -153
- package/src/IncoLightning.gen.sol +0 -15
- package/src/lightning-parts/AccessControl/BaseAccessControlList.gen.sol +0 -19
- package/src/lightning-parts/DecryptionHandler.gen.sol +0 -54
- package/src/lightning-parts/DecryptionHandler.sol +0 -307
- package/src/lightning-parts/DecryptionHandler.types.sol +0 -34
- package/src/lightning-parts/EncryptedInput.gen.sol +0 -16
- package/src/lightning-parts/EncryptedOperations.gen.sol +0 -59
- package/src/lightning-parts/TEELifecycle.gen.sol +0 -58
- package/src/lightning-parts/TrivialEncryption.gen.sol +0 -15
- package/src/lightning-parts/primitives/HandleGeneration.gen.sol +0 -19
- package/src/lightning-parts/primitives/HandleMetadata.gen.sol +0 -4
- package/src/lightning-parts/primitives/SignatureVerifier.gen.sol +0 -16
- package/src/test/FibonacciDecrypt.sol +0 -49
- package/src/test/TEELifecycle/TEELifecycleHWTest.t.sol +0 -119
- package/src/test/TEELifecycle/addnode_data/eoa.txt +0 -1
- package/src/test/TEELifecycle/addnode_data/quote.bin +0 -0
- package/src/test/TEELifecycle/bootstrap_data/ecies_pubkey.bin +0 -1
- package/src/test/TEELifecycle/bootstrap_data/eip712_signature.bin +0 -1
- package/src/test/TEELifecycle/bootstrap_data/eoa.txt +0 -1
- package/src/test/TEELifecycle/bootstrap_data/qe_identity +0 -1
- package/src/test/TEELifecycle/bootstrap_data/qe_identity_signature.bin +0 -1
- package/src/test/TEELifecycle/bootstrap_data/quote.bin +0 -0
- package/src/test/TEELifecycle/bootstrap_data/tcb_info +0 -1
- package/src/test/TEELifecycle/bootstrap_data/tcb_info_signature.bin +0 -1
- package/src/test/TEELifecycle/test_cert/AttestationReportSigningCA.crl +0 -0
- package/src/test/TEELifecycle/test_cert/Intel_SGX_Attestation_RootCA.cer +0 -0
- package/src/test/TEELifecycle/test_cert/Intel_SGX_PCK_CRL.crl +0 -0
- package/src/test/TEELifecycle/test_cert/Intel_SGX_PCK_PlatformCA.cer +0 -0
- package/src/test/TEELifecycle/test_cert/Intel_SGX_TCB_Signing.cer +0 -0
- 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 {
|
|
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
|
|
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
|
+
}
|
|
@@ -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
|
|
8
|
-
import {
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
}
|