@inco/lightning 0.8.0-devnet-28 → 0.8.0-devnet-30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/manifest.yaml +17 -0
- package/package.json +1 -1
- package/src/DeployUtils.sol +22 -28
- package/src/Lib.alphanet.sol +28 -2
- package/src/Lib.demonet.sol +28 -2
- package/src/Lib.devnet.sol +28 -2
- package/src/Lib.sol +28 -2
- package/src/Lib.template.sol +46 -2
- package/src/Lib.testnet.sol +28 -2
- package/src/Types.sol +3 -0
- package/src/libs/incoLightning_alphanet_v0_297966649.sol +28 -2
- package/src/libs/incoLightning_alphanet_v1_725458969.sol +28 -2
- package/src/libs/incoLightning_alphanet_v2_976644394.sol +28 -2
- package/src/libs/incoLightning_demonet_v0_863421733.sol +28 -2
- package/src/libs/incoLightning_demonet_v2_467437523.sol +28 -2
- package/src/libs/incoLightning_devnet_v0_340846814.sol +28 -2
- package/src/libs/incoLightning_devnet_v1_904635675.sol +28 -2
- package/src/libs/incoLightning_devnet_v2_295237520.sol +28 -2
- package/src/libs/incoLightning_devnet_v3_976859633.sol +28 -2
- package/src/libs/incoLightning_devnet_v4_409204766.sol +28 -2
- package/src/libs/incoLightning_devnet_v5_203964628.sol +28 -2
- package/src/libs/incoLightning_devnet_v6_281949651.sol +28 -2
- package/src/libs/incoLightning_devnet_v7_24560427.sol +28 -2
- package/src/libs/incoLightning_devnet_v8_985328058.sol +28 -2
- package/src/libs/incoLightning_devnet_v9_269218568.sol +28 -2
- package/src/libs/incoLightning_testnet_v0_183408998.sol +28 -2
- package/src/libs/incoLightning_testnet_v2_889158349.sol +28 -2
- package/src/lightning-parts/AccessControl/interfaces/IBaseAccessControlList.sol +1 -0
- package/src/lightning-parts/EList.sol +1 -1
- package/src/lightning-parts/EncryptedInput.sol +18 -3
- package/src/lightning-parts/EncryptedOperations.sol +0 -14
- package/src/lightning-parts/interfaces/IEncryptedOperations.sol +0 -1
- package/src/lightning-parts/test/HandleMetadata.t.sol +0 -7
- package/src/test/EListTester.sol +4 -0
- package/src/test/FakeIncoInfra/MockOpHandler.sol +7 -9
- package/src/test/FakeIncoInfra/getOpForSelector.sol +0 -2
- package/src/test/IncoTest.sol +17 -5
- package/src/test/OpsTest.sol +3 -2
- package/src/test/TestLib.t.sol +142 -1
- package/src/test/TestUpgrade.t.sol +24 -47
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
pragma solidity ^0.8;
|
|
7
7
|
|
|
8
8
|
import { IncoLightning } from "../IncoLightning.sol";
|
|
9
|
-
import { ebool, euint256, eaddress, ETypes, elist, IndexOutOfRange, InvalidRange, SliceOutOfRange, UnsupportedListType } from "../Types.sol";
|
|
9
|
+
import { ebool, euint256, eaddress, ETypes, elist, IndexOutOfRange, InvalidRange, SliceOutOfRange, UnsupportedListType, HandleMismatch, InvalidTEEAttestation, UnexpectedDecryptedValue } from "../Types.sol";
|
|
10
|
+
import { asBool } from "../shared/TypeUtils.sol";
|
|
10
11
|
import { DecryptionAttestation, ElementAttestationWithProof } from "../lightning-parts/DecryptionAttester.types.sol";
|
|
11
12
|
|
|
12
13
|
IncoLightning constant inco = IncoLightning(payable(0x43119Ad1F673E998CE4f3BB305bB92Bd5ab97E3B));
|
|
@@ -687,7 +688,8 @@ library e {
|
|
|
687
688
|
/// @dev costs the inco fee
|
|
688
689
|
/// @return The encrypted random value
|
|
689
690
|
function rand() internal returns (euint256) {
|
|
690
|
-
bytes32
|
|
691
|
+
bytes32 boundHandle = euint256.unwrap(asEuint256(0));
|
|
692
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
691
693
|
return euint256.wrap(result);
|
|
692
694
|
}
|
|
693
695
|
|
|
@@ -1194,4 +1196,28 @@ library e {
|
|
|
1194
1196
|
function verifyEListDecryption(elist elistHandle, ElementAttestationWithProof[] memory proofElements, bytes32 proof, bytes[] memory signatures) internal view returns (bool) {
|
|
1195
1197
|
return inco.incoVerifier().isValidEListDecryptionAttestation(elist.unwrap(elistHandle), proofElements, proof, signatures);
|
|
1196
1198
|
}
|
|
1199
|
+
|
|
1200
|
+
/// @notice Checks a decryption attestation for an encrypted bool against an expected plaintext value
|
|
1201
|
+
/// @param handle The encrypted handle
|
|
1202
|
+
/// @param expected The expected plaintext value
|
|
1203
|
+
/// @param decryption The decryption attestation to verify
|
|
1204
|
+
/// @param signatures The covalidator signatures for the attestation
|
|
1205
|
+
/// @dev Reverts if the handle doesn't match, the decrypted value doesn't match the expected value, or the attestation is invalid
|
|
1206
|
+
function requireEqual(ebool handle, bool expected, DecryptionAttestation memory decryption, bytes[] memory signatures) internal view {
|
|
1207
|
+
require(ebool.unwrap(handle) == decryption.handle, HandleMismatch());
|
|
1208
|
+
require(asBool(decryption.value) == expected, UnexpectedDecryptedValue());
|
|
1209
|
+
require(inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures), InvalidTEEAttestation());
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
/// @notice Checks a decryption attestation for an encrypted uint256 against an expected plaintext value
|
|
1213
|
+
/// @param handle The encrypted handle
|
|
1214
|
+
/// @param expected The expected plaintext value
|
|
1215
|
+
/// @param decryption The decryption attestation to verify
|
|
1216
|
+
/// @param signatures The covalidator signatures for the attestation
|
|
1217
|
+
/// @dev Reverts if the handle doesn't match, the decrypted value doesn't match the expected value, or the attestation is invalid
|
|
1218
|
+
function requireEqual(euint256 handle, uint256 expected, DecryptionAttestation memory decryption, bytes[] memory signatures) internal view {
|
|
1219
|
+
require(euint256.unwrap(handle) == decryption.handle, HandleMismatch());
|
|
1220
|
+
require(uint256(decryption.value) == expected, UnexpectedDecryptedValue());
|
|
1221
|
+
require(inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures), InvalidTEEAttestation());
|
|
1222
|
+
}
|
|
1197
1223
|
}
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
pragma solidity ^0.8;
|
|
7
7
|
|
|
8
8
|
import { IncoLightning } from "../IncoLightning.sol";
|
|
9
|
-
import { ebool, euint256, eaddress, ETypes, elist, IndexOutOfRange, InvalidRange, SliceOutOfRange, UnsupportedListType } from "../Types.sol";
|
|
9
|
+
import { ebool, euint256, eaddress, ETypes, elist, IndexOutOfRange, InvalidRange, SliceOutOfRange, UnsupportedListType, HandleMismatch, InvalidTEEAttestation, UnexpectedDecryptedValue } from "../Types.sol";
|
|
10
|
+
import { asBool } from "../shared/TypeUtils.sol";
|
|
10
11
|
import { DecryptionAttestation, ElementAttestationWithProof } from "../lightning-parts/DecryptionAttester.types.sol";
|
|
11
12
|
|
|
12
13
|
IncoLightning constant inco = IncoLightning(payable(0x6c9132D324231D2F68a1491686b0d4c10ee7d257));
|
|
@@ -687,7 +688,8 @@ library e {
|
|
|
687
688
|
/// @dev costs the inco fee
|
|
688
689
|
/// @return The encrypted random value
|
|
689
690
|
function rand() internal returns (euint256) {
|
|
690
|
-
bytes32
|
|
691
|
+
bytes32 boundHandle = euint256.unwrap(asEuint256(0));
|
|
692
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
691
693
|
return euint256.wrap(result);
|
|
692
694
|
}
|
|
693
695
|
|
|
@@ -1194,4 +1196,28 @@ library e {
|
|
|
1194
1196
|
function verifyEListDecryption(elist elistHandle, ElementAttestationWithProof[] memory proofElements, bytes32 proof, bytes[] memory signatures) internal view returns (bool) {
|
|
1195
1197
|
return inco.incoVerifier().isValidEListDecryptionAttestation(elist.unwrap(elistHandle), proofElements, proof, signatures);
|
|
1196
1198
|
}
|
|
1199
|
+
|
|
1200
|
+
/// @notice Checks a decryption attestation for an encrypted bool against an expected plaintext value
|
|
1201
|
+
/// @param handle The encrypted handle
|
|
1202
|
+
/// @param expected The expected plaintext value
|
|
1203
|
+
/// @param decryption The decryption attestation to verify
|
|
1204
|
+
/// @param signatures The covalidator signatures for the attestation
|
|
1205
|
+
/// @dev Reverts if the handle doesn't match, the decrypted value doesn't match the expected value, or the attestation is invalid
|
|
1206
|
+
function requireEqual(ebool handle, bool expected, DecryptionAttestation memory decryption, bytes[] memory signatures) internal view {
|
|
1207
|
+
require(ebool.unwrap(handle) == decryption.handle, HandleMismatch());
|
|
1208
|
+
require(asBool(decryption.value) == expected, UnexpectedDecryptedValue());
|
|
1209
|
+
require(inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures), InvalidTEEAttestation());
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
/// @notice Checks a decryption attestation for an encrypted uint256 against an expected plaintext value
|
|
1213
|
+
/// @param handle The encrypted handle
|
|
1214
|
+
/// @param expected The expected plaintext value
|
|
1215
|
+
/// @param decryption The decryption attestation to verify
|
|
1216
|
+
/// @param signatures The covalidator signatures for the attestation
|
|
1217
|
+
/// @dev Reverts if the handle doesn't match, the decrypted value doesn't match the expected value, or the attestation is invalid
|
|
1218
|
+
function requireEqual(euint256 handle, uint256 expected, DecryptionAttestation memory decryption, bytes[] memory signatures) internal view {
|
|
1219
|
+
require(euint256.unwrap(handle) == decryption.handle, HandleMismatch());
|
|
1220
|
+
require(uint256(decryption.value) == expected, UnexpectedDecryptedValue());
|
|
1221
|
+
require(inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures), InvalidTEEAttestation());
|
|
1222
|
+
}
|
|
1197
1223
|
}
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
pragma solidity ^0.8;
|
|
7
7
|
|
|
8
8
|
import { IncoLightning } from "../IncoLightning.sol";
|
|
9
|
-
import { ebool, euint256, eaddress, ETypes, elist, IndexOutOfRange, InvalidRange, SliceOutOfRange, UnsupportedListType } from "../Types.sol";
|
|
9
|
+
import { ebool, euint256, eaddress, ETypes, elist, IndexOutOfRange, InvalidRange, SliceOutOfRange, UnsupportedListType, HandleMismatch, InvalidTEEAttestation, UnexpectedDecryptedValue } from "../Types.sol";
|
|
10
|
+
import { asBool } from "../shared/TypeUtils.sol";
|
|
10
11
|
import { DecryptionAttestation, ElementAttestationWithProof } from "../lightning-parts/DecryptionAttester.types.sol";
|
|
11
12
|
|
|
12
13
|
IncoLightning constant inco = IncoLightning(payable(0x63D8135aF4D393B1dB43B649010c8D3EE19FC9fd));
|
|
@@ -687,7 +688,8 @@ library e {
|
|
|
687
688
|
/// @dev costs the inco fee
|
|
688
689
|
/// @return The encrypted random value
|
|
689
690
|
function rand() internal returns (euint256) {
|
|
690
|
-
bytes32
|
|
691
|
+
bytes32 boundHandle = euint256.unwrap(asEuint256(0));
|
|
692
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
691
693
|
return euint256.wrap(result);
|
|
692
694
|
}
|
|
693
695
|
|
|
@@ -1194,4 +1196,28 @@ library e {
|
|
|
1194
1196
|
function verifyEListDecryption(elist elistHandle, ElementAttestationWithProof[] memory proofElements, bytes32 proof, bytes[] memory signatures) internal view returns (bool) {
|
|
1195
1197
|
return inco.incoVerifier().isValidEListDecryptionAttestation(elist.unwrap(elistHandle), proofElements, proof, signatures);
|
|
1196
1198
|
}
|
|
1199
|
+
|
|
1200
|
+
/// @notice Checks a decryption attestation for an encrypted bool against an expected plaintext value
|
|
1201
|
+
/// @param handle The encrypted handle
|
|
1202
|
+
/// @param expected The expected plaintext value
|
|
1203
|
+
/// @param decryption The decryption attestation to verify
|
|
1204
|
+
/// @param signatures The covalidator signatures for the attestation
|
|
1205
|
+
/// @dev Reverts if the handle doesn't match, the decrypted value doesn't match the expected value, or the attestation is invalid
|
|
1206
|
+
function requireEqual(ebool handle, bool expected, DecryptionAttestation memory decryption, bytes[] memory signatures) internal view {
|
|
1207
|
+
require(ebool.unwrap(handle) == decryption.handle, HandleMismatch());
|
|
1208
|
+
require(asBool(decryption.value) == expected, UnexpectedDecryptedValue());
|
|
1209
|
+
require(inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures), InvalidTEEAttestation());
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
/// @notice Checks a decryption attestation for an encrypted uint256 against an expected plaintext value
|
|
1213
|
+
/// @param handle The encrypted handle
|
|
1214
|
+
/// @param expected The expected plaintext value
|
|
1215
|
+
/// @param decryption The decryption attestation to verify
|
|
1216
|
+
/// @param signatures The covalidator signatures for the attestation
|
|
1217
|
+
/// @dev Reverts if the handle doesn't match, the decrypted value doesn't match the expected value, or the attestation is invalid
|
|
1218
|
+
function requireEqual(euint256 handle, uint256 expected, DecryptionAttestation memory decryption, bytes[] memory signatures) internal view {
|
|
1219
|
+
require(euint256.unwrap(handle) == decryption.handle, HandleMismatch());
|
|
1220
|
+
require(uint256(decryption.value) == expected, UnexpectedDecryptedValue());
|
|
1221
|
+
require(inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures), InvalidTEEAttestation());
|
|
1222
|
+
}
|
|
1197
1223
|
}
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
pragma solidity ^0.8;
|
|
7
7
|
|
|
8
8
|
import { IncoLightning } from "../IncoLightning.sol";
|
|
9
|
-
import { ebool, euint256, eaddress, ETypes, elist, IndexOutOfRange, InvalidRange, SliceOutOfRange, UnsupportedListType } from "../Types.sol";
|
|
9
|
+
import { ebool, euint256, eaddress, ETypes, elist, IndexOutOfRange, InvalidRange, SliceOutOfRange, UnsupportedListType, HandleMismatch, InvalidTEEAttestation, UnexpectedDecryptedValue } from "../Types.sol";
|
|
10
|
+
import { asBool } from "../shared/TypeUtils.sol";
|
|
10
11
|
import { DecryptionAttestation, ElementAttestationWithProof } from "../lightning-parts/DecryptionAttester.types.sol";
|
|
11
12
|
|
|
12
13
|
IncoLightning constant inco = IncoLightning(payable(0x168FDc3Ae19A5d5b03614578C58974FF30FCBe92));
|
|
@@ -687,7 +688,8 @@ library e {
|
|
|
687
688
|
/// @dev costs the inco fee
|
|
688
689
|
/// @return The encrypted random value
|
|
689
690
|
function rand() internal returns (euint256) {
|
|
690
|
-
bytes32
|
|
691
|
+
bytes32 boundHandle = euint256.unwrap(asEuint256(0));
|
|
692
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
691
693
|
return euint256.wrap(result);
|
|
692
694
|
}
|
|
693
695
|
|
|
@@ -1194,4 +1196,28 @@ library e {
|
|
|
1194
1196
|
function verifyEListDecryption(elist elistHandle, ElementAttestationWithProof[] memory proofElements, bytes32 proof, bytes[] memory signatures) internal view returns (bool) {
|
|
1195
1197
|
return inco.incoVerifier().isValidEListDecryptionAttestation(elist.unwrap(elistHandle), proofElements, proof, signatures);
|
|
1196
1198
|
}
|
|
1199
|
+
|
|
1200
|
+
/// @notice Checks a decryption attestation for an encrypted bool against an expected plaintext value
|
|
1201
|
+
/// @param handle The encrypted handle
|
|
1202
|
+
/// @param expected The expected plaintext value
|
|
1203
|
+
/// @param decryption The decryption attestation to verify
|
|
1204
|
+
/// @param signatures The covalidator signatures for the attestation
|
|
1205
|
+
/// @dev Reverts if the handle doesn't match, the decrypted value doesn't match the expected value, or the attestation is invalid
|
|
1206
|
+
function requireEqual(ebool handle, bool expected, DecryptionAttestation memory decryption, bytes[] memory signatures) internal view {
|
|
1207
|
+
require(ebool.unwrap(handle) == decryption.handle, HandleMismatch());
|
|
1208
|
+
require(asBool(decryption.value) == expected, UnexpectedDecryptedValue());
|
|
1209
|
+
require(inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures), InvalidTEEAttestation());
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
/// @notice Checks a decryption attestation for an encrypted uint256 against an expected plaintext value
|
|
1213
|
+
/// @param handle The encrypted handle
|
|
1214
|
+
/// @param expected The expected plaintext value
|
|
1215
|
+
/// @param decryption The decryption attestation to verify
|
|
1216
|
+
/// @param signatures The covalidator signatures for the attestation
|
|
1217
|
+
/// @dev Reverts if the handle doesn't match, the decrypted value doesn't match the expected value, or the attestation is invalid
|
|
1218
|
+
function requireEqual(euint256 handle, uint256 expected, DecryptionAttestation memory decryption, bytes[] memory signatures) internal view {
|
|
1219
|
+
require(euint256.unwrap(handle) == decryption.handle, HandleMismatch());
|
|
1220
|
+
require(uint256(decryption.value) == expected, UnexpectedDecryptedValue());
|
|
1221
|
+
require(inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures), InvalidTEEAttestation());
|
|
1222
|
+
}
|
|
1197
1223
|
}
|
|
@@ -8,6 +8,7 @@ import {AllowanceProof} from "../AdvancedAccessControl.types.sol";
|
|
|
8
8
|
interface IBaseAccessControlList is IVerifierAddressGetter, IEventCounter {
|
|
9
9
|
|
|
10
10
|
function allow(bytes32 handle, address account) external;
|
|
11
|
+
function reveal(bytes32 handle) external;
|
|
11
12
|
function allowTransient(bytes32 handle, address account) external;
|
|
12
13
|
function allowedTransient(bytes32 handle, address account) external view returns (bool);
|
|
13
14
|
function persistAllowed(bytes32 handle, address account) external view returns (bool);
|
|
@@ -75,7 +75,7 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
|
|
|
75
75
|
bytes32[] memory handles = new bytes32[](inputs.length);
|
|
76
76
|
for (uint256 i = 0; i < inputs.length; i++) {
|
|
77
77
|
// we check payment for multiple inputs ahead of this func
|
|
78
|
-
handles[i] =
|
|
78
|
+
handles[i] = newInputNotPayingNotEmitting(inputs[i], user, listType);
|
|
79
79
|
}
|
|
80
80
|
return newEListFromHandles(handles, listType);
|
|
81
81
|
}
|
|
@@ -138,6 +138,9 @@ abstract contract EncryptedInput is
|
|
|
138
138
|
returns (bytes32 newHandle)
|
|
139
139
|
{
|
|
140
140
|
newHandle = _newInput(input, user, inputType);
|
|
141
|
+
// We allow to user since this is harmless and it is convenient to use the allow mapping to track inputs.
|
|
142
|
+
// NOTE: the allow must come after emitting the new input event, since allow emits its own event.
|
|
143
|
+
allowInternal(newHandle, user);
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
/// @dev Internal function to process encrypted input without fee payment.
|
|
@@ -148,6 +151,21 @@ abstract contract EncryptedInput is
|
|
|
148
151
|
function newInputNotPaying(bytes calldata input, address user, ETypes inputType)
|
|
149
152
|
internal
|
|
150
153
|
returns (bytes32 newHandle)
|
|
154
|
+
{
|
|
155
|
+
newHandle = _newInput(input, user, inputType);
|
|
156
|
+
// We allow to user since this is harmless and it is convenient to use the allow mapping to track inputs.
|
|
157
|
+
// NOTE: the allow must come after emitting the new input event, since allow emits its own event.
|
|
158
|
+
allowInternal(newHandle, user);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/// @dev Internal function to process encrypted input without fee payment and without emitting events.
|
|
162
|
+
/// Used by EList for importing multiple inputs without emitting individual events for each input.
|
|
163
|
+
/// @param user The user address that encrypted the value.
|
|
164
|
+
/// @param inputType The type of encrypted value.
|
|
165
|
+
/// @return newHandle The generated handle.
|
|
166
|
+
function newInputNotPayingNotEmitting(bytes calldata input, address user, ETypes inputType)
|
|
167
|
+
internal
|
|
168
|
+
returns (bytes32 newHandle)
|
|
151
169
|
{
|
|
152
170
|
newHandle = _newInput(input, user, inputType);
|
|
153
171
|
}
|
|
@@ -198,9 +216,6 @@ abstract contract EncryptedInput is
|
|
|
198
216
|
eventId: id
|
|
199
217
|
});
|
|
200
218
|
setDigest(abi.encodePacked(handle, id));
|
|
201
|
-
// We allow to user since this is harmless and it is convenient to use the allow mapping to track inputs.
|
|
202
|
-
// NOTE: the allow must come after emitting the new input event, since allow emits its own event.
|
|
203
|
-
allowInternal(handle, user);
|
|
204
219
|
allowTransientInternal(handle, msg.sender);
|
|
205
220
|
}
|
|
206
221
|
|
|
@@ -66,7 +66,6 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
66
66
|
event ELt(euint256 indexed lhs, euint256 indexed rhs, ebool indexed result, uint256 eventId);
|
|
67
67
|
event EMin(euint256 indexed lhs, euint256 indexed rhs, euint256 indexed result, uint256 eventId);
|
|
68
68
|
event EMax(euint256 indexed lhs, euint256 indexed rhs, euint256 indexed result, uint256 eventId);
|
|
69
|
-
event ERand(uint256 indexed counter, ETypes randType, bytes32 indexed result, uint256 eventId);
|
|
70
69
|
event ERandBounded(
|
|
71
70
|
uint256 indexed counter, ETypes randType, bytes32 indexed upperBound, bytes32 indexed result, uint256 eventId
|
|
72
71
|
);
|
|
@@ -416,19 +415,6 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
416
415
|
setDigest(abi.encodePacked(result, id));
|
|
417
416
|
}
|
|
418
417
|
|
|
419
|
-
/// @notice Generates an encrypted random value of the specified type.
|
|
420
|
-
/// @dev This is a paid operation.
|
|
421
|
-
/// @param randType The type of random value to generate.
|
|
422
|
-
/// @return result An encrypted random value.
|
|
423
|
-
function eRand(ETypes randType) external payable paying returns (bytes32 result) {
|
|
424
|
-
require(isTypeSupported(randType), UnsupportedType(randType));
|
|
425
|
-
randCounter++;
|
|
426
|
-
result = createResultHandle(EOps.Rand, randType, abi.encodePacked(bytes32(randCounter)));
|
|
427
|
-
uint256 id = getNextEventId();
|
|
428
|
-
emit ERand(randCounter, randType, result, id);
|
|
429
|
-
setDigest(abi.encodePacked(result, id));
|
|
430
|
-
}
|
|
431
|
-
|
|
432
418
|
/// @notice Generates an encrypted random value bounded by an upper limit.
|
|
433
419
|
/// @dev This is a paid operation. The result is in the range [0, upperBound).
|
|
434
420
|
/// @param upperBound The encrypted upper bound (exclusive). If the upper bound is e(0), the whole bit width of randType is sampled.
|
|
@@ -29,7 +29,6 @@ interface IEncryptedOperations is IBaseAccessControlList, IHandleGeneration {
|
|
|
29
29
|
function eMax(euint256 lhs, euint256 rhs) external returns (euint256 result);
|
|
30
30
|
function eNot(ebool operand) external returns (ebool result);
|
|
31
31
|
function eCast(bytes32 ct, ETypes toType) external returns (bytes32 result);
|
|
32
|
-
function eRand(ETypes randType) external payable returns (bytes32 result);
|
|
33
32
|
function eRandBounded(bytes32 upperBound, ETypes randType) external payable returns (bytes32 result);
|
|
34
33
|
function eIfThenElse(ebool condition, bytes32 ifTrue, bytes32 ifFalse) external returns (bytes32 result);
|
|
35
34
|
|
|
@@ -326,13 +326,6 @@ contract TestHandleMetadata is
|
|
|
326
326
|
this.eCast(euint256.unwrap(a), unsupportedType);
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
-
/// @notice Test eRand with unsupported type (line 282)
|
|
330
|
-
function testERandUnsupportedType() public {
|
|
331
|
-
ETypes unsupportedType = ETypes.Uint4UNSUPPORTED;
|
|
332
|
-
vm.expectRevert(abi.encodeWithSelector(EncryptedOperations.UnsupportedType.selector, unsupportedType));
|
|
333
|
-
this.eRand{value: FEE}(unsupportedType);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
329
|
/// @notice Test eRandBounded with unsupported type (line 291)
|
|
337
330
|
function testERandBoundedUnsupportedType() public {
|
|
338
331
|
euint256 bound = this.asEuint256(100);
|
package/src/test/EListTester.sol
CHANGED
|
@@ -152,6 +152,10 @@ contract ElistTester is IncoUtils {
|
|
|
152
152
|
return list;
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
+
function listReveal() public {
|
|
156
|
+
inco.reveal(elist.unwrap(list));
|
|
157
|
+
}
|
|
158
|
+
|
|
155
159
|
function listReverse() public payable returns (elist) {
|
|
156
160
|
uint256 typeBits = typeBitSize(ETypes(uint8(uint256(elist.unwrap(list)) >> 16)));
|
|
157
161
|
list = inco.listReverse{value: uint256(inco.lengthOf(elist.unwrap(list))) * typeBits * BIT_FEE}(list);
|
|
@@ -46,10 +46,6 @@ contract MockOpHandler is FakeIncoInfraBase, FakeComputeServer {
|
|
|
46
46
|
ebool value = ebool.wrap(log.topics[1]);
|
|
47
47
|
ebool result = ebool.wrap(log.topics[2]);
|
|
48
48
|
handleENot(value, result);
|
|
49
|
-
} else if (op == EOps.Rand) {
|
|
50
|
-
uint256 counter = uint256(log.topics[1]);
|
|
51
|
-
euint256 result = euint256.wrap(log.topics[2]);
|
|
52
|
-
handleERand(counter, result);
|
|
53
49
|
} else if (op == EOps.RandBounded) {
|
|
54
50
|
uint256 counter = uint256(log.topics[1]);
|
|
55
51
|
euint256 upperBound = euint256.wrap(log.topics[2]);
|
|
@@ -85,12 +81,14 @@ contract MockOpHandler is FakeIncoInfraBase, FakeComputeServer {
|
|
|
85
81
|
set(ebool.unwrap(result), asBytes32(!getBoolValue(value)));
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
function handleERand(uint256 counter, euint256 result) private {
|
|
89
|
-
set(euint256.unwrap(result), bytes32(counter));
|
|
90
|
-
}
|
|
91
|
-
|
|
92
84
|
function handleERandBounded(uint256 counter, euint256 upperBound, euint256 result) private {
|
|
93
|
-
|
|
85
|
+
uint256 bound = getUint256Value(upperBound);
|
|
86
|
+
if (bound == 0) {
|
|
87
|
+
// upperBound of 0 means unbounded (used by rand())
|
|
88
|
+
set(euint256.unwrap(result), bytes32(counter));
|
|
89
|
+
} else {
|
|
90
|
+
set(euint256.unwrap(result), bytes32(counter % bound));
|
|
91
|
+
}
|
|
94
92
|
}
|
|
95
93
|
|
|
96
94
|
function handleIfThenElse(ebool control, bytes32 lhs, bytes32 rhs, bytes32 result) private {
|
|
@@ -59,8 +59,6 @@ function getOpForSelector(bytes32 opEventSelector) pure returns (EOps) {
|
|
|
59
59
|
return EOps.TrivialEncrypt;
|
|
60
60
|
} else if (opEventSelector == EncryptedOperations.EIfThenElse.selector) {
|
|
61
61
|
return EOps.IfThenElse;
|
|
62
|
-
} else if (opEventSelector == EncryptedOperations.ERand.selector) {
|
|
63
|
-
return EOps.Rand;
|
|
64
62
|
} else if (opEventSelector == EncryptedOperations.ERandBounded.selector) {
|
|
65
63
|
return EOps.RandBounded;
|
|
66
64
|
} else if (opEventSelector == BaseAccessControlList.Allow.selector) {
|
package/src/test/IncoTest.sol
CHANGED
|
@@ -12,11 +12,12 @@ import {FakeQuoteVerifier} from "./FakeIncoInfra/FakeQuoteVerifier.sol";
|
|
|
12
12
|
import {IOwnable} from "../../src/shared/IOwnable.sol";
|
|
13
13
|
import {MockRemoteAttestation} from "./FakeIncoInfra/MockRemoteAttestation.sol";
|
|
14
14
|
import {BootstrapResult} from "../lightning-parts/TEELifecycle.types.sol";
|
|
15
|
+
import {Safe} from "safe-smart-account/Safe.sol";
|
|
16
|
+
import {SafeProxyFactory} from "safe-smart-account/proxies/SafeProxyFactory.sol";
|
|
15
17
|
|
|
16
18
|
contract IncoTest is MockOpHandler, DeployUtils, FakeDecryptionAttester, MockRemoteAttestation {
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
address immutable owner;
|
|
20
|
+
address owner;
|
|
20
21
|
// forge-lint: disable-next-line(screaming-snake-case-immutable)
|
|
21
22
|
address immutable testDeployer;
|
|
22
23
|
|
|
@@ -31,7 +32,6 @@ contract IncoTest is MockOpHandler, DeployUtils, FakeDecryptionAttester, MockRem
|
|
|
31
32
|
0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80;
|
|
32
33
|
|
|
33
34
|
constructor() {
|
|
34
|
-
owner = getLabeledAddress("owner");
|
|
35
35
|
// extracted from the deploy script running as bare simulation with:
|
|
36
36
|
// forge script src/script/Deploy.s.sol:Deploy
|
|
37
37
|
testDeployer = deployedBy;
|
|
@@ -42,17 +42,29 @@ contract IncoTest is MockOpHandler, DeployUtils, FakeDecryptionAttester, MockRem
|
|
|
42
42
|
|
|
43
43
|
function setUp() public virtual {
|
|
44
44
|
deployCreateX();
|
|
45
|
+
|
|
46
|
+
// Create a Safe multisig (alice, bob, carol) with threshold 2 to act as owner
|
|
47
|
+
Safe master = new Safe();
|
|
48
|
+
SafeProxyFactory factory = new SafeProxyFactory();
|
|
49
|
+
address[] memory safeOwners = new address[](3);
|
|
50
|
+
safeOwners[0] = alice;
|
|
51
|
+
safeOwners[1] = bob;
|
|
52
|
+
safeOwners[2] = carol;
|
|
53
|
+
bytes memory setupData = abi.encodeWithSelector(
|
|
54
|
+
Safe.setup.selector, safeOwners, 2, address(0), bytes(""), address(0), address(0), 0, payable(address(0))
|
|
55
|
+
);
|
|
56
|
+
owner = address(Safe(payable(factory.createProxyWithNonce(address(master), setupData, 0))));
|
|
57
|
+
|
|
45
58
|
vm.startPrank(testDeployer);
|
|
46
59
|
vm.setEnv("SHOULD_SETUP_TEE_SIGNER", "true"); // results in a network pubkey and decrypt signer being populated in the TEE Lifecycle
|
|
47
60
|
(IIncoLightning proxy,) = deployIncoLightningUsingConfig({
|
|
48
61
|
deployer: testDeployer,
|
|
62
|
+
owner: owner,
|
|
49
63
|
// The highest precedent deployment
|
|
50
64
|
// We select the pepper that will be used that will be generated in the lib.sol (usually "testnet"), but currently "alphanet" has higher major version
|
|
51
65
|
pepper: "devnet",
|
|
52
66
|
quoteVerifier: new FakeQuoteVerifier()
|
|
53
67
|
});
|
|
54
|
-
IOwnable(address(proxy)).transferOwnership(owner);
|
|
55
|
-
IOwnable(address(inco.incoVerifier())).transferOwnership(owner);
|
|
56
68
|
vm.stopPrank();
|
|
57
69
|
console.log("Deployed %s (proxy) to: %s", proxy.getName(), address(proxy));
|
|
58
70
|
console.log("Generated inco address: %s", address(inco));
|
package/src/test/OpsTest.sol
CHANGED
|
@@ -380,8 +380,9 @@ contract OpsTest is Fee {
|
|
|
380
380
|
|
|
381
381
|
// ============ RANDOM NUMBER GENERATION ============
|
|
382
382
|
|
|
383
|
-
function
|
|
384
|
-
euint256 result =
|
|
383
|
+
function testRandUnbounded() external payable returns (euint256) {
|
|
384
|
+
euint256 result =
|
|
385
|
+
euint256.wrap(inco.eRandBounded{value: getFee()}(euint256.unwrap(inco.asEuint256(0)), ETypes.Uint256));
|
|
385
386
|
inco.allow(euint256.unwrap(result), address(this));
|
|
386
387
|
inco.allow(euint256.unwrap(result), msg.sender);
|
|
387
388
|
return result;
|
package/src/test/TestLib.t.sol
CHANGED
|
@@ -7,9 +7,12 @@ import {FEE} from "../lightning-parts/Fee.sol";
|
|
|
7
7
|
import {
|
|
8
8
|
ETypes,
|
|
9
9
|
elist,
|
|
10
|
+
HandleMismatch,
|
|
10
11
|
IndexOutOfRange,
|
|
11
12
|
InvalidRange,
|
|
13
|
+
InvalidTEEAttestation,
|
|
12
14
|
SliceOutOfRange,
|
|
15
|
+
UnexpectedDecryptedValue,
|
|
13
16
|
UnsupportedListType,
|
|
14
17
|
UnsupportedType
|
|
15
18
|
} from "../Types.sol";
|
|
@@ -17,6 +20,27 @@ import {EncryptedOperations} from "../lightning-parts/EncryptedOperations.sol";
|
|
|
17
20
|
import {DecryptionAttestation, ElementAttestationWithProof} from "../lightning-parts/DecryptionAttester.types.sol";
|
|
18
21
|
import {AllowanceProof, AllowanceVoucher} from "../lightning-parts/AccessControl/AdvancedAccessControl.sol";
|
|
19
22
|
|
|
23
|
+
/// @notice Wrapper to expose internal requireEqual as an external call so vm.expectRevert works
|
|
24
|
+
contract RequireEqualCaller {
|
|
25
|
+
|
|
26
|
+
function callEbool(ebool handle, bool expected, DecryptionAttestation memory decryption, bytes[] memory signatures)
|
|
27
|
+
external
|
|
28
|
+
view
|
|
29
|
+
{
|
|
30
|
+
e.requireEqual(handle, expected, decryption, signatures);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function callEuint256(
|
|
34
|
+
euint256 handle,
|
|
35
|
+
uint256 expected,
|
|
36
|
+
DecryptionAttestation memory decryption,
|
|
37
|
+
bytes[] memory signatures
|
|
38
|
+
) external view {
|
|
39
|
+
e.requireEqual(handle, expected, decryption, signatures);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
20
44
|
/// @notice Tests for Lib.sol library functions to achieve 100% coverage
|
|
21
45
|
/// @dev This file tests all the scalar variants and uncovered branches in the library
|
|
22
46
|
contract TestLib is IncoTest {
|
|
@@ -853,7 +877,7 @@ contract TestLib is IncoTest {
|
|
|
853
877
|
assertFalse(isValid, "Invalid value should return false");
|
|
854
878
|
}
|
|
855
879
|
|
|
856
|
-
function
|
|
880
|
+
function testVerifyDecryption_Euint256_InvalidTEEAttestations() public {
|
|
857
881
|
// Create an encrypted value
|
|
858
882
|
euint256 encrypted = e.asEuint256(12345);
|
|
859
883
|
processAllOperations();
|
|
@@ -925,6 +949,123 @@ contract TestLib is IncoTest {
|
|
|
925
949
|
});
|
|
926
950
|
}
|
|
927
951
|
|
|
952
|
+
// ============ REQUIRE EQUAL TESTS ============
|
|
953
|
+
|
|
954
|
+
function testRequireEqual_Ebool_ValidAttestation_True() public {
|
|
955
|
+
ebool encrypted = e.asEbool(true);
|
|
956
|
+
processAllOperations();
|
|
957
|
+
|
|
958
|
+
(DecryptionAttestation memory attestation, bytes[] memory signatures) = getDecryptionAttestation(
|
|
959
|
+
address(this), HandleWithProof({handle: ebool.unwrap(encrypted), proof: _emptyAllowanceProof()})
|
|
960
|
+
);
|
|
961
|
+
|
|
962
|
+
e.requireEqual(encrypted, true, attestation, signatures);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
function testRequireEqual_Ebool_ValidAttestation_False() public {
|
|
966
|
+
ebool encrypted = e.asEbool(false);
|
|
967
|
+
processAllOperations();
|
|
968
|
+
|
|
969
|
+
(DecryptionAttestation memory attestation, bytes[] memory signatures) = getDecryptionAttestation(
|
|
970
|
+
address(this), HandleWithProof({handle: ebool.unwrap(encrypted), proof: _emptyAllowanceProof()})
|
|
971
|
+
);
|
|
972
|
+
|
|
973
|
+
e.requireEqual(encrypted, false, attestation, signatures);
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
function testRequireEqual_Ebool_WrongValue() public {
|
|
977
|
+
ebool encrypted = e.asEbool(true);
|
|
978
|
+
processAllOperations();
|
|
979
|
+
|
|
980
|
+
(DecryptionAttestation memory attestation, bytes[] memory signatures) = getDecryptionAttestation(
|
|
981
|
+
address(this), HandleWithProof({handle: ebool.unwrap(encrypted), proof: _emptyAllowanceProof()})
|
|
982
|
+
);
|
|
983
|
+
|
|
984
|
+
RequireEqualCaller caller = new RequireEqualCaller();
|
|
985
|
+
vm.expectRevert(abi.encodeWithSelector(UnexpectedDecryptedValue.selector));
|
|
986
|
+
caller.callEbool(encrypted, false, attestation, signatures);
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
function testRequireEqual_Ebool_HandleMismatch() public {
|
|
990
|
+
ebool encryptedA = e.asEbool(true);
|
|
991
|
+
ebool encryptedB = e.asEbool(false);
|
|
992
|
+
processAllOperations();
|
|
993
|
+
|
|
994
|
+
(DecryptionAttestation memory attestation, bytes[] memory signatures) = getDecryptionAttestation(
|
|
995
|
+
address(this), HandleWithProof({handle: ebool.unwrap(encryptedA), proof: _emptyAllowanceProof()})
|
|
996
|
+
);
|
|
997
|
+
|
|
998
|
+
RequireEqualCaller caller = new RequireEqualCaller();
|
|
999
|
+
vm.expectRevert(abi.encodeWithSelector(HandleMismatch.selector));
|
|
1000
|
+
caller.callEbool(encryptedB, true, attestation, signatures);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
function testRequireEqual_Ebool_InvalidTEEAttestations() public {
|
|
1004
|
+
ebool encrypted = e.asEbool(true);
|
|
1005
|
+
processAllOperations();
|
|
1006
|
+
|
|
1007
|
+
(DecryptionAttestation memory attestation,) = getDecryptionAttestation(
|
|
1008
|
+
address(this), HandleWithProof({handle: ebool.unwrap(encrypted), proof: _emptyAllowanceProof()})
|
|
1009
|
+
);
|
|
1010
|
+
|
|
1011
|
+
bytes[] memory invalidSignatures = new bytes[](0);
|
|
1012
|
+
RequireEqualCaller caller = new RequireEqualCaller();
|
|
1013
|
+
vm.expectRevert(abi.encodeWithSelector(InvalidTEEAttestation.selector));
|
|
1014
|
+
caller.callEbool(encrypted, true, attestation, invalidSignatures);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
function testRequireEqual_Euint256_ValidAttestation() public {
|
|
1018
|
+
euint256 encrypted = e.asEuint256(12345);
|
|
1019
|
+
processAllOperations();
|
|
1020
|
+
|
|
1021
|
+
(DecryptionAttestation memory attestation, bytes[] memory signatures) = getDecryptionAttestation(
|
|
1022
|
+
address(this), HandleWithProof({handle: euint256.unwrap(encrypted), proof: _emptyAllowanceProof()})
|
|
1023
|
+
);
|
|
1024
|
+
|
|
1025
|
+
e.requireEqual(encrypted, uint256(attestation.value), attestation, signatures);
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
function testRequireEqual_Euint256_WrongValue() public {
|
|
1029
|
+
euint256 encrypted = e.asEuint256(12345);
|
|
1030
|
+
processAllOperations();
|
|
1031
|
+
|
|
1032
|
+
(DecryptionAttestation memory attestation, bytes[] memory signatures) = getDecryptionAttestation(
|
|
1033
|
+
address(this), HandleWithProof({handle: euint256.unwrap(encrypted), proof: _emptyAllowanceProof()})
|
|
1034
|
+
);
|
|
1035
|
+
|
|
1036
|
+
RequireEqualCaller caller = new RequireEqualCaller();
|
|
1037
|
+
vm.expectRevert(abi.encodeWithSelector(UnexpectedDecryptedValue.selector));
|
|
1038
|
+
caller.callEuint256(encrypted, 99999, attestation, signatures);
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
function testRequireEqual_Euint256_HandleMismatch() public {
|
|
1042
|
+
euint256 encryptedA = e.asEuint256(111);
|
|
1043
|
+
euint256 encryptedB = e.asEuint256(222);
|
|
1044
|
+
processAllOperations();
|
|
1045
|
+
|
|
1046
|
+
(DecryptionAttestation memory attestation, bytes[] memory signatures) = getDecryptionAttestation(
|
|
1047
|
+
address(this), HandleWithProof({handle: euint256.unwrap(encryptedA), proof: _emptyAllowanceProof()})
|
|
1048
|
+
);
|
|
1049
|
+
|
|
1050
|
+
RequireEqualCaller caller = new RequireEqualCaller();
|
|
1051
|
+
vm.expectRevert(abi.encodeWithSelector(HandleMismatch.selector));
|
|
1052
|
+
caller.callEuint256(encryptedB, uint256(attestation.value), attestation, signatures);
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
function testRequireEqual_Euint256_InvalidTEEAttestations() public {
|
|
1056
|
+
euint256 encrypted = e.asEuint256(12345);
|
|
1057
|
+
processAllOperations();
|
|
1058
|
+
|
|
1059
|
+
(DecryptionAttestation memory attestation,) = getDecryptionAttestation(
|
|
1060
|
+
address(this), HandleWithProof({handle: euint256.unwrap(encrypted), proof: _emptyAllowanceProof()})
|
|
1061
|
+
);
|
|
1062
|
+
|
|
1063
|
+
bytes[] memory invalidSignatures = new bytes[](0);
|
|
1064
|
+
RequireEqualCaller caller = new RequireEqualCaller();
|
|
1065
|
+
vm.expectRevert(abi.encodeWithSelector(InvalidTEEAttestation.selector));
|
|
1066
|
+
caller.callEuint256(encrypted, uint256(attestation.value), attestation, invalidSignatures);
|
|
1067
|
+
}
|
|
1068
|
+
|
|
928
1069
|
// ============ ELIST PURE FUNCTION TESTS ============
|
|
929
1070
|
// Note: Most EList functions in Lib.sol are thin wrappers around inco.* calls.
|
|
930
1071
|
|