@inco/lightning 0.2.17 → 0.3.2

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.
Files changed (42) hide show
  1. package/manifest.yaml +29 -0
  2. package/package.json +5 -1
  3. package/src/DeployTEE.sol +153 -0
  4. package/src/DeployUtils.sol +17 -9
  5. package/src/Errors.sol +4 -0
  6. package/src/IncoLightning.gen.sol +1 -1
  7. package/src/IncoLightning.sol +2 -1
  8. package/src/Types.sol +45 -3
  9. package/src/lightning-parts/EncryptedInput.gen.sol +1 -0
  10. package/src/lightning-parts/EncryptedInput.sol +1 -1
  11. package/src/lightning-parts/EncryptedOperations.gen.sol +1 -1
  12. package/src/lightning-parts/EncryptedOperations.sol +8 -6
  13. package/src/lightning-parts/TEELifecycle.gen.sol +58 -0
  14. package/src/lightning-parts/TEELifecycle.sol +255 -0
  15. package/src/lightning-parts/TEELifecycle.types.sol +21 -0
  16. package/src/lightning-parts/primitives/SignatureVerifier.gen.sol +1 -0
  17. package/src/lightning-parts/primitives/SignatureVerifier.sol +11 -0
  18. package/src/lightning-parts/test/HandleMetadata.t.sol +1 -1
  19. package/src/test/FakeIncoInfra/FakeQuoteVerifier.sol +29 -0
  20. package/src/test/FakeIncoInfra/MockRemoteAttestation.sol +37 -0
  21. package/src/test/FibonacciDecrypt.sol +1 -0
  22. package/src/test/IncoTest.sol +5 -1
  23. package/src/test/TEELifecycle/README.md +53 -0
  24. package/src/test/TEELifecycle/TEELifecycleHWTest.t.sol +119 -0
  25. package/src/test/TEELifecycle/TEELifecycleMockTest.t.sol +145 -0
  26. package/src/test/TEELifecycle/addnode_data/eoa.txt +1 -0
  27. package/src/test/TEELifecycle/addnode_data/quote.bin +0 -0
  28. package/src/test/TEELifecycle/bootstrap_data/ecies_pubkey.bin +1 -0
  29. package/src/test/TEELifecycle/bootstrap_data/eip712_signature.bin +1 -0
  30. package/src/test/TEELifecycle/bootstrap_data/eoa.txt +1 -0
  31. package/src/test/TEELifecycle/bootstrap_data/qe_identity +1 -0
  32. package/src/test/TEELifecycle/bootstrap_data/qe_identity_signature.bin +1 -0
  33. package/src/test/TEELifecycle/bootstrap_data/quote.bin +0 -0
  34. package/src/test/TEELifecycle/bootstrap_data/tcb_info +1 -0
  35. package/src/test/TEELifecycle/bootstrap_data/tcb_info_signature.bin +1 -0
  36. package/src/test/TEELifecycle/test_cert/AttestationReportSigningCA.crl +0 -0
  37. package/src/test/TEELifecycle/test_cert/Intel_SGX_Attestation_RootCA.cer +0 -0
  38. package/src/test/TEELifecycle/test_cert/Intel_SGX_PCK_CRL.crl +0 -0
  39. package/src/test/TEELifecycle/test_cert/Intel_SGX_PCK_PlatformCA.cer +0 -0
  40. package/src/test/TEELifecycle/test_cert/Intel_SGX_TCB_Signing.cer +0 -0
  41. package/src/test/TestFakeInfra.t.sol +18 -1
  42. package/src/test/TestUpgrade.t.sol +314 -0
package/manifest.yaml CHANGED
@@ -139,6 +139,35 @@ incoLightning_devnet_v0_340846814:
139
139
  executorAddress: "0x3B22be60Ae699933959CA3cE147C96caa88Ccd3D"
140
140
  salt: "0x8202d2d747784cb7d48868e44c42c4bf162a70bc00b001d6742fded0dd599ede"
141
141
  deployments:
142
+ - name: incoLightningPreview_0_2_1__340846814
143
+ chainId: "4801"
144
+ chainName: World Chain Sepolia
145
+ version:
146
+ major: 0
147
+ minor: 2
148
+ patch: 1
149
+ shortSalt: "340846814"
150
+ decryptSigner: "0x138AcbDC1FA02b955949d8Da09E546Ea7748710f"
151
+ eciesPublicKey: "0x038a582d29083c2f3fefe024bf4dd9ab913ab8973716977da5f01106e0b84095b1"
152
+ blockNumber: "17365942"
153
+ deployDate: 2025-08-15T17:35:15.208Z
154
+ commit: v0.2.17-35-g8cca6b4e-dirty
155
+ active: true
156
+ - name: incoLightningPreview_0_2_1__340846814
157
+ chainId: "9746"
158
+ chainName: Plasma Testnet
159
+ version:
160
+ major: 0
161
+ minor: 2
162
+ patch: 1
163
+ shortSalt: "340846814"
164
+ decryptSigner: "0x138AcbDC1FA02b955949d8Da09E546Ea7748710f"
165
+ eciesPublicKey: "0x048a582d29083c2f3fefe024bf4dd9ab913ab8973716977da5f01106e0b8\
166
+ 4095b1e647a9e377175fcb66bda05087c93b05e1fd53a704d0914bb23a0b2a69e9f235"
167
+ blockNumber: "3339121"
168
+ deployDate: 2025-08-07T12:14:56.788Z
169
+ commit: v0.2.17-28-gfd11c1aa-dirty
170
+ active: true
142
171
  - name: incoLightning_0_2_0__340846814
143
172
  chainId: "84532"
144
173
  chainName: Base Sepolia
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inco/lightning",
3
- "version": "0.2.17",
3
+ "version": "0.3.2",
4
4
  "repository": "https://github.com/Inco-fhevm/inco-monorepo",
5
5
  "files": [
6
6
  "src/",
@@ -18,8 +18,12 @@
18
18
  "@inco/shared": "^0.1.0",
19
19
  "@openzeppelin/contracts": "^5.2.0",
20
20
  "@openzeppelin/contracts-upgradeable": "^5.2.0",
21
+ "@safe-global/safe-smart-account": "https://github.com/safe-global/safe-smart-account.git#v1.5.0",
22
+ "automata-dcap-attestation": "https://github.com/automata-network/automata-dcap-attestation.git#evm-v1.0.0",
23
+ "automata-on-chain-pccs": "https://github.com/automata-network/automata-on-chain-pccs.git#v1.0.0",
21
24
  "ds-test": "https://github.com/dapphub/ds-test",
22
25
  "forge-std": "https://github.com/foundry-rs/forge-std",
26
+ "solady": "https://github.com/Vectorized/solady.git#v0.1.24",
23
27
  "tsx": "^4.19.3"
24
28
  },
25
29
  "devDependencies": {
@@ -0,0 +1,153 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {Vm} from "forge-std/Vm.sol";
6
+ import {console} from "forge-std/console.sol";
7
+
8
+ import {IQuoteVerifier} from "automata-dcap-attestation/interfaces/IQuoteVerifier.sol";
9
+ import {TEELifecycle} from "./lightning-parts/TEELifecycle.sol";
10
+
11
+ import {CA} from "@automata-network/on-chain-pccs/Common.sol";
12
+ import {EnclaveIdentityJsonObj, IdentityObj, EnclaveIdentityHelper} from "@automata-network/on-chain-pccs/helpers/EnclaveIdentityHelper.sol";
13
+ import {TcbInfoJsonObj, FmspcTcbHelper} from "@automata-network/on-chain-pccs/helpers/FmspcTcbHelper.sol";
14
+ import {PCKHelper} from "@automata-network/on-chain-pccs/helpers/PCKHelper.sol";
15
+ import {X509CRLHelper} from "@automata-network/on-chain-pccs/helpers/X509CRLHelper.sol";
16
+ import {AutomataFmspcTcbDao} from "@automata-network/on-chain-pccs/automata_pccs/AutomataFmspcTcbDao.sol";
17
+ import {AutomataEnclaveIdentityDao} from "@automata-network/on-chain-pccs/automata_pccs/AutomataEnclaveIdentityDao.sol";
18
+ import {AutomataPcsDao} from "@automata-network/on-chain-pccs/automata_pccs/AutomataPcsDao.sol";
19
+ import {AutomataPckDao} from "@automata-network/on-chain-pccs/automata_pccs/AutomataPckDao.sol";
20
+ import {AutomataDaoStorage} from "@automata-network/on-chain-pccs/automata_pccs/shared/AutomataDaoStorage.sol";
21
+ import {PCCSRouter} from "@automata-network/dcap-attestation/PCCSRouter.sol";
22
+ import {V4QuoteVerifier} from "@automata-network/dcap-attestation/verifiers/V4QuoteVerifier.sol";
23
+
24
+ // For now we don't use deployments for TEELifecycle, as we do for IncoLightning.
25
+ // @todo: Use deployments for TEELifecycle
26
+ // ref: https://github.com/Inco-fhevm/inco-monorepo/issues/875
27
+ string constant EIP712_NAME = "TEELifecycle";
28
+ string constant EIP712_VERSION = "1.0.0";
29
+
30
+ // DeployTEE is a script that deplots all TEE-related supporting contracts for IncoLightning.
31
+ contract DeployTEE is Script {
32
+
33
+ // The default address of the P256 Verifier contract that is used to verify the P256 signatures.
34
+ // It is deployed with this address on Ethereum L1, OP Mainnet, Base, Arbitrum.
35
+ // @dev From: https://github.com/daimo-eth/p256-verifier?tab=readme-ov-file#usage
36
+ address public P256_VERIFIER = 0xc2b78104907F722DABAc4C69f826a522B2754De4;
37
+
38
+ // The PCCSRouter contract is used as the entrypoint for the management of collateral used to verify quotes.
39
+ // It is used by the QuoteVerifier to fetch collateral.
40
+ PCCSRouter public pccsRouter;
41
+
42
+ // These helpers are used to parse the collateral files and upload them to the PCCSRouter.
43
+ AutomataFmspcTcbDao fmspcTcbDao;
44
+ AutomataEnclaveIdentityDao enclaveIdDao;
45
+
46
+ // This function deploys a TEELifecycle contract that is used to manage the TEE lifecycle for the IncoLightning contract.
47
+ // @dev The TEELifecycle contract is used to manage the TEE lifecycle for the IncoLightning contract.
48
+ // It is used to verify quotes, and to manage the TEE lifecycle.
49
+ // It is also used to manage the EOA signers for the IncoLightning contract.
50
+ // @param quoteVerifierAddress The address of the QuoteVerifier contract to be used by the TEELifecycle contract.
51
+ function deployTEELifecycle(address deployer, address quoteVerifierAddress) internal returns (TEELifecycle) {
52
+ // TODO: Currently TEELifecycle is not UUPS
53
+ // ref: https://github.com/Inco-fhevm/inco-monorepo/issues/875
54
+ TEELifecycle implementation = new TEELifecycle();
55
+ implementation.initialize(
56
+ deployer,
57
+ EIP712_NAME,
58
+ EIP712_VERSION,
59
+ quoteVerifierAddress
60
+ );
61
+ return implementation;
62
+ }
63
+
64
+ // This function deploys a QuoteVerifier contract that is used to verify quotes for the IncoLightning contract.
65
+ // @dev: TDX_HW environment variable is used to determine whether to use the FakeQuoteVerifier or the V4QuoteVerifier.
66
+ // @dev We deploy two flavors of the QuoteVerifier contract:
67
+ // - FakeQuoteVerifier: A fake implementation of the QuoteVerifier contract that is used to test the IncoLightning contract.
68
+ // This is used for testing purposes, and returns true for all quote verifications.
69
+ // - V4QuoteVerifier: The real implementation of the QuoteVerifier contract that is used to verify quotes for the IncoLightning contract.
70
+ // This is taken from the automata-dcap-attestation package.
71
+ function deployQuoteVerifier() internal returns (IQuoteVerifier quoteVerifier) {
72
+ // deploys the QuoteVerifier contract
73
+ quoteVerifier = new V4QuoteVerifier(
74
+ P256_VERIFIER,
75
+ address(pccsRouter)
76
+ );
77
+
78
+ pccsRouter.setAuthorized(address(quoteVerifier), true);
79
+ }
80
+
81
+ function deployPCCS(address owner, string memory collateralDir) internal {
82
+
83
+ EnclaveIdentityHelper enclaveIdHelper = new EnclaveIdentityHelper();
84
+ FmspcTcbHelper tcbHelper = new FmspcTcbHelper();
85
+ PCKHelper x509 = new PCKHelper();
86
+ X509CRLHelper x509Crl = new X509CRLHelper();
87
+
88
+ AutomataDaoStorage pccsStorage = new AutomataDaoStorage(owner);
89
+ AutomataPcsDao pcsDao = new AutomataPcsDao(address(pccsStorage), P256_VERIFIER, address(x509), address(x509Crl));
90
+ AutomataPckDao pckDao = new AutomataPckDao(address(pccsStorage), P256_VERIFIER, address(pcsDao), address(x509), address(x509Crl));
91
+ enclaveIdDao = new AutomataEnclaveIdentityDao(
92
+ address(pccsStorage), P256_VERIFIER, address(pcsDao), address(enclaveIdHelper), address(x509), address(x509Crl)
93
+ );
94
+ fmspcTcbDao = new AutomataFmspcTcbDao(address(pccsStorage), P256_VERIFIER, address(pcsDao), address(tcbHelper), address(x509), address(x509Crl));
95
+ // grants dao permissions to write to the storage
96
+ pccsStorage.grantDao(address(pcsDao));
97
+ pccsStorage.grantDao(address(pckDao));
98
+ pccsStorage.grantDao(address(fmspcTcbDao));
99
+ pccsStorage.grantDao(address(enclaveIdDao));
100
+
101
+ // grants admin address permission to read collaterals
102
+ pccsRouter = new PCCSRouter(
103
+ owner,
104
+ address(enclaveIdDao),
105
+ address(fmspcTcbDao),
106
+ address(pcsDao),
107
+ address(pckDao),
108
+ address(x509),
109
+ address(x509Crl),
110
+ address(tcbHelper)
111
+ );
112
+ // allow PCCS Router to read collaterals from the storage
113
+ pccsStorage.setCallerAuthorization(address(pccsRouter), true);
114
+
115
+ // Upload Root Certs/CRLs
116
+ bytes memory rootCaDer = vm.readFileBinary(string.concat(collateralDir, "Intel_SGX_Attestation_RootCA.cer"));
117
+ pcsDao.upsertPcsCertificates(CA.ROOT, rootCaDer);
118
+ bytes memory tcbDer = vm.readFileBinary(string.concat(collateralDir, "Intel_SGX_TCB_Signing.cer"));
119
+ pcsDao.upsertPcsCertificates(CA.SIGNING, tcbDer);
120
+ bytes memory platformDer = vm.readFileBinary(string.concat(collateralDir, "Intel_SGX_PCK_PlatformCA.cer"));
121
+ pcsDao.upsertPcsCertificates(CA.PLATFORM, platformDer);
122
+ bytes memory platformCrlDer = vm.readFileBinary(string.concat(collateralDir, "Intel_SGX_PCK_CRL.crl"));
123
+ pcsDao.upsertPckCrl(CA.PLATFORM, platformCrlDer);
124
+ bytes memory rootCrlDer = vm.readFileBinary(string.concat(collateralDir, "AttestationReportSigningCA.crl"));
125
+
126
+ pcsDao.upsertRootCACrl(rootCrlDer);
127
+ }
128
+
129
+ // This function deploys the P256 Verifier contract that is used to verify P256 signatures.
130
+ // @dev The code is taken from https://github.com/automata-network/automata-on-chain-pccs/blob/v1.0.0/test/TestSetupBase.t.sol#L91
131
+ function deployP256() internal {
132
+ // Known chains that have the P256 Verifier deployed:
133
+ // Ethereum Mainnet, Optimism Mainnet, Base, Arbitrum
134
+ // https://github.com/daimo-eth/p256-verifier/tree/master/broadcast/Deploy.s.sol
135
+ if (block.chainid == 1 || block.chainid == 10 || block.chainid == 8453 || block.chainid == 84531 ) {
136
+ console.log("P256 Verifier contract is already deployed on this chain, skipping deployment.");
137
+ return;
138
+ }
139
+ require(block.chainid == 31337, "Deploying P256 Verifier is only supported on Anvil chain");
140
+ bytes memory txdata =
141
+ hex"00000000000000000000000000000000000000000000000000000000000000006080806040523461001657610dd1908161001c8239f35b600080fdfe60e06040523461001a57610012366100c7565b602081519101f35b600080fd5b6040810190811067ffffffffffffffff82111761003b57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60e0810190811067ffffffffffffffff82111761003b57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761003b57604052565b60a08103610193578060201161001a57600060409180831161018f578060601161018f578060801161018f5760a01161018c57815182810181811067ffffffffffffffff82111761015f579061013291845260603581526080356020820152833560203584356101ab565b15610156575060ff6001915b5191166020820152602081526101538161001f565b90565b60ff909161013e565b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80fd5b5080fd5b5060405160006020820152602081526101538161001f565b909283158015610393575b801561038b575b8015610361575b6103585780519060206101dc818301938451906103bd565b1561034d57604051948186019082825282604088015282606088015260808701527fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f60a08701527fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551958660c082015260c081526102588161006a565b600080928192519060055afa903d15610345573d9167ffffffffffffffff831161031857604051926102b1857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160185610086565b83523d828585013e5b156102eb57828280518101031261018c5750015190516102e693929185908181890994099151906104eb565b061490565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526001600452fd5b6024827f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b6060916102ba565b505050505050600090565b50505050600090565b507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310156101c4565b5082156101bd565b507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410156101b6565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90818110801590610466575b8015610455575b61044d577f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b8282818080957fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0991818180090908089180091490565b505050600090565b50801580156103f1575082156103f1565b50818310156103ea565b7f800000000000000000000000000000000000000000000000000000000000000081146104bc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b909192608052600091600160a05260a05193600092811580610718575b61034d57610516838261073d565b95909460ff60c05260005b600060c05112156106ef575b60a05181036106a1575050507f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5957f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2969594939291965b600060c05112156105c7575050505050507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff91506105c260a051610ca2565b900990565b956105d9929394959660a05191610a98565b9097929181928960a0528192819a6105f66080518960c051610722565b61060160c051610470565b60c0528061061b5750505050505b96959493929196610583565b969b5061067b96939550919350916001810361068857507f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5937f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29693610952565b979297919060a05261060f565b6002036106985786938a93610952565b88938893610952565b600281036106ba57505050829581959493929196610583565b9197917ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161060f575095508495849661060f565b506106ff6080518560c051610722565b8061070b60c051610470565b60c052156105215761052d565b5060805115610508565b91906002600192841c831b16921c1681018091116104bc5790565b8015806107ab575b6107635761075f91610756916107b3565b92919091610c42565b9091565b50507f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296907f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f590565b508115610745565b919082158061094a575b1561080f57507f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29691507f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5906001908190565b7fb01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a917fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808481600186090894817f94e82e0c1ed3bdb90743191a9c5bbf0d88fc827fd214cc5f0b5ec6ba27673d6981600184090893841561091b575050808084800993840994818460010994828088600109957f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29609918784038481116104bc5784908180867fffffffff00000001000000000000000000000000fffffffffffffffffffffffd0991818580090808978885038581116104bc578580949281930994080908935b93929190565b9350935050921560001461093b5761093291610b6d565b91939092610915565b50506000806000926000610915565b5080156107bd565b91949592939095811580610a90575b15610991575050831580610989575b61097a5793929190565b50600093508392508291508190565b508215610970565b85919294951580610a88575b610a78577fffffffff00000001000000000000000000000000ffffffffffffffffffffffff968703918783116104bc5787838189850908938689038981116104bc5789908184840908928315610a5d575050818880959493928180848196099b8c9485099b8c920999099609918784038481116104bc5784908180867fffffffff00000001000000000000000000000000fffffffffffffffffffffffd0991818580090808978885038581116104bc578580949281930994080908929190565b965096505050509093501560001461093b5761093291610b6d565b9550509150915091906001908190565b50851561099d565b508015610961565b939092821580610b65575b61097a577fffffffff00000001000000000000000000000000ffffffffffffffffffffffff908185600209948280878009809709948380888a0998818080808680097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099280096003090884808a7fffffffff00000001000000000000000000000000fffffffffffffffffffffffd09818380090898898603918683116104bc57888703908782116104bc578780969481809681950994089009089609930990565b508015610aa3565b919091801580610c3a575b610c2d577fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90818460020991808084800980940991817fffffffff00000001000000000000000000000000fffffffffffffffffffffffc81808088860994800960030908958280837fffffffff00000001000000000000000000000000fffffffffffffffffffffffd09818980090896878403918483116104bc57858503928584116104bc5785809492819309940890090892565b5060009150819081908190565b508215610b78565b909392821580610c9a575b610c8d57610c5a90610ca2565b9182917fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80809581940980099009930990565b5050509050600090600090565b508015610c4d565b604051906020918281019183835283604083015283606083015260808201527fffffffff00000001000000000000000000000000fffffffffffffffffffffffd60a08201527fffffffff00000001000000000000000000000000ffffffffffffffffffffffff60c082015260c08152610d1a8161006a565b600080928192519060055afa903d15610d93573d9167ffffffffffffffff83116103185760405192610d73857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160185610086565b83523d828585013e5b156102eb57828280518101031261018c5750015190565b606091610d7c56fea2646970667358221220fa55558b04ced380e93d0a46be01bb895ff30f015c50c516e898c341cd0a230264736f6c63430008150033";
142
+
143
+ // deploys the P256 Verifier contract using the default CREATE2 deterministic deployment contract available of EVM chains including on Anvil
144
+ // https://github.com/Arachnid/deterministic-deployment-proxy?tab=readme-ov-file#latest-outputs
145
+ // https://getfoundry.sh/guides/deterministic-deployments-using-create2
146
+ (bool succ,) = address(0x4e59b44847b379578588920cA78FbF26c0B4956C).call(txdata);
147
+ require(succ, "Failed to deploy P256");
148
+
149
+ // check code
150
+ uint256 codesize = P256_VERIFIER.code.length;
151
+ require(codesize > 0, "P256 deployed to the wrong address");
152
+ }
153
+ }
@@ -9,6 +9,7 @@ import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.s
9
9
  import {CONTRACT_NAME, MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION} from "../src/version/IncoLightningConfig.sol";
10
10
  import {console} from "forge-std/console.sol";
11
11
  import {CreateXHelper} from "./CreateXHelper.sol";
12
+ import {IncoLightningPreview} from "@inco/lightning-preview/src/IncoLightningPreview.sol";
12
13
 
13
14
  // can be set to 0x01 so the inco address can exist on only one chain, we want the same contract at the same address
14
15
  // on all chains
@@ -93,12 +94,16 @@ contract DeployUtils is Script {
93
94
  /// @param pepper a value used to avoid address collision on deploying the same contract twice with the same deployer
94
95
  /// @param minorVersionForSalt minor version of the contract to use in the salt
95
96
  /// @param patchVersionForSalt patch version of the contract to use in the salt
97
+ /// @param includePreviewFeatures whether to include preview features in the contract
98
+ /// @param teeLifecycleAddress the address of the TEELifecycle contract to use in the contract
96
99
  function deployIncoLightningUsingConfig(
97
100
  address deployer,
98
101
  string memory pepper,
99
102
  // FIXME: on the next major version (new contract address and state) we should remove these from the salt altogether
100
103
  uint8 minorVersionForSalt,
101
- uint8 patchVersionForSalt
104
+ uint8 patchVersionForSalt,
105
+ bool includePreviewFeatures,
106
+ address teeLifecycleAddress
102
107
  ) internal returns (IncoLightning proxy) {
103
108
  bytes32 salt = getSalt(
104
109
  CONTRACT_NAME,
@@ -114,12 +119,20 @@ contract DeployUtils is Script {
114
119
  vm.toString(salt)
115
120
  );
116
121
  IncoLightning implementation = new IncoLightning(salt);
122
+ if (includePreviewFeatures) {
123
+ IncoLightningPreview preview = new IncoLightningPreview(address(implementation));
124
+ // FIXME: This is hack, we ought to define an interface IIncoLightning here and use that instead
125
+ implementation = IncoLightning(address(preview));
126
+ }
117
127
  proxy = IncoLightning(
118
128
  deployProxy({
119
- deployer: deployer,
120
129
  salt: salt,
121
130
  implem: address(implementation),
122
- initFunctionSelector: IncoLightning.initialize.selector
131
+ initCall: abi.encodeWithSelector(
132
+ IncoLightning.initialize.selector,
133
+ deployer,
134
+ teeLifecycleAddress
135
+ )
123
136
  })
124
137
  );
125
138
  }
@@ -129,17 +142,12 @@ contract DeployUtils is Script {
129
142
  /// the proxy
130
143
  /// @dev deployer is made the owner of the contract
131
144
  function deployProxy(
132
- address deployer,
133
145
  bytes32 salt,
134
146
  address implem,
135
- bytes4 initFunctionSelector
147
+ bytes memory initCall
136
148
  ) internal returns (address proxy) {
137
149
  CreateX createX = CreateX(createXAddress);
138
150
  CreateX.Values memory msgValues = CreateX.Values(0, 0);
139
- bytes memory initCall = abi.encodeWithSelector(
140
- initFunctionSelector,
141
- deployer
142
- );
143
151
  bytes memory bytecode = abi.encodePacked(
144
152
  type(ERC1967Proxy).creationCode,
145
153
  abi.encode(implem, initCall)
package/src/Errors.sol ADDED
@@ -0,0 +1,4 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ error HandleAlreadyExists();
@@ -11,5 +11,5 @@ import { UUPSUpgradeable } from "@openzeppelin/contracts/proxy/utils/UUPSUpgrade
11
11
  import { Version } from "./version/Version.sol";
12
12
 
13
13
  interface IIncoLightningGen {
14
- function initialize(address owner) external;
14
+ function initialize(address owner, address teeLifecycleAddress) external;
15
15
  }
@@ -40,8 +40,9 @@ contract IncoLightning is
40
40
  require(msg.sender == owner());
41
41
  }
42
42
 
43
- function initialize(address owner) public initializer {
43
+ function initialize(address owner, address teeLifecycleAddress) public initializer {
44
44
  __Ownable_init(owner);
45
+ __SignatureVerifier_init(teeLifecycleAddress);
45
46
  }
46
47
 
47
48
  fallback() external {} // must be included for createX deploy
package/src/Types.sol CHANGED
@@ -34,7 +34,25 @@ pragma solidity ^0.8;
34
34
  RandBounded, // 27
35
35
  // These are pseudo-ops part of the decryption/callback system but we need to generate code for them so I am including them
36
36
  DecryptionRequested, // 28
37
- RequestFulfilled // 29
37
+ RequestFulfilled, // 29
38
+ EOP30, EOP31, EOP32, EOP33, EOP34, EOP35, EOP36, EOP37, EOP38, EOP39,
39
+ EOP40, EOP41, EOP42, EOP43, EOP44, EOP45, EOP46, EOP47, EOP48, EOP49,
40
+ EOP50, EOP51, EOP52, EOP53, EOP54, EOP55, EOP56, EOP57, EOP58, EOP59,
41
+ EOP60, EOP61, EOP62, EOP63, EOP64, EOP65, EOP66, EOP67, EOP68, EOP69,
42
+ EOP70, EOP71, EOP72, EOP73, EOP74, EOP75, EOP76, EOP77, EOP78, EOP79,
43
+ EOP80, EOP81, EOP82, EOP83, EOP84, EOP85, EOP86, EOP87, EOP88, EOP89,
44
+ EOP90, EOP91, EOP92, EOP93, EOP94, EOP95, EOP96, EOP97, EOP98, EOP99,
45
+ NewEList, // 100
46
+ EListGet, // 101
47
+ EListGetOr, // 102
48
+ EListSet, // 103
49
+ EListInsert, // 104
50
+ EListAppend, // 105
51
+ EListConcat, // 106
52
+ EListSlice, // 107
53
+ EListRange, // 108
54
+ EListShuffle, // 109
55
+ EListReverse // 110
38
56
  }
39
57
 
40
58
  type ebool is bytes32;
@@ -55,7 +73,24 @@ pragma solidity ^0.8;
55
73
  Uint256,
56
74
  Bytes64UNSUPPORTED,
57
75
  Bytes128UNSUPPORTED,
58
- Bytes256UNSUPPORTED
76
+ Bytes256UNSUPPORTED,
77
+ EmptyType12, // 12
78
+ EmptyType13, // 13
79
+ EmptyType14, // 14
80
+ EmptyType15, // 15
81
+ EmptyType16, // 16
82
+ EmptyType17, // 17
83
+ EmptyType18, // 18
84
+ EmptyType19, // 19
85
+ EmptyType20, EmptyType21, EmptyType22, EmptyType23, EmptyType24, EmptyType25, EmptyType26, EmptyType27, EmptyType28, EmptyType29,
86
+ EmptyType30, EmptyType31, EmptyType32, EmptyType33, EmptyType34, EmptyType35, EmptyType36, EmptyType37, EmptyType38, EmptyType39,
87
+ EmptyType40, EmptyType41, EmptyType42, EmptyType43, EmptyType44, EmptyType45, EmptyType46, EmptyType47, EmptyType48, EmptyType49,
88
+ EmptyType50, EmptyType51, EmptyType52, EmptyType53, EmptyType54, EmptyType55, EmptyType56, EmptyType57, EmptyType58, EmptyType59,
89
+ EmptyType60, EmptyType61, EmptyType62, EmptyType63, EmptyType64, EmptyType65, EmptyType66, EmptyType67, EmptyType68, EmptyType69,
90
+ EmptyType70, EmptyType71, EmptyType72, EmptyType73, EmptyType74, EmptyType75, EmptyType76, EmptyType77, EmptyType78, EmptyType79,
91
+ EmptyType80, EmptyType81, EmptyType82, EmptyType83, EmptyType84, EmptyType85, EmptyType86, EmptyType87, EmptyType88, EmptyType89,
92
+ EmptyType90, EmptyType91, EmptyType92, EmptyType93, EmptyType94, EmptyType95, EmptyType96, EmptyType97, EmptyType98, EmptyType99,
93
+ List // 100
59
94
  }
60
95
 
61
96
  // check correctness of compute
@@ -74,4 +109,11 @@ string constant EVM_HOST_CHAIN_PREFIX = "evm/";
74
109
  uint8 constant HANDLE_VERSION = 0;
75
110
 
76
111
  // IncoLightning only supports single-valued ciphertexts so this is always 0
77
- uint256 constant HANDLE_INDEX = 0;
112
+ // NOTE: this must be a uint8 to get hash agreement!
113
+ uint8 constant HANDLE_INDEX = 0;
114
+
115
+ /// Util function to convert an ETypes to a bit mask
116
+ /// @param t the type to convert to a bit mask
117
+ function typeToBitMask(ETypes t) pure returns (bytes32) {
118
+ return bytes32(1 << uint256(t));
119
+ }
@@ -5,6 +5,7 @@ import { BaseAccessControlList } from "./AccessControl/BaseAccessControlList.sol
5
5
  import { EventCounter } from "./primitives/EventCounter.sol";
6
6
  import { HandleGeneration } from "./primitives/HandleGeneration.sol";
7
7
  import { euint256, ebool, eaddress, ETypes, EVM_HOST_CHAIN_PREFIX, HANDLE_VERSION, HANDLE_INDEX } from "../Types.sol";
8
+ import { HandleAlreadyExists } from "../Errors.sol";
8
9
 
9
10
  interface IEncryptedInputGen {
10
11
  function newEuint256(bytes memory ciphertext, address user) external returns (euint256 newValue);
@@ -6,6 +6,7 @@ import {EventCounter} from "./primitives/EventCounter.sol";
6
6
  import {HandleGeneration} from "./primitives/HandleGeneration.sol";
7
7
  import {euint256, ebool, eaddress, ETypes, EVM_HOST_CHAIN_PREFIX, HANDLE_VERSION, HANDLE_INDEX} from "../Types.sol";
8
8
  import {IEncryptedInputGen} from "./EncryptedInput.gen.sol";
9
+ import {HandleAlreadyExists} from "../Errors.sol";
9
10
 
10
11
  abstract contract EncryptedInput is
11
12
  IEncryptedInputGen,
@@ -13,7 +14,6 @@ abstract contract EncryptedInput is
13
14
  EventCounter,
14
15
  HandleGeneration
15
16
  {
16
- error HandleAlreadyExists();
17
17
 
18
18
  event NewInput(
19
19
  bytes32 indexed result,
@@ -1,7 +1,7 @@
1
1
  /// SPDX-License-Identifier: No License
2
2
  pragma solidity ^0.8;
3
3
 
4
- import { euint256, ebool, EOps, SenderNotAllowedForHandle, ETypes, isTypeSupported } from "../Types.sol";
4
+ import { euint256, ebool, EOps, SenderNotAllowedForHandle, ETypes, isTypeSupported, typeToBitMask } from "../Types.sol";
5
5
  import { BaseAccessControlList } from "./AccessControl/BaseAccessControlList.sol";
6
6
  import { EventCounter } from "./primitives/EventCounter.sol";
7
7
  import { HandleGeneration } from "./primitives/HandleGeneration.sol";
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: No License
2
2
  pragma solidity ^0.8;
3
3
 
4
- import {euint256, ebool, EOps, SenderNotAllowedForHandle, ETypes, isTypeSupported} from "../Types.sol";
4
+ import {euint256, ebool, EOps, SenderNotAllowedForHandle, ETypes, isTypeSupported, typeToBitMask} from "../Types.sol";
5
5
  import {BaseAccessControlList} from "./AccessControl/BaseAccessControlList.sol";
6
6
  import {EventCounter} from "./primitives/EventCounter.sol";
7
7
  import {HandleGeneration} from "./primitives/HandleGeneration.sol";
@@ -16,7 +16,7 @@ abstract contract EncryptedOperations is
16
16
  error UnexpectedType(ETypes actual, bytes32 expectedTypes);
17
17
  error UnsupportedType(ETypes actual);
18
18
 
19
- uint256 private randCounter;
19
+ uint256 internal randCounter;
20
20
 
21
21
  bytes32 constant EBOOL = bytes32(1 << uint256(ETypes.Bool));
22
22
  bytes32 constant EUINT160 = bytes32(1 << uint256(ETypes.AddressOrUint160OrBytes20));
@@ -175,10 +175,6 @@ abstract contract EncryptedOperations is
175
175
  uint256 eventId
176
176
  );
177
177
 
178
- function typeToBitMask(ETypes t) internal pure returns (bytes32) {
179
- return bytes32(1 << uint256(t));
180
- }
181
-
182
178
  modifier checked(euint256 lhs, euint256 rhs) {
183
179
  checkInput(euint256.unwrap(lhs), typeToBitMask(ETypes.Uint256));
184
180
  checkInput(euint256.unwrap(rhs), typeToBitMask(ETypes.Uint256));
@@ -569,6 +565,9 @@ abstract contract EncryptedOperations is
569
565
  bytes32(randCounter++),
570
566
  bytes32(uint256(randType))
571
567
  );
568
+ //NOTE: We pass the incremented randCounter which is incremented using postfix increment above.
569
+ // Due to postfix returning the value before incrementing, the emitted randCounter will be larger by one than the number used to build the handle.
570
+ // So for security and replayability reasons, we always use the incremented randCounter when seeding on the covalidator side, which is fine for as long as we're consistent.
572
571
  emit ERand(randCounter, randType, result, getNewEventId());
573
572
  }
574
573
 
@@ -586,6 +585,9 @@ abstract contract EncryptedOperations is
586
585
  upperBound,
587
586
  bytes32(uint256(randType))
588
587
  );
588
+ //NOTE: We pass the incremented randCounter which is incremented using postfix increment above.
589
+ // Due to postfix returning the value before incrementing, the emitted randCounter will be larger by one than the number used to build the handle.
590
+ // So for security and replayability reasons, we always use the incremented randCounter when seeding on the covalidator side, which is fine for as long as we're consistent.
589
591
  emit ERandBounded(randCounter, randType, upperBound, result, getNewEventId());
590
592
  }
591
593
 
@@ -0,0 +1,58 @@
1
+ /// SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8.19;
3
+
4
+ import "./TEELifecycle.types.sol";
5
+ import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
6
+ import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
7
+ import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
8
+ import { IQuoteVerifier } from "automata-dcap-attestation/interfaces/IQuoteVerifier.sol";
9
+ import { BELE } from "automata-dcap-attestation/utils/BELE.sol";
10
+ import { HEADER_LENGTH } from "automata-dcap-attestation/types/Constants.sol";
11
+ import { TD10ReportBody, Header } from "automata-dcap-attestation/types/V4Structs.sol";
12
+ import { EIP712Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol";
13
+ import { EnclaveIdentityJsonObj, IdentityObj } from "@automata-network/on-chain-pccs/helpers/EnclaveIdentityHelper.sol";
14
+ import { TcbInfoJsonObj } from "@automata-network/on-chain-pccs/helpers/FmspcTcbHelper.sol";
15
+ import { AutomataFmspcTcbDao } from "@automata-network/on-chain-pccs/automata_pccs/AutomataFmspcTcbDao.sol";
16
+ import { AutomataEnclaveIdentityDao } from "@automata-network/on-chain-pccs/automata_pccs/AutomataEnclaveIdentityDao.sol";
17
+
18
+ interface ITEELifecycleGen {
19
+ function initialize(address owner, string memory eip712Name, string memory eip712Version, address quoteVerifierAddress) external;
20
+
21
+ /// @notice Uploads the collateral to the contract
22
+ /// @param tcbInfo - The TCB info to upload
23
+ /// @param identity - The identity to upload
24
+ function uploadCollateral(TcbInfoJsonObj memory tcbInfo, EnclaveIdentityJsonObj memory identity) external;
25
+
26
+ /// @notice Verifies the bootstrap data against the provided quote and signature
27
+ /// @param bootstrapResult - The bootstrap data to verify
28
+ /// @param quote - The quote to verify against
29
+ /// @param signature - The signature to verify against
30
+ function verifyBootstrapResult(BootstrapResult calldata bootstrapResult, bytes calldata quote, bytes calldata signature) external;
31
+
32
+ /// @notice Approves a new TEE version and updates the TEEVersionHistory
33
+ /// @param newMRTD - The MRTD bytes of the new TEE version
34
+ /// @dev This function increments the version number automatically based on the current history
35
+ function approveNewTEEVersion(bytes calldata newMRTD) external;
36
+
37
+ /// @notice Adds a new covalidator to the contract state
38
+ /// @param quote - The quote from the new covalidator that contains the current MRTD and the eoa address of the new party in the report data
39
+ function addNewCovalidator(bytes calldata quote) external;
40
+
41
+ /// @notice Checks if the bootstrap is complete, meaning that there is an active TEE version.
42
+ /// @return true if the bootstrap is complete, false otherwise
43
+ function isBootstrapComplete() external view returns (bool);
44
+
45
+ /// @notice From https://github.com/automata-network/automata-dcap-attestation/blob/evm-v1.0.0/evm/contracts/verifiers/V4QuoteVerifier.sol#L309
46
+ /// @notice Parses the TD10 report body from the raw quote
47
+ /// @param rawQuote - The raw quote bytes
48
+ /// @return report - The parsed TD10 report body
49
+ function parseTD10ReportBody(bytes calldata rawQuote) external pure returns (TD10ReportBody memory report);
50
+
51
+ /// @notice Parses the TD10 report to extract the report data and MRTD
52
+ /// @param tdReport - The TD10 report body
53
+ /// @return reportDataSigner - The signing address of the report data signer
54
+ /// @return reportMRTD - The MRTD bytes from the report
55
+ function parseReport(TD10ReportBody memory tdReport) external pure returns (address, bytes memory);
56
+
57
+ function bootstrapResultDigest(BootstrapResult memory bootstrapResult) external view returns (bytes32);
58
+ }