@inco/lightning 0.5.2 → 0.6.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/manifest.yaml +23 -9
- package/package.json +1 -2
- package/src/DeployUtils.sol +10 -19
- package/src/Lib.alphanet.sol +12 -6
- package/src/Lib.demonet.sol +12 -6
- package/src/Lib.devnet.sol +13 -7
- package/src/Lib.sol +13 -7
- package/src/Lib.template.sol +12 -6
- package/src/Lib.testnet.sol +12 -6
- package/src/Types.sol +4 -1
- package/src/libs/incoLightning_alphanet_v0_297966649.sol +12 -6
- package/src/libs/incoLightning_demonet_v0_863421733.sol +12 -6
- package/src/libs/incoLightning_devnet_v0_340846814.sol +12 -6
- package/src/libs/incoLightning_devnet_v1_904635675.sol +457 -0
- package/src/libs/incoLightning_testnet_v0_183408998.sol +12 -6
- package/src/lightning-parts/AccessControl/BaseAccessControlList.sol +21 -5
- package/src/lightning-parts/AccessControl/test/TestAdvancedAccessControl.t.sol +1 -0
- package/src/lightning-parts/EncryptedInput.sol +22 -6
- package/src/lightning-parts/EncryptedOperations.sol +6 -6
- package/src/lightning-parts/Fee.sol +41 -0
- package/src/lightning-parts/TEELifecycle.sol +170 -67
- package/src/lightning-parts/TEELifecycle.types.sol +9 -12
- package/src/lightning-parts/TrivialEncryption.sol +1 -1
- package/src/lightning-parts/interfaces/IEncryptedInput.sol +3 -3
- package/src/lightning-parts/interfaces/IEncryptedOperations.sol +48 -1
- package/src/lightning-parts/interfaces/ITEELifecycle.sol +2 -2
- package/src/lightning-parts/test/Fee.t.sol +101 -0
- package/src/lightning-parts/test/HandleMetadata.t.sol +4 -3
- package/src/lightning-parts/test/InputsFee.t.sol +65 -0
- package/src/lightning-parts/test/TestDecryptionAttestationInSynchronousFlow.t.sol +1 -0
- package/src/test/AddTwo.sol +18 -6
- package/src/test/FakeIncoInfra/FakeIncoInfraBase.sol +12 -0
- package/src/test/FakeIncoInfra/MockRemoteAttestation.sol +6 -0
- package/src/test/FakeIncoInfra/getOpForSelector.sol +5 -0
- package/src/test/IncoTest.sol +1 -0
- package/src/test/TEELifecycle/TEELifecycleMockTest.t.sol +21 -26
- package/src/test/TestAddTwo.t.sol +9 -1
- package/src/test/TestFakeInfra.t.sol +12 -3
- package/src/version/IncoLightningConfig.sol +3 -1
- package/src/test/TEELifecycle/README.md +0 -53
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// SPDX-License-Identifier: No License
|
|
2
|
+
pragma solidity ^0.8;
|
|
3
|
+
|
|
4
|
+
// the fee should be modified through upgrades to limit gas cost
|
|
5
|
+
uint256 constant FEE = 0.0001 ether;
|
|
6
|
+
|
|
7
|
+
/// @notice Fee utils for lightning functions that require a fee
|
|
8
|
+
/// @dev the fee may be changed through upgrades, develop your apps accordingly!
|
|
9
|
+
abstract contract Fee {
|
|
10
|
+
error FeeNotPaid();
|
|
11
|
+
|
|
12
|
+
/// @notice the fee to pay through msg.value for inputs and randomness IT MAY CHANGE
|
|
13
|
+
function getFee() public pure returns (uint256) {
|
|
14
|
+
return FEE;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
modifier paying() {
|
|
18
|
+
require(msg.value == FEE, FeeNotPaid());
|
|
19
|
+
_;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
modifier payingMultiple(uint256 nbOfFees) {
|
|
23
|
+
require(msg.value == FEE * nbOfFees, FeeNotPaid());
|
|
24
|
+
_;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Refund the difference between msg.value and what was actually spent
|
|
28
|
+
// assumes that all outflows and inflows to the contract are due to the user
|
|
29
|
+
// though the refund is capped at msg.value
|
|
30
|
+
modifier refundUnspent() {
|
|
31
|
+
uint256 balanceBefore = address(this).balance;
|
|
32
|
+
_;
|
|
33
|
+
uint256 balanceAfter = address(this).balance;
|
|
34
|
+
uint256 spent = balanceBefore > balanceAfter ? balanceBefore - balanceAfter : 0;
|
|
35
|
+
uint256 refund = msg.value > spent ? msg.value - spent : 0;
|
|
36
|
+
if (refund > 0) {
|
|
37
|
+
(bool success, ) = msg.sender.call{value: refund}("");
|
|
38
|
+
require(success, "Refund failed");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -2,8 +2,7 @@ pragma solidity ^0.8.19;
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
BootstrapResult,
|
|
5
|
-
|
|
6
|
-
TEEVersionStatus
|
|
5
|
+
UpgradeResult
|
|
7
6
|
} from "./TEELifecycle.types.sol";
|
|
8
7
|
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
|
|
9
8
|
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
|
@@ -28,40 +27,53 @@ abstract contract TEELifecycle is
|
|
|
28
27
|
OwnableUpgradeable,
|
|
29
28
|
EIP712Upgradeable
|
|
30
29
|
{
|
|
30
|
+
// Errors
|
|
31
31
|
error InvalidQuoteVerifierVersion(uint16 actual, uint16 expected);
|
|
32
32
|
error EmptyTcbInfo();
|
|
33
33
|
error EmptyIdentity();
|
|
34
34
|
error BootstrapNotComplete();
|
|
35
35
|
error BootstrapAlreadyCompleted();
|
|
36
|
-
/// @notice
|
|
37
|
-
error
|
|
38
|
-
error
|
|
39
|
-
error InvalidReportMRTD();
|
|
40
|
-
error InvalidBootstrapDataSignature();
|
|
41
|
-
/// @notice MRTD must be exactly 48 bytes
|
|
42
|
-
error MrtdInvalidLength();
|
|
43
|
-
error EOASignerAlreadyInitialized();
|
|
44
|
-
error InvalidMrtdReport();
|
|
36
|
+
/// @notice The TEE version was not found in the TEEVersionHistory
|
|
37
|
+
error TEEVersionNotFound();
|
|
38
|
+
error InvalidReportMrAggregated();
|
|
45
39
|
error InvalidReportDataSigner();
|
|
40
|
+
/// @notice The EIP712 signature recovered an incorrect address
|
|
41
|
+
error InvalidEIP712Signature();
|
|
42
|
+
error EOASignerAlreadyInitialized();
|
|
43
|
+
// @notice The EOA signer in the quote is not an existing EOA signer
|
|
44
|
+
error EOASignerNotFound();
|
|
45
|
+
// @notice The network pubkey signed by the TDX EOA is not the same as the one in the bootstrap result
|
|
46
|
+
error InvalidNetworkPubkey();
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
// Events
|
|
49
|
+
// @notice A new MR_AGGREGATED has been approved
|
|
50
|
+
event NewTEEVersionApproved(uint256 indexed version, bytes32 indexed mrAggregated);
|
|
49
51
|
event NewCovalidatorAdded(address covalidatorAddress, bytes quote);
|
|
50
52
|
event BootstrapStageComplete(
|
|
51
53
|
address indexed newEOASigner,
|
|
52
54
|
BootstrapResult bootstrapResult
|
|
53
55
|
);
|
|
56
|
+
// @notice Emitted to prove that an EOA has upgraded their TDX to a new
|
|
57
|
+
// MR_AGGREGATED. This is done by checking remote attestation of the quote
|
|
58
|
+
// and verifying the EIP712 signature of the bootstrap/upgrade result by
|
|
59
|
+
// the TDX EOA.
|
|
60
|
+
event EOAHasUpdatedTDX(address indexed eoaSigner, bytes32 indexed mrAggregated);
|
|
54
61
|
|
|
62
|
+
// Constants
|
|
55
63
|
bytes32 public constant BootstrapResultStructHash =
|
|
56
64
|
keccak256(bytes("BootstrapResult(bytes ecies_pubkey)"));
|
|
65
|
+
bytes32 public constant UpgradeResultStructHash =
|
|
66
|
+
keccak256(bytes("UpgradeResult(bytes network_pubkey)"));
|
|
57
67
|
|
|
58
68
|
uint16 public constant QUOTE_VERIFIER_VERSION = 4;
|
|
59
69
|
|
|
60
70
|
IQuoteVerifier public quoteVerifier;
|
|
61
|
-
BootstrapResult public VerifiedBootstrapResult;
|
|
62
|
-
bool public BootstrapComplete;
|
|
63
71
|
|
|
64
|
-
|
|
72
|
+
// @notice The list of approved TEE versions, each item is the MR_AGGREGATED 32 bytes
|
|
73
|
+
// @dev The index of the TEE version is the version number
|
|
74
|
+
bytes32[] public ApprovedTEEVersions;
|
|
75
|
+
// @notice The Network key
|
|
76
|
+
// @todo rename to NetworkPubkey https://github.com/Inco-fhevm/inco-monorepo/issues/983
|
|
65
77
|
bytes public ECIESPubkey;
|
|
66
78
|
mapping(address => bool) public EOASigners;
|
|
67
79
|
|
|
@@ -109,10 +121,10 @@ abstract contract TEELifecycle is
|
|
|
109
121
|
}
|
|
110
122
|
|
|
111
123
|
/**
|
|
112
|
-
* @notice
|
|
124
|
+
* @notice Wrapper around activateNewTEEVersion which verifies the bootstrap result and marks the new TEE version as active
|
|
113
125
|
* @param bootstrapResult - The bootstrap data to verify
|
|
114
126
|
* @param quote - The quote to verify against
|
|
115
|
-
* @param signature - The signature
|
|
127
|
+
* @param signature - The EIP712 signature of the bootstrap result by the TDX EOA
|
|
116
128
|
*/
|
|
117
129
|
function verifyBootstrapResult(
|
|
118
130
|
BootstrapResult calldata bootstrapResult,
|
|
@@ -120,63 +132,121 @@ abstract contract TEELifecycle is
|
|
|
120
132
|
bytes calldata signature
|
|
121
133
|
) public onlyOwner {
|
|
122
134
|
// Make sure the bootstrap is not already complete, and that the contract owner
|
|
123
|
-
// has already submitted the pending TEE
|
|
135
|
+
// has already submitted the pending TEE MR_AGGREGATED.
|
|
124
136
|
require(!isBootstrapComplete(), BootstrapAlreadyCompleted());
|
|
125
|
-
require(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
137
|
+
require(ApprovedTEEVersions.length == 1, TEEVersionNotFound());
|
|
138
|
+
|
|
139
|
+
bytes32 digest = bootstrapResultDigest(bootstrapResult);
|
|
140
|
+
address reportDataSigner = _verifyResultForEOA(
|
|
141
|
+
ApprovedTEEVersions[0],
|
|
142
|
+
digest,
|
|
143
|
+
quote,
|
|
144
|
+
signature
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
// For bootstrap phase, we only have one EOA signer
|
|
148
|
+
// So if we arrive here in code, it means that the EOA has signed the bootstrap result
|
|
149
|
+
|
|
150
|
+
// Update contract publicly viewable state
|
|
151
|
+
ECIESPubkey = bootstrapResult.ecies_pubkey;
|
|
152
|
+
EOASigners[reportDataSigner] = true;
|
|
153
|
+
|
|
154
|
+
emit BootstrapStageComplete(reportDataSigner, bootstrapResult);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @notice Verifies the upgrade result for a single EOA. This function does not modify any contract state.
|
|
159
|
+
* It simply serves as an on-chain proof that each TDX has been updated to the newest MR_AGGREGATED.
|
|
160
|
+
* @param upgradeResult - The upgrade data to verify
|
|
161
|
+
* @param quote - The quote to verify against (contains the TDX EOA)
|
|
162
|
+
* @param signature - The EIP712 signature of the upgrade result by the TDX EOA
|
|
163
|
+
*/
|
|
164
|
+
function verifyUpgradeResult(
|
|
165
|
+
bytes32 newMrAggregated,
|
|
166
|
+
UpgradeResult calldata upgradeResult,
|
|
167
|
+
bytes calldata quote,
|
|
168
|
+
bytes calldata signature
|
|
169
|
+
) public {
|
|
170
|
+
require(isBootstrapComplete(), BootstrapNotComplete());
|
|
171
|
+
// Make sure the quote's network pubkey is the same as the one in the bootstrap result
|
|
172
|
+
require(keccak256(ECIESPubkey) == keccak256(upgradeResult.network_pubkey), InvalidNetworkPubkey());
|
|
173
|
+
// Make sure the new MR_AGGREGATED has been pre-approved.
|
|
174
|
+
bool isApproved = _isApprovedTEEVersion(newMrAggregated);
|
|
175
|
+
require(isApproved, TEEVersionNotFound());
|
|
176
|
+
|
|
177
|
+
bytes32 digest = upgradeResultDigest(upgradeResult);
|
|
178
|
+
address reportDataSigner = _verifyResultForEOA(
|
|
179
|
+
newMrAggregated,
|
|
180
|
+
digest,
|
|
181
|
+
quote,
|
|
182
|
+
signature
|
|
129
183
|
);
|
|
184
|
+
// Make sure the new EOA signer is an existing EOA signer
|
|
185
|
+
require(EOASigners[reportDataSigner], EOASignerNotFound());
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* @notice Approves a new TEE version as PENDING and updates the TEEVersionHistory.
|
|
190
|
+
* The new TEE version can be activated by calling verifyBootstrapResult or activateNewTEEVersion.
|
|
191
|
+
* @param newMrAggregated - The MR_AGGREGATED bytes of the new TEE version
|
|
192
|
+
* @dev This function increments the version number automatically based on the current history
|
|
193
|
+
*/
|
|
194
|
+
function approveNewTEEVersion(bytes32 newMrAggregated) public onlyOwner {
|
|
195
|
+
ApprovedTEEVersions.push(newMrAggregated);
|
|
196
|
+
emit NewTEEVersionApproved(ApprovedTEEVersions.length - 1, newMrAggregated);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function _isApprovedTEEVersion(bytes32 newMrAggregated) internal view returns (bool) {
|
|
200
|
+
for (uint256 i = 0; i < ApprovedTEEVersions.length; i++) {
|
|
201
|
+
if (ApprovedTEEVersions[i] == newMrAggregated) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
130
207
|
|
|
131
|
-
|
|
208
|
+
/**
|
|
209
|
+
* @notice Verifies quote and signature from TDX for a single EOA. This is a shared function for bootstrap and upgrade.
|
|
210
|
+
* @param newMrAggregated - The MR_AGGREGATED bytes of the new TEE version
|
|
211
|
+
* @param resultEip712Digest - The EIP712 digest of the result to verify
|
|
212
|
+
* @param quote - The quote to verify against (contains the TDX EOA)
|
|
213
|
+
* @param signature - The EIP712 signature of the digest by the TDX EOA
|
|
214
|
+
* @return reportDataSigner - The address of the report data signer (i.e. the TDX EOA)
|
|
215
|
+
*/
|
|
216
|
+
function _verifyResultForEOA(
|
|
217
|
+
bytes32 newMrAggregated,
|
|
218
|
+
bytes32 resultEip712Digest,
|
|
219
|
+
bytes calldata quote,
|
|
220
|
+
bytes calldata signature
|
|
221
|
+
) internal onlyOwner returns (address) {
|
|
132
222
|
(bool success, bytes memory output) = _verifyAndAttestOnChain(quote);
|
|
133
223
|
require(success, string(output));
|
|
134
224
|
|
|
135
|
-
bytes memory v0MRTD = TEEVersionHistory[0].mrtd;
|
|
136
|
-
|
|
137
225
|
TD10ReportBody memory tdReport = parseTD10ReportBody(quote);
|
|
138
|
-
(address reportDataSigner,
|
|
226
|
+
(address reportDataSigner, bytes32 reportMrAggregated) = parseReport(
|
|
139
227
|
tdReport
|
|
140
228
|
);
|
|
141
229
|
require(
|
|
142
|
-
|
|
143
|
-
|
|
230
|
+
reportMrAggregated == newMrAggregated,
|
|
231
|
+
InvalidReportMrAggregated()
|
|
144
232
|
);
|
|
145
233
|
address recoveredAddress = ECDSA.recover(
|
|
146
|
-
|
|
234
|
+
resultEip712Digest,
|
|
147
235
|
signature
|
|
148
236
|
);
|
|
149
237
|
require(
|
|
150
238
|
recoveredAddress == reportDataSigner,
|
|
151
|
-
|
|
239
|
+
InvalidEIP712Signature()
|
|
152
240
|
);
|
|
153
241
|
|
|
154
|
-
|
|
155
|
-
TEEVersionHistory[0].status = TEEVersionStatus.ACTIVE;
|
|
156
|
-
emit BootstrapStageComplete(reportDataSigner, bootstrapResult);
|
|
157
|
-
ECIESPubkey = bootstrapResult.ecies_pubkey;
|
|
158
|
-
EOASigners[reportDataSigner] = true;
|
|
159
|
-
//TODO: update ECIES public key to ?? contract state and EOA addresses signers to the Signers contract state
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* @notice Approves a new TEE version and updates the TEEVersionHistory
|
|
164
|
-
* @param newMRTD - The MRTD bytes of the new TEE version
|
|
165
|
-
* @dev This function increments the version number automatically based on the current history
|
|
166
|
-
*/
|
|
167
|
-
function approveNewTEEVersion(bytes calldata newMRTD) public onlyOwner {
|
|
168
|
-
require(newMRTD.length == 48, MrtdInvalidLength());
|
|
169
|
-
|
|
170
|
-
TEEVersionHistory.push(
|
|
171
|
-
TEEVersion({mrtd: newMRTD, status: TEEVersionStatus.PENDING})
|
|
172
|
-
);
|
|
242
|
+
emit EOAHasUpdatedTDX(reportDataSigner, newMrAggregated);
|
|
173
243
|
|
|
174
|
-
|
|
244
|
+
return reportDataSigner;
|
|
175
245
|
}
|
|
176
246
|
|
|
177
247
|
/**
|
|
178
248
|
* @notice Adds a new covalidator to the contract state
|
|
179
|
-
* @param quote - The quote from the new covalidator that contains the current
|
|
249
|
+
* @param quote - The quote from the new covalidator that contains the current MR_AGGREGATED and the eoa address of the new party in the report data
|
|
180
250
|
*/
|
|
181
251
|
function addNewCovalidator(bytes calldata quote) public onlyOwner {
|
|
182
252
|
require(isBootstrapComplete(), BootstrapNotComplete());
|
|
@@ -184,30 +254,27 @@ abstract contract TEELifecycle is
|
|
|
184
254
|
(bool success, bytes memory output) = _verifyAndAttestOnChain(quote);
|
|
185
255
|
require(success, string(output));
|
|
186
256
|
TD10ReportBody memory tdReport = parseTD10ReportBody(quote);
|
|
187
|
-
(address reportDataSigner,
|
|
257
|
+
(address reportDataSigner, bytes32 reportMrAggregated) = parseReport(
|
|
188
258
|
tdReport
|
|
189
259
|
);
|
|
190
260
|
require(!EOASigners[reportDataSigner], EOASignerAlreadyInitialized());
|
|
191
261
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
InvalidMrtdReport()
|
|
196
|
-
);
|
|
262
|
+
bool isApproved = _isApprovedTEEVersion(reportMrAggregated);
|
|
263
|
+
require(isApproved, TEEVersionNotFound());
|
|
264
|
+
|
|
197
265
|
require(reportDataSigner != address(0), InvalidReportDataSigner());
|
|
198
266
|
emit NewCovalidatorAdded(reportDataSigner, quote);
|
|
199
267
|
EOASigners[reportDataSigner] = true;
|
|
200
|
-
//TODO: Add the new covalidator signers to the Signers contract state
|
|
201
268
|
}
|
|
202
269
|
|
|
203
270
|
/**
|
|
204
|
-
* @notice Checks if the bootstrap is complete
|
|
271
|
+
* @notice Checks if the bootstrap is complete.
|
|
205
272
|
* @return true if the bootstrap is complete, false otherwise
|
|
206
273
|
*/
|
|
207
274
|
function isBootstrapComplete() public view returns (bool) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
275
|
+
// The network pubkey is set once and once only, during the bootstrap process
|
|
276
|
+
// So we can use the length of the network pubkey to check if the bootstrap is complete
|
|
277
|
+
return ECIESPubkey.length > 0;
|
|
211
278
|
}
|
|
212
279
|
|
|
213
280
|
/**
|
|
@@ -320,15 +387,37 @@ abstract contract TEELifecycle is
|
|
|
320
387
|
}
|
|
321
388
|
|
|
322
389
|
/**
|
|
323
|
-
* @notice Parses the TD10 report to extract the report data and
|
|
390
|
+
* @notice Parses the TD10 report to extract the report data and MR_AGGREGATED
|
|
324
391
|
* @param tdReport - The TD10 report body
|
|
325
392
|
* @return reportDataSigner - The signing address of the report data signer
|
|
326
|
-
* @return
|
|
393
|
+
* @return reportMrAggregated - The MR_AGGREGATED bytes from the report
|
|
327
394
|
*/
|
|
328
395
|
function parseReport(
|
|
329
396
|
TD10ReportBody memory tdReport
|
|
330
|
-
) public pure returns (address,
|
|
331
|
-
return (
|
|
397
|
+
) public pure returns (address, bytes32) {
|
|
398
|
+
return (
|
|
399
|
+
address(bytes20(tdReport.reportData)),
|
|
400
|
+
computeMrAggregated(tdReport.mrTd, tdReport.rtMr0, tdReport.rtMr1, tdReport.rtMr2)
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* @notice Computes the MR_AGGREGATED from the TD10 report body. It is defined as:
|
|
406
|
+
* KECCAK256(mrTd ++ rtMr0 ++ rtMr1 ++ rtMr2 ++ rtMr3)
|
|
407
|
+
* @param mrTd - The MR_TD bytes
|
|
408
|
+
* @param rtMr0 - The RTMR0 bytes
|
|
409
|
+
* @param rtMr1 - The RTMR1 bytes
|
|
410
|
+
* @param rtMr2 - The RTMR2 bytes
|
|
411
|
+
* @return mrAggregated - The MR_AGGREGATED bytes32
|
|
412
|
+
*/
|
|
413
|
+
function computeMrAggregated(
|
|
414
|
+
bytes memory mrTd,
|
|
415
|
+
bytes memory rtMr0,
|
|
416
|
+
bytes memory rtMr1,
|
|
417
|
+
bytes memory rtMr2
|
|
418
|
+
) public pure returns (bytes32) {
|
|
419
|
+
bytes memory message = abi.encodePacked(mrTd, rtMr0, rtMr1, rtMr2);
|
|
420
|
+
return keccak256(message);
|
|
332
421
|
}
|
|
333
422
|
|
|
334
423
|
function bootstrapResultDigest(
|
|
@@ -344,4 +433,18 @@ abstract contract TEELifecycle is
|
|
|
344
433
|
)
|
|
345
434
|
);
|
|
346
435
|
}
|
|
436
|
+
|
|
437
|
+
function upgradeResultDigest(
|
|
438
|
+
UpgradeResult memory upgradeResult
|
|
439
|
+
) public view returns (bytes32) {
|
|
440
|
+
return
|
|
441
|
+
_hashTypedDataV4(
|
|
442
|
+
keccak256(
|
|
443
|
+
abi.encode(
|
|
444
|
+
UpgradeResultStructHash,
|
|
445
|
+
keccak256(upgradeResult.network_pubkey)
|
|
446
|
+
)
|
|
447
|
+
)
|
|
448
|
+
);
|
|
449
|
+
}
|
|
347
450
|
}
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
// SPDX-License-Identifier: No License
|
|
2
2
|
pragma solidity ^0.8.19;
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @notice A struct representing what the TDX EOA signs during the bootstrap process.
|
|
6
|
+
*/
|
|
4
7
|
struct BootstrapResult {
|
|
8
|
+
// TODO: rename to network_pubkey
|
|
9
|
+
// https://github.com/Inco-fhevm/inco-monorepo/issues/983
|
|
5
10
|
bytes ecies_pubkey;
|
|
6
11
|
}
|
|
7
12
|
|
|
8
|
-
enum TEEVersionStatus {
|
|
9
|
-
PENDING,
|
|
10
|
-
ACTIVE
|
|
11
|
-
}
|
|
12
|
-
|
|
13
13
|
/**
|
|
14
|
-
* @notice A struct representing
|
|
15
|
-
* @param mrtd - The MRTD of the TEE version
|
|
16
|
-
* @param status - The status of the TEE version
|
|
14
|
+
* @notice A struct representing what the TDX EOA signs during the upgrade process.
|
|
17
15
|
*/
|
|
18
|
-
struct
|
|
19
|
-
bytes
|
|
20
|
-
|
|
21
|
-
}
|
|
16
|
+
struct UpgradeResult {
|
|
17
|
+
bytes network_pubkey;
|
|
18
|
+
}
|
|
@@ -7,13 +7,13 @@ interface IEncryptedInput {
|
|
|
7
7
|
function newEuint256(
|
|
8
8
|
bytes memory ciphertext,
|
|
9
9
|
address user
|
|
10
|
-
) external returns (euint256 newValue);
|
|
10
|
+
) external payable returns (euint256 newValue);
|
|
11
11
|
function newEbool(
|
|
12
12
|
bytes memory ciphertext,
|
|
13
13
|
address user
|
|
14
|
-
) external returns (ebool newValue);
|
|
14
|
+
) external payable returns (ebool newValue);
|
|
15
15
|
function newEaddress(
|
|
16
16
|
bytes memory ciphertext,
|
|
17
17
|
address user
|
|
18
|
-
) external returns (eaddress newValue);
|
|
18
|
+
) external payable returns (eaddress newValue);
|
|
19
19
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: No License
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
|
-
import {euint256} from "../../Types.sol";
|
|
4
|
+
import {euint256, ebool, ETypes} from "../../Types.sol";
|
|
5
5
|
|
|
6
6
|
interface IEncryptedOperations {
|
|
7
7
|
function eAdd(
|
|
@@ -28,4 +28,51 @@ interface IEncryptedOperations {
|
|
|
28
28
|
bytes32 lhs,
|
|
29
29
|
bytes32 rhs
|
|
30
30
|
) external returns (bytes32 result);
|
|
31
|
+
function eBitOr(bytes32 lhs, bytes32 rhs) external returns (bytes32 result);
|
|
32
|
+
function eBitXor(
|
|
33
|
+
bytes32 lhs,
|
|
34
|
+
bytes32 rhs
|
|
35
|
+
) external returns (bytes32 result);
|
|
36
|
+
function eShl(
|
|
37
|
+
euint256 lhs,
|
|
38
|
+
euint256 rhs
|
|
39
|
+
) external returns (euint256 result);
|
|
40
|
+
function eShr(
|
|
41
|
+
euint256 lhs,
|
|
42
|
+
euint256 rhs
|
|
43
|
+
) external returns (euint256 result);
|
|
44
|
+
function eRotl(
|
|
45
|
+
euint256 lhs,
|
|
46
|
+
euint256 rhs
|
|
47
|
+
) external returns (euint256 result);
|
|
48
|
+
function eRotr(
|
|
49
|
+
euint256 lhs,
|
|
50
|
+
euint256 rhs
|
|
51
|
+
) external returns (euint256 result);
|
|
52
|
+
function eEq(bytes32 lhs, bytes32 rhs) external returns (ebool result);
|
|
53
|
+
function eNe(bytes32 lhs, bytes32 rhs) external returns (ebool result);
|
|
54
|
+
function eGe(euint256 lhs, euint256 rhs) external returns (ebool result);
|
|
55
|
+
function eGt(euint256 lhs, euint256 rhs) external returns (ebool result);
|
|
56
|
+
function eLe(euint256 lhs, euint256 rhs) external returns (ebool result);
|
|
57
|
+
function eLt(euint256 lhs, euint256 rhs) external returns (ebool result);
|
|
58
|
+
function eMin(
|
|
59
|
+
euint256 lhs,
|
|
60
|
+
euint256 rhs
|
|
61
|
+
) external returns (euint256 result);
|
|
62
|
+
function eMax(
|
|
63
|
+
euint256 lhs,
|
|
64
|
+
euint256 rhs
|
|
65
|
+
) external returns (euint256 result);
|
|
66
|
+
function eNot(ebool operand) external returns (ebool result);
|
|
67
|
+
function eCast(bytes32 ct, ETypes toType) external returns (bytes32 result);
|
|
68
|
+
function eRand(ETypes randType) external payable returns (bytes32 result);
|
|
69
|
+
function eRandBounded(
|
|
70
|
+
bytes32 upperBound,
|
|
71
|
+
ETypes randType
|
|
72
|
+
) external payable returns (bytes32 result);
|
|
73
|
+
function eIfThenElse(
|
|
74
|
+
ebool condition,
|
|
75
|
+
bytes32 ifTrue,
|
|
76
|
+
bytes32 ifFalse
|
|
77
|
+
) external returns (bytes32 result);
|
|
31
78
|
}
|
|
@@ -11,14 +11,14 @@ interface ITEELifecycle {
|
|
|
11
11
|
bytes calldata quote,
|
|
12
12
|
bytes calldata signature
|
|
13
13
|
) external;
|
|
14
|
-
function approveNewTEEVersion(
|
|
14
|
+
function approveNewTEEVersion(bytes32 newMrAggregated) external;
|
|
15
15
|
function addNewCovalidator(bytes calldata quote) external;
|
|
16
16
|
function parseTD10ReportBody(
|
|
17
17
|
bytes calldata rawQuote
|
|
18
18
|
) external pure returns (TD10ReportBody memory report);
|
|
19
19
|
function parseReport(
|
|
20
20
|
TD10ReportBody memory tdReport
|
|
21
|
-
) external pure returns (address,
|
|
21
|
+
) external pure returns (address, bytes32);
|
|
22
22
|
function bootstrapResultDigest(
|
|
23
23
|
BootstrapResult memory bootstrapResult
|
|
24
24
|
) external view returns (bytes32);
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// SPDX-License-Identifier: No License
|
|
2
|
+
pragma solidity ^0.8;
|
|
3
|
+
|
|
4
|
+
import {Test} from "forge-std/Test.sol";
|
|
5
|
+
import {Fee, FEE} from "../Fee.sol";
|
|
6
|
+
|
|
7
|
+
contract FeeTester is Fee {
|
|
8
|
+
function costOneFee() public payable paying {
|
|
9
|
+
// do nothing
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function costMultipleVariableFees(
|
|
13
|
+
uint256 nbOfFees
|
|
14
|
+
) public payable payingMultiple(nbOfFees) {
|
|
15
|
+
// do nothing
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function costMultipleFixedFees() public payable payingMultiple(3) {
|
|
19
|
+
// do nothing
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
contract TestFee is Test {
|
|
24
|
+
FeeTester feeTester;
|
|
25
|
+
|
|
26
|
+
function setUp() public {
|
|
27
|
+
feeTester = new FeeTester();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function testGetFee() public view {
|
|
31
|
+
uint256 fee = feeTester.getFee();
|
|
32
|
+
assertEq(fee, FEE);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function testPaying() public {
|
|
36
|
+
// should fail if no fee
|
|
37
|
+
vm.expectRevert(Fee.FeeNotPaid.selector);
|
|
38
|
+
feeTester.costOneFee{value: 0}();
|
|
39
|
+
|
|
40
|
+
// should fail if not enough fee
|
|
41
|
+
vm.expectRevert(Fee.FeeNotPaid.selector);
|
|
42
|
+
feeTester.costOneFee{value: FEE - 1}();
|
|
43
|
+
|
|
44
|
+
// should fail if too much fee
|
|
45
|
+
vm.expectRevert(Fee.FeeNotPaid.selector);
|
|
46
|
+
feeTester.costOneFee{value: FEE + 1}();
|
|
47
|
+
|
|
48
|
+
// should work with exact fee
|
|
49
|
+
feeTester.costOneFee{value: FEE}();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function testPayingMultiple() public {
|
|
53
|
+
// should fail if no fee
|
|
54
|
+
vm.expectRevert(Fee.FeeNotPaid.selector);
|
|
55
|
+
feeTester.costMultipleVariableFees{value: 0}(3);
|
|
56
|
+
|
|
57
|
+
// should fail if not enough fee
|
|
58
|
+
vm.expectRevert(Fee.FeeNotPaid.selector);
|
|
59
|
+
feeTester.costMultipleVariableFees{value: FEE * 3 - 1}(3);
|
|
60
|
+
|
|
61
|
+
// should fail if too much fee
|
|
62
|
+
vm.expectRevert(Fee.FeeNotPaid.selector);
|
|
63
|
+
feeTester.costMultipleVariableFees{value: FEE * 3 + 1}(3);
|
|
64
|
+
|
|
65
|
+
// should work with exact fee
|
|
66
|
+
feeTester.costMultipleVariableFees{value: FEE * 3}(3);
|
|
67
|
+
|
|
68
|
+
// should work with exact fee for fixed number of fees
|
|
69
|
+
feeTester.costMultipleFixedFees{value: FEE * 3}();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function testPayingMultipleZero() public {
|
|
73
|
+
feeTester.costMultipleVariableFees{value: 0}(0);
|
|
74
|
+
|
|
75
|
+
// should fail if too much fee
|
|
76
|
+
vm.expectRevert(Fee.FeeNotPaid.selector);
|
|
77
|
+
feeTester.costMultipleVariableFees{value: FEE + 1}(0);
|
|
78
|
+
|
|
79
|
+
// should work with exact fee
|
|
80
|
+
feeTester.costMultipleVariableFees{value: 0}(0);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function testFuzzPayingMultipleVariableFees(uint8 nbOfFees) public {
|
|
84
|
+
uint256 expectedValue = FEE * nbOfFees;
|
|
85
|
+
|
|
86
|
+
// should work with exact fee
|
|
87
|
+
feeTester.costMultipleVariableFees{value: expectedValue}(nbOfFees);
|
|
88
|
+
|
|
89
|
+
// should fail if not enough fee (unless expectedValue is 0)
|
|
90
|
+
if (expectedValue > 0) {
|
|
91
|
+
vm.expectRevert(Fee.FeeNotPaid.selector);
|
|
92
|
+
feeTester.costMultipleVariableFees{value: expectedValue - 1}(
|
|
93
|
+
nbOfFees
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// should fail if too much fee
|
|
98
|
+
vm.expectRevert(Fee.FeeNotPaid.selector);
|
|
99
|
+
feeTester.costMultipleVariableFees{value: expectedValue + 1}(nbOfFees);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
typeToBitMask
|
|
16
16
|
} from "../../Types.sol";
|
|
17
17
|
import {VerifierAddressGetter} from "../primitives/VerifierAddressGetter.sol";
|
|
18
|
+
import {FEE} from "../Fee.sol";
|
|
18
19
|
|
|
19
20
|
contract TestHandleMetadata is
|
|
20
21
|
EIP712,
|
|
@@ -107,11 +108,11 @@ contract TestHandleMetadata is
|
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
function testEncryptedInputHandleType() public {
|
|
110
|
-
euint256 a = this.newEuint256("ciphertext", address(this));
|
|
111
|
+
euint256 a = this.newEuint256{value: FEE}("ciphertext", address(this));
|
|
111
112
|
assert(typeOf(euint256.unwrap(a)) == ETypes.Uint256);
|
|
112
|
-
ebool b = this.newEbool("ciphertext", address(this));
|
|
113
|
+
ebool b = this.newEbool{value: FEE}("ciphertext", address(this));
|
|
113
114
|
assert(typeOf(ebool.unwrap(b)) == ETypes.Bool);
|
|
114
|
-
eaddress c = this.newEaddress("ciphertext", address(this));
|
|
115
|
+
eaddress c = this.newEaddress{value: FEE}("ciphertext", address(this));
|
|
115
116
|
assert(typeOf(eaddress.unwrap(c)) == ETypes.AddressOrUint160OrBytes20);
|
|
116
117
|
}
|
|
117
118
|
}
|