@inco/lightning 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/README.md +2 -0
- package/manifest.yaml +23 -0
- package/package.json +2 -5
- package/src/DeployUtils.sol +113 -77
- package/src/IIncoLightning.sol +16 -9
- package/src/IncoLightning.sol +18 -9
- package/src/IncoVerifier.sol +47 -0
- package/src/Lib.alphanet.sol +2 -15
- package/src/Lib.demonet.sol +2 -15
- package/src/Lib.devnet.sol +3 -16
- package/src/Lib.sol +3 -16
- package/src/Lib.template.sol +3 -44
- package/src/Lib.testnet.sol +2 -15
- package/src/Types.sol +7 -0
- package/src/interfaces/IIncoLightning.sol +20 -0
- package/src/interfaces/IIncoVerifier.sol +24 -0
- package/src/interfaces/automata-interfaces/BELE.sol +20 -0
- package/src/interfaces/automata-interfaces/IAutomataEnclaveIdentityDao.sol +28 -0
- package/src/interfaces/automata-interfaces/IFmspcTcbDao.sol +10 -0
- package/src/interfaces/automata-interfaces/IPCCSRouter.sol +94 -0
- package/src/interfaces/automata-interfaces/IPCCSRouterExtended.sol +10 -0
- package/src/interfaces/automata-interfaces/IPcsDao.sol +18 -0
- package/src/interfaces/automata-interfaces/IQuoteVerifier.sol +34 -0
- package/src/interfaces/automata-interfaces/Types.sol +193 -0
- package/src/libs/incoLightning_alphanet_v0_297966649.sol +2 -15
- package/src/libs/incoLightning_demonet_v0_863421733.sol +2 -15
- package/src/libs/incoLightning_devnet_v0_340846814.sol +2 -15
- package/src/libs/incoLightning_devnet_v1_887305889.sol +451 -0
- package/src/libs/incoLightning_testnet_v0_183408998.sol +2 -15
- package/src/libs/incoLightning_testnet_v1_938327937.sol +451 -0
- package/src/lightning-parts/AccessControl/AdvancedAccessControl.sol +133 -0
- package/src/lightning-parts/AccessControl/AdvancedAccessControl.types.sol +18 -0
- package/src/lightning-parts/AccessControl/BaseAccessControlList.sol +22 -2
- package/src/lightning-parts/AccessControl/interfaces/IAdvancedAccessControl.sol +25 -0
- package/src/lightning-parts/AccessControl/interfaces/IBaseAccessControlList.sol +24 -0
- package/src/lightning-parts/AccessControl/test/TestAdvancedAccessControl.t.sol +234 -0
- package/src/lightning-parts/AccessControl/test/TestBaseAccessControl.t.sol +4 -3
- package/src/lightning-parts/DecryptionAttester.sol +45 -0
- package/src/lightning-parts/DecryptionAttester.types.sol +7 -0
- package/src/lightning-parts/EncryptedInput.sol +8 -13
- package/src/lightning-parts/EncryptedOperations.sol +2 -2
- package/src/lightning-parts/TEELifecycle.sol +180 -88
- package/src/lightning-parts/TrivialEncryption.sol +8 -10
- package/src/lightning-parts/interfaces/IDecryptionAttester.sol +9 -0
- package/src/lightning-parts/interfaces/IEncryptedInput.sol +19 -0
- package/src/lightning-parts/interfaces/IEncryptedOperations.sol +31 -0
- package/src/lightning-parts/interfaces/ITEELifecycle.sol +26 -0
- package/src/lightning-parts/interfaces/ITrivialEncryption.sol +10 -0
- package/src/lightning-parts/primitives/EventCounter.sol +2 -2
- package/src/lightning-parts/primitives/HandleGeneration.sol +8 -3
- package/src/lightning-parts/primitives/HandleMetadata.sol +1 -1
- package/src/lightning-parts/primitives/LightningAddressGetter.sol +10 -0
- package/src/lightning-parts/primitives/SignatureVerifier.sol +2 -9
- package/src/lightning-parts/primitives/VerifierAddressGetter.sol +13 -0
- package/src/lightning-parts/primitives/{EventCounter.gen.sol → interfaces/IEventCounter.sol} +2 -2
- package/src/lightning-parts/primitives/interfaces/IHandleGeneration.sol +41 -0
- package/src/lightning-parts/primitives/interfaces/ISignatureVerifier.sol +9 -0
- package/src/lightning-parts/primitives/interfaces/IVerifierAddressGetter.sol +8 -0
- package/src/lightning-parts/test/HandleMetadata.t.sol +25 -6
- package/src/lightning-parts/test/TestDecryptionAttestationInSynchronousFlow.t.sol +78 -0
- package/src/periphery/SessionVerifier.sol +63 -0
- package/src/test/AddTwo.sol +18 -33
- package/src/test/FakeIncoInfra/FakeDecryptionAttester.sol +198 -0
- package/src/test/FakeIncoInfra/FakeIncoInfraBase.sol +0 -15
- package/src/test/FakeIncoInfra/FakeQuoteVerifier.sol +10 -6
- package/src/test/FakeIncoInfra/MockOpHandler.sol +0 -7
- package/src/test/FakeIncoInfra/MockRemoteAttestation.sol +19 -7
- package/src/test/FakeIncoInfra/getOpForSelector.sol +0 -3
- package/src/test/IncoTest.sol +12 -11
- package/src/test/TEELifecycle/TEELifecycleMockTest.t.sol +98 -77
- package/src/test/TestAddTwo.t.sol +16 -9
- package/src/test/TestFakeInfra.t.sol +10 -27
- package/src/test/TestUpgrade.t.sol +11 -4
- package/src/test/TestVersion.t.sol +0 -7
- package/src/version/IncoLightningConfig.sol +5 -4
- package/src/version/SessionVerifierConfig.sol +8 -0
- package/src/version/Version.sol +7 -9
- package/src/version/interfaces/IVersion.sol +8 -0
- package/src/DeployTEE.sol +0 -153
- package/src/IncoLightning.gen.sol +0 -15
- package/src/lightning-parts/AccessControl/BaseAccessControlList.gen.sol +0 -24
- package/src/lightning-parts/DecryptionHandler.gen.sol +0 -54
- package/src/lightning-parts/DecryptionHandler.sol +0 -307
- package/src/lightning-parts/DecryptionHandler.types.sol +0 -34
- package/src/lightning-parts/EncryptedInput.gen.sol +0 -16
- package/src/lightning-parts/EncryptedOperations.gen.sol +0 -59
- package/src/lightning-parts/TEELifecycle.gen.sol +0 -58
- package/src/lightning-parts/TrivialEncryption.gen.sol +0 -15
- package/src/lightning-parts/primitives/HandleGeneration.gen.sol +0 -19
- package/src/lightning-parts/primitives/HandleMetadata.gen.sol +0 -4
- package/src/lightning-parts/primitives/SignatureVerifier.gen.sol +0 -16
- package/src/test/FibonacciDecrypt.sol +0 -49
- package/src/test/TEELifecycle/TEELifecycleHWTest.t.sol +0 -119
- package/src/test/TEELifecycle/addnode_data/eoa.txt +0 -1
- package/src/test/TEELifecycle/addnode_data/quote.bin +0 -0
- package/src/test/TEELifecycle/bootstrap_data/ecies_pubkey.bin +0 -1
- package/src/test/TEELifecycle/bootstrap_data/eip712_signature.bin +0 -1
- package/src/test/TEELifecycle/bootstrap_data/eoa.txt +0 -1
- package/src/test/TEELifecycle/bootstrap_data/qe_identity +0 -1
- package/src/test/TEELifecycle/bootstrap_data/qe_identity_signature.bin +0 -1
- package/src/test/TEELifecycle/bootstrap_data/quote.bin +0 -0
- package/src/test/TEELifecycle/bootstrap_data/tcb_info +0 -1
- package/src/test/TEELifecycle/bootstrap_data/tcb_info_signature.bin +0 -1
- package/src/test/TEELifecycle/test_cert/AttestationReportSigningCA.crl +0 -0
- package/src/test/TEELifecycle/test_cert/Intel_SGX_Attestation_RootCA.cer +0 -0
- package/src/test/TEELifecycle/test_cert/Intel_SGX_PCK_CRL.crl +0 -0
- package/src/test/TEELifecycle/test_cert/Intel_SGX_PCK_PlatformCA.cer +0 -0
- package/src/test/TEELifecycle/test_cert/Intel_SGX_TCB_Signing.cer +0 -0
- package/src/version/Version.gen.sol +0 -14
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// SPDX-License-Identifier: No License
|
|
2
|
+
pragma solidity ^0.8;
|
|
3
|
+
|
|
4
|
+
import {ETypes, EOps} from "../../../Types.sol";
|
|
5
|
+
|
|
6
|
+
interface IHandleGeneration {
|
|
7
|
+
function getTrivialEncryptHandle(
|
|
8
|
+
bytes32 plaintextBytes,
|
|
9
|
+
ETypes handleType
|
|
10
|
+
) external view returns (bytes32 generatedHandle);
|
|
11
|
+
function getInputHandle(
|
|
12
|
+
bytes memory ciphertext,
|
|
13
|
+
address user,
|
|
14
|
+
address contractAddress,
|
|
15
|
+
ETypes inputType
|
|
16
|
+
) external view returns (bytes32 generatedHandle);
|
|
17
|
+
function getOpResultHandle(
|
|
18
|
+
EOps op,
|
|
19
|
+
ETypes returnType,
|
|
20
|
+
bytes32 lhs,
|
|
21
|
+
bytes32 rhs
|
|
22
|
+
) external pure returns (bytes32 generatedHandle);
|
|
23
|
+
function getOpResultHandle(
|
|
24
|
+
EOps op,
|
|
25
|
+
ETypes returnType,
|
|
26
|
+
uint256 counter,
|
|
27
|
+
bytes32 upperBound
|
|
28
|
+
) external pure returns (bytes32 generatedHandle);
|
|
29
|
+
function getOpResultHandle(
|
|
30
|
+
EOps op,
|
|
31
|
+
ETypes returnType,
|
|
32
|
+
bytes32 value
|
|
33
|
+
) external pure returns (bytes32 generatedHandle);
|
|
34
|
+
function getOpResultHandle(
|
|
35
|
+
EOps op,
|
|
36
|
+
ETypes returnType,
|
|
37
|
+
bytes32 inputA,
|
|
38
|
+
bytes32 inputB,
|
|
39
|
+
bytes32 inputC
|
|
40
|
+
) external pure returns (bytes32 generatedHandle);
|
|
41
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// SPDX-License-Identifier: No License
|
|
2
|
+
pragma solidity ^0.8;
|
|
3
|
+
|
|
4
|
+
interface ISignatureVerifier {
|
|
5
|
+
function addSigner(address signerAddress) external;
|
|
6
|
+
function removeSigner(address signerAddress) external;
|
|
7
|
+
function isSigner(address signerAddress) external view returns (bool);
|
|
8
|
+
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bool);
|
|
9
|
+
}
|
|
@@ -7,7 +7,14 @@ import {TrivialEncryption} from "../TrivialEncryption.sol";
|
|
|
7
7
|
import {EncryptedOperations} from "../EncryptedOperations.sol";
|
|
8
8
|
import {EncryptedInput} from "../EncryptedInput.sol";
|
|
9
9
|
import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
ETypes,
|
|
12
|
+
ebool,
|
|
13
|
+
euint256,
|
|
14
|
+
eaddress,
|
|
15
|
+
typeToBitMask
|
|
16
|
+
} from "../../Types.sol";
|
|
17
|
+
import {VerifierAddressGetter} from "../primitives/VerifierAddressGetter.sol";
|
|
11
18
|
|
|
12
19
|
contract TestHandleMetadata is
|
|
13
20
|
EIP712,
|
|
@@ -17,7 +24,7 @@ contract TestHandleMetadata is
|
|
|
17
24
|
EncryptedOperations,
|
|
18
25
|
EncryptedInput
|
|
19
26
|
{
|
|
20
|
-
constructor() EIP712("", "") {}
|
|
27
|
+
constructor() EIP712("", "") VerifierAddressGetter(address(0)) {}
|
|
21
28
|
|
|
22
29
|
function testTypeAssignment() public pure {
|
|
23
30
|
bytes32 someHandle = bytes32(keccak256("someHandle"));
|
|
@@ -30,8 +37,12 @@ contract TestHandleMetadata is
|
|
|
30
37
|
ETypes.Uint256
|
|
31
38
|
);
|
|
32
39
|
assert(
|
|
33
|
-
typeOf(
|
|
34
|
-
|
|
40
|
+
typeOf(
|
|
41
|
+
embedIndexTypeVersion(
|
|
42
|
+
someHandle,
|
|
43
|
+
ETypes.AddressOrUint160OrBytes20
|
|
44
|
+
)
|
|
45
|
+
) == ETypes.AddressOrUint160OrBytes20
|
|
35
46
|
);
|
|
36
47
|
}
|
|
37
48
|
|
|
@@ -40,7 +51,9 @@ contract TestHandleMetadata is
|
|
|
40
51
|
assert(typeOf(boolHandle) == ETypes.Bool);
|
|
41
52
|
bytes32 uintHandle = euint256.unwrap(this.asEuint256(42));
|
|
42
53
|
assert(typeOf(uintHandle) == ETypes.Uint256);
|
|
43
|
-
bytes32 addressHandle = eaddress.unwrap(
|
|
54
|
+
bytes32 addressHandle = eaddress.unwrap(
|
|
55
|
+
this.asEaddress(address(0xdeadbeef))
|
|
56
|
+
);
|
|
44
57
|
assert(typeOf(addressHandle) == ETypes.AddressOrUint160OrBytes20);
|
|
45
58
|
}
|
|
46
59
|
|
|
@@ -70,7 +83,13 @@ contract TestHandleMetadata is
|
|
|
70
83
|
this.eIfThenElse(control, ebool.unwrap(c), ebool.unwrap(d))
|
|
71
84
|
) == ETypes.Bool
|
|
72
85
|
);
|
|
73
|
-
assert(
|
|
86
|
+
assert(
|
|
87
|
+
typeOf(
|
|
88
|
+
ebool.unwrap(
|
|
89
|
+
this.eEq(eaddress.unwrap(addr1), eaddress.unwrap(addr2))
|
|
90
|
+
)
|
|
91
|
+
) == ETypes.Bool
|
|
92
|
+
);
|
|
74
93
|
}
|
|
75
94
|
|
|
76
95
|
function testEIfThenElseChecksTypeCoherence() public {
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// SPDX-License-Identifier: No License
|
|
2
|
+
pragma solidity ^0.8;
|
|
3
|
+
|
|
4
|
+
import {IncoTest} from "../../test/IncoTest.sol";
|
|
5
|
+
import {DemoToken} from "@inco/confidential-token-demo/src/DemoToken.sol";
|
|
6
|
+
import {DecryptionAttestation} from "../DecryptionAttester.types.sol";
|
|
7
|
+
import {GWEI} from "@inco/shared/src/TypeUtils.sol";
|
|
8
|
+
import {euint256} from "@inco/lightning/src/Lib.sol"; // import via remapping or compiler fails
|
|
9
|
+
import {AllowanceProof} from "../AccessControl/AdvancedAccessControl.sol";
|
|
10
|
+
import {inco} from "../../Lib.sol";
|
|
11
|
+
import {euint256 as remappedEuint256} from "@inco/lightning/src/Lib.sol";
|
|
12
|
+
|
|
13
|
+
contract TokenBurnCurrentBalance is DemoToken {
|
|
14
|
+
function burnFullCurrentBalance(
|
|
15
|
+
DecryptionAttestation memory decryption,
|
|
16
|
+
bytes memory signature
|
|
17
|
+
) public {
|
|
18
|
+
euint256 currentBalance = confidentialBalanceOf(msg.sender);
|
|
19
|
+
require(
|
|
20
|
+
inco.incoVerifier().isValidDecryptionAttestation(
|
|
21
|
+
decryption,
|
|
22
|
+
signature
|
|
23
|
+
),
|
|
24
|
+
"Invalid Signature"
|
|
25
|
+
);
|
|
26
|
+
require(
|
|
27
|
+
euint256.unwrap(currentBalance) == decryption.handle,
|
|
28
|
+
"Handle mismatch"
|
|
29
|
+
);
|
|
30
|
+
publicBurn(msg.sender, uint256(decryption.value));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
contract TestDecryptionAttestationInSynchronousFlow is IncoTest {
|
|
35
|
+
AllowanceProof emptyProof; // no proof needed when requester has the handle in persisted allowed pairs
|
|
36
|
+
function testSynchronousBurning() public {
|
|
37
|
+
TokenBurnCurrentBalance token = new TokenBurnCurrentBalance();
|
|
38
|
+
token.confidentialTransfer(
|
|
39
|
+
alice,
|
|
40
|
+
fakePrepareEuint256Ciphertext(10 * GWEI),
|
|
41
|
+
""
|
|
42
|
+
);
|
|
43
|
+
processAllOperations(); // saves Alice's balance
|
|
44
|
+
bytes32 aliceCurrentBalanceHandle = euint256.unwrap(
|
|
45
|
+
token.confidentialBalanceOf(alice)
|
|
46
|
+
);
|
|
47
|
+
// simulates Alice requesting for a decryption attestation of Ge op on her balance and the amount
|
|
48
|
+
// she intends to burn, therefore proving to the token contract that the operation will succeed
|
|
49
|
+
(
|
|
50
|
+
DecryptionAttestation memory decryption,
|
|
51
|
+
bytes memory signature
|
|
52
|
+
) = getDecryptionAttestation(
|
|
53
|
+
alice,
|
|
54
|
+
HandleWithProof({
|
|
55
|
+
handle: aliceCurrentBalanceHandle,
|
|
56
|
+
proof: emptyProof
|
|
57
|
+
})
|
|
58
|
+
);
|
|
59
|
+
vm.prank(alice);
|
|
60
|
+
|
|
61
|
+
// the decryption attestation is passed to the token burn method
|
|
62
|
+
token.burnFullCurrentBalance(decryption, signature);
|
|
63
|
+
|
|
64
|
+
processAllOperations();
|
|
65
|
+
|
|
66
|
+
remappedEuint256 remappedFinalAliceBalance = token
|
|
67
|
+
.confidentialBalanceOf(alice);
|
|
68
|
+
bytes32 finalAliceBalance = remappedEuint256.unwrap(
|
|
69
|
+
remappedFinalAliceBalance
|
|
70
|
+
); // compilation trick
|
|
71
|
+
|
|
72
|
+
assertEq(
|
|
73
|
+
uint256(get(finalAliceBalance)),
|
|
74
|
+
0,
|
|
75
|
+
"Alice should have burned all her tokens"
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// SPDX-License-Identifier: No License
|
|
2
|
+
pragma solidity ^0.8;
|
|
3
|
+
|
|
4
|
+
import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
|
|
5
|
+
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
|
6
|
+
import {
|
|
7
|
+
SESSION_VERIFIER_NAME,
|
|
8
|
+
SESSION_VERIFIER_MAJOR_VERSION,
|
|
9
|
+
SESSION_VERIFIER_MINOR_VERSION,
|
|
10
|
+
SESSION_VERIFIER_PATCH_VERSION
|
|
11
|
+
} from "../version/SessionVerifierConfig.sol";
|
|
12
|
+
import {Version} from "../version/Version.sol";
|
|
13
|
+
import {ALLOWANCE_GRANTED_MAGIC_VALUE} from "../Types.sol";
|
|
14
|
+
|
|
15
|
+
/// @notice a Session grants a temporary access to a decrypter to all data held by the sharer
|
|
16
|
+
/// @dev abi encode this struct in the sharerArgData field of the voucher
|
|
17
|
+
struct Session {
|
|
18
|
+
address decrypter;
|
|
19
|
+
uint256 expiresAt;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/// @notice Inco access sharing verifier mainly meant for browser dapp sessions, grants access to all data held by
|
|
23
|
+
/// the sharer to one decrypter for a limited time.
|
|
24
|
+
/// @dev define the selector of canUseSession in the voucher to use this verifier
|
|
25
|
+
contract SessionVerifier is UUPSUpgradeable, OwnableUpgradeable, Version {
|
|
26
|
+
constructor(
|
|
27
|
+
bytes32 salt
|
|
28
|
+
)
|
|
29
|
+
Version(
|
|
30
|
+
SESSION_VERIFIER_MAJOR_VERSION,
|
|
31
|
+
SESSION_VERIFIER_MINOR_VERSION,
|
|
32
|
+
SESSION_VERIFIER_PATCH_VERSION,
|
|
33
|
+
salt,
|
|
34
|
+
SESSION_VERIFIER_NAME
|
|
35
|
+
)
|
|
36
|
+
{}
|
|
37
|
+
|
|
38
|
+
// todo add text mention of what is being signed
|
|
39
|
+
function canUseSession(
|
|
40
|
+
bytes32 /* handle */,
|
|
41
|
+
address account,
|
|
42
|
+
bytes memory sharerArgData,
|
|
43
|
+
bytes memory /* requesterArgData */
|
|
44
|
+
) external view returns (bytes32) {
|
|
45
|
+
Session memory session = abi.decode(sharerArgData, (Session));
|
|
46
|
+
if (
|
|
47
|
+
session.expiresAt >= block.timestamp && session.decrypter == account
|
|
48
|
+
) {
|
|
49
|
+
return ALLOWANCE_GRANTED_MAGIC_VALUE;
|
|
50
|
+
}
|
|
51
|
+
return bytes32(0);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function _authorizeUpgrade(address) internal view override {
|
|
55
|
+
require(msg.sender == owner());
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function initialize(address owner) public initializer {
|
|
59
|
+
__Ownable_init(owner);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
fallback() external {} // must be included for createX deploy
|
|
63
|
+
}
|
package/src/test/AddTwo.sol
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
// SPDX-License-Identifier: No License
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
|
-
import {IncoLightning} from "../IncoLightning.sol";
|
|
5
4
|
import {euint256} from "../Types.sol";
|
|
5
|
+
import {IncoLightning} from "../IncoLightning.sol";
|
|
6
|
+
|
|
7
|
+
// import {console} from "forge-std/console.sol";
|
|
6
8
|
|
|
9
|
+
// To implement such a contract, we would normally import e form Lib.sol. For test purposes, we take inco as
|
|
10
|
+
// a constructor argument instead, so we can test it from other deployment addresses.
|
|
7
11
|
contract AddTwo {
|
|
8
|
-
IncoLightning
|
|
12
|
+
IncoLightning inco;
|
|
9
13
|
|
|
10
14
|
constructor(IncoLightning _inco) {
|
|
11
15
|
inco = _inco;
|
|
@@ -14,48 +18,29 @@ contract AddTwo {
|
|
|
14
18
|
// Stores the result of the last callback.
|
|
15
19
|
uint256 public lastResult;
|
|
16
20
|
|
|
17
|
-
function addTwo(euint256 a)
|
|
18
|
-
|
|
19
|
-
return inco.eAdd(a,
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function addTwoScalar(euint256 a) external returns (euint256) {
|
|
23
|
-
uint256 two = 2;
|
|
24
|
-
return inco.eAdd(a, inco.asEuint256(two));
|
|
21
|
+
function addTwo(euint256 a) public returns (euint256) {
|
|
22
|
+
euint256 two = inco.asEuint256(2);
|
|
23
|
+
return inco.eAdd(a, two);
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
// To generate a different handle with the same result, instead of adding 2 we add 1 + 1
|
|
28
|
-
function addTwoAlt(euint256 a)
|
|
29
|
-
|
|
30
|
-
return inco.eAdd(a, inco.eAdd(
|
|
27
|
+
function addTwoAlt(euint256 a) public returns (euint256) {
|
|
28
|
+
euint256 one = inco.asEuint256(1);
|
|
29
|
+
return inco.eAdd(a, inco.eAdd(one, one));
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
function addTwoEOA(
|
|
34
33
|
bytes memory uint256EInput
|
|
35
|
-
) external returns (
|
|
34
|
+
) external returns (euint256 result, euint256 resultRevealed) {
|
|
36
35
|
euint256 value = inco.newEuint256(uint256EInput, msg.sender);
|
|
37
|
-
|
|
36
|
+
result = addTwo(value);
|
|
37
|
+
|
|
38
38
|
inco.allow(euint256.unwrap(result), address(this));
|
|
39
39
|
inco.allow(euint256.unwrap(result), msg.sender);
|
|
40
40
|
|
|
41
|
-
// Used to test attested reveal functionality.
|
|
42
|
-
|
|
41
|
+
// Used to test attested reveal functionality.
|
|
42
|
+
// Note that msg.sender is not allowed, instead we call .reveal() that gives permission to anyone.
|
|
43
|
+
resultRevealed = addTwoAlt(value);
|
|
43
44
|
inco.reveal(euint256.unwrap(resultRevealed));
|
|
44
|
-
|
|
45
|
-
uint256 requestId = inco.requestDecryption(
|
|
46
|
-
this.callback.selector,
|
|
47
|
-
block.timestamp + 2 hours,
|
|
48
|
-
euint256.unwrap(result),
|
|
49
|
-
""
|
|
50
|
-
);
|
|
51
|
-
return (requestId, result, resultRevealed);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function callback(
|
|
55
|
-
uint256 /* requestId */,
|
|
56
|
-
uint256 result,
|
|
57
|
-
bytes memory /* data */
|
|
58
|
-
) external {
|
|
59
|
-
lastResult = result;
|
|
60
45
|
}
|
|
61
46
|
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// SPDX-License-Identifier: No License
|
|
2
|
+
pragma solidity ^0.8;
|
|
3
|
+
|
|
4
|
+
import {FakeIncoInfraBase} from "./FakeIncoInfraBase.sol";
|
|
5
|
+
import {inco} from "../../Lib.sol";
|
|
6
|
+
import {DecryptionAttestation} from "../../lightning-parts/DecryptionAttester.types.sol";
|
|
7
|
+
import {AllowanceProof} from "../../lightning-parts/AccessControl/AdvancedAccessControl.sol";
|
|
8
|
+
import {SenderNotAllowedForHandle, EOps, ETypes} from "../../Types.sol";
|
|
9
|
+
import {FakeComputeServer} from "./FakeComputeServer.sol";
|
|
10
|
+
|
|
11
|
+
/// @notice simulates the TEE / covalidator offchain API for decryption attestations requests
|
|
12
|
+
/// The signing and checking of the decryption request is out of scope of this simulation, it is assumed that when
|
|
13
|
+
/// called in tests, it emulates the act of a requester emitting a decryption request
|
|
14
|
+
/// One can request decryption attestations on one handle, or on a handle not existing onchain resulting from an
|
|
15
|
+
/// operation on existing handles, or on a mix of existing handles and plaintexts values (which get trivial encrypted)
|
|
16
|
+
/// as long as the handles are allowed for the requester
|
|
17
|
+
contract FakeDecryptionAttester is FakeIncoInfraBase, FakeComputeServer {
|
|
18
|
+
struct HandleWithProof {
|
|
19
|
+
bytes32 handle;
|
|
20
|
+
AllowanceProof proof; // sharer == address(0) means no proof
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// The following 4 functions mimic expected behavior of the TEE / covalidator over offchain API
|
|
24
|
+
|
|
25
|
+
/// @notice request decryption attestation for an existing handle
|
|
26
|
+
function getDecryptionAttestation(
|
|
27
|
+
address requester,
|
|
28
|
+
HandleWithProof memory handle
|
|
29
|
+
)
|
|
30
|
+
internal
|
|
31
|
+
returns (
|
|
32
|
+
DecryptionAttestation memory decryption,
|
|
33
|
+
bytes memory signature
|
|
34
|
+
)
|
|
35
|
+
{
|
|
36
|
+
checkAccessControl(requester, handle);
|
|
37
|
+
(decryption, signature) = _getDecryptionAttestation(
|
|
38
|
+
handle.handle,
|
|
39
|
+
get(handle.handle)
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// The following 3 functions are for requesting decryption over a handle resulting of an operation
|
|
44
|
+
// only binary ops are supported for now (2 params)
|
|
45
|
+
|
|
46
|
+
/// @notice request decryption attestation for a binary operation on 2 existing handles
|
|
47
|
+
function getDecryptionAttestation(
|
|
48
|
+
address requester,
|
|
49
|
+
HandleWithProof memory lhs,
|
|
50
|
+
HandleWithProof memory rhs,
|
|
51
|
+
EOps op
|
|
52
|
+
)
|
|
53
|
+
internal
|
|
54
|
+
returns (
|
|
55
|
+
DecryptionAttestation memory decryption,
|
|
56
|
+
bytes memory signature
|
|
57
|
+
)
|
|
58
|
+
{
|
|
59
|
+
checkAccessControl(requester, lhs);
|
|
60
|
+
checkAccessControl(requester, rhs);
|
|
61
|
+
bytes32 result = computeBinaryOp(get(lhs.handle), get(rhs.handle), op);
|
|
62
|
+
(decryption, signature) = _getDecryptionAttestation(
|
|
63
|
+
lhs.handle,
|
|
64
|
+
rhs.handle,
|
|
65
|
+
result,
|
|
66
|
+
op
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/// @notice request decryption attestation for a binary operation on a handle and a plaintext value (lhs)
|
|
71
|
+
function getDecryptionAttestation(
|
|
72
|
+
address requester,
|
|
73
|
+
uint256 lhs,
|
|
74
|
+
HandleWithProof memory rhs,
|
|
75
|
+
EOps op
|
|
76
|
+
)
|
|
77
|
+
internal
|
|
78
|
+
returns (
|
|
79
|
+
DecryptionAttestation memory decryption,
|
|
80
|
+
bytes memory signature
|
|
81
|
+
)
|
|
82
|
+
{
|
|
83
|
+
checkAccessControl(requester, rhs);
|
|
84
|
+
bytes32 lhsHandle = inco.getTrivialEncryptHandle(
|
|
85
|
+
bytes32(lhs),
|
|
86
|
+
ETypes.Uint256
|
|
87
|
+
);
|
|
88
|
+
bytes32 result = computeBinaryOp(bytes32(lhs), get(rhs.handle), op);
|
|
89
|
+
(decryption, signature) = _getDecryptionAttestation(
|
|
90
|
+
lhsHandle,
|
|
91
|
+
rhs.handle,
|
|
92
|
+
result,
|
|
93
|
+
op
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/// @notice request decryption attestation for a binary operation on a handle and a plaintext value (rhs)
|
|
98
|
+
function getDecryptionAttestation(
|
|
99
|
+
address requester,
|
|
100
|
+
HandleWithProof memory lhs,
|
|
101
|
+
uint256 rhs,
|
|
102
|
+
EOps op
|
|
103
|
+
)
|
|
104
|
+
internal
|
|
105
|
+
returns (
|
|
106
|
+
DecryptionAttestation memory decryption,
|
|
107
|
+
bytes memory signature
|
|
108
|
+
)
|
|
109
|
+
{
|
|
110
|
+
checkAccessControl(requester, lhs);
|
|
111
|
+
bytes32 rhsHandle = inco.getTrivialEncryptHandle(
|
|
112
|
+
bytes32(rhs),
|
|
113
|
+
ETypes.Uint256
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
bytes32 result = computeBinaryOp(get(lhs.handle), bytes32(rhs), op);
|
|
117
|
+
(decryption, signature) = _getDecryptionAttestation(
|
|
118
|
+
lhs.handle,
|
|
119
|
+
rhsHandle,
|
|
120
|
+
result,
|
|
121
|
+
op
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/// Private methods ///
|
|
126
|
+
|
|
127
|
+
function checkAccessControl(
|
|
128
|
+
address requester,
|
|
129
|
+
HandleWithProof memory handle
|
|
130
|
+
) private {
|
|
131
|
+
if (handle.proof.sharer == address(0)) {
|
|
132
|
+
require(
|
|
133
|
+
inco.isAllowed(handle.handle, requester),
|
|
134
|
+
SenderNotAllowedForHandle(handle.handle, requester)
|
|
135
|
+
);
|
|
136
|
+
} else {
|
|
137
|
+
require(
|
|
138
|
+
inco.incoVerifier().isAllowedWithProof(
|
|
139
|
+
handle.handle,
|
|
140
|
+
requester,
|
|
141
|
+
handle.proof
|
|
142
|
+
),
|
|
143
|
+
SenderNotAllowedForHandle(handle.handle, requester)
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function _getDecryptionAttestation(
|
|
149
|
+
bytes32 handle,
|
|
150
|
+
bytes32 value
|
|
151
|
+
)
|
|
152
|
+
private
|
|
153
|
+
view
|
|
154
|
+
returns (
|
|
155
|
+
DecryptionAttestation memory decryption,
|
|
156
|
+
bytes memory signature
|
|
157
|
+
)
|
|
158
|
+
{
|
|
159
|
+
decryption = DecryptionAttestation({handle: handle, value: value});
|
|
160
|
+
signature = signDecryption(decryption);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function signDecryption(
|
|
164
|
+
DecryptionAttestation memory decryption
|
|
165
|
+
) private view returns (bytes memory signature) {
|
|
166
|
+
// todo change this to don't call inco and call verifier directly
|
|
167
|
+
bytes32 digest = inco.incoVerifier().decryptionAttestationDigest(
|
|
168
|
+
decryption
|
|
169
|
+
);
|
|
170
|
+
signature = getSignatureForDigest(digest, teePrivKey);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function _getDecryptionAttestation(
|
|
174
|
+
bytes32 lhsHandle,
|
|
175
|
+
bytes32 rhsHandle,
|
|
176
|
+
bytes32 encodedResult,
|
|
177
|
+
EOps op
|
|
178
|
+
)
|
|
179
|
+
private
|
|
180
|
+
view
|
|
181
|
+
returns (
|
|
182
|
+
DecryptionAttestation memory decryption,
|
|
183
|
+
bytes memory signature
|
|
184
|
+
)
|
|
185
|
+
{
|
|
186
|
+
ETypes resultType = opToResultType(op);
|
|
187
|
+
decryption = DecryptionAttestation({
|
|
188
|
+
handle: inco.getOpResultHandle(
|
|
189
|
+
op,
|
|
190
|
+
resultType,
|
|
191
|
+
lhsHandle,
|
|
192
|
+
rhsHandle
|
|
193
|
+
),
|
|
194
|
+
value: encodedResult
|
|
195
|
+
});
|
|
196
|
+
signature = signDecryption(decryption);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
@@ -3,9 +3,7 @@ pragma solidity ^0.8;
|
|
|
3
3
|
|
|
4
4
|
import {ebool, euint256, ETypes} from "../../Types.sol";
|
|
5
5
|
import {inco} from "../../Lib.sol";
|
|
6
|
-
import {Vm} from "forge-std/Test.sol";
|
|
7
6
|
import {TestUtils} from "@inco/shared/src/TestUtils.sol";
|
|
8
|
-
import {DecryptionResult} from "../../lightning-parts/DecryptionHandler.sol";
|
|
9
7
|
import {KVStore} from "./KVStore.sol";
|
|
10
8
|
|
|
11
9
|
/// @notice simulates what inco does offchain but over plaintexts
|
|
@@ -19,19 +17,6 @@ contract FakeIncoInfraBase is TestUtils, KVStore {
|
|
|
19
17
|
(teePrivKey, teePubkeyAddress) = getLabeledKeyPair("tee");
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
function handleDecryptionRequest(
|
|
23
|
-
uint256 requestId,
|
|
24
|
-
bytes32 handle
|
|
25
|
-
) internal {
|
|
26
|
-
DecryptionResult memory result = DecryptionResult({
|
|
27
|
-
abiEncodedResult: get(handle),
|
|
28
|
-
requestId: requestId,
|
|
29
|
-
handle: handle
|
|
30
|
-
});
|
|
31
|
-
vm.prank(teePubkeyAddress);
|
|
32
|
-
inco.fulfillRequest(result, "");
|
|
33
|
-
}
|
|
34
|
-
|
|
35
20
|
function fakePrepareEuint256Ciphertext(
|
|
36
21
|
uint256 value
|
|
37
22
|
) internal pure returns (bytes memory ciphertext) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: No License
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
|
-
import {IPCCSRouter} from "
|
|
5
|
-
import {Header} from "
|
|
6
|
-
import {IQuoteVerifier} from "automata-
|
|
4
|
+
import {IPCCSRouter} from "../../interfaces/automata-interfaces/IPCCSRouter.sol";
|
|
5
|
+
import {Header} from "../../interfaces/automata-interfaces/Types.sol";
|
|
6
|
+
import {IQuoteVerifier} from "../../interfaces/automata-interfaces/IQuoteVerifier.sol";
|
|
7
7
|
|
|
8
8
|
// This contract is used to test the IncoLightning contract. It is a simple implementation of the QuoteVerifier interface.
|
|
9
9
|
// It is used to test the IncoLightning contract without relying on the real QuoteVerifier contract.
|
|
@@ -18,12 +18,16 @@ contract FakeQuoteVerifier is IQuoteVerifier {
|
|
|
18
18
|
return 4;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
function verifyQuote(
|
|
21
|
+
function verifyQuote(
|
|
22
|
+
Header calldata,
|
|
23
|
+
bytes calldata quote
|
|
24
|
+
) external pure returns (bool, bytes memory) {
|
|
22
25
|
return (true, quote);
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
function verifyZkOutput(
|
|
28
|
+
function verifyZkOutput(
|
|
29
|
+
bytes calldata quote
|
|
30
|
+
) external pure returns (bool, bytes memory) {
|
|
26
31
|
return (true, quote);
|
|
27
32
|
}
|
|
28
|
-
|
|
29
33
|
}
|
|
@@ -4,7 +4,6 @@ pragma solidity ^0.8;
|
|
|
4
4
|
import {Vm} from "forge-std/Test.sol";
|
|
5
5
|
import {inco} from "../../Lib.sol";
|
|
6
6
|
import {ebool, euint256, ETypes, EOps} from "../../Types.sol";
|
|
7
|
-
import {DecryptionRequested} from "../../lightning-parts/DecryptionHandler.sol";
|
|
8
7
|
import {FakeComputeServer} from "./FakeComputeServer.sol";
|
|
9
8
|
import {FakeIncoInfraBase} from "./FakeIncoInfraBase.sol";
|
|
10
9
|
import {asBytes32} from "@inco/shared/src/TypeUtils.sol";
|
|
@@ -71,12 +70,6 @@ contract MockOpHandler is FakeIncoInfraBase, FakeComputeServer {
|
|
|
71
70
|
(ETypes, bytes, uint256)
|
|
72
71
|
);
|
|
73
72
|
handleEInput(result, inputType, ciphertext);
|
|
74
|
-
} else if (op == EOps.DecryptionRequested) {
|
|
75
|
-
uint256 requestId = uint256(log.topics[1]);
|
|
76
|
-
bytes32 handle = log.topics[2];
|
|
77
|
-
// other fields ignored for now
|
|
78
|
-
// todo cheats to trigger decryption later
|
|
79
|
-
handleDecryptionRequest(requestId, handle);
|
|
80
73
|
}
|
|
81
74
|
}
|
|
82
75
|
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
4
|
import {TestUtils} from "@inco/shared/src/TestUtils.sol";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
import {
|
|
6
|
+
HEADER_LENGTH,
|
|
7
|
+
MINIMUM_QUOTE_LENGTH,
|
|
8
|
+
TDX_TEE
|
|
9
|
+
} from "../../interfaces/automata-interfaces/Types.sol";
|
|
9
10
|
|
|
10
11
|
contract MockRemoteAttestation is TestUtils {
|
|
11
12
|
function createQuote(
|
|
@@ -31,7 +32,18 @@ contract MockRemoteAttestation is TestUtils {
|
|
|
31
32
|
bytes memory prefix = new bytes(HEADER_LENGTH + 136 - 8);
|
|
32
33
|
bytes memory middle = new bytes(520 - 184);
|
|
33
34
|
bytes memory reportDataSuffix = new bytes(44);
|
|
34
|
-
bytes memory suffix = new bytes(
|
|
35
|
-
|
|
35
|
+
bytes memory suffix = new bytes(
|
|
36
|
+
MINIMUM_QUOTE_LENGTH - HEADER_LENGTH - 584
|
|
37
|
+
);
|
|
38
|
+
quote = abi.encodePacked(
|
|
39
|
+
version,
|
|
40
|
+
tdxTEEType,
|
|
41
|
+
prefix,
|
|
42
|
+
mrtd,
|
|
43
|
+
middle,
|
|
44
|
+
abi.encodePacked(signer),
|
|
45
|
+
reportDataSuffix,
|
|
46
|
+
suffix
|
|
47
|
+
);
|
|
36
48
|
}
|
|
37
|
-
}
|
|
49
|
+
}
|