@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
|
@@ -15,6 +15,7 @@ import {FakeComputeServer} from "./FakeComputeServer.sol";
|
|
|
15
15
|
/// operation on existing handles, or on a mix of existing handles and plaintexts values (which get trivial encrypted)
|
|
16
16
|
/// as long as the handles are allowed for the requester
|
|
17
17
|
contract FakeDecryptionAttester is FakeIncoInfraBase, FakeComputeServer {
|
|
18
|
+
|
|
18
19
|
struct HandleWithProof {
|
|
19
20
|
bytes32 handle;
|
|
20
21
|
AllowanceProof proof; // sharer == address(0) means no proof
|
|
@@ -23,21 +24,12 @@ contract FakeDecryptionAttester is FakeIncoInfraBase, FakeComputeServer {
|
|
|
23
24
|
// The following 4 functions mimic expected behavior of the TEE / covalidator over offchain API
|
|
24
25
|
|
|
25
26
|
/// @notice request decryption attestation for an existing handle
|
|
26
|
-
function getDecryptionAttestation(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
)
|
|
30
|
-
internal
|
|
31
|
-
returns (
|
|
32
|
-
DecryptionAttestation memory decryption,
|
|
33
|
-
bytes memory signature
|
|
34
|
-
)
|
|
27
|
+
function getDecryptionAttestation(address requester, HandleWithProof memory handle)
|
|
28
|
+
internal
|
|
29
|
+
returns (DecryptionAttestation memory decryption, bytes[] memory signatures)
|
|
35
30
|
{
|
|
36
31
|
checkAccessControl(requester, handle);
|
|
37
|
-
(decryption,
|
|
38
|
-
handle.handle,
|
|
39
|
-
get(handle.handle)
|
|
40
|
-
);
|
|
32
|
+
(decryption, signatures) = _getDecryptionAttestation(handle.handle, get(handle.handle));
|
|
41
33
|
}
|
|
42
34
|
|
|
43
35
|
// The following 3 functions are for requesting decryption over a handle resulting of an operation
|
|
@@ -49,152 +41,76 @@ contract FakeDecryptionAttester is FakeIncoInfraBase, FakeComputeServer {
|
|
|
49
41
|
HandleWithProof memory lhs,
|
|
50
42
|
HandleWithProof memory rhs,
|
|
51
43
|
EOps op
|
|
52
|
-
)
|
|
53
|
-
internal
|
|
54
|
-
returns (
|
|
55
|
-
DecryptionAttestation memory decryption,
|
|
56
|
-
bytes memory signature
|
|
57
|
-
)
|
|
58
|
-
{
|
|
44
|
+
) internal returns (DecryptionAttestation memory decryption, bytes memory signature) {
|
|
59
45
|
checkAccessControl(requester, lhs);
|
|
60
46
|
checkAccessControl(requester, rhs);
|
|
61
47
|
bytes32 result = computeBinaryOp(get(lhs.handle), get(rhs.handle), op);
|
|
62
|
-
(decryption, signature) = _getDecryptionAttestation(
|
|
63
|
-
lhs.handle,
|
|
64
|
-
rhs.handle,
|
|
65
|
-
result,
|
|
66
|
-
op
|
|
67
|
-
);
|
|
48
|
+
(decryption, signature) = _getDecryptionAttestation(lhs.handle, rhs.handle, result, op);
|
|
68
49
|
}
|
|
69
50
|
|
|
70
51
|
/// @notice request decryption attestation for a binary operation on a handle and a plaintext value (lhs)
|
|
71
|
-
function getDecryptionAttestation(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
HandleWithProof memory rhs,
|
|
75
|
-
EOps op
|
|
76
|
-
)
|
|
77
|
-
internal
|
|
78
|
-
returns (
|
|
79
|
-
DecryptionAttestation memory decryption,
|
|
80
|
-
bytes memory signature
|
|
81
|
-
)
|
|
52
|
+
function getDecryptionAttestation(address requester, uint256 lhs, HandleWithProof memory rhs, EOps op)
|
|
53
|
+
internal
|
|
54
|
+
returns (DecryptionAttestation memory decryption, bytes memory signature)
|
|
82
55
|
{
|
|
83
56
|
checkAccessControl(requester, rhs);
|
|
84
|
-
bytes32 lhsHandle = inco.getTrivialEncryptHandle(
|
|
85
|
-
bytes32(lhs),
|
|
86
|
-
ETypes.Uint256
|
|
87
|
-
);
|
|
57
|
+
bytes32 lhsHandle = inco.getTrivialEncryptHandle(bytes32(lhs), ETypes.Uint256);
|
|
88
58
|
bytes32 result = computeBinaryOp(bytes32(lhs), get(rhs.handle), op);
|
|
89
|
-
(decryption, signature) = _getDecryptionAttestation(
|
|
90
|
-
lhsHandle,
|
|
91
|
-
rhs.handle,
|
|
92
|
-
result,
|
|
93
|
-
op
|
|
94
|
-
);
|
|
59
|
+
(decryption, signature) = _getDecryptionAttestation(lhsHandle, rhs.handle, result, op);
|
|
95
60
|
}
|
|
96
61
|
|
|
97
62
|
/// @notice request decryption attestation for a binary operation on a handle and a plaintext value (rhs)
|
|
98
|
-
function getDecryptionAttestation(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
uint256 rhs,
|
|
102
|
-
EOps op
|
|
103
|
-
)
|
|
104
|
-
internal
|
|
105
|
-
returns (
|
|
106
|
-
DecryptionAttestation memory decryption,
|
|
107
|
-
bytes memory signature
|
|
108
|
-
)
|
|
63
|
+
function getDecryptionAttestation(address requester, HandleWithProof memory lhs, uint256 rhs, EOps op)
|
|
64
|
+
internal
|
|
65
|
+
returns (DecryptionAttestation memory decryption, bytes memory signature)
|
|
109
66
|
{
|
|
110
67
|
checkAccessControl(requester, lhs);
|
|
111
|
-
bytes32 rhsHandle = inco.getTrivialEncryptHandle(
|
|
112
|
-
bytes32(rhs),
|
|
113
|
-
ETypes.Uint256
|
|
114
|
-
);
|
|
68
|
+
bytes32 rhsHandle = inco.getTrivialEncryptHandle(bytes32(rhs), ETypes.Uint256);
|
|
115
69
|
|
|
116
70
|
bytes32 result = computeBinaryOp(get(lhs.handle), bytes32(rhs), op);
|
|
117
|
-
(decryption, signature) = _getDecryptionAttestation(
|
|
118
|
-
lhs.handle,
|
|
119
|
-
rhsHandle,
|
|
120
|
-
result,
|
|
121
|
-
op
|
|
122
|
-
);
|
|
71
|
+
(decryption, signature) = _getDecryptionAttestation(lhs.handle, rhsHandle, result, op);
|
|
123
72
|
}
|
|
124
73
|
|
|
125
74
|
/// Private methods ///
|
|
126
75
|
|
|
127
|
-
function checkAccessControl(
|
|
128
|
-
address requester,
|
|
129
|
-
HandleWithProof memory handle
|
|
130
|
-
) private {
|
|
76
|
+
function checkAccessControl(address requester, HandleWithProof memory handle) private {
|
|
131
77
|
if (handle.proof.sharer == address(0)) {
|
|
132
|
-
require(
|
|
133
|
-
inco.isAllowed(handle.handle, requester),
|
|
134
|
-
SenderNotAllowedForHandle(handle.handle, requester)
|
|
135
|
-
);
|
|
78
|
+
require(inco.isAllowed(handle.handle, requester), SenderNotAllowedForHandle(handle.handle, requester));
|
|
136
79
|
} else {
|
|
137
80
|
require(
|
|
138
|
-
inco.incoVerifier().isAllowedWithProof(
|
|
139
|
-
handle.handle,
|
|
140
|
-
requester,
|
|
141
|
-
handle.proof
|
|
142
|
-
),
|
|
81
|
+
inco.incoVerifier().isAllowedWithProof(handle.handle, requester, handle.proof),
|
|
143
82
|
SenderNotAllowedForHandle(handle.handle, requester)
|
|
144
83
|
);
|
|
145
84
|
}
|
|
146
85
|
}
|
|
147
86
|
|
|
148
|
-
function _getDecryptionAttestation(
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
private
|
|
153
|
-
view
|
|
154
|
-
returns (
|
|
155
|
-
DecryptionAttestation memory decryption,
|
|
156
|
-
bytes memory signature
|
|
157
|
-
)
|
|
87
|
+
function _getDecryptionAttestation(bytes32 handle, bytes32 value)
|
|
88
|
+
private
|
|
89
|
+
view
|
|
90
|
+
returns (DecryptionAttestation memory decryption, bytes[] memory signatures)
|
|
158
91
|
{
|
|
159
92
|
decryption = DecryptionAttestation({handle: handle, value: value});
|
|
160
|
-
signature = signDecryption(decryption);
|
|
93
|
+
bytes memory signature = signDecryption(decryption);
|
|
94
|
+
signatures = new bytes[](1);
|
|
95
|
+
signatures[0] = signature;
|
|
161
96
|
}
|
|
162
97
|
|
|
163
|
-
function signDecryption(
|
|
164
|
-
DecryptionAttestation memory decryption
|
|
165
|
-
) private view returns (bytes memory signature) {
|
|
98
|
+
function signDecryption(DecryptionAttestation memory decryption) private view returns (bytes memory signature) {
|
|
166
99
|
// todo change this to don't call inco and call verifier directly
|
|
167
|
-
bytes32 digest = inco.incoVerifier().decryptionAttestationDigest(
|
|
168
|
-
decryption
|
|
169
|
-
);
|
|
100
|
+
bytes32 digest = inco.incoVerifier().decryptionAttestationDigest(decryption);
|
|
170
101
|
signature = getSignatureForDigest(digest, teePrivKey);
|
|
171
102
|
}
|
|
172
103
|
|
|
173
|
-
function _getDecryptionAttestation(
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
EOps op
|
|
178
|
-
)
|
|
179
|
-
private
|
|
180
|
-
view
|
|
181
|
-
returns (
|
|
182
|
-
DecryptionAttestation memory decryption,
|
|
183
|
-
bytes memory signature
|
|
184
|
-
)
|
|
104
|
+
function _getDecryptionAttestation(bytes32 lhsHandle, bytes32 rhsHandle, bytes32 encodedResult, EOps op)
|
|
105
|
+
private
|
|
106
|
+
view
|
|
107
|
+
returns (DecryptionAttestation memory decryption, bytes memory signature)
|
|
185
108
|
{
|
|
186
109
|
ETypes resultType = opToResultType(op);
|
|
187
110
|
decryption = DecryptionAttestation({
|
|
188
|
-
handle: inco.getOpResultHandle(
|
|
189
|
-
op,
|
|
190
|
-
resultType,
|
|
191
|
-
abi.encodePacked(
|
|
192
|
-
lhsHandle,
|
|
193
|
-
rhsHandle
|
|
194
|
-
)
|
|
195
|
-
),
|
|
196
|
-
value: encodedResult
|
|
111
|
+
handle: inco.getOpResultHandle(op, resultType, abi.encodePacked(lhsHandle, rhsHandle)), value: encodedResult
|
|
197
112
|
});
|
|
198
113
|
signature = signDecryption(decryption);
|
|
199
114
|
}
|
|
115
|
+
|
|
200
116
|
}
|
|
@@ -9,74 +9,60 @@ import {HandleGeneration} from "../../lightning-parts/primitives/HandleGeneratio
|
|
|
9
9
|
|
|
10
10
|
/// @notice simulates what inco does offchain but over plaintexts
|
|
11
11
|
contract FakeIncoInfraBase is TestUtils, KVStore, HandleGeneration {
|
|
12
|
-
error UnsupportedTypeInput(ETypes inputType);
|
|
13
|
-
|
|
14
|
-
address immutable teePubkeyAddress;
|
|
15
|
-
uint256 immutable teePrivKey;
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
(teePrivKey, teePubkeyAddress) = getLabeledKeyPair("tee");
|
|
19
|
-
}
|
|
13
|
+
error UnsupportedTypeInput(ETypes inputType);
|
|
20
14
|
|
|
21
|
-
function getCiphertextInput(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
) public view returns (bytes memory input) {
|
|
15
|
+
function getCiphertextInput(bytes32 word, address user, address contractAddress, ETypes inputType)
|
|
16
|
+
public
|
|
17
|
+
view
|
|
18
|
+
returns (bytes memory input)
|
|
19
|
+
{
|
|
27
20
|
// We need a single word here to get correct encoding
|
|
28
21
|
bytes memory ciphertext = abi.encode(word);
|
|
29
22
|
bytes32 handle = getInputHandle(ciphertext, address(inco), user, contractAddress, inputType);
|
|
30
23
|
input = abi.encode(handle, ciphertext);
|
|
31
24
|
}
|
|
32
25
|
|
|
33
|
-
function fakePrepareEuint256Ciphertext(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
26
|
+
function fakePrepareEuint256Ciphertext(uint256 value, address userAddress, address contractAddress)
|
|
27
|
+
internal
|
|
28
|
+
view
|
|
29
|
+
returns (bytes memory ciphertext)
|
|
30
|
+
{
|
|
38
31
|
ciphertext = getCiphertextInput(bytes32(value), userAddress, contractAddress, ETypes.Uint256);
|
|
39
32
|
}
|
|
40
33
|
|
|
41
|
-
|
|
42
|
-
function fakeDecryptEuint256Ciphertext(
|
|
43
|
-
bytes memory ciphertext
|
|
44
|
-
) internal pure returns (uint256 value) {
|
|
34
|
+
function fakeDecryptEuint256Ciphertext(bytes memory ciphertext) internal pure returns (uint256 value) {
|
|
45
35
|
(value) = abi.decode(ciphertext, (uint256));
|
|
46
36
|
}
|
|
47
37
|
|
|
48
|
-
function fakeDecryptEuint160Ciphertext(
|
|
49
|
-
bytes memory ciphertext
|
|
50
|
-
) internal pure returns (uint160 value) {
|
|
38
|
+
function fakeDecryptEuint160Ciphertext(bytes memory ciphertext) internal pure returns (uint160 value) {
|
|
51
39
|
value = abi.decode(ciphertext, (uint160));
|
|
52
40
|
}
|
|
53
41
|
|
|
54
|
-
function fakePrepareEboolCiphertext(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
42
|
+
function fakePrepareEboolCiphertext(bool value, address userAddress, address contractAddress)
|
|
43
|
+
internal
|
|
44
|
+
view
|
|
45
|
+
returns (bytes memory ciphertext)
|
|
46
|
+
{
|
|
59
47
|
bytes32 b = bytes32(uint256(value ? 1 : 0));
|
|
60
48
|
ciphertext = getCiphertextInput(b, userAddress, contractAddress, ETypes.Bool);
|
|
61
49
|
}
|
|
62
50
|
|
|
63
|
-
function fakePrepareEaddressCiphertext(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
ciphertext = getCiphertextInput(
|
|
51
|
+
function fakePrepareEaddressCiphertext(address value, address userAddress, address contractAddress)
|
|
52
|
+
internal
|
|
53
|
+
view
|
|
54
|
+
returns (bytes memory ciphertext)
|
|
55
|
+
{
|
|
56
|
+
ciphertext = getCiphertextInput(
|
|
57
|
+
bytes32(uint256(uint160(value))), userAddress, contractAddress, ETypes.AddressOrUint160OrBytes20
|
|
58
|
+
);
|
|
69
59
|
}
|
|
70
60
|
|
|
71
|
-
function fakeDecryptEaddressCiphertext(
|
|
72
|
-
bytes memory ciphertext
|
|
73
|
-
) internal pure returns (address value) {
|
|
61
|
+
function fakeDecryptEaddressCiphertext(bytes memory ciphertext) internal pure returns (address value) {
|
|
74
62
|
value = abi.decode(ciphertext, (address));
|
|
75
63
|
}
|
|
76
64
|
|
|
77
|
-
function fakeDecryptEboolCiphertext(
|
|
78
|
-
bytes memory ciphertext
|
|
79
|
-
) internal pure returns (bool value) {
|
|
65
|
+
function fakeDecryptEboolCiphertext(bytes memory ciphertext) internal pure returns (bool value) {
|
|
80
66
|
value = abi.decode(ciphertext, (bool));
|
|
81
67
|
}
|
|
82
68
|
|
|
@@ -84,9 +70,7 @@ contract FakeIncoInfraBase is TestUtils, KVStore, HandleGeneration {
|
|
|
84
70
|
return ebool.wrap(bytes32(value ? uint256(1) : uint256(0)));
|
|
85
71
|
}
|
|
86
72
|
|
|
87
|
-
function fakeEncryptUint256(
|
|
88
|
-
uint256 value
|
|
89
|
-
) internal pure returns (euint256) {
|
|
73
|
+
function fakeEncryptUint256(uint256 value) internal pure returns (euint256) {
|
|
90
74
|
return euint256.wrap(bytes32(value));
|
|
91
75
|
}
|
|
92
76
|
|
|
@@ -94,9 +78,8 @@ contract FakeIncoInfraBase is TestUtils, KVStore, HandleGeneration {
|
|
|
94
78
|
return ebool.unwrap(handle) == bytes32(uint256(1));
|
|
95
79
|
}
|
|
96
80
|
|
|
97
|
-
function fakeDecryptEuint256(
|
|
98
|
-
euint256 handle
|
|
99
|
-
) internal pure returns (uint256) {
|
|
81
|
+
function fakeDecryptEuint256(euint256 handle) internal pure returns (uint256) {
|
|
100
82
|
return uint256(euint256.unwrap(handle));
|
|
101
83
|
}
|
|
84
|
+
|
|
102
85
|
}
|
|
@@ -8,6 +8,7 @@ import {IQuoteVerifier} from "../../interfaces/automata-interfaces/IQuoteVerifie
|
|
|
8
8
|
// This contract is used to test the IncoLightning contract. It is a simple implementation of the QuoteVerifier interface.
|
|
9
9
|
// It is used to test the IncoLightning contract without relying on the real QuoteVerifier contract.
|
|
10
10
|
contract FakeQuoteVerifier is IQuoteVerifier {
|
|
11
|
+
|
|
11
12
|
/// @dev immutable
|
|
12
13
|
function pccsRouter() external pure returns (IPCCSRouter) {
|
|
13
14
|
return IPCCSRouter(address(0));
|
|
@@ -18,16 +19,12 @@ contract FakeQuoteVerifier is IQuoteVerifier {
|
|
|
18
19
|
return 4;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
function verifyQuote(
|
|
22
|
-
Header calldata,
|
|
23
|
-
bytes calldata quote
|
|
24
|
-
) external pure returns (bool, bytes memory) {
|
|
22
|
+
function verifyQuote(Header calldata, bytes calldata quote) external pure returns (bool, bytes memory) {
|
|
25
23
|
return (true, quote);
|
|
26
24
|
}
|
|
27
25
|
|
|
28
|
-
function verifyZkOutput(
|
|
29
|
-
bytes calldata quote
|
|
30
|
-
) external pure returns (bool, bytes memory) {
|
|
26
|
+
function verifyZkOutput(bytes calldata quote) external pure returns (bool, bytes memory) {
|
|
31
27
|
return (true, quote);
|
|
32
28
|
}
|
|
29
|
+
|
|
33
30
|
}
|
|
@@ -7,6 +7,7 @@ import {asBool} from "../..//shared/TypeUtils.sol";
|
|
|
7
7
|
|
|
8
8
|
/// @notice key-value store, knows the value behind each handle
|
|
9
9
|
contract KVStore is HandleMetadata {
|
|
10
|
+
|
|
10
11
|
mapping(bytes32 => bytes32) private store;
|
|
11
12
|
|
|
12
13
|
function set(bytes32 key, bytes32 value) internal {
|
|
@@ -38,4 +39,5 @@ contract KVStore is HandleMetadata {
|
|
|
38
39
|
function checkType(bytes32 handle, ETypes requiredType) private pure {
|
|
39
40
|
assert(typeOf(handle) == requiredType);
|
|
40
41
|
}
|
|
42
|
+
|
|
41
43
|
}
|
|
@@ -10,6 +10,7 @@ import {asBytes32} from "../../shared/TypeUtils.sol";
|
|
|
10
10
|
import {getOpForSelector} from "./getOpForSelector.sol";
|
|
11
11
|
|
|
12
12
|
contract MockOpHandler is FakeIncoInfraBase, FakeComputeServer {
|
|
13
|
+
|
|
13
14
|
function processAllOperations() internal {
|
|
14
15
|
Vm.Log[] memory logs = vm.getRecordedLogs();
|
|
15
16
|
for (uint256 i = 0; i < logs.length; i++) {
|
|
@@ -24,10 +25,7 @@ contract MockOpHandler is FakeIncoInfraBase, FakeComputeServer {
|
|
|
24
25
|
EOps op = getOpForSelector(eventSelector);
|
|
25
26
|
if (op == EOps.TrivialEncrypt) {
|
|
26
27
|
bytes32 result = log.topics[1];
|
|
27
|
-
(bytes32 plainTextBytes
|
|
28
|
-
log.data,
|
|
29
|
-
(bytes32, ETypes, uint256)
|
|
30
|
-
);
|
|
28
|
+
(bytes32 plainTextBytes,,) = abi.decode(log.data, (bytes32, ETypes, uint256));
|
|
31
29
|
handleTrivialEncryption(result, plainTextBytes);
|
|
32
30
|
} else if (isBinaryUintOp(op)) {
|
|
33
31
|
bytes32 lhs = log.topics[1];
|
|
@@ -65,18 +63,12 @@ contract MockOpHandler is FakeIncoInfraBase, FakeComputeServer {
|
|
|
65
63
|
} else if (op == EOps.NewInput) {
|
|
66
64
|
bytes32 result = log.topics[1];
|
|
67
65
|
// contractAddress and user topics are ignored
|
|
68
|
-
(bytes memory ciphertext,
|
|
69
|
-
log.data,
|
|
70
|
-
(bytes, uint256)
|
|
71
|
-
);
|
|
66
|
+
(bytes memory ciphertext,) = abi.decode(log.data, (bytes, uint256));
|
|
72
67
|
handleEInput(result, ciphertext);
|
|
73
68
|
}
|
|
74
69
|
}
|
|
75
70
|
|
|
76
|
-
function handleEInput(
|
|
77
|
-
bytes32 result,
|
|
78
|
-
bytes memory ciphertext
|
|
79
|
-
) private {
|
|
71
|
+
function handleEInput(bytes32 result, bytes memory ciphertext) private {
|
|
80
72
|
ETypes inputType = typeOf(result);
|
|
81
73
|
if (inputType == ETypes.Uint256) {
|
|
82
74
|
set(result, bytes32(fakeDecryptEuint256Ciphertext(ciphertext)));
|
|
@@ -97,23 +89,11 @@ contract MockOpHandler is FakeIncoInfraBase, FakeComputeServer {
|
|
|
97
89
|
set(euint256.unwrap(result), bytes32(counter));
|
|
98
90
|
}
|
|
99
91
|
|
|
100
|
-
function handleERandBounded(
|
|
101
|
-
|
|
102
|
-
euint256 upperBound,
|
|
103
|
-
euint256 result
|
|
104
|
-
) private {
|
|
105
|
-
set(
|
|
106
|
-
euint256.unwrap(result),
|
|
107
|
-
bytes32(counter % getUint256Value(upperBound))
|
|
108
|
-
);
|
|
92
|
+
function handleERandBounded(uint256 counter, euint256 upperBound, euint256 result) private {
|
|
93
|
+
set(euint256.unwrap(result), bytes32(counter % getUint256Value(upperBound)));
|
|
109
94
|
}
|
|
110
95
|
|
|
111
|
-
function handleIfThenElse(
|
|
112
|
-
ebool control,
|
|
113
|
-
bytes32 lhs,
|
|
114
|
-
bytes32 rhs,
|
|
115
|
-
bytes32 result
|
|
116
|
-
) private {
|
|
96
|
+
function handleIfThenElse(ebool control, bytes32 lhs, bytes32 rhs, bytes32 result) private {
|
|
117
97
|
set(result, bytes32(getBoolValue(control) ? get(lhs) : get(rhs)));
|
|
118
98
|
}
|
|
119
99
|
|
|
@@ -126,10 +106,8 @@ contract MockOpHandler is FakeIncoInfraBase, FakeComputeServer {
|
|
|
126
106
|
}
|
|
127
107
|
}
|
|
128
108
|
|
|
129
|
-
function handleTrivialEncryption(
|
|
130
|
-
bytes32 result,
|
|
131
|
-
bytes32 plainTextBytes
|
|
132
|
-
) private {
|
|
109
|
+
function handleTrivialEncryption(bytes32 result, bytes32 plainTextBytes) private {
|
|
133
110
|
set(result, plainTextBytes);
|
|
134
111
|
}
|
|
112
|
+
|
|
135
113
|
}
|
|
@@ -2,23 +2,19 @@
|
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
4
|
import {TestUtils} from "../../shared/TestUtils.sol";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
TDX_TEE
|
|
9
|
-
} from "../../interfaces/automata-interfaces/Types.sol";
|
|
5
|
+
import {HEADER_LENGTH, MINIMUM_QUOTE_LENGTH, TDX_TEE} from "../../interfaces/automata-interfaces/Types.sol";
|
|
6
|
+
import {BootstrapResult} from "../../lightning-parts/TEELifecycle.types.sol";
|
|
7
|
+
import {ITEELifecycle} from "../../lightning-parts/interfaces/ITEELifecycle.sol";
|
|
10
8
|
|
|
11
9
|
contract MockRemoteAttestation is TestUtils {
|
|
10
|
+
|
|
12
11
|
/**
|
|
13
12
|
* @notice Creates a mock quote for the given MRTD and signer
|
|
14
13
|
* The RTMR0, RTMR1, RTMR2 are set to zeros
|
|
15
14
|
* @dev This function is the same as the non-TDX version of
|
|
16
15
|
* get_tdx_quote in attestation/src/remote_attestation.rs
|
|
17
16
|
*/
|
|
18
|
-
function createQuote(
|
|
19
|
-
bytes memory mrtd,
|
|
20
|
-
address signer
|
|
21
|
-
) public pure returns (bytes memory quote) {
|
|
17
|
+
function createQuote(bytes memory mrtd, address signer) public pure returns (bytes memory quote) {
|
|
22
18
|
// Mock implementation of quote creation
|
|
23
19
|
require(mrtd.length == 48, "MRTD should be 48 bytes");
|
|
24
20
|
/* Quote structure:
|
|
@@ -34,22 +30,55 @@ contract MockRemoteAttestation is TestUtils {
|
|
|
34
30
|
|
|
35
31
|
*/
|
|
36
32
|
bytes4 version = 0x04000000; // Version 4
|
|
37
|
-
bytes4
|
|
33
|
+
bytes4 tdxTeeType = TDX_TEE; // TDX TEETYPE
|
|
38
34
|
bytes memory prefix = new bytes(HEADER_LENGTH + 136 - 8);
|
|
39
35
|
bytes memory middle = new bytes(520 - 184);
|
|
40
36
|
bytes memory reportDataSuffix = new bytes(44);
|
|
41
|
-
bytes memory suffix = new bytes(
|
|
42
|
-
MINIMUM_QUOTE_LENGTH - HEADER_LENGTH - 584
|
|
43
|
-
);
|
|
37
|
+
bytes memory suffix = new bytes(MINIMUM_QUOTE_LENGTH - HEADER_LENGTH - 584);
|
|
44
38
|
quote = abi.encodePacked(
|
|
45
|
-
version,
|
|
46
|
-
tdxTEEType,
|
|
47
|
-
prefix,
|
|
48
|
-
mrtd,
|
|
49
|
-
middle,
|
|
50
|
-
abi.encodePacked(signer),
|
|
51
|
-
reportDataSuffix,
|
|
52
|
-
suffix
|
|
39
|
+
version, tdxTeeType, prefix, mrtd, middle, abi.encodePacked(signer), reportDataSuffix, suffix
|
|
53
40
|
);
|
|
54
41
|
}
|
|
42
|
+
|
|
43
|
+
// Helper function to create a successful bootstrap result
|
|
44
|
+
function successfulBootstrapResult(
|
|
45
|
+
ITEELifecycle teeLifecycle,
|
|
46
|
+
bytes memory eciesPublicKey,
|
|
47
|
+
address signer,
|
|
48
|
+
uint256 signerPrivKey
|
|
49
|
+
)
|
|
50
|
+
internal
|
|
51
|
+
returns (
|
|
52
|
+
BootstrapResult memory bootstrapResult,
|
|
53
|
+
bytes memory quote,
|
|
54
|
+
bytes memory signature,
|
|
55
|
+
bytes32 mrAggregated
|
|
56
|
+
)
|
|
57
|
+
{
|
|
58
|
+
bytes memory eciesPubkey = eciesPublicKey;
|
|
59
|
+
// See DEFAULT_MRTD in attestation/src/remote_attestation.rs
|
|
60
|
+
bytes memory mrtd =
|
|
61
|
+
hex"010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101";
|
|
62
|
+
// See DEFAULT_MR_AGGREGATED in attestation/src/remote_attestation.rs to
|
|
63
|
+
// see the calculation of the default value.
|
|
64
|
+
mrAggregated = hex"c3a67bac251d4946d7b17481d39631676042fe3afab06e70c22105ad8383c19f";
|
|
65
|
+
bootstrapResult = BootstrapResult({ecies_pubkey: eciesPubkey});
|
|
66
|
+
|
|
67
|
+
quote = createQuote(mrtd, signer);
|
|
68
|
+
signature = signBootstrapResult(bootstrapResult, signerPrivKey, teeLifecycle);
|
|
69
|
+
// We set the signer address and priv key as part of the bootstrap for non-tee setups
|
|
70
|
+
teeEOA = signer;
|
|
71
|
+
teePrivKey = signerPrivKey;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Helper function to sign the bootstrap result
|
|
75
|
+
function signBootstrapResult(BootstrapResult memory bootstrapResult, uint256 privateKey, ITEELifecycle teeLifecycle)
|
|
76
|
+
internal
|
|
77
|
+
view
|
|
78
|
+
returns (bytes memory)
|
|
79
|
+
{
|
|
80
|
+
bytes32 bootstrapResultDigest = teeLifecycle.bootstrapResultDigest(bootstrapResult);
|
|
81
|
+
return getSignatureForDigest(bootstrapResultDigest, privateKey);
|
|
82
|
+
}
|
|
83
|
+
|
|
55
84
|
}
|
package/src/test/IncoTest.sol
CHANGED
|
@@ -10,15 +10,26 @@ import {FakeDecryptionAttester} from "./FakeIncoInfra/FakeDecryptionAttester.sol
|
|
|
10
10
|
import {console} from "forge-std/console.sol";
|
|
11
11
|
import {FakeQuoteVerifier} from "./FakeIncoInfra/FakeQuoteVerifier.sol";
|
|
12
12
|
import {IOwnable} from "../../src/shared/IOwnable.sol";
|
|
13
|
+
import {MockRemoteAttestation} from "./FakeIncoInfra/MockRemoteAttestation.sol";
|
|
14
|
+
import {BootstrapResult} from "../lightning-parts/TEELifecycle.types.sol";
|
|
13
15
|
|
|
14
|
-
contract IncoTest is MockOpHandler, DeployUtils, FakeDecryptionAttester {
|
|
16
|
+
contract IncoTest is MockOpHandler, DeployUtils, FakeDecryptionAttester, MockRemoteAttestation {
|
|
17
|
+
|
|
18
|
+
// forge-lint: disable-next-line(screaming-snake-case-immutable)
|
|
15
19
|
address immutable owner;
|
|
20
|
+
// forge-lint: disable-next-line(screaming-snake-case-immutable)
|
|
16
21
|
address immutable testDeployer;
|
|
17
22
|
|
|
23
|
+
// Constants for testing
|
|
24
|
+
bytes testNetworkPubkey = hex"02516bda9e68a1c3dce74dc1b6ed7d91a91d51c1e1933947f06331cef59631e9eb";
|
|
25
|
+
address private constant ANVIL_ZEROTH_ADDRESS = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
|
|
26
|
+
uint256 private constant ANVIL_ZEROTH_PRIVATE_KEY =
|
|
27
|
+
0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80;
|
|
28
|
+
|
|
18
29
|
constructor() {
|
|
19
30
|
owner = getLabeledAddress("owner");
|
|
20
31
|
// extracted from the deploy script running as bare simulation with:
|
|
21
|
-
//
|
|
32
|
+
// forge script src/script/Deploy.s.sol:Deploy
|
|
22
33
|
testDeployer = deployedBy;
|
|
23
34
|
vm.label(testDeployer, "testDeployer");
|
|
24
35
|
vm.label(address(this), "testRunner");
|
|
@@ -29,7 +40,7 @@ contract IncoTest is MockOpHandler, DeployUtils, FakeDecryptionAttester {
|
|
|
29
40
|
deployCreateX();
|
|
30
41
|
vm.startPrank(testDeployer);
|
|
31
42
|
vm.setEnv("USE_TDX_HW", "false"); // results in the test deployment using the FakeQuoteVerifier
|
|
32
|
-
(IIncoLightning proxy,
|
|
43
|
+
(IIncoLightning proxy,) = deployIncoLightningUsingConfig({
|
|
33
44
|
deployer: testDeployer,
|
|
34
45
|
// The highest precedent deployment
|
|
35
46
|
// We select the pepper that will be used that will be generated in the lib.sol (usually "testnet"), but currently "alphanet" has higher major version
|
|
@@ -39,19 +50,21 @@ contract IncoTest is MockOpHandler, DeployUtils, FakeDecryptionAttester {
|
|
|
39
50
|
IOwnable(address(proxy)).transferOwnership(owner);
|
|
40
51
|
IOwnable(address(inco.incoVerifier())).transferOwnership(owner);
|
|
41
52
|
vm.stopPrank();
|
|
42
|
-
console.log(
|
|
43
|
-
"Deployed %s (proxy) to: %s",
|
|
44
|
-
proxy.getName(),
|
|
45
|
-
address(proxy)
|
|
46
|
-
);
|
|
53
|
+
console.log("Deployed %s (proxy) to: %s", proxy.getName(), address(proxy));
|
|
47
54
|
console.log("Generated inco address: %s", address(inco));
|
|
48
55
|
require(
|
|
49
56
|
address(proxy) == address(inco),
|
|
50
57
|
"generated inco address in Lib.sol does not match address of inco deployed by IncoTest"
|
|
51
58
|
);
|
|
52
59
|
vm.startPrank(owner);
|
|
53
|
-
|
|
60
|
+
(BootstrapResult memory bootstrapResult, bytes memory quote, bytes memory signature, bytes32 mrAggregated) = successfulBootstrapResult(
|
|
61
|
+
inco.incoVerifier(), testNetworkPubkey, ANVIL_ZEROTH_ADDRESS, ANVIL_ZEROTH_PRIVATE_KEY
|
|
62
|
+
);
|
|
63
|
+
inco.incoVerifier().approveNewTeeVersion(mrAggregated);
|
|
64
|
+
inco.incoVerifier().verifyBootstrapResult(bootstrapResult, quote, signature);
|
|
65
|
+
inco.incoVerifier().setThreshold(1);
|
|
54
66
|
vm.stopPrank();
|
|
55
67
|
vm.recordLogs();
|
|
56
68
|
}
|
|
69
|
+
|
|
57
70
|
}
|