@inco/lightning 0.6.8 → 0.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -2
- package/manifest.yaml +0 -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.template.sol +40 -159
- package/src/Types.sol +233 -97
- package/src/interfaces/IIncoLightning.sol +2 -0
- package/src/interfaces/IIncoVerifier.sol +7 -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_devnet_v1_887305889.sol +5 -3
- package/src/libs/incoLightning_testnet_v1_938327937.sol +5 -3
- package/src/lightning-parts/AccessControl/AdvancedAccessControl.sol +41 -75
- 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 +42 -83
- 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 +93 -440
- package/src/lightning-parts/Fee.sol +3 -1
- package/src/lightning-parts/TEELifecycle.sol +95 -225
- 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 +146 -419
- package/src/pasted-dependencies/ICreateX.sol +58 -102
- package/src/periphery/SessionVerifier.sol +5 -7
- 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 +14 -13
- package/src/test/AddTwo.sol +9 -7
- package/src/test/FakeIncoInfra/FakeComputeServer.sol +11 -53
- package/src/test/FakeIncoInfra/FakeDecryptionAttester.sol +35 -118
- 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 +44 -21
- package/src/test/IncoTest.sol +15 -9
- package/src/test/OpsTest.sol +429 -0
- package/src/test/TEELifecycle/TEELifecycleMockTest.t.sol +58 -104
- package/src/test/TestAddTwo.t.sol +4 -3
- package/src/test/TestDeploy.t.sol +5 -6
- package/src/test/TestExtractDataOfEventTooLarge.t.sol +7 -14
- 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 +1 -1
- package/src/version/Version.sol +48 -51
- package/src/version/interfaces/IVersion.sol +6 -0
|
@@ -7,6 +7,7 @@ uint256 constant FEE = 0.0001 ether;
|
|
|
7
7
|
/// @notice Fee utils for lightning functions that require a fee
|
|
8
8
|
/// @dev the fee may be changed through upgrades, develop your apps accordingly!
|
|
9
9
|
abstract contract Fee {
|
|
10
|
+
|
|
10
11
|
error FeeNotPaid();
|
|
11
12
|
|
|
12
13
|
/// @notice the fee to pay through msg.value for inputs and randomness IT MAY CHANGE
|
|
@@ -34,8 +35,9 @@ abstract contract Fee {
|
|
|
34
35
|
uint256 spent = balanceBefore > balanceAfter ? balanceBefore - balanceAfter : 0;
|
|
35
36
|
uint256 refund = msg.value > spent ? msg.value - spent : 0;
|
|
36
37
|
if (refund > 0) {
|
|
37
|
-
(bool success,
|
|
38
|
+
(bool success,) = msg.sender.call{value: refund}("");
|
|
38
39
|
require(success, "Refund failed");
|
|
39
40
|
}
|
|
40
41
|
}
|
|
42
|
+
|
|
41
43
|
}
|
|
@@ -11,48 +11,47 @@ import {
|
|
|
11
11
|
TcbInfoJsonObj,
|
|
12
12
|
EnclaveIdentityJsonObj,
|
|
13
13
|
IdentityObj,
|
|
14
|
-
|
|
14
|
+
Td10ReportBody,
|
|
15
15
|
Header,
|
|
16
16
|
HEADER_LENGTH
|
|
17
17
|
} from "../interfaces/automata-interfaces/Types.sol";
|
|
18
18
|
import {IFmspcTcbDao} from "../interfaces/automata-interfaces/IFmspcTcbDao.sol";
|
|
19
19
|
import {IAutomataEnclaveIdentityDao} from "../interfaces/automata-interfaces/IAutomataEnclaveIdentityDao.sol";
|
|
20
|
+
import {SignatureVerifier} from "./primitives/SignatureVerifier.sol";
|
|
20
21
|
|
|
21
22
|
contract TEELifecycleStorage {
|
|
22
|
-
|
|
23
|
+
|
|
24
|
+
struct StorageForTeeLifecycle {
|
|
23
25
|
IQuoteVerifier quoteVerifier;
|
|
24
|
-
BootstrapResult
|
|
25
|
-
bool
|
|
26
|
+
BootstrapResult verifiedBootstrapResult;
|
|
27
|
+
bool bootstrapComplete;
|
|
26
28
|
// @notice The list of approved TEE versions, each item is the MR_AGGREGATED 32 bytes
|
|
27
29
|
// @dev The index of the TEE version is the version number
|
|
28
|
-
bytes32[]
|
|
30
|
+
bytes32[] approvedTeeVersions;
|
|
29
31
|
// @notice The Network key
|
|
30
32
|
// @todo rename to NetworkPubkey https://github.com/Inco-fhevm/inco-monorepo/issues/983
|
|
31
|
-
bytes
|
|
32
|
-
mapping(address => bool) EOASigners;
|
|
33
|
+
bytes eciesPubkey;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
bytes32 private constant
|
|
36
|
-
keccak256("inco.storage.TEELifecycle");
|
|
36
|
+
bytes32 private constant TEE_LIFECYCLE_STORAGE_LOCATION = keccak256("inco.storage.TEELifecycle");
|
|
37
37
|
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
pure
|
|
41
|
-
returns (StorageForTEELifecycle storage $)
|
|
42
|
-
{
|
|
43
|
-
bytes32 loc = TEELifecycleStorageLocation;
|
|
38
|
+
function getTeeLifecycleStorage() internal pure returns (StorageForTeeLifecycle storage $) {
|
|
39
|
+
bytes32 loc = TEE_LIFECYCLE_STORAGE_LOCATION;
|
|
44
40
|
assembly {
|
|
45
41
|
$.slot := loc
|
|
46
42
|
}
|
|
47
43
|
}
|
|
44
|
+
|
|
48
45
|
}
|
|
49
46
|
|
|
50
47
|
abstract contract TEELifecycle is
|
|
51
48
|
TEELifecycleStorage,
|
|
52
49
|
ITEELifecycle,
|
|
53
50
|
OwnableUpgradeable,
|
|
51
|
+
SignatureVerifier,
|
|
54
52
|
EIP712Upgradeable
|
|
55
53
|
{
|
|
54
|
+
|
|
56
55
|
// Errors
|
|
57
56
|
error InvalidQuoteVerifierVersion(uint16 actual, uint16 expected);
|
|
58
57
|
error EmptyTcbInfo();
|
|
@@ -66,53 +65,34 @@ abstract contract TEELifecycle is
|
|
|
66
65
|
error IndexOutOfBounds();
|
|
67
66
|
/// @notice The EIP712 signature recovered an incorrect address
|
|
68
67
|
error InvalidEIP712Signature();
|
|
69
|
-
error EOASignerAlreadyInitialized();
|
|
70
|
-
// @notice The EOA signer in the quote is not an existing EOA signer
|
|
71
|
-
error EOASignerNotFound();
|
|
72
68
|
// @notice The network pubkey signed by the TDX EOA is not the same as the one in the bootstrap result
|
|
73
69
|
error InvalidNetworkPubkey();
|
|
74
70
|
|
|
75
71
|
// Events
|
|
76
72
|
// @notice A new MR_AGGREGATED has been approved
|
|
77
|
-
event NewTEEVersionApproved(
|
|
78
|
-
uint256 indexed version,
|
|
79
|
-
bytes32 indexed mrAggregated
|
|
80
|
-
);
|
|
73
|
+
event NewTEEVersionApproved(uint256 indexed version, bytes32 indexed mrAggregated);
|
|
81
74
|
event NewCovalidatorAdded(address covalidatorAddress, bytes quote);
|
|
82
|
-
event BootstrapStageComplete(
|
|
83
|
-
address indexed newEOASigner,
|
|
84
|
-
BootstrapResult bootstrapResult
|
|
85
|
-
);
|
|
75
|
+
event BootstrapStageComplete(address indexed newEoaSigner, BootstrapResult bootstrapResult);
|
|
86
76
|
// @notice Emitted to prove that an EOA has upgraded their TDX to a new
|
|
87
77
|
// MR_AGGREGATED. This is done by checking remote attestation of the quote
|
|
88
78
|
// and verifying the EIP712 signature of the bootstrap/upgrade result by
|
|
89
79
|
// the TDX EOA.
|
|
90
|
-
event
|
|
91
|
-
address indexed eoaSigner,
|
|
92
|
-
bytes32 indexed mrAggregated
|
|
93
|
-
);
|
|
80
|
+
event SignerHasUpdatedTDX(address indexed eoaSigner, bytes32 indexed mrAggregated);
|
|
94
81
|
|
|
95
82
|
// Constants
|
|
96
|
-
bytes32 public constant
|
|
97
|
-
|
|
98
|
-
bytes32 public constant
|
|
99
|
-
keccak256(bytes("UpgradeResult(bytes network_pubkey)"));
|
|
100
|
-
bytes32 public constant AddNodeResultStructHash =
|
|
101
|
-
keccak256(bytes("AddNodeResult(bytes network_pubkey)"));
|
|
83
|
+
bytes32 public constant BOOTSTRAP_RESULT_STRUCT_HASH = keccak256(bytes("BootstrapResult(bytes ecies_pubkey)"));
|
|
84
|
+
bytes32 public constant UPGRADE_RESULT_STRUCT_HASH = keccak256(bytes("UpgradeResult(bytes network_pubkey)"));
|
|
85
|
+
bytes32 public constant ADD_NODE_RESULT_STRUCT_HASH = keccak256(bytes("AddNodeResult(bytes network_pubkey)"));
|
|
102
86
|
|
|
103
87
|
uint16 public constant QUOTE_VERIFIER_VERSION = 4;
|
|
104
88
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
getTEELifecycleStorage().quoteVerifier = _quoteVerifier;
|
|
89
|
+
// forge-lint: disable-next-line(mixed-case-function)
|
|
90
|
+
function __TeeLifecycle_init(IQuoteVerifier _quoteVerifier) internal onlyInitializing {
|
|
91
|
+
getTeeLifecycleStorage().quoteVerifier = _quoteVerifier;
|
|
109
92
|
uint16 actualQuoteVerifierVersion = _quoteVerifier.quoteVersion();
|
|
110
93
|
require(
|
|
111
94
|
actualQuoteVerifierVersion == QUOTE_VERIFIER_VERSION,
|
|
112
|
-
InvalidQuoteVerifierVersion(
|
|
113
|
-
actualQuoteVerifierVersion,
|
|
114
|
-
QUOTE_VERIFIER_VERSION
|
|
115
|
-
)
|
|
95
|
+
InvalidQuoteVerifierVersion(actualQuoteVerifierVersion, QUOTE_VERIFIER_VERSION)
|
|
116
96
|
);
|
|
117
97
|
}
|
|
118
98
|
|
|
@@ -121,30 +101,18 @@ abstract contract TEELifecycle is
|
|
|
121
101
|
* @param tcbInfo - The TCB info to upload
|
|
122
102
|
* @param identity - The identity to upload
|
|
123
103
|
*/
|
|
124
|
-
function uploadCollateral(
|
|
125
|
-
TcbInfoJsonObj memory tcbInfo,
|
|
126
|
-
EnclaveIdentityJsonObj memory identity
|
|
127
|
-
) public onlyOwner {
|
|
104
|
+
function uploadCollateral(TcbInfoJsonObj memory tcbInfo, EnclaveIdentityJsonObj memory identity) public onlyOwner {
|
|
128
105
|
require(bytes(tcbInfo.tcbInfoStr).length != 0, EmptyTcbInfo());
|
|
129
106
|
require(bytes(identity.identityStr).length != 0, EmptyIdentity());
|
|
130
107
|
|
|
131
108
|
IQuoteVerifier _quoteVerifier = quoteVerifier();
|
|
132
109
|
|
|
133
|
-
IFmspcTcbDao fmspcTcbDao = IFmspcTcbDao(
|
|
134
|
-
_quoteVerifier.pccsRouter().fmspcTcbDaoAddr()
|
|
135
|
-
);
|
|
110
|
+
IFmspcTcbDao fmspcTcbDao = IFmspcTcbDao(_quoteVerifier.pccsRouter().fmspcTcbDaoAddr());
|
|
136
111
|
fmspcTcbDao.upsertFmspcTcb(tcbInfo);
|
|
137
|
-
IAutomataEnclaveIdentityDao enclaveIdDao =
|
|
138
|
-
_quoteVerifier.pccsRouter().qeIdDaoAddr()
|
|
139
|
-
);
|
|
140
|
-
(
|
|
141
|
-
.EnclaveIdentityLib()
|
|
142
|
-
.parseIdentityString(identity.identityStr);
|
|
143
|
-
enclaveIdDao.upsertEnclaveIdentity(
|
|
144
|
-
uint256(identityObj.id),
|
|
145
|
-
4,
|
|
146
|
-
identity
|
|
147
|
-
);
|
|
112
|
+
IAutomataEnclaveIdentityDao enclaveIdDao =
|
|
113
|
+
IAutomataEnclaveIdentityDao(_quoteVerifier.pccsRouter().qeIdDaoAddr());
|
|
114
|
+
(IdentityObj memory identityObj,) = enclaveIdDao.EnclaveIdentityLib().parseIdentityString(identity.identityStr);
|
|
115
|
+
enclaveIdDao.upsertEnclaveIdentity(uint256(identityObj.id), 4, identity);
|
|
148
116
|
}
|
|
149
117
|
|
|
150
118
|
/**
|
|
@@ -158,27 +126,22 @@ abstract contract TEELifecycle is
|
|
|
158
126
|
bytes calldata quote,
|
|
159
127
|
bytes calldata signature
|
|
160
128
|
) public onlyOwner {
|
|
161
|
-
|
|
129
|
+
StorageForTeeLifecycle storage $ = getTeeLifecycleStorage();
|
|
162
130
|
|
|
163
131
|
// Make sure the bootstrap is not already complete, and that the contract owner
|
|
164
132
|
// has already submitted the pending TEE MR_AGGREGATED.
|
|
165
133
|
require(!isBootstrapComplete(), BootstrapAlreadyCompleted());
|
|
166
|
-
require($.
|
|
134
|
+
require($.approvedTeeVersions.length == 1, TEEVersionNotFound());
|
|
167
135
|
|
|
168
136
|
bytes32 digest = bootstrapResultDigest(bootstrapResult);
|
|
169
|
-
address reportDataSigner =
|
|
170
|
-
$.ApprovedTEEVersions[0],
|
|
171
|
-
digest,
|
|
172
|
-
quote,
|
|
173
|
-
signature
|
|
174
|
-
);
|
|
137
|
+
address reportDataSigner = _verifyResultForEoa($.approvedTeeVersions[0], digest, quote, signature);
|
|
175
138
|
|
|
176
139
|
// For bootstrap phase, we only have one EOA signer
|
|
177
140
|
// So if we arrive here in code, it means that the EOA has signed the bootstrap result
|
|
178
141
|
|
|
179
142
|
// Update contract publicly viewable state
|
|
180
|
-
|
|
181
|
-
$.
|
|
143
|
+
addSigner(reportDataSigner);
|
|
144
|
+
$.eciesPubkey = bootstrapResult.ecies_pubkey;
|
|
182
145
|
|
|
183
146
|
emit BootstrapStageComplete(reportDataSigner, bootstrapResult);
|
|
184
147
|
}
|
|
@@ -196,27 +159,19 @@ abstract contract TEELifecycle is
|
|
|
196
159
|
bytes calldata quote,
|
|
197
160
|
bytes calldata signature
|
|
198
161
|
) public {
|
|
199
|
-
|
|
162
|
+
StorageForTeeLifecycle storage $ = getTeeLifecycleStorage();
|
|
200
163
|
|
|
201
164
|
require(isBootstrapComplete(), BootstrapNotComplete());
|
|
202
165
|
// Make sure the quote's network pubkey is the same as the one in the bootstrap result
|
|
203
|
-
require(
|
|
204
|
-
keccak256($.ECIESPubkey) == keccak256(upgradeResult.network_pubkey),
|
|
205
|
-
InvalidNetworkPubkey()
|
|
206
|
-
);
|
|
166
|
+
require(keccak256($.eciesPubkey) == keccak256(upgradeResult.networkPubkey), InvalidNetworkPubkey());
|
|
207
167
|
// Make sure the new MR_AGGREGATED has been pre-approved.
|
|
208
|
-
bool isApproved =
|
|
168
|
+
bool isApproved = _isApprovedTeeVersion(newMrAggregated);
|
|
209
169
|
require(isApproved, TEEVersionNotFound());
|
|
210
170
|
|
|
211
171
|
bytes32 digest = upgradeResultDigest(upgradeResult);
|
|
212
|
-
address reportDataSigner =
|
|
213
|
-
newMrAggregated,
|
|
214
|
-
digest,
|
|
215
|
-
quote,
|
|
216
|
-
signature
|
|
217
|
-
);
|
|
172
|
+
address reportDataSigner = _verifyResultForEoa(newMrAggregated, digest, quote, signature);
|
|
218
173
|
// Make sure the new EOA signer is an existing EOA signer
|
|
219
|
-
require(
|
|
174
|
+
require(isSigner(reportDataSigner), SignerNotFound(reportDataSigner));
|
|
220
175
|
}
|
|
221
176
|
|
|
222
177
|
/**
|
|
@@ -229,28 +184,20 @@ abstract contract TEELifecycle is
|
|
|
229
184
|
bytes calldata quote,
|
|
230
185
|
bytes calldata signature
|
|
231
186
|
) public onlyOwner {
|
|
232
|
-
|
|
187
|
+
StorageForTeeLifecycle storage $ = getTeeLifecycleStorage();
|
|
233
188
|
|
|
234
189
|
require(isBootstrapComplete(), BootstrapNotComplete());
|
|
235
190
|
// Make sure the quote's network pubkey is the same as the one in the bootstrap result
|
|
236
|
-
require(
|
|
237
|
-
keccak256($.ECIESPubkey) == keccak256(addNodeResult.network_pubkey),
|
|
238
|
-
InvalidNetworkPubkey()
|
|
239
|
-
);
|
|
191
|
+
require(keccak256($.eciesPubkey) == keccak256(addNodeResult.networkPubkey), InvalidNetworkPubkey());
|
|
240
192
|
// Make sure the new MR_AGGREGATED has been pre-approved.
|
|
241
|
-
bool isApproved =
|
|
193
|
+
bool isApproved = _isApprovedTeeVersion(newMrAggregated);
|
|
242
194
|
require(isApproved, TEEVersionNotFound());
|
|
243
195
|
|
|
244
196
|
bytes32 digest = addNodeResultDigest(addNodeResult);
|
|
245
|
-
address reportDataSigner =
|
|
246
|
-
newMrAggregated,
|
|
247
|
-
digest,
|
|
248
|
-
quote,
|
|
249
|
-
signature
|
|
250
|
-
);
|
|
197
|
+
address reportDataSigner = _verifyResultForEoa(newMrAggregated, digest, quote, signature);
|
|
251
198
|
|
|
252
199
|
// Add this new EOA signer as a new signer to the contract state
|
|
253
|
-
|
|
200
|
+
addSigner(reportDataSigner);
|
|
254
201
|
}
|
|
255
202
|
|
|
256
203
|
/**
|
|
@@ -259,21 +206,16 @@ abstract contract TEELifecycle is
|
|
|
259
206
|
* @param newMrAggregated - The MR_AGGREGATED bytes of the new TEE version
|
|
260
207
|
* @dev This function increments the version number automatically based on the current history
|
|
261
208
|
*/
|
|
262
|
-
function
|
|
263
|
-
|
|
264
|
-
$.
|
|
265
|
-
emit NewTEEVersionApproved(
|
|
266
|
-
$.ApprovedTEEVersions.length - 1,
|
|
267
|
-
newMrAggregated
|
|
268
|
-
);
|
|
209
|
+
function approveNewTeeVersion(bytes32 newMrAggregated) public onlyOwner {
|
|
210
|
+
StorageForTeeLifecycle storage $ = getTeeLifecycleStorage();
|
|
211
|
+
$.approvedTeeVersions.push(newMrAggregated);
|
|
212
|
+
emit NewTEEVersionApproved($.approvedTeeVersions.length - 1, newMrAggregated);
|
|
269
213
|
}
|
|
270
214
|
|
|
271
|
-
function
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
for (uint256 i = 0; i < $.ApprovedTEEVersions.length; i++) {
|
|
276
|
-
if ($.ApprovedTEEVersions[i] == newMrAggregated) {
|
|
215
|
+
function _isApprovedTeeVersion(bytes32 newMrAggregated) internal view returns (bool) {
|
|
216
|
+
StorageForTeeLifecycle storage $ = getTeeLifecycleStorage();
|
|
217
|
+
for (uint256 i = 0; i < $.approvedTeeVersions.length; i++) {
|
|
218
|
+
if ($.approvedTeeVersions[i] == newMrAggregated) {
|
|
277
219
|
return true;
|
|
278
220
|
}
|
|
279
221
|
}
|
|
@@ -288,7 +230,7 @@ abstract contract TEELifecycle is
|
|
|
288
230
|
* @param signature - The EIP712 signature of the digest by the TDX EOA
|
|
289
231
|
* @return reportDataSigner - The address of the report data signer (i.e. the TDX EOA)
|
|
290
232
|
*/
|
|
291
|
-
function
|
|
233
|
+
function _verifyResultForEoa(
|
|
292
234
|
bytes32 newMrAggregated,
|
|
293
235
|
bytes32 resultEip712Digest,
|
|
294
236
|
bytes calldata quote,
|
|
@@ -297,18 +239,13 @@ abstract contract TEELifecycle is
|
|
|
297
239
|
(bool success, bytes memory output) = _verifyAndAttestOnChain(quote);
|
|
298
240
|
require(success, string(output));
|
|
299
241
|
|
|
300
|
-
|
|
301
|
-
(address reportDataSigner, bytes32 reportMrAggregated) = parseReport(
|
|
302
|
-
|
|
303
|
-
);
|
|
304
|
-
require(
|
|
305
|
-
reportMrAggregated == newMrAggregated,
|
|
306
|
-
InvalidReportMrAggregated()
|
|
307
|
-
);
|
|
242
|
+
Td10ReportBody memory tdReport = parseTd10ReportBody(quote);
|
|
243
|
+
(address reportDataSigner, bytes32 reportMrAggregated) = parseReport(tdReport);
|
|
244
|
+
require(reportMrAggregated == newMrAggregated, InvalidReportMrAggregated());
|
|
308
245
|
address recoveredAddress = ECDSA.recover(resultEip712Digest, signature);
|
|
309
246
|
require(recoveredAddress == reportDataSigner, InvalidEIP712Signature());
|
|
310
247
|
|
|
311
|
-
emit
|
|
248
|
+
emit SignerHasUpdatedTDX(reportDataSigner, newMrAggregated);
|
|
312
249
|
|
|
313
250
|
return reportDataSigner;
|
|
314
251
|
}
|
|
@@ -320,7 +257,7 @@ abstract contract TEELifecycle is
|
|
|
320
257
|
function isBootstrapComplete() public view returns (bool) {
|
|
321
258
|
// The network pubkey is set once and once only, during the bootstrap process
|
|
322
259
|
// So we can use the length of the network pubkey to check if the bootstrap is complete
|
|
323
|
-
return
|
|
260
|
+
return getTeeLifecycleStorage().eciesPubkey.length > 0;
|
|
324
261
|
}
|
|
325
262
|
|
|
326
263
|
/**
|
|
@@ -332,9 +269,11 @@ abstract contract TEELifecycle is
|
|
|
332
269
|
* For verification failures, the output is simply a UTF-8 encoded string, describing the reason for failure.
|
|
333
270
|
* @dev can directly type-cast the failed output as a string
|
|
334
271
|
*/
|
|
335
|
-
function _verifyAndAttestOnChain(
|
|
336
|
-
|
|
337
|
-
|
|
272
|
+
function _verifyAndAttestOnChain(bytes calldata rawQuote)
|
|
273
|
+
internal
|
|
274
|
+
view
|
|
275
|
+
returns (bool success, bytes memory output)
|
|
276
|
+
{
|
|
338
277
|
// Parse the header
|
|
339
278
|
Header memory header;
|
|
340
279
|
(success, header) = _parseQuoteHeader(rawQuote);
|
|
@@ -348,19 +287,14 @@ abstract contract TEELifecycle is
|
|
|
348
287
|
|
|
349
288
|
// We found a supported version, begin verifying the quote
|
|
350
289
|
// Note: The quote header cannot be trusted yet, it will be validated by the Verifier library
|
|
351
|
-
(success, output) =
|
|
352
|
-
header,
|
|
353
|
-
rawQuote
|
|
354
|
-
);
|
|
290
|
+
(success, output) = getTeeLifecycleStorage().quoteVerifier.verifyQuote(header, rawQuote);
|
|
355
291
|
}
|
|
356
292
|
|
|
357
293
|
/**
|
|
358
294
|
* @notice From https://github.com/automata-network/automata-dcap-attestation/blob/evm-v1.0.0/evm/contracts/AttestationEntrypointBase.sol#L168
|
|
359
295
|
* @notice Parses the header to get basic information about the quote, such as the version, TEE types etc.
|
|
360
296
|
*/
|
|
361
|
-
function _parseQuoteHeader(
|
|
362
|
-
bytes calldata rawQuote
|
|
363
|
-
) private pure returns (bool success, Header memory header) {
|
|
297
|
+
function _parseQuoteHeader(bytes calldata rawQuote) private pure returns (bool success, Header memory header) {
|
|
364
298
|
success = rawQuote.length >= HEADER_LENGTH;
|
|
365
299
|
if (success) {
|
|
366
300
|
uint16 version = uint16(BELE.leBytesToBeUint(rawQuote[0:2]));
|
|
@@ -389,44 +323,18 @@ abstract contract TEELifecycle is
|
|
|
389
323
|
* @param rawQuote - The raw quote bytes
|
|
390
324
|
* @return report - The parsed TD10 report body
|
|
391
325
|
*/
|
|
392
|
-
function
|
|
393
|
-
|
|
394
|
-
) public pure returns (TD10ReportBody memory report) {
|
|
395
|
-
report = TD10ReportBody({
|
|
326
|
+
function parseTd10ReportBody(bytes calldata rawQuote) public pure returns (Td10ReportBody memory report) {
|
|
327
|
+
report = Td10ReportBody({
|
|
396
328
|
teeTcbSvn: bytes16(rawQuote[HEADER_LENGTH:HEADER_LENGTH + 16]),
|
|
397
329
|
mrSeam: bytes(rawQuote[HEADER_LENGTH + 16:HEADER_LENGTH + 64]),
|
|
398
|
-
mrsignerSeam: bytes(
|
|
399
|
-
|
|
400
|
-
),
|
|
401
|
-
|
|
402
|
-
uint64(
|
|
403
|
-
BELE.leBytesToBeUint(
|
|
404
|
-
rawQuote[HEADER_LENGTH + 112:HEADER_LENGTH + 120]
|
|
405
|
-
)
|
|
406
|
-
)
|
|
407
|
-
),
|
|
408
|
-
tdAttributes: bytes8(
|
|
409
|
-
uint64(
|
|
410
|
-
BELE.leBytesToBeUint(
|
|
411
|
-
rawQuote[HEADER_LENGTH + 120:HEADER_LENGTH + 128]
|
|
412
|
-
)
|
|
413
|
-
)
|
|
414
|
-
),
|
|
415
|
-
xFAM: bytes8(
|
|
416
|
-
uint64(
|
|
417
|
-
BELE.leBytesToBeUint(
|
|
418
|
-
rawQuote[HEADER_LENGTH + 128:HEADER_LENGTH + 136]
|
|
419
|
-
)
|
|
420
|
-
)
|
|
421
|
-
),
|
|
330
|
+
mrsignerSeam: bytes(rawQuote[HEADER_LENGTH + 64:HEADER_LENGTH + 112]),
|
|
331
|
+
seamAttributes: bytes8(uint64(BELE.leBytesToBeUint(rawQuote[HEADER_LENGTH + 112:HEADER_LENGTH + 120]))),
|
|
332
|
+
tdAttributes: bytes8(uint64(BELE.leBytesToBeUint(rawQuote[HEADER_LENGTH + 120:HEADER_LENGTH + 128]))),
|
|
333
|
+
xFAM: bytes8(uint64(BELE.leBytesToBeUint(rawQuote[HEADER_LENGTH + 128:HEADER_LENGTH + 136]))),
|
|
422
334
|
mrTd: bytes(rawQuote[HEADER_LENGTH + 136:HEADER_LENGTH + 184]),
|
|
423
|
-
mrConfigId: bytes(
|
|
424
|
-
rawQuote[HEADER_LENGTH + 184:HEADER_LENGTH + 232]
|
|
425
|
-
),
|
|
335
|
+
mrConfigId: bytes(rawQuote[HEADER_LENGTH + 184:HEADER_LENGTH + 232]),
|
|
426
336
|
mrOwner: bytes(rawQuote[HEADER_LENGTH + 232:HEADER_LENGTH + 280]),
|
|
427
|
-
mrOwnerConfig: bytes(
|
|
428
|
-
rawQuote[HEADER_LENGTH + 280:HEADER_LENGTH + 328]
|
|
429
|
-
),
|
|
337
|
+
mrOwnerConfig: bytes(rawQuote[HEADER_LENGTH + 280:HEADER_LENGTH + 328]),
|
|
430
338
|
rtMr0: bytes(rawQuote[HEADER_LENGTH + 328:HEADER_LENGTH + 376]),
|
|
431
339
|
rtMr1: bytes(rawQuote[HEADER_LENGTH + 376:HEADER_LENGTH + 424]),
|
|
432
340
|
rtMr2: bytes(rawQuote[HEADER_LENGTH + 424:HEADER_LENGTH + 472]),
|
|
@@ -441,17 +349,10 @@ abstract contract TEELifecycle is
|
|
|
441
349
|
* @return reportDataSigner - The signing address of the report data signer
|
|
442
350
|
* @return reportMrAggregated - The MR_AGGREGATED bytes from the report
|
|
443
351
|
*/
|
|
444
|
-
function parseReport(
|
|
445
|
-
TD10ReportBody memory tdReport
|
|
446
|
-
) public pure returns (address, bytes32) {
|
|
352
|
+
function parseReport(Td10ReportBody memory tdReport) public pure returns (address, bytes32) {
|
|
447
353
|
return (
|
|
448
354
|
address(bytes20(tdReport.reportData)),
|
|
449
|
-
computeMrAggregated(
|
|
450
|
-
tdReport.mrTd,
|
|
451
|
-
tdReport.rtMr0,
|
|
452
|
-
tdReport.rtMr1,
|
|
453
|
-
tdReport.rtMr2
|
|
454
|
-
)
|
|
355
|
+
computeMrAggregated(tdReport.mrTd, tdReport.rtMr0, tdReport.rtMr1, tdReport.rtMr2)
|
|
455
356
|
);
|
|
456
357
|
}
|
|
457
358
|
|
|
@@ -464,74 +365,43 @@ abstract contract TEELifecycle is
|
|
|
464
365
|
* @param rtMr2 - The RTMR2 bytes
|
|
465
366
|
* @return mrAggregated - The MR_AGGREGATED bytes32
|
|
466
367
|
*/
|
|
467
|
-
function computeMrAggregated(
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
) public pure returns (bytes32) {
|
|
368
|
+
function computeMrAggregated(bytes memory mrTd, bytes memory rtMr0, bytes memory rtMr1, bytes memory rtMr2)
|
|
369
|
+
public
|
|
370
|
+
pure
|
|
371
|
+
returns (bytes32)
|
|
372
|
+
{
|
|
473
373
|
bytes memory message = abi.encodePacked(mrTd, rtMr0, rtMr1, rtMr2);
|
|
474
374
|
return keccak256(message);
|
|
475
375
|
}
|
|
476
376
|
|
|
477
377
|
function quoteVerifier() public view returns (IQuoteVerifier) {
|
|
478
|
-
return
|
|
378
|
+
return getTeeLifecycleStorage().quoteVerifier;
|
|
479
379
|
}
|
|
480
380
|
|
|
481
|
-
function
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
require(index < $.ApprovedTEEVersions.length, IndexOutOfBounds());
|
|
486
|
-
return $.ApprovedTEEVersions[index];
|
|
381
|
+
function approvedTeeVersions(uint256 index) external view returns (bytes32) {
|
|
382
|
+
StorageForTeeLifecycle storage $ = getTeeLifecycleStorage();
|
|
383
|
+
require(index < $.approvedTeeVersions.length, IndexOutOfBounds());
|
|
384
|
+
return $.approvedTeeVersions[index];
|
|
487
385
|
}
|
|
488
386
|
|
|
489
387
|
function eciesPubkey() external view returns (bytes memory) {
|
|
490
|
-
return
|
|
388
|
+
return getTeeLifecycleStorage().eciesPubkey;
|
|
491
389
|
}
|
|
492
390
|
|
|
493
|
-
function
|
|
494
|
-
return
|
|
391
|
+
function bootstrapResultDigest(BootstrapResult memory bootstrapResult) public view returns (bytes32) {
|
|
392
|
+
return _hashTypedDataV4(
|
|
393
|
+
keccak256(abi.encode(BOOTSTRAP_RESULT_STRUCT_HASH, keccak256(bootstrapResult.ecies_pubkey)))
|
|
394
|
+
);
|
|
495
395
|
}
|
|
496
396
|
|
|
497
|
-
function
|
|
498
|
-
BootstrapResult memory bootstrapResult
|
|
499
|
-
) public view returns (bytes32) {
|
|
397
|
+
function upgradeResultDigest(UpgradeResult memory upgradeResult) public view returns (bytes32) {
|
|
500
398
|
return
|
|
501
|
-
_hashTypedDataV4(
|
|
502
|
-
keccak256(
|
|
503
|
-
abi.encode(
|
|
504
|
-
BootstrapResultStructHash,
|
|
505
|
-
keccak256(bootstrapResult.ecies_pubkey)
|
|
506
|
-
)
|
|
507
|
-
)
|
|
508
|
-
);
|
|
399
|
+
_hashTypedDataV4(keccak256(abi.encode(UPGRADE_RESULT_STRUCT_HASH, keccak256(upgradeResult.networkPubkey))));
|
|
509
400
|
}
|
|
510
401
|
|
|
511
|
-
function
|
|
512
|
-
UpgradeResult memory upgradeResult
|
|
513
|
-
) public view returns (bytes32) {
|
|
402
|
+
function addNodeResultDigest(AddNodeResult memory addNodeResult) public view returns (bytes32) {
|
|
514
403
|
return
|
|
515
|
-
_hashTypedDataV4(
|
|
516
|
-
keccak256(
|
|
517
|
-
abi.encode(
|
|
518
|
-
UpgradeResultStructHash,
|
|
519
|
-
keccak256(upgradeResult.network_pubkey)
|
|
520
|
-
)
|
|
521
|
-
)
|
|
522
|
-
);
|
|
404
|
+
_hashTypedDataV4(keccak256(abi.encode(ADD_NODE_RESULT_STRUCT_HASH, keccak256(addNodeResult.networkPubkey))));
|
|
523
405
|
}
|
|
524
406
|
|
|
525
|
-
function addNodeResultDigest(
|
|
526
|
-
AddNodeResult memory addNodeResult
|
|
527
|
-
) public view returns (bytes32) {
|
|
528
|
-
return
|
|
529
|
-
_hashTypedDataV4(
|
|
530
|
-
keccak256(abi.encode(
|
|
531
|
-
AddNodeResultStructHash,
|
|
532
|
-
keccak256(addNodeResult.network_pubkey)
|
|
533
|
-
)
|
|
534
|
-
)
|
|
535
|
-
);
|
|
536
|
-
}
|
|
537
407
|
}
|
|
@@ -5,8 +5,9 @@ pragma solidity ^0.8.19;
|
|
|
5
5
|
* @notice A struct representing what the TDX EOA signs during the bootstrap process.
|
|
6
6
|
*/
|
|
7
7
|
struct BootstrapResult {
|
|
8
|
-
// TODO: rename to
|
|
8
|
+
// TODO: rename to networkPubkey
|
|
9
9
|
// https://github.com/Inco-fhevm/inco-monorepo/issues/983
|
|
10
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
10
11
|
bytes ecies_pubkey;
|
|
11
12
|
}
|
|
12
13
|
|
|
@@ -14,12 +15,12 @@ struct BootstrapResult {
|
|
|
14
15
|
* @notice A struct representing what the TDX EOA signs during the upgrade process.
|
|
15
16
|
*/
|
|
16
17
|
struct UpgradeResult {
|
|
17
|
-
bytes
|
|
18
|
+
bytes networkPubkey;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* @notice A struct representing what the TDX EOA signs during the add node process.
|
|
22
23
|
*/
|
|
23
24
|
struct AddNodeResult {
|
|
24
|
-
bytes
|
|
25
|
+
bytes networkPubkey;
|
|
25
26
|
}
|
|
@@ -7,18 +7,9 @@ import {BaseAccessControlList} from "./AccessControl/BaseAccessControlList.sol";
|
|
|
7
7
|
import {HandleGeneration} from "./primitives/HandleGeneration.sol";
|
|
8
8
|
import {ITrivialEncryption} from "./interfaces/ITrivialEncryption.sol";
|
|
9
9
|
|
|
10
|
-
abstract contract TrivialEncryption is
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
BaseAccessControlList,
|
|
14
|
-
HandleGeneration
|
|
15
|
-
{
|
|
16
|
-
event TrivialEncrypt(
|
|
17
|
-
bytes32 indexed result,
|
|
18
|
-
bytes32 plainTextBytes,
|
|
19
|
-
ETypes handleType,
|
|
20
|
-
uint256 eventId
|
|
21
|
-
);
|
|
10
|
+
abstract contract TrivialEncryption is ITrivialEncryption, EventCounter, BaseAccessControlList, HandleGeneration {
|
|
11
|
+
|
|
12
|
+
event TrivialEncrypt(bytes32 indexed result, bytes32 plainTextBytes, ETypes handleType, uint256 eventId);
|
|
22
13
|
|
|
23
14
|
function asEuint256(uint256 value) external returns (euint256 newEuint256) {
|
|
24
15
|
return euint256.wrap(newTrivialEncrypt(bytes32(value), ETypes.Uint256));
|
|
@@ -31,20 +22,15 @@ abstract contract TrivialEncryption is
|
|
|
31
22
|
|
|
32
23
|
function asEaddress(address value) external returns (eaddress newEaddress) {
|
|
33
24
|
bytes32 castedValue = bytes32(uint256(uint160(value)));
|
|
34
|
-
return
|
|
35
|
-
eaddress.wrap(
|
|
36
|
-
newTrivialEncrypt(castedValue, ETypes.AddressOrUint160OrBytes20)
|
|
37
|
-
);
|
|
25
|
+
return eaddress.wrap(newTrivialEncrypt(castedValue, ETypes.AddressOrUint160OrBytes20));
|
|
38
26
|
}
|
|
39
27
|
|
|
40
|
-
function newTrivialEncrypt(
|
|
41
|
-
bytes32 plainTextBytes,
|
|
42
|
-
ETypes handleType
|
|
43
|
-
) internal returns (bytes32 newHandle) {
|
|
28
|
+
function newTrivialEncrypt(bytes32 plainTextBytes, ETypes handleType) internal returns (bytes32 newHandle) {
|
|
44
29
|
newHandle = getTrivialEncryptHandle(plainTextBytes, handleType);
|
|
45
30
|
allowTransientInternal(newHandle, msg.sender);
|
|
46
31
|
uint256 id = getNextEventId();
|
|
47
32
|
emit TrivialEncrypt(newHandle, plainTextBytes, handleType, id);
|
|
48
33
|
setDigest(abi.encodePacked(newHandle, id));
|
|
49
34
|
}
|
|
35
|
+
|
|
50
36
|
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
// SPDX-License-Identifier: No License
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {DecryptionAttestation} from "../DecryptionAttester.types.sol";
|
|
5
5
|
|
|
6
6
|
interface IDecryptionAttester {
|
|
7
|
+
|
|
7
8
|
function decryptionAttestationDigest(DecryptionAttestation memory decryption) external view returns (bytes32);
|
|
8
|
-
function isValidDecryptionAttestation(DecryptionAttestation memory decryption, bytes memory
|
|
9
|
+
function isValidDecryptionAttestation(DecryptionAttestation memory decryption, bytes[] memory signatures)
|
|
10
|
+
external
|
|
11
|
+
view
|
|
12
|
+
returns (bool);
|
|
13
|
+
|
|
9
14
|
}
|
|
@@ -4,16 +4,9 @@ pragma solidity ^0.8;
|
|
|
4
4
|
import {euint256, ebool, eaddress} from "../../Types.sol";
|
|
5
5
|
|
|
6
6
|
interface IEncryptedInput {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
) external payable returns (
|
|
11
|
-
|
|
12
|
-
bytes memory ciphertext,
|
|
13
|
-
address user
|
|
14
|
-
) external payable returns (ebool newValue);
|
|
15
|
-
function newEaddress(
|
|
16
|
-
bytes memory ciphertext,
|
|
17
|
-
address user
|
|
18
|
-
) external payable returns (eaddress newValue);
|
|
7
|
+
|
|
8
|
+
function newEuint256(bytes memory ciphertext, address user) external payable returns (euint256 newValue);
|
|
9
|
+
function newEbool(bytes memory ciphertext, address user) external payable returns (ebool newValue);
|
|
10
|
+
function newEaddress(bytes memory ciphertext, address user) external payable returns (eaddress newValue);
|
|
11
|
+
|
|
19
12
|
}
|