@inco/lightning 0.9.0-devnet-test-10 → 0.10.0-devnet-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.
Files changed (89) hide show
  1. package/manifest.yaml +150 -0
  2. package/package.json +8 -8
  3. package/src/CreateXHelper.sol +1 -1
  4. package/src/DeployUtils.sol +22 -28
  5. package/src/IncoLightning.sol +27 -18
  6. package/src/IncoVerifier.sol +1 -1
  7. package/src/Lib.alphanet.sol +294 -13
  8. package/src/Lib.demonet.sol +294 -13
  9. package/src/Lib.devnet.sol +294 -13
  10. package/src/Lib.sol +294 -13
  11. package/src/Lib.template.sol +357 -13
  12. package/src/Lib.testnet.sol +294 -13
  13. package/src/Types.sol +44 -0
  14. package/src/interfaces/IIncoLightning.sol +8 -12
  15. package/src/interfaces/automata-interfaces/BELE.sol +1 -1
  16. package/src/interfaces/automata-interfaces/IPCCSRouter.sol +1 -1
  17. package/src/interfaces/automata-interfaces/IPcsDao.sol +1 -1
  18. package/src/interfaces/automata-interfaces/IQuoteVerifier.sol +1 -1
  19. package/src/interfaces/automata-interfaces/Types.sol +1 -1
  20. package/src/libs/incoLightning_alphanet_v0_297966649.sol +294 -13
  21. package/src/libs/incoLightning_alphanet_v1_725458969.sol +294 -13
  22. package/src/libs/incoLightning_alphanet_v2_976644394.sol +294 -13
  23. package/src/libs/incoLightning_demonet_v0_863421733.sol +294 -13
  24. package/src/libs/incoLightning_demonet_v2_467437523.sol +294 -13
  25. package/src/libs/incoLightning_devnet_v0_340846814.sol +294 -13
  26. package/src/libs/incoLightning_devnet_v10_266391127.sol +1223 -0
  27. package/src/libs/incoLightning_devnet_v1_904635675.sol +294 -13
  28. package/src/libs/incoLightning_devnet_v2_295237520.sol +294 -13
  29. package/src/libs/incoLightning_devnet_v3_976859633.sol +294 -13
  30. package/src/libs/incoLightning_devnet_v4_409204766.sol +294 -13
  31. package/src/libs/incoLightning_devnet_v5_203964628.sol +1223 -0
  32. package/src/libs/incoLightning_devnet_v6_281949651.sol +1223 -0
  33. package/src/libs/incoLightning_devnet_v7_24560427.sol +1223 -0
  34. package/src/libs/incoLightning_devnet_v8_985328058.sol +1223 -0
  35. package/src/libs/incoLightning_devnet_v9_269218568.sol +1223 -0
  36. package/src/libs/incoLightning_testnet_v0_183408998.sol +294 -13
  37. package/src/libs/incoLightning_testnet_v2_889158349.sol +294 -13
  38. package/src/lightning-parts/AccessControl/AdvancedAccessControl.sol +8 -3
  39. package/src/lightning-parts/AccessControl/BaseAccessControlList.sol +0 -16
  40. package/src/lightning-parts/AccessControl/interfaces/IAdvancedAccessControl.sol +1 -1
  41. package/src/lightning-parts/AccessControl/interfaces/IBaseAccessControlList.sol +3 -2
  42. package/src/lightning-parts/AccessControl/test/TestAdvancedAccessControl.t.sol +18 -1
  43. package/src/lightning-parts/AccessControl/test/TestBaseAccessControl.t.sol +0 -43
  44. package/src/lightning-parts/DecryptionAttester.sol +124 -2
  45. package/src/lightning-parts/DecryptionAttester.types.sol +20 -0
  46. package/src/lightning-parts/EList.sol +397 -0
  47. package/src/lightning-parts/EncryptedInput.sol +78 -8
  48. package/src/lightning-parts/EncryptedOperations.sol +40 -34
  49. package/src/lightning-parts/Fee.sol +29 -0
  50. package/src/lightning-parts/TEELifecycle.sol +38 -30
  51. package/src/lightning-parts/TEELifecycle.types.sol +1 -1
  52. package/src/lightning-parts/TrivialEncryption.sol +1 -2
  53. package/src/lightning-parts/interfaces/IDecryptionAttester.sol +16 -1
  54. package/src/lightning-parts/interfaces/IEList.sol +38 -0
  55. package/src/lightning-parts/interfaces/IEncryptedInput.sol +9 -1
  56. package/src/lightning-parts/interfaces/IEncryptedOperations.sol +3 -2
  57. package/src/lightning-parts/interfaces/ITEELifecycle.sol +1 -1
  58. package/src/lightning-parts/interfaces/ITrivialEncryption.sol +3 -1
  59. package/src/lightning-parts/primitives/EListHandleGeneration.sol +66 -0
  60. package/src/lightning-parts/primitives/EListHandleMetadata.sol +67 -0
  61. package/src/lightning-parts/primitives/HandleGeneration.sol +31 -8
  62. package/src/lightning-parts/primitives/HandleMetadata.sol +10 -3
  63. package/src/lightning-parts/primitives/interfaces/IEListHandleMetadata.sol +8 -0
  64. package/src/lightning-parts/primitives/test/SignatureVerifier.t.sol +1 -1
  65. package/src/lightning-parts/test/Elist.t.sol +218 -0
  66. package/src/lightning-parts/test/HandleMetadata.t.sol +66 -23
  67. package/src/lightning-parts/test/TestDecryptionAttestationInSynchronousFlow.t.sol +41 -13
  68. package/src/misc/ABIHelper.sol +15 -0
  69. package/src/pasted-dependencies/ICreateX.sol +1 -1
  70. package/src/periphery/IncoUtils.sol +1 -1
  71. package/src/periphery/SessionVerifier.sol +4 -4
  72. package/src/shared/IOwnable.sol +1 -1
  73. package/src/shared/IUUPSUpgradable.sol +1 -1
  74. package/src/shared/TestUtils.sol +8 -1
  75. package/src/test/EListTester.sol +171 -0
  76. package/src/test/FakeIncoInfra/FakeComputeServer.sol +2 -2
  77. package/src/test/FakeIncoInfra/FakeIncoInfraBase.sol +3 -3
  78. package/src/test/FakeIncoInfra/MockOpHandler.sol +7 -9
  79. package/src/test/FakeIncoInfra/MockRemoteAttestation.sol +2 -1
  80. package/src/test/FakeIncoInfra/getOpForSelector.sol +0 -2
  81. package/src/test/IncoTest.sol +17 -5
  82. package/src/test/OpsTest.sol +3 -2
  83. package/src/test/TEELifecycle/TEELifecycleMockTest.t.sol +85 -57
  84. package/src/test/TestDeploy.t.sol +73 -1
  85. package/src/test/TestFakeInfra.t.sol +32 -6
  86. package/src/test/TestLib.t.sol +986 -19
  87. package/src/test/TestReceive.t.sol +42 -0
  88. package/src/test/TestUpgrade.t.sol +34 -63
  89. package/src/version/IncoLightningConfig.sol +1 -1
@@ -3,11 +3,25 @@
3
3
  pragma solidity ^0.8;
4
4
 
5
5
  import {IncoLightning} from "./IncoLightning.sol";
6
- import {ebool, euint256, eaddress, ETypes} from "./Types.sol";
7
- import {DecryptionAttestation} from "./lightning-parts/DecryptionAttester.types.sol";
6
+ import {
7
+ ebool,
8
+ euint256,
9
+ eaddress,
10
+ ETypes,
11
+ elist,
12
+ IndexOutOfRange,
13
+ InvalidRange,
14
+ SliceOutOfRange,
15
+ UnsupportedListType,
16
+ HandleMismatch,
17
+ InvalidTEEAttestation,
18
+ UnexpectedDecryptedValue
19
+ } from "./Types.sol";
20
+ import {asBool} from "./shared/TypeUtils.sol";
21
+ import {DecryptionAttestation, ElementAttestationWithProof} from "./lightning-parts/DecryptionAttester.types.sol";
8
22
 
9
23
  // forge-lint: disable-next-line(screaming-snake-case-const)
10
- IncoLightning constant inco = IncoLightning(0x000000000000000000000000000000000000baBe);
24
+ IncoLightning constant inco = IncoLightning(payable(0x000000000000000000000000000000000000baBe));
11
25
  // forge-lint: disable-next-line(screaming-snake-case-const)
12
26
  address constant deployedBy = 0x000000000000000000000000000000000000baBe;
13
27
 
@@ -684,13 +698,15 @@ library e {
684
698
  /// @dev costs the inco fee
685
699
  /// @return The encrypted random value
686
700
  function rand() internal returns (euint256) {
687
- bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRand.selector, ETypes.Uint256));
701
+ bytes32 boundHandle = euint256.unwrap(asEuint256(0));
702
+ bytes32 result =
703
+ _callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
688
704
  return euint256.wrap(result);
689
705
  }
690
706
 
691
707
  /// @notice Generates a random encrypted uint256 less than a plaintext upper bound (costs the inco fee)
692
708
  /// @dev costs the inco fee
693
- /// @param upperBound The plaintext upper bound
709
+ /// @param upperBound The plaintext upper bound (exclusive). If the upper bound is 0, the whole 256bit range is sampled, equivalent to providing type(uint256).max as upper bound.
694
710
  /// @return The encrypted random value
695
711
  function randBounded(uint256 upperBound) internal returns (euint256) {
696
712
  bytes32 boundHandle = euint256.unwrap(asEuint256(upperBound));
@@ -701,7 +717,7 @@ library e {
701
717
 
702
718
  /// @notice Generates a random encrypted uint256 less than an encrypted upper bound (costs the inco fee)
703
719
  /// @dev costs the inco fee
704
- /// @param upperBound The encrypted upper bound
720
+ /// @param upperBound The encrypted upper bound (exclusive). If the upper bound is e(0), the whole 256bit range is sampled, equivalent to providing e(type(uint256).max) as upper bound.
705
721
  /// @return The encrypted random value
706
722
  function randBounded(euint256 upperBound) internal returns (euint256) {
707
723
  bytes32 boundHandle = euint256.unwrap(s(upperBound));
@@ -731,13 +747,6 @@ library e {
731
747
  return inco.asEaddress(a);
732
748
  }
733
749
 
734
- /// @notice Casts an encrypted uint256 to an encrypted bool
735
- /// @param a The encrypted uint256 value
736
- /// @return The encrypted bool value
737
- function asEbool(euint256 a) internal returns (ebool) {
738
- return ebool.wrap(inco.eCast(euint256.unwrap(a), ETypes.Bool));
739
- }
740
-
741
750
  /// @notice Casts an encrypted bool to an encrypted uint256
742
751
  /// @param a The encrypted bool value
743
752
  /// @return The encrypted uint256 value
@@ -945,4 +954,339 @@ library e {
945
954
  return abi.decode(result, (bytes32));
946
955
  }
947
956
 
957
+ // ═══════════════════════════════════════════════════════════
958
+ // EList helpers
959
+ // ═══════════════════════════════════════════════════════════
960
+
961
+ /// @notice Returns the type of the elements contained within the list.
962
+ /// @param handle EList handle to read container type from.
963
+ /// @return ret Type of each element in the list.
964
+ function listTypeOf(elist handle) internal pure returns (ETypes ret) {
965
+ return ETypes(uint8(uint256(elist.unwrap(handle)) >> 16));
966
+ }
967
+
968
+ /// @notice Creates a new empty list. Type must be specified ahead of time and can not be changed.
969
+ /// @param listType Type of each element in the list.
970
+ /// @return ret A new elist handle
971
+ function newEList(ETypes listType) internal returns (elist ret) {
972
+ return inco.newEList(new bytes32[](0), listType);
973
+ }
974
+
975
+ /// @notice Creates a new list from existing array of handles.
976
+ /// @param handles An array of handles to create a new list from
977
+ /// @param listType Type of each element in the list.
978
+ /// @return ret A new elist handle
979
+ function newEList(bytes32[] memory handles, ETypes listType) internal returns (elist ret) {
980
+ return inco.newEList{value: inco.getEListFee(uint16(handles.length), listType)}(handles, listType);
981
+ }
982
+
983
+ /// @notice Takes an array of user encrypted ciphertexts and returns a new elist handle.
984
+ /// @param ciphertexts An array of encrypted user inputs
985
+ /// @param listType Expected type of each element in the list.
986
+ /// @param user Address of the user encrypting the ciphertexts.
987
+ /// @return ret A new elist handle
988
+ /// @dev each ciphertext costs the inco fee
989
+ function newEList(bytes[] memory ciphertexts, ETypes listType, address user) internal returns (elist ret) {
990
+ return inco.newEList{value: inco.getEListFee(uint16(ciphertexts.length), listType)}(ciphertexts, listType, user);
991
+ }
992
+
993
+ /// @notice Appends an ebool element at the end of a list.
994
+ /// @param a An elist handle to append to.
995
+ /// @param b Element value to be appended.
996
+ /// @return ret A new elist handle with length len(a)+1.
997
+ function append(elist a, ebool b) internal returns (elist ret) {
998
+ return inco.listAppend{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(a, ebool.unwrap(s(b)));
999
+ }
1000
+
1001
+ /// @notice Appends an euint256 element at the end of a list.
1002
+ /// @param a An elist handle to append to.
1003
+ /// @param b Element value to be appended.
1004
+ /// @return ret A new elist handle with length len(a)+1.
1005
+ function append(elist a, euint256 b) internal returns (elist ret) {
1006
+ return inco.listAppend{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(a, euint256.unwrap(s(b)));
1007
+ }
1008
+
1009
+ /// @notice Replaces an element at some hidden index "i" (ebool variant).
1010
+ /// @dev If the encrypted index is out of bounds, the operation is silently ignored
1011
+ /// and the returned list is identical to the input. This avoids leaking index validity.
1012
+ /// @param a EList handle to modify element in.
1013
+ /// @param i Hidden index position of an element to modify.
1014
+ /// @param b Element value to be changed.
1015
+ /// @return ret A new elist handle
1016
+ function set(elist a, euint256 i, ebool b) internal returns (elist ret) {
1017
+ return
1018
+ inco.listSet{value: inco.getEListFee(length(a), listTypeOf(a))}(
1019
+ a, euint256.unwrap(s(i)), ebool.unwrap(s(b))
1020
+ );
1021
+ }
1022
+
1023
+ /// @notice Replaces an element at some hidden index "i" (euint256 variant).
1024
+ /// @dev If the encrypted index is out of bounds, the operation is silently ignored
1025
+ /// and the returned list is identical to the input. This avoids leaking index validity.
1026
+ /// @param a EList handle to modify element in.
1027
+ /// @param i Hidden index position of an element to modify.
1028
+ /// @param b Element value to be changed.
1029
+ /// @return ret A new elist handle
1030
+ function set(elist a, euint256 i, euint256 b) internal returns (elist ret) {
1031
+ return inco.listSet{value: inco.getEListFee(length(a), listTypeOf(a))}(
1032
+ a, euint256.unwrap(s(i)), euint256.unwrap(s(b))
1033
+ );
1034
+ }
1035
+
1036
+ /// @notice Replaces an element at plaintext index "i" (ebool variant). Reverts if out of range.
1037
+ /// @param a EList handle to modify element in.
1038
+ /// @param i Index position of element to modify.
1039
+ /// @param b Element value to be changed.
1040
+ /// @return ret A new elist handle
1041
+ function set(elist a, uint16 i, ebool b) internal returns (elist ret) {
1042
+ require(i < length(a), IndexOutOfRange(i, length(a)));
1043
+ return inco.listSet{value: inco.getEListFee(length(a), listTypeOf(a))}(
1044
+ a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b))
1045
+ );
1046
+ }
1047
+
1048
+ /// @notice Replaces an element at plaintext index "i" (euint256 variant). Reverts if out of range.
1049
+ /// @param a EList handle to modify element in.
1050
+ /// @param i Index position of element to modify.
1051
+ /// @param b Element value to be changed.
1052
+ /// @return ret A new elist handle
1053
+ function set(elist a, uint16 i, euint256 b) internal returns (elist ret) {
1054
+ require(i < length(a), IndexOutOfRange(i, length(a)));
1055
+ return inco.listSet{value: inco.getEListFee(length(a), listTypeOf(a))}(
1056
+ a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b))
1057
+ );
1058
+ }
1059
+
1060
+ /// @notice Return hidden element at some hidden position (ebool variant).
1061
+ /// @param a EList handle to get element from.
1062
+ /// @param i Hidden index position to get element at.
1063
+ /// @param defaultValue A default element value returned if index is out of range.
1064
+ /// @return ret A new handle for the element or the defaultValue
1065
+ function getOr(elist a, euint256 i, ebool defaultValue) internal returns (ebool ret) {
1066
+ return ebool.wrap(inco.listGetOr(a, euint256.unwrap(s(i)), ebool.unwrap(s(defaultValue))));
1067
+ }
1068
+
1069
+ /// @notice Return hidden element at some hidden position (euint256 variant).
1070
+ /// @param a EList handle to get element from.
1071
+ /// @param i Hidden index position to get element at.
1072
+ /// @param defaultValue A default element value returned if index is out of range.
1073
+ /// @return ret A new handle for the element or the defaultValue
1074
+ function getOr(elist a, euint256 i, euint256 defaultValue) internal returns (euint256 ret) {
1075
+ return euint256.wrap(inco.listGetOr(a, euint256.unwrap(s(i)), euint256.unwrap(s(defaultValue))));
1076
+ }
1077
+
1078
+ /// @notice Return hidden element at a known position as ebool.
1079
+ /// @param a EList handle to get element from.
1080
+ /// @param i Index position to get element at.
1081
+ /// @return ret Returns a handle for the element.
1082
+ function getEbool(elist a, uint16 i) internal returns (ebool ret) {
1083
+ return ebool.wrap(inco.listGet(a, i));
1084
+ }
1085
+
1086
+ /// @notice Return hidden element at a known position as euint256.
1087
+ /// @param a EList handle to get element from.
1088
+ /// @param i Index position to get element at.
1089
+ /// @return ret Returns a handle for the element.
1090
+ function getEuint256(elist a, uint16 i) internal returns (euint256 ret) {
1091
+ return euint256.wrap(inco.listGet(a, i));
1092
+ }
1093
+
1094
+ /// @notice Inserts a hidden element at a desired hidden position (ebool, hidden index).
1095
+ /// @param a An elist handle to insert into.
1096
+ /// @param i Hidden index position to insert at.
1097
+ /// @param b Element value to be inserted.
1098
+ /// @return ret A new elist handle with length len(a)+1.
1099
+ function insert(elist a, euint256 i, ebool b) internal returns (elist ret) {
1100
+ return inco.listInsert{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(
1101
+ a, euint256.unwrap(s(i)), ebool.unwrap(s(b))
1102
+ );
1103
+ }
1104
+
1105
+ /// @notice Inserts an ebool element at a known position. Reverts if out of range.
1106
+ /// @param a An elist handle to insert into.
1107
+ /// @param i Index position to insert at.
1108
+ /// @param b Element value to be inserted.
1109
+ /// @return ret A new elist handle with length len(a)+1.
1110
+ function insert(elist a, uint16 i, ebool b) internal returns (elist ret) {
1111
+ require(i < length(a), IndexOutOfRange(i, length(a)));
1112
+ return inco.listInsert{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(
1113
+ a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b))
1114
+ );
1115
+ }
1116
+
1117
+ /// @notice Inserts a hidden element at a desired hidden position (euint256, hidden index).
1118
+ /// @param a An elist handle to insert into.
1119
+ /// @param i Hidden index position to insert at.
1120
+ /// @param b Element value to be inserted.
1121
+ /// @return ret A new elist handle with length len(a)+1.
1122
+ function insert(elist a, euint256 i, euint256 b) internal returns (elist ret) {
1123
+ return inco.listInsert{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(
1124
+ a, euint256.unwrap(s(i)), euint256.unwrap(s(b))
1125
+ );
1126
+ }
1127
+
1128
+ /// @notice Inserts a euint256 element at a known position. Reverts if out of range.
1129
+ /// @param a An elist handle to insert into.
1130
+ /// @param i Index position to insert at.
1131
+ /// @param b Element value to be inserted.
1132
+ /// @return ret A new elist handle with length len(a)+1.
1133
+ function insert(elist a, uint16 i, euint256 b) internal returns (elist ret) {
1134
+ require(i < length(a), IndexOutOfRange(i, length(a)));
1135
+ return inco.listInsert{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(
1136
+ a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b))
1137
+ );
1138
+ }
1139
+
1140
+ /// @notice Concatenates two elists into one.
1141
+ /// @param a EList handle to be prepended
1142
+ /// @param b EList handle to be appended
1143
+ /// @return ret A new elist handle with length len(a)+len(b).
1144
+ function concat(elist a, elist b) internal returns (elist ret) {
1145
+ return inco.listConcat{value: inco.getEListFee(length(a) + length(b), listTypeOf(a))}(a, b);
1146
+ }
1147
+
1148
+ /// @notice Slices a list from plaintext start to plaintext end.
1149
+ /// @param a EList handle to be sliced
1150
+ /// @param start Starting index (inclusive).
1151
+ /// @param end End index (exclusive). Must be >= start and within bounds.
1152
+ /// @return ret A new sliced list with length "end-start".
1153
+ function slice(elist a, uint16 start, uint16 end) internal returns (elist ret) {
1154
+ require(end >= start, InvalidRange(start, end));
1155
+ require(end <= length(a), SliceOutOfRange(start, end, length(a)));
1156
+ require(start < length(a), SliceOutOfRange(start, end, length(a)));
1157
+ bytes32 defaultValue;
1158
+ if (ETypes.Uint256 == listTypeOf(a)) {
1159
+ defaultValue = euint256.unwrap(asEuint256(0));
1160
+ } else if (ETypes.Bool == listTypeOf(a)) {
1161
+ defaultValue = ebool.unwrap(asEbool(false));
1162
+ } else {
1163
+ revert UnsupportedListType(listTypeOf(a));
1164
+ }
1165
+ return inco.listSlice{value: inco.getEListFee(end - start, listTypeOf(a))}(
1166
+ a, euint256.unwrap(asEuint256(start)), end - start, defaultValue
1167
+ );
1168
+ }
1169
+
1170
+ /// @notice Slices at a hidden index with a specified length (euint256 default).
1171
+ /// @param a EList handle to be sliced.
1172
+ /// @param start Hidden starting index.
1173
+ /// @param len Length of the desired slice.
1174
+ /// @param defaultValue Default value if out of range.
1175
+ /// @return ret A new sliced list with length "len".
1176
+ function sliceLen(elist a, euint256 start, uint16 len, euint256 defaultValue) internal returns (elist ret) {
1177
+ return inco.listSlice{value: inco.getEListFee(len, listTypeOf(a))}(
1178
+ a, euint256.unwrap(s(start)), len, euint256.unwrap(s(defaultValue))
1179
+ );
1180
+ }
1181
+
1182
+ /// @notice Slices at a hidden index with a specified length (ebool default).
1183
+ /// @param a EList handle to be sliced.
1184
+ /// @param start Hidden starting index.
1185
+ /// @param len Length of the desired slice.
1186
+ /// @param defaultValue Default value if out of range.
1187
+ /// @return ret A new sliced list with length "len".
1188
+ function sliceLen(elist a, euint256 start, uint16 len, ebool defaultValue) internal returns (elist ret) {
1189
+ return inco.listSlice{value: inco.getEListFee(len, listTypeOf(a))}(
1190
+ a, euint256.unwrap(s(start)), len, ebool.unwrap(s(defaultValue))
1191
+ );
1192
+ }
1193
+
1194
+ /// @notice Creates a new list populated with ordered values from within range.
1195
+ /// @param start Start value of the range, inclusive.
1196
+ /// @param end End of the range, exclusive. Must be >= start.
1197
+ /// @return ret A new elist handle with length "end-start"
1198
+ function range(uint16 start, uint16 end, ETypes listType) internal returns (elist ret) {
1199
+ return inco.listRange{value: inco.getEListFee(end - start, listType)}(start, end, listType);
1200
+ }
1201
+
1202
+ /// @notice Deterministically shuffles elements within a list.
1203
+ /// @dev costs the inco fee
1204
+ /// @param a elist handle to be shuffled
1205
+ /// @return ret A new elist handle with elements shuffled
1206
+ function shuffle(elist a) internal returns (elist ret) {
1207
+ return inco.listShuffle{value: inco.getEListFee(length(a), listTypeOf(a))}(a);
1208
+ }
1209
+
1210
+ /// @notice A convenience function equivalent to range() followed by shuffle().
1211
+ /// @dev costs the inco fee
1212
+ /// @param start Start value of the range, inclusive.
1213
+ /// @param end End of the range, exclusive. Must be >= start.
1214
+ /// @return ret A new elist handle in random order with length "end-start".
1215
+ function shuffledRange(uint16 start, uint16 end, ETypes listType) internal returns (elist ret) {
1216
+ uint256 fee = inco.getEListFee(end - start, listType);
1217
+ elist rangeList = inco.listRange{value: fee}(start, end, listType);
1218
+ return inco.listShuffle{value: fee}(rangeList);
1219
+ }
1220
+
1221
+ /// @notice Reverses the order of elements in a list.
1222
+ /// @param a Elist handle to be reversed
1223
+ /// @return ret A new elist handle with elements in reverse order
1224
+ function reverse(elist a) internal returns (elist ret) {
1225
+ return inco.listReverse{value: inco.getEListFee(length(a), listTypeOf(a))}(a);
1226
+ }
1227
+
1228
+ /// @notice Returns the length of the list in plaintext. Pure function, no gas cost.
1229
+ /// @param a EList handle to read the length from
1230
+ /// @return len The length of the list
1231
+ function length(elist a) internal pure returns (uint16 len) {
1232
+ return inco.lengthOf(elist.unwrap(a));
1233
+ }
1234
+
1235
+ /**
1236
+ * @notice verifyEListDecryption verifies elist decryption attestation and commitment proof. Each element can be either a pre-computed hash or a commitment-value pair.
1237
+ * @param elistHandle The elist handle that was decrypted
1238
+ * @param proofElements Array of proof elements. Each can provide either pairHash directly, or commitment+value to compute the pairHash
1239
+ * @param proof The expected proof that should match keccak256 of all concatenated pair hashes
1240
+ * @param signatures Array of signatures from attesters
1241
+ * @return bool True if verification succeeds
1242
+ * @dev For privacy, publish only pairHash. For transparency, publish commitment+value. Can mix both in the same array.
1243
+ */
1244
+ function verifyEListDecryption(
1245
+ elist elistHandle,
1246
+ ElementAttestationWithProof[] memory proofElements,
1247
+ bytes32 proof,
1248
+ bytes[] memory signatures
1249
+ ) internal view returns (bool) {
1250
+ return inco.incoVerifier()
1251
+ .isValidEListDecryptionAttestation(elist.unwrap(elistHandle), proofElements, proof, signatures);
1252
+ }
1253
+
1254
+ /**
1255
+ * @notice Checks a decryption attestation for an encrypted bool against an expected plaintext value
1256
+ * @param handle The encrypted handle
1257
+ * @param expected The expected plaintext value
1258
+ * @param decryption The decryption attestation to verify
1259
+ * @param signatures The covalidator signatures for the attestation
1260
+ * @dev Reverts if the handle doesn't match, the decrypted value doesn't match the expected value, or the attestation is invalid
1261
+ */
1262
+ function requireEqual(
1263
+ ebool handle,
1264
+ bool expected,
1265
+ DecryptionAttestation memory decryption,
1266
+ bytes[] memory signatures
1267
+ ) internal view {
1268
+ require(ebool.unwrap(handle) == decryption.handle, HandleMismatch());
1269
+ require(asBool(decryption.value) == expected, UnexpectedDecryptedValue());
1270
+ require(inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures), InvalidTEEAttestation());
1271
+ }
1272
+
1273
+ /**
1274
+ * @notice Checks a decryption attestation for an encrypted uint256 against an expected plaintext value
1275
+ * @param handle The encrypted handle
1276
+ * @param expected The expected plaintext value
1277
+ * @param decryption The decryption attestation to verify
1278
+ * @param signatures The covalidator signatures for the attestation
1279
+ * @dev Reverts if the handle doesn't match, the decrypted value doesn't match the expected value, or the attestation is invalid
1280
+ */
1281
+ function requireEqual(
1282
+ euint256 handle,
1283
+ uint256 expected,
1284
+ DecryptionAttestation memory decryption,
1285
+ bytes[] memory signatures
1286
+ ) internal view {
1287
+ require(euint256.unwrap(handle) == decryption.handle, HandleMismatch());
1288
+ require(uint256(decryption.value) == expected, UnexpectedDecryptedValue());
1289
+ require(inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures), InvalidTEEAttestation());
1290
+ }
1291
+
948
1292
  }