@inco/lightning 0.6.8 → 0.7.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/CHANGELOG.md +6 -0
- package/README.md +29 -2
- package/manifest.yaml +35 -42
- package/package.json +5 -2
- package/src/CreateXHelper.sol +3 -1
- package/src/DeployUtils.sol +36 -71
- package/src/Errors.sol +1 -1
- package/src/IIncoLightning.sol +2 -0
- package/src/IncoLightning.sol +5 -17
- package/src/IncoVerifier.sol +12 -18
- package/src/Lib.alphanet.sol +1 -1
- package/src/Lib.sol +1 -1
- package/src/Lib.template.sol +35 -153
- package/src/Types.sol +231 -97
- package/src/interfaces/IIncoLightning.sol +2 -0
- package/src/interfaces/IIncoVerifier.sol +6 -12
- package/src/interfaces/automata-interfaces/BELE.sol +2 -0
- package/src/interfaces/automata-interfaces/IAutomataEnclaveIdentityDao.sol +9 -11
- package/src/interfaces/automata-interfaces/IFmspcTcbDao.sol +3 -3
- package/src/interfaces/automata-interfaces/IPCCSRouter.sol +13 -47
- package/src/interfaces/automata-interfaces/IPCCSRouterExtended.sol +2 -0
- package/src/interfaces/automata-interfaces/IPcsDao.sol +6 -11
- package/src/interfaces/automata-interfaces/IQuoteVerifier.sol +4 -7
- package/src/interfaces/automata-interfaces/Types.sol +7 -6
- package/src/libs/incoLightning_alphanet_v2_976644394.sol +478 -0
- package/src/libs/incoLightning_devnet_v1_887305889.sol +5 -3
- package/src/libs/incoLightning_testnet_v1_938327937.sol +5 -3
- package/src/lightning-parts/AccessControl/AdvancedAccessControl.sol +39 -72
- package/src/lightning-parts/AccessControl/BaseAccessControlList.sol +31 -62
- package/src/lightning-parts/AccessControl/interfaces/IAdvancedAccessControl.sol +8 -15
- package/src/lightning-parts/AccessControl/interfaces/IBaseAccessControlList.sol +5 -12
- package/src/lightning-parts/AccessControl/test/TestAdvancedAccessControl.t.sol +44 -84
- package/src/lightning-parts/AccessControl/test/TestBaseAccessControl.t.sol +2 -0
- package/src/lightning-parts/DecryptionAttester.sol +14 -28
- package/src/lightning-parts/EncryptedInput.sol +23 -52
- package/src/lightning-parts/EncryptedOperations.sol +96 -438
- package/src/lightning-parts/Fee.sol +3 -1
- package/src/lightning-parts/TEELifecycle.sol +94 -223
- package/src/lightning-parts/TEELifecycle.types.sol +4 -3
- package/src/lightning-parts/TrivialEncryption.sol +6 -20
- package/src/lightning-parts/interfaces/IDecryptionAttester.sol +7 -2
- package/src/lightning-parts/interfaces/IEncryptedInput.sol +5 -12
- package/src/lightning-parts/interfaces/IEncryptedOperations.sol +17 -61
- package/src/lightning-parts/interfaces/ITEELifecycle.sol +7 -11
- package/src/lightning-parts/interfaces/ITrivialEncryption.sol +2 -0
- package/src/lightning-parts/primitives/EventCounter.sol +7 -8
- package/src/lightning-parts/primitives/HandleGeneration.sol +20 -32
- package/src/lightning-parts/primitives/HandleMetadata.sol +7 -17
- package/src/lightning-parts/primitives/LightningAddressGetter.sol +3 -0
- package/src/lightning-parts/primitives/SignatureVerifier.sol +91 -27
- package/src/lightning-parts/primitives/VerifierAddressGetter.sol +3 -0
- package/src/lightning-parts/primitives/interfaces/IEventCounter.sol +2 -0
- package/src/lightning-parts/primitives/interfaces/IHandleGeneration.sol +10 -2
- package/src/lightning-parts/primitives/interfaces/ISignatureVerifier.sol +4 -2
- package/src/lightning-parts/primitives/interfaces/IVerifierAddressGetter.sol +2 -0
- package/src/lightning-parts/primitives/test/SignatureVerifier.t.sol +838 -0
- package/src/lightning-parts/test/Fee.t.sol +6 -6
- package/src/lightning-parts/test/HandleMetadata.t.sol +21 -76
- package/src/lightning-parts/test/InputsFee.t.sol +7 -28
- package/src/lightning-parts/test/TestDecryptionAttestationInSynchronousFlow.t.sol +16 -48
- package/src/pasted-dependencies/CreateX.sol +154 -455
- package/src/pasted-dependencies/ICreateX.sol +55 -102
- package/src/periphery/SessionVerifier.sol +10 -8
- package/src/shared/IOwnable.sol +3 -0
- package/src/shared/IUUPSUpgradable.sol +5 -1
- package/src/shared/JsonUtils.sol +3 -5
- package/src/shared/TestUtils.sol +15 -13
- package/src/test/AddTwo.sol +9 -7
- package/src/test/FakeIncoInfra/FakeComputeServer.sol +11 -53
- package/src/test/FakeIncoInfra/FakeDecryptionAttester.sol +35 -119
- package/src/test/FakeIncoInfra/FakeIncoInfraBase.sol +31 -48
- package/src/test/FakeIncoInfra/FakeQuoteVerifier.sol +4 -7
- package/src/test/FakeIncoInfra/KVStore.sol +2 -0
- package/src/test/FakeIncoInfra/MockOpHandler.sol +9 -31
- package/src/test/FakeIncoInfra/MockRemoteAttestation.sol +50 -21
- package/src/test/IncoTest.sol +22 -9
- package/src/test/OpsTest.sol +438 -0
- package/src/test/TEELifecycle/TEELifecycleMockTest.t.sol +57 -104
- package/src/test/TestAddTwo.t.sol +4 -3
- package/src/test/TestDeploy.t.sol +5 -6
- package/src/test/TestExtractDataOfEventTooLarge.t.sol +7 -9
- package/src/test/TestFakeInfra.t.sol +15 -38
- package/src/test/TestUpgrade.t.sol +40 -135
- package/src/test/TestVersion.t.sol +6 -5
- package/src/version/IncoLightningConfig.sol +2 -2
- package/src/version/Version.sol +46 -48
- package/src/version/interfaces/IVersion.sol +6 -0
|
@@ -8,55 +8,46 @@ import {VerifierAddressGetter} from "../primitives/VerifierAddressGetter.sol";
|
|
|
8
8
|
import {AllowanceProof} from "../AccessControl/AdvancedAccessControl.types.sol";
|
|
9
9
|
|
|
10
10
|
contract AccessControlListStorage {
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
struct AclStorage {
|
|
12
13
|
mapping(bytes32 handle => mapping(address account => bool isAllowed)) persistedAllowedPairs;
|
|
13
14
|
mapping(bytes32 handle => bool isAllowed) persistedAllowedForDecryption;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
bytes32 private constant
|
|
17
|
+
bytes32 private constant ACL_STORAGE_LOCATION = keccak256("inco.storage.ACL");
|
|
17
18
|
|
|
18
|
-
function
|
|
19
|
-
bytes32 loc =
|
|
19
|
+
function getAclStorage() internal pure returns (AclStorage storage $) {
|
|
20
|
+
bytes32 loc = ACL_STORAGE_LOCATION;
|
|
20
21
|
assembly {
|
|
21
22
|
$.slot := loc
|
|
22
23
|
}
|
|
23
24
|
}
|
|
25
|
+
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
abstract contract BaseAccessControlList is
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
abstract contract BaseAccessControlList is
|
|
29
|
+
IBaseAccessControlList,
|
|
30
|
+
AccessControlListStorage,
|
|
31
|
+
VerifierAddressGetter,
|
|
32
|
+
EventCounter
|
|
33
|
+
{
|
|
34
|
+
|
|
35
|
+
error ProofVerificationFailed(address verifyingContract, bytes4 callFunction, bytes argData);
|
|
32
36
|
|
|
33
|
-
event Allow(
|
|
34
|
-
bytes32 handle,
|
|
35
|
-
address account,
|
|
36
|
-
uint256 eventId
|
|
37
|
-
);
|
|
37
|
+
event Allow(bytes32 handle, address account, uint256 eventId);
|
|
38
38
|
|
|
39
|
-
event Reveal(
|
|
40
|
-
bytes32 handle,
|
|
41
|
-
uint256 eventId
|
|
42
|
-
);
|
|
39
|
+
event Reveal(bytes32 handle, uint256 eventId);
|
|
43
40
|
|
|
44
41
|
/// @dev persistent
|
|
45
42
|
function allow(bytes32 handle, address account) public {
|
|
46
|
-
require(
|
|
47
|
-
isAllowed(handle, msg.sender),
|
|
48
|
-
SenderNotAllowedForHandle(handle, msg.sender)
|
|
49
|
-
);
|
|
43
|
+
require(isAllowed(handle, msg.sender), SenderNotAllowedForHandle(handle, msg.sender));
|
|
50
44
|
allowInternal(handle, account);
|
|
51
45
|
}
|
|
52
46
|
|
|
53
47
|
/// @dev Permanently allows public decryption/reencryption access to anyone for the given handle.
|
|
54
48
|
function reveal(bytes32 handle) public {
|
|
55
|
-
require(
|
|
56
|
-
|
|
57
|
-
SenderNotAllowedForHandle(handle, msg.sender)
|
|
58
|
-
);
|
|
59
|
-
ACLStorage storage $ = getACLStorage();
|
|
49
|
+
require(isAllowed(handle, msg.sender), SenderNotAllowedForHandle(handle, msg.sender));
|
|
50
|
+
AclStorage storage $ = getAclStorage();
|
|
60
51
|
$.persistedAllowedForDecryption[handle] = true;
|
|
61
52
|
uint256 id = getNextEventId();
|
|
62
53
|
emit Reveal(handle, id);
|
|
@@ -65,7 +56,7 @@ abstract contract BaseAccessControlList is IBaseAccessControlList, AccessControl
|
|
|
65
56
|
|
|
66
57
|
/// @dev persistent
|
|
67
58
|
function allowInternal(bytes32 handle, address account) internal {
|
|
68
|
-
|
|
59
|
+
AclStorage storage $ = getAclStorage();
|
|
69
60
|
$.persistedAllowedPairs[handle][account] = true;
|
|
70
61
|
uint256 id = getNextEventId();
|
|
71
62
|
emit Allow(handle, account, id);
|
|
@@ -74,10 +65,7 @@ abstract contract BaseAccessControlList is IBaseAccessControlList, AccessControl
|
|
|
74
65
|
|
|
75
66
|
// todo current transient allowance is unsafe, make storage account bound + how to clean between UserOps
|
|
76
67
|
function allowTransient(bytes32 handle, address account) public {
|
|
77
|
-
require(
|
|
78
|
-
isAllowed(handle, msg.sender),
|
|
79
|
-
SenderNotAllowedForHandle(handle, msg.sender)
|
|
80
|
-
);
|
|
68
|
+
require(isAllowed(handle, msg.sender), SenderNotAllowedForHandle(handle, msg.sender));
|
|
81
69
|
allowTransientInternal(handle, account);
|
|
82
70
|
}
|
|
83
71
|
|
|
@@ -93,10 +81,7 @@ abstract contract BaseAccessControlList is IBaseAccessControlList, AccessControl
|
|
|
93
81
|
}
|
|
94
82
|
}
|
|
95
83
|
|
|
96
|
-
function allowedTransient(
|
|
97
|
-
bytes32 handle,
|
|
98
|
-
address account
|
|
99
|
-
) public view returns (bool) {
|
|
84
|
+
function allowedTransient(bytes32 handle, address account) public view returns (bool) {
|
|
100
85
|
bool isAllowedTransient;
|
|
101
86
|
bytes32 key = keccak256(abi.encodePacked(handle, account));
|
|
102
87
|
assembly {
|
|
@@ -110,11 +95,7 @@ abstract contract BaseAccessControlList is IBaseAccessControlList, AccessControl
|
|
|
110
95
|
let length := tload(0)
|
|
111
96
|
tstore(0, 0)
|
|
112
97
|
let lengthPlusOne := add(length, 1)
|
|
113
|
-
for {
|
|
114
|
-
let i := 1
|
|
115
|
-
} lt(i, lengthPlusOne) {
|
|
116
|
-
i := add(i, 1)
|
|
117
|
-
} {
|
|
98
|
+
for { let i := 1 } lt(i, lengthPlusOne) { i := add(i, 1) } {
|
|
118
99
|
let handle := tload(i)
|
|
119
100
|
tstore(i, 0)
|
|
120
101
|
tstore(handle, 0)
|
|
@@ -126,36 +107,24 @@ abstract contract BaseAccessControlList is IBaseAccessControlList, AccessControl
|
|
|
126
107
|
require(
|
|
127
108
|
incoVerifier.isAllowedWithProof(handle, msg.sender, proof),
|
|
128
109
|
ProofVerificationFailed(
|
|
129
|
-
proof.voucher.verifyingContract,
|
|
130
|
-
proof.voucher.callFunction,
|
|
131
|
-
proof.voucher.sharerArgData
|
|
110
|
+
proof.voucher.verifyingContract, proof.voucher.callFunction, proof.voucher.sharerArgData
|
|
132
111
|
)
|
|
133
112
|
);
|
|
134
113
|
allowInternal(handle, msg.sender);
|
|
135
114
|
}
|
|
136
115
|
|
|
137
|
-
function persistAllowed(
|
|
138
|
-
|
|
139
|
-
address account
|
|
140
|
-
) public view returns (bool) {
|
|
141
|
-
ACLStorage storage $ = getACLStorage();
|
|
116
|
+
function persistAllowed(bytes32 handle, address account) public view returns (bool) {
|
|
117
|
+
AclStorage storage $ = getAclStorage();
|
|
142
118
|
return $.persistedAllowedPairs[handle][account];
|
|
143
119
|
}
|
|
144
120
|
|
|
145
|
-
function isAllowed(
|
|
146
|
-
|
|
147
|
-
address account
|
|
148
|
-
) public view returns (bool) {
|
|
149
|
-
return
|
|
150
|
-
allowedTransient(handle, account) ||
|
|
151
|
-
persistAllowed(handle, account) ||
|
|
152
|
-
isRevealed(handle);
|
|
121
|
+
function isAllowed(bytes32 handle, address account) public view returns (bool) {
|
|
122
|
+
return allowedTransient(handle, account) || persistAllowed(handle, account) || isRevealed(handle);
|
|
153
123
|
}
|
|
154
124
|
|
|
155
|
-
function isRevealed(
|
|
156
|
-
|
|
157
|
-
) public view returns (bool) {
|
|
158
|
-
ACLStorage storage $ = getACLStorage();
|
|
125
|
+
function isRevealed(bytes32 handle) public view returns (bool) {
|
|
126
|
+
AclStorage storage $ = getAclStorage();
|
|
159
127
|
return $.persistedAllowedForDecryption[handle];
|
|
160
128
|
}
|
|
129
|
+
|
|
161
130
|
}
|
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
// SPDX-License-Identifier: No License
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
AllowanceProof,
|
|
6
|
-
AllowanceVoucher
|
|
7
|
-
} from "../AdvancedAccessControl.types.sol";
|
|
4
|
+
import {AllowanceProof, AllowanceVoucher} from "../AdvancedAccessControl.types.sol";
|
|
8
5
|
|
|
9
6
|
interface IVoucherEip712Checker {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
|
|
8
|
+
function allowanceVoucherDigest(AllowanceVoucher memory voucher) external view returns (bytes32);
|
|
9
|
+
|
|
13
10
|
}
|
|
14
11
|
|
|
15
12
|
interface IAdvancedAccessControl is IVoucherEip712Checker {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
AllowanceProof memory proof
|
|
20
|
-
) external returns (bool);
|
|
21
|
-
function getActiveVouchersSessionNonce(
|
|
22
|
-
address account
|
|
23
|
-
) external view returns (bytes32);
|
|
13
|
+
|
|
14
|
+
function isAllowedWithProof(bytes32 handle, address account, AllowanceProof memory proof) external returns (bool);
|
|
15
|
+
function getActiveVouchersSessionNonce(address account) external view returns (bytes32);
|
|
24
16
|
function updateActiveVouchersSessionNonce() external;
|
|
17
|
+
|
|
25
18
|
}
|
|
@@ -5,20 +5,13 @@ import {IVerifierAddressGetter} from "../../primitives/interfaces/IVerifierAddre
|
|
|
5
5
|
import {AllowanceProof} from "../AdvancedAccessControl.types.sol";
|
|
6
6
|
|
|
7
7
|
interface IBaseAccessControlList is IVerifierAddressGetter {
|
|
8
|
+
|
|
8
9
|
function allow(bytes32 handle, address account) external;
|
|
9
10
|
function allowTransient(bytes32 handle, address account) external;
|
|
10
|
-
function allowedTransient(
|
|
11
|
-
bytes32 handle,
|
|
12
|
-
address account
|
|
13
|
-
) external view returns (bool);
|
|
11
|
+
function allowedTransient(bytes32 handle, address account) external view returns (bool);
|
|
14
12
|
function cleanTransientStorage() external;
|
|
15
|
-
function persistAllowed(
|
|
16
|
-
|
|
17
|
-
address account
|
|
18
|
-
) external view returns (bool);
|
|
19
|
-
function isAllowed(
|
|
20
|
-
bytes32 handle,
|
|
21
|
-
address account
|
|
22
|
-
) external view returns (bool);
|
|
13
|
+
function persistAllowed(bytes32 handle, address account) external view returns (bool);
|
|
14
|
+
function isAllowed(bytes32 handle, address account) external view returns (bool);
|
|
23
15
|
function claimHandle(bytes32 handle, AllowanceProof memory proof) external;
|
|
16
|
+
|
|
24
17
|
}
|
|
@@ -11,6 +11,7 @@ import {ALLOWANCE_GRANTED_MAGIC_VALUE} from "../../../Types.sol";
|
|
|
11
11
|
import {IIncoVerifier} from "../../../interfaces/IIncoVerifier.sol";
|
|
12
12
|
|
|
13
13
|
contract SomeContractWithConfidentialData {
|
|
14
|
+
|
|
14
15
|
using e for bytes;
|
|
15
16
|
using e for euint256;
|
|
16
17
|
|
|
@@ -20,9 +21,11 @@ contract SomeContractWithConfidentialData {
|
|
|
20
21
|
secret = ciphertext.newEuint256(msg.sender);
|
|
21
22
|
secret.allow(msg.sender);
|
|
22
23
|
}
|
|
24
|
+
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
contract SomeVerifier {
|
|
28
|
+
|
|
26
29
|
struct SharerArg {
|
|
27
30
|
bytes32 handleShared;
|
|
28
31
|
address allowedAccount;
|
|
@@ -32,40 +35,43 @@ contract SomeVerifier {
|
|
|
32
35
|
bytes2 mustBeBeef;
|
|
33
36
|
}
|
|
34
37
|
|
|
35
|
-
function someCheck(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
) public pure returns (bytes32) {
|
|
38
|
+
function someCheck(bytes32 handle, address account, bytes memory sharerArgData, bytes memory requesterArgData)
|
|
39
|
+
public
|
|
40
|
+
pure
|
|
41
|
+
returns (bytes32)
|
|
42
|
+
{
|
|
41
43
|
SharerArg memory sharerArg = abi.decode(sharerArgData, (SharerArg));
|
|
42
|
-
RequesterArg memory requesterArg = abi.decode(
|
|
43
|
-
requesterArgData,
|
|
44
|
-
(RequesterArg)
|
|
45
|
-
);
|
|
44
|
+
RequesterArg memory requesterArg = abi.decode(requesterArgData, (RequesterArg));
|
|
46
45
|
if (
|
|
47
|
-
requesterArg.mustBeBeef == bytes2(0xbeef) &&
|
|
48
|
-
|
|
49
|
-
sharerArg.allowedAccount == account
|
|
46
|
+
requesterArg.mustBeBeef == bytes2(0xbeef) && sharerArg.handleShared == handle
|
|
47
|
+
&& sharerArg.allowedAccount == account
|
|
50
48
|
) {
|
|
51
49
|
return ALLOWANCE_GRANTED_MAGIC_VALUE;
|
|
52
50
|
}
|
|
53
51
|
return bytes32(0);
|
|
54
52
|
}
|
|
53
|
+
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
contract DoesNotVerifyAnything {
|
|
57
|
+
|
|
58
58
|
function someCheck(
|
|
59
|
-
bytes32 /* handle
|
|
60
|
-
address /* account
|
|
61
|
-
bytes memory /* sharerArgData
|
|
59
|
+
bytes32, /* handle */
|
|
60
|
+
address, /* account */
|
|
61
|
+
bytes memory, /* sharerArgData */
|
|
62
62
|
bytes memory /* requesterArgData */
|
|
63
|
-
)
|
|
63
|
+
)
|
|
64
|
+
public
|
|
65
|
+
pure
|
|
66
|
+
returns (bytes32)
|
|
67
|
+
{
|
|
64
68
|
return ALLOWANCE_GRANTED_MAGIC_VALUE;
|
|
65
69
|
}
|
|
70
|
+
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
contract TestAdvancedAccessControl is IncoTest {
|
|
74
|
+
|
|
69
75
|
SomeContractWithConfidentialData someContract;
|
|
70
76
|
bytes32 secretHandle;
|
|
71
77
|
IIncoVerifier incoVerifier;
|
|
@@ -83,35 +89,21 @@ contract TestAdvancedAccessControl is IncoTest {
|
|
|
83
89
|
|
|
84
90
|
function testAdvancedSharingWithSession() public {
|
|
85
91
|
SessionVerifier sessionVerifier = new SessionVerifier("");
|
|
86
|
-
assertFalse(
|
|
87
|
-
|
|
88
|
-
"bob should't be allowed on secret yet"
|
|
89
|
-
);
|
|
90
|
-
assertTrue(
|
|
91
|
-
inco.isAllowed(secretHandle, alice),
|
|
92
|
-
"alice should be allowed on secret"
|
|
93
|
-
);
|
|
92
|
+
assertFalse(inco.isAllowed(secretHandle, bob), "bob should't be allowed on secret yet");
|
|
93
|
+
assertTrue(inco.isAllowed(secretHandle, alice), "alice should be allowed on secret");
|
|
94
94
|
AllowanceVoucher memory aliceSessionVoucherForBob = AllowanceVoucher({
|
|
95
95
|
sessionNonce: bytes32(0),
|
|
96
96
|
verifyingContract: address(sessionVerifier),
|
|
97
97
|
callFunction: SessionVerifier.canUseSession.selector,
|
|
98
|
-
sharerArgData: abi.encode(
|
|
99
|
-
Session({decrypter: bob, expiresAt: block.timestamp + 1 days})
|
|
100
|
-
)
|
|
98
|
+
sharerArgData: abi.encode(Session({decrypter: bob, expiresAt: block.timestamp + 1 days}))
|
|
101
99
|
});
|
|
102
|
-
AllowanceProof memory bobsProof = getBobsProof(
|
|
103
|
-
aliceSessionVoucherForBob
|
|
104
|
-
);
|
|
100
|
+
AllowanceProof memory bobsProof = getBobsProof(aliceSessionVoucherForBob);
|
|
105
101
|
assertTrue(
|
|
106
|
-
incoVerifier.isAllowedWithProof(secretHandle, bob, bobsProof),
|
|
107
|
-
"bob should be allowed on secret with proof"
|
|
102
|
+
incoVerifier.isAllowedWithProof(secretHandle, bob, bobsProof), "bob should be allowed on secret with proof"
|
|
108
103
|
);
|
|
109
104
|
vm.prank(bob);
|
|
110
105
|
inco.claimHandle(secretHandle, bobsProof);
|
|
111
|
-
assertTrue(
|
|
112
|
-
inco.persistAllowed(secretHandle, bob),
|
|
113
|
-
"bob should have claimed persistent allowance on secret"
|
|
114
|
-
);
|
|
106
|
+
assertTrue(inco.persistAllowed(secretHandle, bob), "bob should have claimed persistent allowance on secret");
|
|
115
107
|
}
|
|
116
108
|
|
|
117
109
|
function testVoucherSessionIdCheck() public {
|
|
@@ -137,24 +129,16 @@ contract TestAdvancedAccessControl is IncoTest {
|
|
|
137
129
|
AllowanceProof memory invalidBobProof = getBobsProof(voucher);
|
|
138
130
|
// the session nonce should be checked by inco
|
|
139
131
|
vm.expectRevert(
|
|
140
|
-
abi.encodeWithSelector(
|
|
141
|
-
AdvancedAccessControl.InvalidVoucherSessionNonce.selector,
|
|
142
|
-
madeUpNonce,
|
|
143
|
-
bytes32(0)
|
|
144
|
-
)
|
|
132
|
+
abi.encodeWithSelector(AdvancedAccessControl.InvalidVoucherSessionNonce.selector, madeUpNonce, bytes32(0))
|
|
145
133
|
);
|
|
146
134
|
incoVerifier.isAllowedWithProof(secretHandle, bob, invalidBobProof);
|
|
147
135
|
vm.prank(alice);
|
|
148
136
|
incoVerifier.updateActiveVouchersSessionNonce();
|
|
149
|
-
bytes32 alicesNewNonce = incoVerifier.getActiveVouchersSessionNonce(
|
|
150
|
-
alice
|
|
151
|
-
);
|
|
137
|
+
bytes32 alicesNewNonce = incoVerifier.getActiveVouchersSessionNonce(alice);
|
|
152
138
|
// previously valid voucher should now be invalid
|
|
153
139
|
vm.expectRevert(
|
|
154
140
|
abi.encodeWithSelector(
|
|
155
|
-
AdvancedAccessControl.InvalidVoucherSessionNonce.selector,
|
|
156
|
-
bytes32(0),
|
|
157
|
-
alicesNewNonce
|
|
141
|
+
AdvancedAccessControl.InvalidVoucherSessionNonce.selector, bytes32(0), alicesNewNonce
|
|
158
142
|
)
|
|
159
143
|
);
|
|
160
144
|
incoVerifier.isAllowedWithProof(secretHandle, bob, bobsFirstProof);
|
|
@@ -177,59 +161,35 @@ contract TestAdvancedAccessControl is IncoTest {
|
|
|
177
161
|
sessionNonce: bytes32(0),
|
|
178
162
|
verifyingContract: address(verifier),
|
|
179
163
|
callFunction: verifier.someCheck.selector,
|
|
180
|
-
sharerArgData: abi.encode(
|
|
181
|
-
SomeVerifier.SharerArg({
|
|
182
|
-
handleShared: secretHandle,
|
|
183
|
-
allowedAccount: bob
|
|
184
|
-
})
|
|
185
|
-
)
|
|
164
|
+
sharerArgData: abi.encode(SomeVerifier.SharerArg({handleShared: secretHandle, allowedAccount: bob}))
|
|
186
165
|
});
|
|
187
166
|
AllowanceProof memory bobsProof = AllowanceProof({
|
|
188
167
|
sharer: alice,
|
|
189
168
|
voucher: voucher,
|
|
190
169
|
voucherSignature: getAliceSig(voucher),
|
|
191
|
-
requesterArgData: abi.encode(
|
|
192
|
-
SomeVerifier.RequesterArg({mustBeBeef: bytes2(0xbeef)})
|
|
193
|
-
)
|
|
170
|
+
requesterArgData: abi.encode(SomeVerifier.RequesterArg({mustBeBeef: bytes2(0xbeef)}))
|
|
194
171
|
});
|
|
195
172
|
assertTrue(
|
|
196
|
-
incoVerifier.isAllowedWithProof(secretHandle, bob, bobsProof),
|
|
197
|
-
"bob should be allowed on secret with proof"
|
|
173
|
+
incoVerifier.isAllowedWithProof(secretHandle, bob, bobsProof), "bob should be allowed on secret with proof"
|
|
198
174
|
);
|
|
199
175
|
bobsProof = AllowanceProof({
|
|
200
176
|
sharer: alice,
|
|
201
177
|
voucher: voucher,
|
|
202
178
|
voucherSignature: getAliceSig(voucher),
|
|
203
|
-
requesterArgData: abi.encode(
|
|
204
|
-
SomeVerifier.RequesterArg({mustBeBeef: bytes2(0xbebe)})
|
|
205
|
-
)
|
|
179
|
+
requesterArgData: abi.encode(SomeVerifier.RequesterArg({mustBeBeef: bytes2(0xbebe)}))
|
|
206
180
|
});
|
|
207
|
-
assertFalse(
|
|
208
|
-
incoVerifier.isAllowedWithProof(secretHandle, bob, bobsProof),
|
|
209
|
-
"all parameters should be checked"
|
|
210
|
-
);
|
|
181
|
+
assertFalse(incoVerifier.isAllowedWithProof(secretHandle, bob, bobsProof), "all parameters should be checked");
|
|
211
182
|
}
|
|
212
183
|
|
|
213
|
-
function getBobsProof(
|
|
214
|
-
AllowanceVoucher memory alicesVoucher
|
|
215
|
-
) private view returns (AllowanceProof memory) {
|
|
184
|
+
function getBobsProof(AllowanceVoucher memory alicesVoucher) private view returns (AllowanceProof memory) {
|
|
216
185
|
bytes memory voucherSignature = getAliceSig(alicesVoucher);
|
|
217
|
-
return
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
voucher: alicesVoucher,
|
|
221
|
-
voucherSignature: voucherSignature,
|
|
222
|
-
requesterArgData: ""
|
|
223
|
-
});
|
|
186
|
+
return AllowanceProof({
|
|
187
|
+
sharer: alice, voucher: alicesVoucher, voucherSignature: voucherSignature, requesterArgData: ""
|
|
188
|
+
});
|
|
224
189
|
}
|
|
225
190
|
|
|
226
|
-
function getAliceSig(
|
|
227
|
-
|
|
228
|
-
) private view returns (bytes memory) {
|
|
229
|
-
return
|
|
230
|
-
getSignatureForDigest(
|
|
231
|
-
incoVerifier.allowanceVoucherDigest(voucher),
|
|
232
|
-
alicePrivKey
|
|
233
|
-
);
|
|
191
|
+
function getAliceSig(AllowanceVoucher memory voucher) private view returns (bytes memory) {
|
|
192
|
+
return getSignatureForDigest(incoVerifier.allowanceVoucherDigest(voucher), alicePrivKey);
|
|
234
193
|
}
|
|
194
|
+
|
|
235
195
|
}
|
|
@@ -7,6 +7,7 @@ import {euint256, inco} from "../../../Lib.sol";
|
|
|
7
7
|
import {IncoTest} from "../../../test/IncoTest.sol";
|
|
8
8
|
|
|
9
9
|
contract TestBaseAccessControl is BaseAccessControlList, IncoTest {
|
|
10
|
+
|
|
10
11
|
constructor() VerifierAddressGetter(address(0)) {}
|
|
11
12
|
|
|
12
13
|
function testHandleZeroIsDisallowed() public view {
|
|
@@ -23,4 +24,5 @@ contract TestBaseAccessControl is BaseAccessControlList, IncoTest {
|
|
|
23
24
|
assert(inco.isAllowed(euint256.unwrap(secret), address(this)));
|
|
24
25
|
assert(inco.isAllowed(euint256.unwrap(secret), alice));
|
|
25
26
|
}
|
|
27
|
+
|
|
26
28
|
}
|
|
@@ -9,37 +9,23 @@ import {IDecryptionAttester} from "./interfaces/IDecryptionAttester.sol";
|
|
|
9
9
|
// todo pre charging transient decrypted values leads to a superior DevX
|
|
10
10
|
|
|
11
11
|
// todo #1032 add DecryptionAttester to IncoVerifier, will include signature verifier as well and fix #874
|
|
12
|
-
abstract contract DecryptionAttester is
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
EIP712Upgradeable
|
|
16
|
-
{
|
|
17
|
-
bytes32 constant DecryptionAttestationStructHash =
|
|
12
|
+
abstract contract DecryptionAttester is IDecryptionAttester, SignatureVerifier, EIP712Upgradeable {
|
|
13
|
+
|
|
14
|
+
bytes32 constant DECRYPTION_ATTESTATION_STRUCT_HASH =
|
|
18
15
|
keccak256("DecryptionAttestation(bytes32 handle,bytes32 value)");
|
|
19
16
|
|
|
20
|
-
function decryptionAttestationDigest(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
_hashTypedDataV4(
|
|
25
|
-
keccak256(
|
|
26
|
-
abi.encode(
|
|
27
|
-
DecryptionAttestationStructHash,
|
|
28
|
-
decryption.handle,
|
|
29
|
-
decryption.value
|
|
30
|
-
)
|
|
31
|
-
)
|
|
32
|
-
);
|
|
17
|
+
function decryptionAttestationDigest(DecryptionAttestation memory decryption) public view returns (bytes32) {
|
|
18
|
+
return _hashTypedDataV4(
|
|
19
|
+
keccak256(abi.encode(DECRYPTION_ATTESTATION_STRUCT_HASH, decryption.handle, decryption.value))
|
|
20
|
+
);
|
|
33
21
|
}
|
|
34
22
|
|
|
35
|
-
function isValidDecryptionAttestation(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
decryptionAttestationDigest(decryption),
|
|
42
|
-
signature
|
|
43
|
-
);
|
|
23
|
+
function isValidDecryptionAttestation(DecryptionAttestation memory decryption, bytes[] memory signatures)
|
|
24
|
+
public
|
|
25
|
+
view
|
|
26
|
+
returns (bool)
|
|
27
|
+
{
|
|
28
|
+
return isValidSignature(decryptionAttestationDigest(decryption), signatures);
|
|
44
29
|
}
|
|
30
|
+
|
|
45
31
|
}
|
|
@@ -20,68 +20,43 @@ error ExternalHandleDoesNotMatchComputedHandle(
|
|
|
20
20
|
address contractAddress
|
|
21
21
|
);
|
|
22
22
|
|
|
23
|
-
abstract contract EncryptedInput is
|
|
24
|
-
|
|
25
|
-
BaseAccessControlList,
|
|
26
|
-
HandleGeneration,
|
|
27
|
-
Fee
|
|
28
|
-
{
|
|
23
|
+
abstract contract EncryptedInput is IEncryptedInput, BaseAccessControlList, HandleGeneration, Fee {
|
|
24
|
+
|
|
29
25
|
event NewInput(
|
|
30
|
-
bytes32 indexed result,
|
|
31
|
-
address indexed contractAddress,
|
|
32
|
-
address indexed user,
|
|
33
|
-
bytes ciphertext,
|
|
34
|
-
uint256 eventId
|
|
26
|
+
bytes32 indexed result, address indexed contractAddress, address indexed user, bytes ciphertext, uint256 eventId
|
|
35
27
|
);
|
|
36
28
|
|
|
37
|
-
function newEuint256(
|
|
38
|
-
bytes memory input,
|
|
39
|
-
address user
|
|
40
|
-
) external payable returns (euint256 newValue) {
|
|
29
|
+
function newEuint256(bytes memory input, address user) external payable returns (euint256 newValue) {
|
|
41
30
|
return euint256.wrap(newInput(input, user, ETypes.Uint256));
|
|
42
31
|
}
|
|
43
32
|
|
|
44
|
-
function newEbool(
|
|
45
|
-
bytes memory input,
|
|
46
|
-
address user
|
|
47
|
-
) external payable returns (ebool newValue) {
|
|
33
|
+
function newEbool(bytes memory input, address user) external payable returns (ebool newValue) {
|
|
48
34
|
return ebool.wrap(newInput(input, user, ETypes.Bool));
|
|
49
35
|
}
|
|
50
36
|
|
|
51
|
-
function newEaddress(
|
|
52
|
-
|
|
53
|
-
address user
|
|
54
|
-
) external payable returns (eaddress newValue) {
|
|
55
|
-
return
|
|
56
|
-
eaddress.wrap(
|
|
57
|
-
newInput(input, user, ETypes.AddressOrUint160OrBytes20)
|
|
58
|
-
);
|
|
37
|
+
function newEaddress(bytes memory input, address user) external payable returns (eaddress newValue) {
|
|
38
|
+
return eaddress.wrap(newInput(input, user, ETypes.AddressOrUint160OrBytes20));
|
|
59
39
|
}
|
|
60
40
|
|
|
61
|
-
function newInput(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
41
|
+
function newInput(bytes memory ciphertext, address user, ETypes inputType)
|
|
42
|
+
internal
|
|
43
|
+
paying
|
|
44
|
+
returns (bytes32 newHandle)
|
|
45
|
+
{
|
|
66
46
|
newHandle = _newInput(ciphertext, user, inputType);
|
|
67
47
|
}
|
|
68
48
|
|
|
69
|
-
function newInputNotPaying(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
) internal returns (bytes32 newHandle) {
|
|
49
|
+
function newInputNotPaying(bytes memory ciphertext, address user, ETypes inputType)
|
|
50
|
+
internal
|
|
51
|
+
returns (bytes32 newHandle)
|
|
52
|
+
{
|
|
74
53
|
newHandle = _newInput(ciphertext, user, inputType);
|
|
75
54
|
}
|
|
76
55
|
|
|
77
56
|
/// @notice Creates a new input with a prepended handle as a checksum.
|
|
78
57
|
/// @param input The input that contains the handle prepended to the ciphertext.
|
|
79
58
|
/// @param user The user address associated with the input.
|
|
80
|
-
function _newInput(
|
|
81
|
-
bytes memory input,
|
|
82
|
-
address user,
|
|
83
|
-
ETypes inputType
|
|
84
|
-
) private returns (bytes32 handle) {
|
|
59
|
+
function _newInput(bytes memory input, address user, ETypes inputType) private returns (bytes32 handle) {
|
|
85
60
|
// Since there is no sensible way to handle abi.decode errors (https://github.com/argotorg/solidity/issues/10381)
|
|
86
61
|
// at least fail early on a conservative minimum length
|
|
87
62
|
require(input.length >= 64, "Input too short, should be at least 64 bytes");
|
|
@@ -102,17 +77,13 @@ abstract contract EncryptedInput is
|
|
|
102
77
|
// We assume that providing the same handle (which via HADU implies same plaintext, same context, and same
|
|
103
78
|
// instance of encryption)
|
|
104
79
|
require(!isAllowed(handle, user), HandleAlreadyExists(handle));
|
|
105
|
-
// We allow to user since this is harmless and it is convenient to use the allow mapping to track existing
|
|
106
|
-
allowInternal(handle, user);
|
|
107
|
-
allowTransientInternal(handle, msg.sender);
|
|
108
80
|
uint256 id = getNextEventId();
|
|
109
|
-
emit NewInput({
|
|
110
|
-
result: handle,
|
|
111
|
-
contractAddress: msg.sender,
|
|
112
|
-
user: user,
|
|
113
|
-
ciphertext: ciphertext,
|
|
114
|
-
eventId: id
|
|
115
|
-
});
|
|
81
|
+
emit NewInput({result: handle, contractAddress: msg.sender, user: user, ciphertext: ciphertext, eventId: id});
|
|
116
82
|
setDigest(abi.encodePacked(handle, id));
|
|
83
|
+
// We allow to user since this is harmless and it is convenient to use the allow mapping to track inputs.
|
|
84
|
+
// NOTE: the allow must come after emitting the new input event, since allow emits its own event.
|
|
85
|
+
allowInternal(handle, user);
|
|
86
|
+
allowTransientInternal(handle, msg.sender);
|
|
117
87
|
}
|
|
88
|
+
|
|
118
89
|
}
|