@inco/lightning 0.6.8 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +29 -2
- package/manifest.yaml +35 -42
- package/package.json +5 -2
- package/src/CreateXHelper.sol +3 -1
- package/src/DeployUtils.sol +36 -71
- package/src/Errors.sol +1 -1
- package/src/IIncoLightning.sol +2 -0
- package/src/IncoLightning.sol +5 -17
- package/src/IncoVerifier.sol +12 -18
- package/src/Lib.alphanet.sol +1 -1
- package/src/Lib.sol +1 -1
- package/src/Lib.template.sol +35 -153
- package/src/Types.sol +231 -97
- package/src/interfaces/IIncoLightning.sol +2 -0
- package/src/interfaces/IIncoVerifier.sol +6 -12
- package/src/interfaces/automata-interfaces/BELE.sol +2 -0
- package/src/interfaces/automata-interfaces/IAutomataEnclaveIdentityDao.sol +9 -11
- package/src/interfaces/automata-interfaces/IFmspcTcbDao.sol +3 -3
- package/src/interfaces/automata-interfaces/IPCCSRouter.sol +13 -47
- package/src/interfaces/automata-interfaces/IPCCSRouterExtended.sol +2 -0
- package/src/interfaces/automata-interfaces/IPcsDao.sol +6 -11
- package/src/interfaces/automata-interfaces/IQuoteVerifier.sol +4 -7
- package/src/interfaces/automata-interfaces/Types.sol +7 -6
- package/src/libs/incoLightning_alphanet_v2_976644394.sol +478 -0
- package/src/libs/incoLightning_devnet_v1_887305889.sol +5 -3
- package/src/libs/incoLightning_testnet_v1_938327937.sol +5 -3
- package/src/lightning-parts/AccessControl/AdvancedAccessControl.sol +39 -72
- package/src/lightning-parts/AccessControl/BaseAccessControlList.sol +31 -62
- package/src/lightning-parts/AccessControl/interfaces/IAdvancedAccessControl.sol +8 -15
- package/src/lightning-parts/AccessControl/interfaces/IBaseAccessControlList.sol +5 -12
- package/src/lightning-parts/AccessControl/test/TestAdvancedAccessControl.t.sol +44 -84
- package/src/lightning-parts/AccessControl/test/TestBaseAccessControl.t.sol +2 -0
- package/src/lightning-parts/DecryptionAttester.sol +14 -28
- package/src/lightning-parts/EncryptedInput.sol +23 -52
- package/src/lightning-parts/EncryptedOperations.sol +96 -438
- package/src/lightning-parts/Fee.sol +3 -1
- package/src/lightning-parts/TEELifecycle.sol +94 -223
- package/src/lightning-parts/TEELifecycle.types.sol +4 -3
- package/src/lightning-parts/TrivialEncryption.sol +6 -20
- package/src/lightning-parts/interfaces/IDecryptionAttester.sol +7 -2
- package/src/lightning-parts/interfaces/IEncryptedInput.sol +5 -12
- package/src/lightning-parts/interfaces/IEncryptedOperations.sol +17 -61
- package/src/lightning-parts/interfaces/ITEELifecycle.sol +7 -11
- package/src/lightning-parts/interfaces/ITrivialEncryption.sol +2 -0
- package/src/lightning-parts/primitives/EventCounter.sol +7 -8
- package/src/lightning-parts/primitives/HandleGeneration.sol +20 -32
- package/src/lightning-parts/primitives/HandleMetadata.sol +7 -17
- package/src/lightning-parts/primitives/LightningAddressGetter.sol +3 -0
- package/src/lightning-parts/primitives/SignatureVerifier.sol +91 -27
- package/src/lightning-parts/primitives/VerifierAddressGetter.sol +3 -0
- package/src/lightning-parts/primitives/interfaces/IEventCounter.sol +2 -0
- package/src/lightning-parts/primitives/interfaces/IHandleGeneration.sol +10 -2
- package/src/lightning-parts/primitives/interfaces/ISignatureVerifier.sol +4 -2
- package/src/lightning-parts/primitives/interfaces/IVerifierAddressGetter.sol +2 -0
- package/src/lightning-parts/primitives/test/SignatureVerifier.t.sol +838 -0
- package/src/lightning-parts/test/Fee.t.sol +6 -6
- package/src/lightning-parts/test/HandleMetadata.t.sol +21 -76
- package/src/lightning-parts/test/InputsFee.t.sol +7 -28
- package/src/lightning-parts/test/TestDecryptionAttestationInSynchronousFlow.t.sol +16 -48
- package/src/pasted-dependencies/CreateX.sol +154 -455
- package/src/pasted-dependencies/ICreateX.sol +55 -102
- package/src/periphery/SessionVerifier.sol +10 -8
- package/src/shared/IOwnable.sol +3 -0
- package/src/shared/IUUPSUpgradable.sol +5 -1
- package/src/shared/JsonUtils.sol +3 -5
- package/src/shared/TestUtils.sol +15 -13
- package/src/test/AddTwo.sol +9 -7
- package/src/test/FakeIncoInfra/FakeComputeServer.sol +11 -53
- package/src/test/FakeIncoInfra/FakeDecryptionAttester.sol +35 -119
- package/src/test/FakeIncoInfra/FakeIncoInfraBase.sol +31 -48
- package/src/test/FakeIncoInfra/FakeQuoteVerifier.sol +4 -7
- package/src/test/FakeIncoInfra/KVStore.sol +2 -0
- package/src/test/FakeIncoInfra/MockOpHandler.sol +9 -31
- package/src/test/FakeIncoInfra/MockRemoteAttestation.sol +50 -21
- package/src/test/IncoTest.sol +22 -9
- package/src/test/OpsTest.sol +438 -0
- package/src/test/TEELifecycle/TEELifecycleMockTest.t.sol +57 -104
- package/src/test/TestAddTwo.t.sol +4 -3
- package/src/test/TestDeploy.t.sol +5 -6
- package/src/test/TestExtractDataOfEventTooLarge.t.sol +7 -9
- package/src/test/TestFakeInfra.t.sol +15 -38
- package/src/test/TestUpgrade.t.sol +40 -135
- package/src/test/TestVersion.t.sol +6 -5
- package/src/version/IncoLightningConfig.sol +2 -2
- package/src/version/Version.sol +46 -48
- package/src/version/interfaces/IVersion.sol +6 -0
|
@@ -4,75 +4,31 @@ pragma solidity ^0.8;
|
|
|
4
4
|
import {euint256, ebool, ETypes} from "../../Types.sol";
|
|
5
5
|
|
|
6
6
|
interface IEncryptedOperations {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
) external returns (euint256 result);
|
|
11
|
-
function
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
) external returns (euint256 result);
|
|
15
|
-
function eMul(
|
|
16
|
-
euint256 lhs,
|
|
17
|
-
euint256 rhs
|
|
18
|
-
) external returns (euint256 result);
|
|
19
|
-
function eDiv(
|
|
20
|
-
euint256 lhs,
|
|
21
|
-
euint256 rhs
|
|
22
|
-
) external returns (euint256 result);
|
|
23
|
-
function eRem(
|
|
24
|
-
euint256 lhs,
|
|
25
|
-
euint256 rhs
|
|
26
|
-
) external returns (euint256 result);
|
|
27
|
-
function eBitAnd(
|
|
28
|
-
bytes32 lhs,
|
|
29
|
-
bytes32 rhs
|
|
30
|
-
) external returns (bytes32 result);
|
|
7
|
+
|
|
8
|
+
function eAdd(euint256 lhs, euint256 rhs) external returns (euint256 result);
|
|
9
|
+
function eSub(euint256 lhs, euint256 rhs) external returns (euint256 result);
|
|
10
|
+
function eMul(euint256 lhs, euint256 rhs) external returns (euint256 result);
|
|
11
|
+
function eDiv(euint256 lhs, euint256 rhs) external returns (euint256 result);
|
|
12
|
+
function eRem(euint256 lhs, euint256 rhs) external returns (euint256 result);
|
|
13
|
+
function eBitAnd(bytes32 lhs, bytes32 rhs) external returns (bytes32 result);
|
|
31
14
|
function eBitOr(bytes32 lhs, bytes32 rhs) external returns (bytes32 result);
|
|
32
|
-
function eBitXor(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
) external returns (
|
|
36
|
-
function
|
|
37
|
-
euint256 lhs,
|
|
38
|
-
euint256 rhs
|
|
39
|
-
) external returns (euint256 result);
|
|
40
|
-
function eShr(
|
|
41
|
-
euint256 lhs,
|
|
42
|
-
euint256 rhs
|
|
43
|
-
) external returns (euint256 result);
|
|
44
|
-
function eRotl(
|
|
45
|
-
euint256 lhs,
|
|
46
|
-
euint256 rhs
|
|
47
|
-
) external returns (euint256 result);
|
|
48
|
-
function eRotr(
|
|
49
|
-
euint256 lhs,
|
|
50
|
-
euint256 rhs
|
|
51
|
-
) external returns (euint256 result);
|
|
15
|
+
function eBitXor(bytes32 lhs, bytes32 rhs) external returns (bytes32 result);
|
|
16
|
+
function eShl(euint256 lhs, euint256 rhs) external returns (euint256 result);
|
|
17
|
+
function eShr(euint256 lhs, euint256 rhs) external returns (euint256 result);
|
|
18
|
+
function eRotl(euint256 lhs, euint256 rhs) external returns (euint256 result);
|
|
19
|
+
function eRotr(euint256 lhs, euint256 rhs) external returns (euint256 result);
|
|
52
20
|
function eEq(bytes32 lhs, bytes32 rhs) external returns (ebool result);
|
|
53
21
|
function eNe(bytes32 lhs, bytes32 rhs) external returns (ebool result);
|
|
54
22
|
function eGe(euint256 lhs, euint256 rhs) external returns (ebool result);
|
|
55
23
|
function eGt(euint256 lhs, euint256 rhs) external returns (ebool result);
|
|
56
24
|
function eLe(euint256 lhs, euint256 rhs) external returns (ebool result);
|
|
57
25
|
function eLt(euint256 lhs, euint256 rhs) external returns (ebool result);
|
|
58
|
-
function eMin(
|
|
59
|
-
|
|
60
|
-
euint256 rhs
|
|
61
|
-
) external returns (euint256 result);
|
|
62
|
-
function eMax(
|
|
63
|
-
euint256 lhs,
|
|
64
|
-
euint256 rhs
|
|
65
|
-
) external returns (euint256 result);
|
|
26
|
+
function eMin(euint256 lhs, euint256 rhs) external returns (euint256 result);
|
|
27
|
+
function eMax(euint256 lhs, euint256 rhs) external returns (euint256 result);
|
|
66
28
|
function eNot(ebool operand) external returns (ebool result);
|
|
67
29
|
function eCast(bytes32 ct, ETypes toType) external returns (bytes32 result);
|
|
68
30
|
function eRand(ETypes randType) external payable returns (bytes32 result);
|
|
69
|
-
function eRandBounded(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
) external payable returns (bytes32 result);
|
|
73
|
-
function eIfThenElse(
|
|
74
|
-
ebool condition,
|
|
75
|
-
bytes32 ifTrue,
|
|
76
|
-
bytes32 ifFalse
|
|
77
|
-
) external returns (bytes32 result);
|
|
31
|
+
function eRandBounded(bytes32 upperBound, ETypes randType) external payable returns (bytes32 result);
|
|
32
|
+
function eIfThenElse(ebool condition, bytes32 ifTrue, bytes32 ifFalse) external returns (bytes32 result);
|
|
33
|
+
|
|
78
34
|
}
|
|
@@ -3,9 +3,10 @@ pragma solidity ^0.8.19;
|
|
|
3
3
|
|
|
4
4
|
import {BootstrapResult, UpgradeResult, AddNodeResult} from "../TEELifecycle.types.sol";
|
|
5
5
|
import {IQuoteVerifier} from "../../interfaces/automata-interfaces/IQuoteVerifier.sol";
|
|
6
|
-
import {
|
|
6
|
+
import {Td10ReportBody} from "../../interfaces/automata-interfaces/Types.sol";
|
|
7
7
|
|
|
8
8
|
interface ITEELifecycle {
|
|
9
|
+
|
|
9
10
|
function verifyBootstrapResult(
|
|
10
11
|
BootstrapResult calldata bootstrapResult,
|
|
11
12
|
bytes calldata quote,
|
|
@@ -23,15 +24,10 @@ interface ITEELifecycle {
|
|
|
23
24
|
bytes calldata quote,
|
|
24
25
|
bytes calldata signature
|
|
25
26
|
) external;
|
|
26
|
-
function
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
) external
|
|
30
|
-
function parseReport(
|
|
31
|
-
TD10ReportBody memory tdReport
|
|
32
|
-
) external pure returns (address, bytes32);
|
|
33
|
-
function bootstrapResultDigest(
|
|
34
|
-
BootstrapResult memory bootstrapResult
|
|
35
|
-
) external view returns (bytes32);
|
|
27
|
+
function approveNewTeeVersion(bytes32 newMrAggregated) external;
|
|
28
|
+
function parseTd10ReportBody(bytes calldata rawQuote) external pure returns (Td10ReportBody memory report);
|
|
29
|
+
function parseReport(Td10ReportBody memory tdReport) external pure returns (address, bytes32);
|
|
30
|
+
function bootstrapResultDigest(BootstrapResult memory bootstrapResult) external view returns (bytes32);
|
|
36
31
|
function quoteVerifier() external view returns (IQuoteVerifier);
|
|
32
|
+
|
|
37
33
|
}
|
|
@@ -4,7 +4,9 @@ pragma solidity ^0.8;
|
|
|
4
4
|
import {euint256, ebool, eaddress} from "../../Types.sol";
|
|
5
5
|
|
|
6
6
|
interface ITrivialEncryption {
|
|
7
|
+
|
|
7
8
|
function asEuint256(uint256 value) external returns (euint256 newEuint256);
|
|
8
9
|
function asEbool(bool value) external returns (ebool newEbool);
|
|
9
10
|
function asEaddress(address value) external returns (eaddress newEaddress);
|
|
11
|
+
|
|
10
12
|
}
|
|
@@ -4,27 +4,25 @@ pragma solidity ^0.8;
|
|
|
4
4
|
import {IEventCounter} from "./interfaces/IEventCounter.sol";
|
|
5
5
|
|
|
6
6
|
contract EventCounterStorage {
|
|
7
|
+
|
|
7
8
|
struct Storage {
|
|
8
9
|
// TODO: change type to bytes32 when we rename away from "counter".
|
|
9
10
|
uint256 eventCounter;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
bytes32 private constant
|
|
13
|
-
keccak256("lightning.storage.EventCounter");
|
|
13
|
+
bytes32 private constant EVENT_COUNTER_STORAGE_LOCATION = keccak256("lightning.storage.EventCounter");
|
|
14
14
|
|
|
15
|
-
function getEventCounterStorage()
|
|
16
|
-
|
|
17
|
-
pure
|
|
18
|
-
returns (Storage storage $)
|
|
19
|
-
{
|
|
20
|
-
bytes32 loc = eventCounterStorageLocation;
|
|
15
|
+
function getEventCounterStorage() internal pure returns (Storage storage $) {
|
|
16
|
+
bytes32 loc = EVENT_COUNTER_STORAGE_LOCATION;
|
|
21
17
|
assembly {
|
|
22
18
|
$.slot := loc
|
|
23
19
|
}
|
|
24
20
|
}
|
|
21
|
+
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
contract EventCounter is IEventCounter, EventCounterStorage {
|
|
25
|
+
|
|
28
26
|
function getNewEventId() internal returns (uint256 newEventId) {
|
|
29
27
|
newEventId = getEventCounterStorage().eventCounter++;
|
|
30
28
|
}
|
|
@@ -43,4 +41,5 @@ contract EventCounter is IEventCounter, EventCounterStorage {
|
|
|
43
41
|
function getEventCounter() public view returns (uint256) {
|
|
44
42
|
return getNextEventId();
|
|
45
43
|
}
|
|
44
|
+
|
|
46
45
|
}
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
// SPDX-License-Identifier: No License
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
ETypes,
|
|
6
|
-
EOps,
|
|
7
|
-
EVM_HOST_CHAIN_PREFIX,
|
|
8
|
-
HANDLE_INDEX
|
|
9
|
-
} from "../../Types.sol";
|
|
4
|
+
import {ETypes, EOps, EVM_HOST_CHAIN_PREFIX, HANDLE_INDEX} from "../../Types.sol";
|
|
10
5
|
import {HandleMetadata} from "./HandleMetadata.sol";
|
|
11
6
|
import {IHandleGeneration} from "./interfaces/IHandleGeneration.sol";
|
|
12
7
|
|
|
13
8
|
contract HandleGeneration is IHandleGeneration, HandleMetadata {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
|
|
10
|
+
function getTrivialEncryptHandle(bytes32 plaintextBytes, ETypes handleType)
|
|
11
|
+
public
|
|
12
|
+
pure
|
|
13
|
+
returns (bytes32 generatedHandle)
|
|
14
|
+
{
|
|
18
15
|
generatedHandle = keccak256(
|
|
19
16
|
abi.encodePacked(
|
|
20
17
|
EOps.TrivialEncrypt, // !! Note[Silas]: I reordered this to be first element for greater regularity 26/08/2025 (remove this note after 1 month) !!
|
|
@@ -24,20 +21,12 @@ contract HandleGeneration is IHandleGeneration, HandleMetadata {
|
|
|
24
21
|
generatedHandle = embedTypeVersion(generatedHandle, handleType);
|
|
25
22
|
}
|
|
26
23
|
|
|
27
|
-
function getInputHandle(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return
|
|
34
|
-
getInputHandle(
|
|
35
|
-
ciphertext,
|
|
36
|
-
address(this),
|
|
37
|
-
user,
|
|
38
|
-
contractAddress,
|
|
39
|
-
inputType
|
|
40
|
-
);
|
|
24
|
+
function getInputHandle(bytes memory ciphertext, address user, address contractAddress, ETypes inputType)
|
|
25
|
+
internal
|
|
26
|
+
view
|
|
27
|
+
returns (bytes32 generatedHandle)
|
|
28
|
+
{
|
|
29
|
+
return getInputHandle(ciphertext, address(this), user, contractAddress, inputType);
|
|
41
30
|
}
|
|
42
31
|
|
|
43
32
|
function getInputHandle(
|
|
@@ -49,9 +38,7 @@ contract HandleGeneration is IHandleGeneration, HandleMetadata {
|
|
|
49
38
|
) internal view returns (bytes32 generatedHandle) {
|
|
50
39
|
// Here we ensure that our hashing scheme is binary-compatible between IncoLightning and IncoFhevm, this helps
|
|
51
40
|
// keep client-side code consistent in its ciphertext, context => handle mappings
|
|
52
|
-
bytes32 ctIndexHash = keccak256(
|
|
53
|
-
abi.encodePacked(keccak256(ciphertext), HANDLE_INDEX)
|
|
54
|
-
);
|
|
41
|
+
bytes32 ctIndexHash = keccak256(abi.encodePacked(keccak256(ciphertext), HANDLE_INDEX));
|
|
55
42
|
bytes32 prehandle = embedIndexTypeVersion(ctIndexHash, inputType);
|
|
56
43
|
// We must also propagate the handle metadata to the final handle
|
|
57
44
|
generatedHandle = embedIndexTypeVersion(
|
|
@@ -69,11 +56,12 @@ contract HandleGeneration is IHandleGeneration, HandleMetadata {
|
|
|
69
56
|
);
|
|
70
57
|
}
|
|
71
58
|
|
|
72
|
-
function getOpResultHandle(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
59
|
+
function getOpResultHandle(EOps op, ETypes returnType, bytes memory packedInputs)
|
|
60
|
+
public
|
|
61
|
+
pure
|
|
62
|
+
returns (bytes32 generatedHandle)
|
|
63
|
+
{
|
|
77
64
|
generatedHandle = embedTypeVersion(keccak256(abi.encodePacked(op, packedInputs)), returnType);
|
|
78
65
|
}
|
|
66
|
+
|
|
79
67
|
}
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
// SPDX-License-Identifier: No License
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {HANDLE_VERSION, HANDLE_INDEX, ETypes} from "../../Types.sol";
|
|
5
5
|
|
|
6
6
|
contract HandleMetadata {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
ETypes inputType
|
|
10
|
-
) internal pure returns (bytes32 result) {
|
|
7
|
+
|
|
8
|
+
function embedIndexTypeVersion(bytes32 prehandle, ETypes inputType) internal pure returns (bytes32 result) {
|
|
11
9
|
// Create a mask to clear the last three bytes
|
|
12
|
-
bytes32 mask = bytes32(
|
|
13
|
-
uint256(
|
|
14
|
-
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF
|
|
15
|
-
)
|
|
16
|
-
);
|
|
10
|
+
bytes32 mask = bytes32(uint256(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF));
|
|
17
11
|
// Clear the last three bytes of the original value
|
|
18
12
|
bytes32 clearedOriginal = prehandle & mask;
|
|
19
13
|
// Combine the cleared original value with the new last three bytes
|
|
@@ -21,13 +15,8 @@ contract HandleMetadata {
|
|
|
21
15
|
result = embedTypeVersion(result, inputType);
|
|
22
16
|
}
|
|
23
17
|
|
|
24
|
-
function embedTypeVersion(
|
|
25
|
-
|
|
26
|
-
ETypes handleType
|
|
27
|
-
) internal pure returns (bytes32 result) {
|
|
28
|
-
result =
|
|
29
|
-
prehandle &
|
|
30
|
-
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000;
|
|
18
|
+
function embedTypeVersion(bytes32 prehandle, ETypes handleType) internal pure returns (bytes32 result) {
|
|
19
|
+
result = prehandle & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000;
|
|
31
20
|
result = bytes32(uint256(result) | (uint256(handleType) << 8)); // append type
|
|
32
21
|
result = bytes32(uint256(result) | HANDLE_VERSION);
|
|
33
22
|
}
|
|
@@ -35,4 +24,5 @@ contract HandleMetadata {
|
|
|
35
24
|
function typeOf(bytes32 handle) internal pure returns (ETypes) {
|
|
36
25
|
return ETypes(uint8(uint256(handle) >> 8));
|
|
37
26
|
}
|
|
27
|
+
|
|
38
28
|
}
|
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
4
|
abstract contract LightningAddressGetter {
|
|
5
|
+
|
|
6
|
+
// forge-lint: disable-next-line(screaming-snake-case-immutable)
|
|
5
7
|
address internal immutable incoLightningAddress;
|
|
6
8
|
|
|
7
9
|
constructor(address _incoLightningAddress) {
|
|
8
10
|
incoLightningAddress = _incoLightningAddress;
|
|
9
11
|
}
|
|
12
|
+
|
|
10
13
|
}
|
|
@@ -4,64 +4,128 @@ pragma solidity ^0.8;
|
|
|
4
4
|
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
|
5
5
|
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
|
|
6
6
|
import {ISignatureVerifier} from "./interfaces/ISignatureVerifier.sol";
|
|
7
|
-
import {TEELifecycle} from "../TEELifecycle.sol";
|
|
8
7
|
|
|
9
8
|
contract SignatureVerifierStorage {
|
|
9
|
+
|
|
10
10
|
struct StorageForSigVerifier {
|
|
11
|
+
address[] signers;
|
|
11
12
|
mapping(address => bool) isSigner;
|
|
13
|
+
uint256 threshold;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
// State changelog:
|
|
15
17
|
// 0.2.0: Shifting state location to support multiple signers
|
|
16
|
-
bytes32 private constant
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
internal
|
|
21
|
-
pure
|
|
22
|
-
returns (StorageForSigVerifier storage $)
|
|
23
|
-
{
|
|
24
|
-
bytes32 loc = SignatureVerifierStorageLocation;
|
|
18
|
+
bytes32 private constant SIGNATURE_VERIFIER_STORAGE_LOCATION = keccak256("inco.storage.SignatureVerifier.v0.2.0");
|
|
19
|
+
|
|
20
|
+
function getSigVerifierStorage() internal pure returns (StorageForSigVerifier storage $) {
|
|
21
|
+
bytes32 loc = SIGNATURE_VERIFIER_STORAGE_LOCATION;
|
|
25
22
|
assembly {
|
|
26
23
|
$.slot := loc
|
|
27
24
|
}
|
|
28
25
|
}
|
|
26
|
+
|
|
29
27
|
}
|
|
30
28
|
|
|
31
29
|
abstract contract SignatureVerifier is ISignatureVerifier, OwnableUpgradeable, SignatureVerifierStorage {
|
|
30
|
+
|
|
31
|
+
// we use ECDSA as the signers are meant to be EOAs controlled by TEEs, and no smart contract wallet
|
|
32
32
|
using ECDSA for bytes32;
|
|
33
33
|
|
|
34
34
|
error SignerNotFound(address signerAddress);
|
|
35
|
+
error SignerAlreadyAdded(address signerAddress);
|
|
36
|
+
error InvalidThreshold(uint256 threshold, uint256 nbOfSigners);
|
|
37
|
+
error SignersNotInAscendingOrder(address currentSigner, address lastSigner);
|
|
35
38
|
|
|
36
39
|
event AddedSignatureVerifier(address signerAddress);
|
|
37
40
|
event RemovedSignatureVerifier(address signerAddress);
|
|
41
|
+
event ThresholdChanged(uint256 oldThreshold, uint256 newThreshold);
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
function addSigner(address signerAddress)
|
|
41
|
-
getSigVerifierStorage()
|
|
43
|
+
/// @dev internal sensible function, should be used only as part of an onlyOwner function / access controlled
|
|
44
|
+
function addSigner(address signerAddress) internal {
|
|
45
|
+
StorageForSigVerifier storage $ = getSigVerifierStorage();
|
|
46
|
+
require(!isSigner(signerAddress), SignerAlreadyAdded(signerAddress));
|
|
47
|
+
$.signers.push(signerAddress);
|
|
48
|
+
$.isSigner[signerAddress] = true;
|
|
42
49
|
emit AddedSignatureVerifier(signerAddress);
|
|
43
50
|
}
|
|
44
51
|
|
|
45
|
-
// @todo: This function should be removed once we have a way to read the signers from the TEELifecycle contract
|
|
46
52
|
function removeSigner(address signerAddress) external onlyOwner {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
StorageForSigVerifier storage $ = getSigVerifierStorage();
|
|
54
|
+
require(isSigner(signerAddress), SignerNotFound(signerAddress));
|
|
55
|
+
require($.signers.length - 1 >= $.threshold, InvalidThreshold($.threshold, $.signers.length - 1));
|
|
56
|
+
|
|
57
|
+
// Find and remove the signer from the array
|
|
58
|
+
for (uint256 i = 0; i < $.signers.length; i++) {
|
|
59
|
+
if ($.signers[i] == signerAddress) {
|
|
60
|
+
// Move the last element to this position and pop
|
|
61
|
+
$.signers[i] = $.signers[$.signers.length - 1];
|
|
62
|
+
$.signers.pop();
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
$.isSigner[signerAddress] = false;
|
|
68
|
+
emit RemovedSignatureVerifier(signerAddress);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function setThreshold(uint256 newThreshold) external onlyOwner {
|
|
72
|
+
StorageForSigVerifier storage $ = getSigVerifierStorage();
|
|
73
|
+
require(newThreshold <= $.signers.length, InvalidThreshold(newThreshold, $.signers.length));
|
|
74
|
+
require(newThreshold > 0, InvalidThreshold(newThreshold, $.signers.length));
|
|
75
|
+
|
|
76
|
+
uint256 oldThreshold = $.threshold;
|
|
77
|
+
$.threshold = newThreshold;
|
|
78
|
+
emit ThresholdChanged(oldThreshold, newThreshold);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function getThreshold() public view returns (uint256) {
|
|
82
|
+
return getSigVerifierStorage().threshold;
|
|
53
83
|
}
|
|
54
84
|
|
|
55
|
-
// @todo: This function should read from the TEELifecycle contract instead of the storage
|
|
56
85
|
function isSigner(address signerAddress) public view returns (bool) {
|
|
57
86
|
return getSigVerifierStorage().isSigner[signerAddress];
|
|
58
87
|
}
|
|
59
88
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
) public view returns (bool) {
|
|
64
|
-
address signerAddress = hash.recover(signature);
|
|
65
|
-
return getSigVerifierStorage().isSigner[signerAddress];
|
|
89
|
+
/// @dev each signer id is NOT fixed, it can change over time, be removed, readded, etc.
|
|
90
|
+
function getSignerAtIndex(uint256 index) public view returns (address) {
|
|
91
|
+
return getSigVerifierStorage().signers[index];
|
|
66
92
|
}
|
|
93
|
+
|
|
94
|
+
function getSignersCount() public view returns (uint256) {
|
|
95
|
+
return getSigVerifierStorage().signers.length;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/// @dev signature signers MUST be in ascending order, reverts with SignersNotInAscendingOrder if not
|
|
99
|
+
/// @dev signatures beyond the threshold are ignored
|
|
100
|
+
function isValidSignature(bytes32 digest, bytes[] memory signatures) public view returns (bool) {
|
|
101
|
+
StorageForSigVerifier storage $ = getSigVerifierStorage();
|
|
102
|
+
uint256 threshold = $.threshold;
|
|
103
|
+
uint256 signaturesLength = signatures.length;
|
|
104
|
+
|
|
105
|
+
// if threshold is 0, we can't accept any signatures yet
|
|
106
|
+
if (threshold == 0 || signaturesLength < threshold) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
address lastSigner = address(0);
|
|
111
|
+
uint256 correctSignaturesCount = 0;
|
|
112
|
+
uint256 i = 0;
|
|
113
|
+
|
|
114
|
+
while (correctSignaturesCount < threshold && i < signaturesLength) {
|
|
115
|
+
address currentSigner = digest.recover(signatures[i]);
|
|
116
|
+
|
|
117
|
+
// Ensure signers are in ascending order to prevent duplicates
|
|
118
|
+
// Revert is used instead of return false to signal the user/developer an error (call malformed) is on his side
|
|
119
|
+
require(currentSigner > lastSigner, SignersNotInAscendingOrder(currentSigner, lastSigner));
|
|
120
|
+
lastSigner = currentSigner;
|
|
121
|
+
|
|
122
|
+
if (isSigner(currentSigner)) {
|
|
123
|
+
correctSignaturesCount++;
|
|
124
|
+
}
|
|
125
|
+
i++;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return correctSignaturesCount >= threshold;
|
|
129
|
+
}
|
|
130
|
+
|
|
67
131
|
}
|
|
@@ -5,9 +5,12 @@ import {IIncoVerifier} from "../../interfaces/IIncoVerifier.sol";
|
|
|
5
5
|
import {IVerifierAddressGetter} from "./interfaces/IVerifierAddressGetter.sol";
|
|
6
6
|
|
|
7
7
|
abstract contract VerifierAddressGetter is IVerifierAddressGetter {
|
|
8
|
+
|
|
9
|
+
// forge-lint: disable-next-line(screaming-snake-case-immutable)
|
|
8
10
|
IIncoVerifier public immutable incoVerifier;
|
|
9
11
|
|
|
10
12
|
constructor(address _incoVerifier) {
|
|
11
13
|
incoVerifier = IIncoVerifier(_incoVerifier);
|
|
12
14
|
}
|
|
15
|
+
|
|
13
16
|
}
|
|
@@ -4,7 +4,15 @@ pragma solidity ^0.8;
|
|
|
4
4
|
import {ETypes, EOps} from "../../../Types.sol";
|
|
5
5
|
|
|
6
6
|
interface IHandleGeneration {
|
|
7
|
-
function getTrivialEncryptHandle(bytes32 plaintextBytes, ETypes handleType) external view returns (bytes32 generatedHandle);
|
|
8
7
|
|
|
9
|
-
function
|
|
8
|
+
function getTrivialEncryptHandle(bytes32 plaintextBytes, ETypes handleType)
|
|
9
|
+
external
|
|
10
|
+
view
|
|
11
|
+
returns (bytes32 generatedHandle);
|
|
12
|
+
|
|
13
|
+
function getOpResultHandle(EOps op, ETypes returnType, bytes memory packedInputs)
|
|
14
|
+
external
|
|
15
|
+
pure
|
|
16
|
+
returns (bytes32 generatedHandle);
|
|
17
|
+
|
|
10
18
|
}
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
4
|
interface ISignatureVerifier {
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
function removeSigner(address signerAddress) external;
|
|
7
7
|
function isSigner(address signerAddress) external view returns (bool);
|
|
8
|
-
function isValidSignature(bytes32 hash, bytes memory
|
|
8
|
+
function isValidSignature(bytes32 hash, bytes[] memory signatures) external view returns (bool);
|
|
9
|
+
function setThreshold(uint256 newThreshold) external;
|
|
10
|
+
|
|
9
11
|
}
|