@inco/lightning 0.8.0-devnet-9 → 0.8.0-devnet-10
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 +22 -0
- package/package.json +1 -1
- package/src/IncoLightning.sol +2 -11
- package/src/Lib.alphanet.sol +261 -2
- package/src/Lib.demonet.sol +261 -2
- package/src/Lib.devnet.sol +262 -3
- package/src/Lib.sol +262 -3
- package/src/Lib.template.sol +283 -2
- package/src/Lib.testnet.sol +261 -2
- package/src/Types.sol +13 -0
- package/src/interfaces/IIncoLightning.sol +2 -12
- package/src/libs/incoLightning_alphanet_v0_297966649.sol +261 -2
- package/src/libs/incoLightning_alphanet_v1_725458969.sol +261 -2
- package/src/libs/incoLightning_alphanet_v2_976644394.sol +261 -2
- package/src/libs/incoLightning_demonet_v0_863421733.sol +261 -2
- package/src/libs/incoLightning_demonet_v2_467437523.sol +261 -2
- package/src/libs/incoLightning_devnet_v0_340846814.sol +261 -2
- package/src/libs/incoLightning_devnet_v1_904635675.sol +261 -2
- package/src/libs/incoLightning_devnet_v2_295237520.sol +261 -2
- package/src/libs/incoLightning_devnet_v3_976859633.sol +261 -2
- package/src/libs/incoLightning_devnet_v4_409204766.sol +261 -2
- package/src/libs/incoLightning_devnet_v5_203964628.sol +261 -2
- package/src/libs/incoLightning_devnet_v6_281949651.sol +1201 -0
- package/src/libs/incoLightning_testnet_v0_183408998.sol +261 -2
- package/src/libs/incoLightning_testnet_v2_889158349.sol +261 -2
- package/src/lightning-parts/AccessControl/interfaces/IBaseAccessControlList.sol +2 -1
- package/src/lightning-parts/DecryptionAttester.sol +38 -2
- package/src/lightning-parts/DecryptionAttester.types.sol +14 -0
- package/src/lightning-parts/EList.sol +323 -0
- package/src/lightning-parts/TrivialEncryption.sol +1 -2
- package/src/lightning-parts/interfaces/IDecryptionAttester.sol +7 -1
- package/src/lightning-parts/interfaces/IEList.sol +35 -0
- package/src/lightning-parts/interfaces/IEncryptedInput.sol +3 -1
- package/src/lightning-parts/interfaces/IEncryptedOperations.sol +3 -1
- package/src/lightning-parts/interfaces/ITrivialEncryption.sol +3 -1
- package/src/lightning-parts/primitives/EListHandleGeneration.sol +63 -0
- package/src/lightning-parts/primitives/EListHandleMetadata.sol +60 -0
- package/src/lightning-parts/primitives/interfaces/IEListHandleMetadata.sol +8 -0
- package/src/lightning-parts/test/Elist.t.sol +67 -0
- package/src/misc/ABIHelper.sol +15 -0
- package/src/shared/TestUtils.sol +8 -1
- package/src/test/EListTester.sol +148 -0
- package/src/version/IncoLightningConfig.sol +1 -1
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
pragma solidity ^0.8;
|
|
7
7
|
|
|
8
8
|
import { IncoLightning } from "../IncoLightning.sol";
|
|
9
|
-
import { ebool, euint256, eaddress, ETypes } from "../Types.sol";
|
|
10
|
-
import { DecryptionAttestation } from "../lightning-parts/DecryptionAttester.types.sol";
|
|
9
|
+
import { ebool, euint256, eaddress, ETypes, elist, IndexOutOfRange, InvalidRange, SliceOutOfRange, UnsupportedListType } from "../Types.sol";
|
|
10
|
+
import { DecryptionAttestation, ElementDecryptionProof } from "../lightning-parts/DecryptionAttester.types.sol";
|
|
11
11
|
|
|
12
12
|
IncoLightning constant inco = IncoLightning(0x63D8135aF4D393B1dB43B649010c8D3EE19FC9fd);
|
|
13
13
|
address constant deployedBy = 0x8202D2D747784Cb7D48868E44C42C4bf162a70BC;
|
|
@@ -939,4 +939,263 @@ library e {
|
|
|
939
939
|
}
|
|
940
940
|
return abi.decode(result, (bytes32));
|
|
941
941
|
}
|
|
942
|
+
|
|
943
|
+
/// @notice Returns the type of the elements contained within the list.
|
|
944
|
+
/// @param handle EList handle to read container type from.
|
|
945
|
+
/// @return ret Type of each element in the list.
|
|
946
|
+
function listTypeOf(elist handle) internal pure returns (ETypes ret) {
|
|
947
|
+
return ETypes(uint8(uint256(elist.unwrap(handle)) >> 16));
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
/// @notice Creates a new empty list. Type must be specified ahead of time and can not be changed.
|
|
951
|
+
/// @param listType Type of each element in the list.
|
|
952
|
+
/// @return ret A new elist handle
|
|
953
|
+
function newEList(ETypes listType) internal returns (elist ret) {
|
|
954
|
+
return inco.newEList(new bytes32[](0), listType);
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
/// @notice Creates a new list from existing array of handles.
|
|
958
|
+
/// @param handles An array of handles to create a new list from
|
|
959
|
+
/// @param listType Type of each element in the list.
|
|
960
|
+
/// @return ret A new elist handle
|
|
961
|
+
function newEList(bytes32[] memory handles, ETypes listType) internal returns (elist ret) {
|
|
962
|
+
return inco.newEList(handles, listType);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
/// @notice Takes an array of user encrypted ciphertexts and returns a new elist handle.
|
|
966
|
+
/// @param ciphertexts An array of encrypted user inputs
|
|
967
|
+
/// @param listType Expected type of each element in the list.
|
|
968
|
+
/// @param user Address of the user encrypting the ciphertexts.
|
|
969
|
+
/// @return ret A new elist handle
|
|
970
|
+
/// @dev each ciphertext costs the inco fee
|
|
971
|
+
function newEList(bytes[] memory ciphertexts, ETypes listType, address user) internal returns (elist ret) {
|
|
972
|
+
return inco.newEList{value: inco.getFee() * ciphertexts.length}(ciphertexts, listType, user);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
/// @notice Appends an ebool element at the end of a list.
|
|
976
|
+
/// @param a An elist handle to append to.
|
|
977
|
+
/// @param b Element value to be appended.
|
|
978
|
+
/// @return ret A new elist handle with length len(a)+1.
|
|
979
|
+
function append(elist a, ebool b) internal returns (elist ret) {
|
|
980
|
+
return inco.listAppend(a, ebool.unwrap(s(b)));
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
/// @notice Appends an euint256 element at the end of a list.
|
|
984
|
+
/// @param a An elist handle to append to.
|
|
985
|
+
/// @param b Element value to be appended.
|
|
986
|
+
/// @return ret A new elist handle with length len(a)+1.
|
|
987
|
+
function append(elist a, euint256 b) internal returns (elist ret) {
|
|
988
|
+
return inco.listAppend(a, euint256.unwrap(s(b)));
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
/// @notice Replaces an element at some hidden index "i" (ebool variant).
|
|
992
|
+
/// @param a EList handle to modify element in.
|
|
993
|
+
/// @param i Hidden index position of an element to modify.
|
|
994
|
+
/// @param b Element value to be changed.
|
|
995
|
+
/// @return ret A new elist handle
|
|
996
|
+
function set(elist a, euint256 i, ebool b) internal returns (elist ret) {
|
|
997
|
+
return inco.listSet(a, euint256.unwrap(s(i)), ebool.unwrap(s(b)));
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
/// @notice Replaces an element at some hidden index "i" (euint256 variant).
|
|
1001
|
+
/// @param a EList handle to modify element in.
|
|
1002
|
+
/// @param i Hidden index position of an element to modify.
|
|
1003
|
+
/// @param b Element value to be changed.
|
|
1004
|
+
/// @return ret A new elist handle
|
|
1005
|
+
function set(elist a, euint256 i, euint256 b) internal returns (elist ret) {
|
|
1006
|
+
return inco.listSet(a, euint256.unwrap(s(i)), euint256.unwrap(s(b)));
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
/// @notice Replaces an element at plaintext index "i" (ebool variant). Reverts if out of range.
|
|
1010
|
+
/// @param a EList handle to modify element in.
|
|
1011
|
+
/// @param i Index position of element to modify.
|
|
1012
|
+
/// @param b Element value to be changed.
|
|
1013
|
+
/// @return ret A new elist handle
|
|
1014
|
+
function set(elist a, uint16 i, ebool b) internal returns (elist ret) {
|
|
1015
|
+
require(i < length(a), IndexOutOfRange(i, length(a)));
|
|
1016
|
+
return inco.listSet(a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b)));
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
/// @notice Replaces an element at plaintext index "i" (euint256 variant). Reverts if out of range.
|
|
1020
|
+
/// @param a EList handle to modify element in.
|
|
1021
|
+
/// @param i Index position of element to modify.
|
|
1022
|
+
/// @param b Element value to be changed.
|
|
1023
|
+
/// @return ret A new elist handle
|
|
1024
|
+
function set(elist a, uint16 i, euint256 b) internal returns (elist ret) {
|
|
1025
|
+
require(i < length(a), IndexOutOfRange(i, length(a)));
|
|
1026
|
+
return inco.listSet(a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b)));
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
/// @notice Return hidden element at some hidden position (ebool variant).
|
|
1030
|
+
/// @param a EList handle to get element from.
|
|
1031
|
+
/// @param i Hidden index position to get element at.
|
|
1032
|
+
/// @param defaultValue A default element value returned if index is out of range.
|
|
1033
|
+
/// @return ret A new handle for the element or the defaultValue
|
|
1034
|
+
function getOr(elist a, euint256 i, ebool defaultValue) internal returns (ebool ret) {
|
|
1035
|
+
return ebool.wrap(inco.listGetOr(a, euint256.unwrap(s(i)), ebool.unwrap(s(defaultValue))));
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
/// @notice Return hidden element at some hidden position (euint256 variant).
|
|
1039
|
+
/// @param a EList handle to get element from.
|
|
1040
|
+
/// @param i Hidden index position to get element at.
|
|
1041
|
+
/// @param defaultValue A default element value returned if index is out of range.
|
|
1042
|
+
/// @return ret A new handle for the element or the defaultValue
|
|
1043
|
+
function getOr(elist a, euint256 i, euint256 defaultValue) internal returns (euint256 ret) {
|
|
1044
|
+
return euint256.wrap(inco.listGetOr(a, euint256.unwrap(s(i)), euint256.unwrap(s(defaultValue))));
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
/// @notice Return hidden element at a known position as ebool.
|
|
1048
|
+
/// @param a EList handle to get element from.
|
|
1049
|
+
/// @param i Index position to get element at.
|
|
1050
|
+
/// @return ret Returns a handle for the element.
|
|
1051
|
+
function getEbool(elist a, uint16 i) internal returns (ebool ret) {
|
|
1052
|
+
return ebool.wrap(inco.listGet(a, i));
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
/// @notice Return hidden element at a known position as euint256.
|
|
1056
|
+
/// @param a EList handle to get element from.
|
|
1057
|
+
/// @param i Index position to get element at.
|
|
1058
|
+
/// @return ret Returns a handle for the element.
|
|
1059
|
+
function getEuint256(elist a, uint16 i) internal returns (euint256 ret) {
|
|
1060
|
+
return euint256.wrap(inco.listGet(a, i));
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
/// @notice Inserts a hidden element at a desired hidden position (ebool, hidden index).
|
|
1064
|
+
/// @param a An elist handle to insert into.
|
|
1065
|
+
/// @param i Hidden index position to insert at.
|
|
1066
|
+
/// @param b Element value to be inserted.
|
|
1067
|
+
/// @return ret A new elist handle with length len(a)+1.
|
|
1068
|
+
function insert(elist a, euint256 i, ebool b) internal returns (elist ret) {
|
|
1069
|
+
return inco.listInsert(a, euint256.unwrap(s(i)), ebool.unwrap(s(b)));
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
/// @notice Inserts an ebool element at a known position. Reverts if out of range.
|
|
1073
|
+
/// @param a An elist handle to insert into.
|
|
1074
|
+
/// @param i Index position to insert at.
|
|
1075
|
+
/// @param b Element value to be inserted.
|
|
1076
|
+
/// @return ret A new elist handle with length len(a)+1.
|
|
1077
|
+
function insert(elist a, uint16 i, ebool b) internal returns (elist ret) {
|
|
1078
|
+
require(i < length(a), IndexOutOfRange(i, length(a)));
|
|
1079
|
+
return inco.listInsert(a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b)));
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/// @notice Inserts a hidden element at a desired hidden position (euint256, hidden index).
|
|
1083
|
+
/// @param a An elist handle to insert into.
|
|
1084
|
+
/// @param i Hidden index position to insert at.
|
|
1085
|
+
/// @param b Element value to be inserted.
|
|
1086
|
+
/// @return ret A new elist handle with length len(a)+1.
|
|
1087
|
+
function insert(elist a, euint256 i, euint256 b) internal returns (elist ret) {
|
|
1088
|
+
return inco.listInsert(a, euint256.unwrap(s(i)), euint256.unwrap(s(b)));
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
/// @notice Inserts a euint256 element at a known position. Reverts if out of range.
|
|
1092
|
+
/// @param a An elist handle to insert into.
|
|
1093
|
+
/// @param i Index position to insert at.
|
|
1094
|
+
/// @param b Element value to be inserted.
|
|
1095
|
+
/// @return ret A new elist handle with length len(a)+1.
|
|
1096
|
+
function insert(elist a, uint16 i, euint256 b) internal returns (elist ret) {
|
|
1097
|
+
require(i < length(a), IndexOutOfRange(i, length(a)));
|
|
1098
|
+
return inco.listInsert(a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b)));
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
/// @notice Concatenates two elists into one.
|
|
1102
|
+
/// @param a EList handle to be prepended
|
|
1103
|
+
/// @param b EList handle to be appended
|
|
1104
|
+
/// @return ret A new elist handle with length len(a)+len(b).
|
|
1105
|
+
function concat(elist a, elist b) internal returns (elist ret) {
|
|
1106
|
+
return inco.listConcat(a, b);
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
/// @notice Slices a list from plaintext start to plaintext end.
|
|
1110
|
+
/// @param a EList handle to be sliced
|
|
1111
|
+
/// @param start Starting index (inclusive).
|
|
1112
|
+
/// @param end End index (exclusive). Must be >= start and within bounds.
|
|
1113
|
+
/// @return ret A new sliced list with length "end-start".
|
|
1114
|
+
function slice(elist a, uint16 start, uint16 end) internal returns (elist ret) {
|
|
1115
|
+
require(end >= start, InvalidRange(start, end));
|
|
1116
|
+
require(end <= length(a), SliceOutOfRange(start, end, length(a)));
|
|
1117
|
+
require(start < length(a), SliceOutOfRange(start, end, length(a)));
|
|
1118
|
+
bytes32 defaultValue;
|
|
1119
|
+
if (ETypes.Uint256 == listTypeOf(a)) {
|
|
1120
|
+
defaultValue = euint256.unwrap(asEuint256(0));
|
|
1121
|
+
} else if (ETypes.Bool == listTypeOf(a)) {
|
|
1122
|
+
defaultValue = ebool.unwrap(asEbool(false));
|
|
1123
|
+
} else {
|
|
1124
|
+
revert UnsupportedListType(listTypeOf(a));
|
|
1125
|
+
}
|
|
1126
|
+
return inco.listSlice(a, euint256.unwrap(asEuint256(start)), end - start, defaultValue);
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
/// @notice Slices at a hidden index with a specified length (euint256 default).
|
|
1130
|
+
/// @param a EList handle to be sliced.
|
|
1131
|
+
/// @param start Hidden starting index.
|
|
1132
|
+
/// @param len Length of the desired slice.
|
|
1133
|
+
/// @param defaultValue Default value if out of range.
|
|
1134
|
+
/// @return ret A new sliced list with length "len".
|
|
1135
|
+
function sliceLen(elist a, euint256 start, uint16 len, euint256 defaultValue) internal returns (elist ret) {
|
|
1136
|
+
return inco.listSlice(a, euint256.unwrap(s(start)), len, euint256.unwrap(s(defaultValue)));
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
/// @notice Slices at a hidden index with a specified length (ebool default).
|
|
1140
|
+
/// @param a EList handle to be sliced.
|
|
1141
|
+
/// @param start Hidden starting index.
|
|
1142
|
+
/// @param len Length of the desired slice.
|
|
1143
|
+
/// @param defaultValue Default value if out of range.
|
|
1144
|
+
/// @return ret A new sliced list with length "len".
|
|
1145
|
+
function sliceLen(elist a, euint256 start, uint16 len, ebool defaultValue) internal returns (elist ret) {
|
|
1146
|
+
return inco.listSlice(a, euint256.unwrap(s(start)), len, ebool.unwrap(s(defaultValue)));
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
/// @notice Creates a new list populated with ordered values from within range.
|
|
1150
|
+
/// @param start Start value of the range, inclusive.
|
|
1151
|
+
/// @param end End of the range, exclusive. Must be >= start.
|
|
1152
|
+
/// @return ret A new elist handle with length "end-start"
|
|
1153
|
+
function range(uint16 start, uint16 end) internal returns (elist ret) {
|
|
1154
|
+
return inco.listRange(start, end);
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
/// @notice Deterministically shuffles elements within a list.
|
|
1158
|
+
/// @dev costs the inco fee
|
|
1159
|
+
/// @param a elist handle to be shuffled
|
|
1160
|
+
/// @return ret A new elist handle with elements shuffled
|
|
1161
|
+
function shuffle(elist a) internal returns (elist ret) {
|
|
1162
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.listShuffle.selector, a));
|
|
1163
|
+
return elist.wrap(result);
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
/// @notice A convenience function equivalent to range() followed by shuffle().
|
|
1167
|
+
/// @dev costs the inco fee
|
|
1168
|
+
/// @param start Start value of the range, inclusive.
|
|
1169
|
+
/// @param end End of the range, exclusive. Must be >= start.
|
|
1170
|
+
/// @return ret A new elist handle in random order with length "end-start".
|
|
1171
|
+
function shuffledRange(uint16 start, uint16 end) internal returns (elist ret) {
|
|
1172
|
+
elist rangeList = inco.listRange(start, end);
|
|
1173
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.listShuffle.selector, rangeList));
|
|
1174
|
+
return elist.wrap(result);
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
/// @notice Reverses the order of elements in a list.
|
|
1178
|
+
/// @param a Elist handle to be reversed
|
|
1179
|
+
/// @return ret A new elist handle with elements in reverse order
|
|
1180
|
+
function reverse(elist a) internal returns (elist ret) {
|
|
1181
|
+
return inco.listReverse(a);
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
/// @notice Returns the length of the list in plaintext. Pure function, no gas cost.
|
|
1185
|
+
/// @param a EList handle to read the length from
|
|
1186
|
+
/// @return len The length of the list
|
|
1187
|
+
function length(elist a) internal pure returns (uint16 len) {
|
|
1188
|
+
return inco.lengthOf(elist.unwrap(a));
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
/// @notice verifyEListDecryption verifies elist decryption attestation and commitment proof. Each element can be either a pre-computed hash or a commitment-value pair.
|
|
1192
|
+
/// @param elistHandle The elist handle that was decrypted
|
|
1193
|
+
/// @param proofElements Array of proof elements. Each can provide either pairHash directly, or commitment+value to compute the pairHash
|
|
1194
|
+
/// @param proof The expected proof that should match keccak256 of all concatenated pair hashes
|
|
1195
|
+
/// @param signatures Array of signatures from attesters
|
|
1196
|
+
/// @return bool True if verification succeeds
|
|
1197
|
+
/// @dev For privacy, publish only pairHash. For transparency, publish commitment+value. Can mix both in the same array.
|
|
1198
|
+
function verifyEListDecryption(elist elistHandle, ElementDecryptionProof[] memory proofElements, bytes32 proof, bytes[] memory signatures) internal view returns (bool) {
|
|
1199
|
+
return inco.incoVerifier().isValidEListDecryptionAttestation(elist.unwrap(elistHandle), proofElements, proof, signatures);
|
|
1200
|
+
}
|
|
942
1201
|
}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
pragma solidity ^0.8;
|
|
7
7
|
|
|
8
8
|
import { IncoLightning } from "../IncoLightning.sol";
|
|
9
|
-
import { ebool, euint256, eaddress, ETypes } from "../Types.sol";
|
|
10
|
-
import { DecryptionAttestation } from "../lightning-parts/DecryptionAttester.types.sol";
|
|
9
|
+
import { ebool, euint256, eaddress, ETypes, elist, IndexOutOfRange, InvalidRange, SliceOutOfRange, UnsupportedListType } from "../Types.sol";
|
|
10
|
+
import { DecryptionAttestation, ElementDecryptionProof } from "../lightning-parts/DecryptionAttester.types.sol";
|
|
11
11
|
|
|
12
12
|
IncoLightning constant inco = IncoLightning(0x168FDc3Ae19A5d5b03614578C58974FF30FCBe92);
|
|
13
13
|
address constant deployedBy = 0x8202D2D747784Cb7D48868E44C42C4bf162a70BC;
|
|
@@ -939,4 +939,263 @@ library e {
|
|
|
939
939
|
}
|
|
940
940
|
return abi.decode(result, (bytes32));
|
|
941
941
|
}
|
|
942
|
+
|
|
943
|
+
/// @notice Returns the type of the elements contained within the list.
|
|
944
|
+
/// @param handle EList handle to read container type from.
|
|
945
|
+
/// @return ret Type of each element in the list.
|
|
946
|
+
function listTypeOf(elist handle) internal pure returns (ETypes ret) {
|
|
947
|
+
return ETypes(uint8(uint256(elist.unwrap(handle)) >> 16));
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
/// @notice Creates a new empty list. Type must be specified ahead of time and can not be changed.
|
|
951
|
+
/// @param listType Type of each element in the list.
|
|
952
|
+
/// @return ret A new elist handle
|
|
953
|
+
function newEList(ETypes listType) internal returns (elist ret) {
|
|
954
|
+
return inco.newEList(new bytes32[](0), listType);
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
/// @notice Creates a new list from existing array of handles.
|
|
958
|
+
/// @param handles An array of handles to create a new list from
|
|
959
|
+
/// @param listType Type of each element in the list.
|
|
960
|
+
/// @return ret A new elist handle
|
|
961
|
+
function newEList(bytes32[] memory handles, ETypes listType) internal returns (elist ret) {
|
|
962
|
+
return inco.newEList(handles, listType);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
/// @notice Takes an array of user encrypted ciphertexts and returns a new elist handle.
|
|
966
|
+
/// @param ciphertexts An array of encrypted user inputs
|
|
967
|
+
/// @param listType Expected type of each element in the list.
|
|
968
|
+
/// @param user Address of the user encrypting the ciphertexts.
|
|
969
|
+
/// @return ret A new elist handle
|
|
970
|
+
/// @dev each ciphertext costs the inco fee
|
|
971
|
+
function newEList(bytes[] memory ciphertexts, ETypes listType, address user) internal returns (elist ret) {
|
|
972
|
+
return inco.newEList{value: inco.getFee() * ciphertexts.length}(ciphertexts, listType, user);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
/// @notice Appends an ebool element at the end of a list.
|
|
976
|
+
/// @param a An elist handle to append to.
|
|
977
|
+
/// @param b Element value to be appended.
|
|
978
|
+
/// @return ret A new elist handle with length len(a)+1.
|
|
979
|
+
function append(elist a, ebool b) internal returns (elist ret) {
|
|
980
|
+
return inco.listAppend(a, ebool.unwrap(s(b)));
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
/// @notice Appends an euint256 element at the end of a list.
|
|
984
|
+
/// @param a An elist handle to append to.
|
|
985
|
+
/// @param b Element value to be appended.
|
|
986
|
+
/// @return ret A new elist handle with length len(a)+1.
|
|
987
|
+
function append(elist a, euint256 b) internal returns (elist ret) {
|
|
988
|
+
return inco.listAppend(a, euint256.unwrap(s(b)));
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
/// @notice Replaces an element at some hidden index "i" (ebool variant).
|
|
992
|
+
/// @param a EList handle to modify element in.
|
|
993
|
+
/// @param i Hidden index position of an element to modify.
|
|
994
|
+
/// @param b Element value to be changed.
|
|
995
|
+
/// @return ret A new elist handle
|
|
996
|
+
function set(elist a, euint256 i, ebool b) internal returns (elist ret) {
|
|
997
|
+
return inco.listSet(a, euint256.unwrap(s(i)), ebool.unwrap(s(b)));
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
/// @notice Replaces an element at some hidden index "i" (euint256 variant).
|
|
1001
|
+
/// @param a EList handle to modify element in.
|
|
1002
|
+
/// @param i Hidden index position of an element to modify.
|
|
1003
|
+
/// @param b Element value to be changed.
|
|
1004
|
+
/// @return ret A new elist handle
|
|
1005
|
+
function set(elist a, euint256 i, euint256 b) internal returns (elist ret) {
|
|
1006
|
+
return inco.listSet(a, euint256.unwrap(s(i)), euint256.unwrap(s(b)));
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
/// @notice Replaces an element at plaintext index "i" (ebool variant). Reverts if out of range.
|
|
1010
|
+
/// @param a EList handle to modify element in.
|
|
1011
|
+
/// @param i Index position of element to modify.
|
|
1012
|
+
/// @param b Element value to be changed.
|
|
1013
|
+
/// @return ret A new elist handle
|
|
1014
|
+
function set(elist a, uint16 i, ebool b) internal returns (elist ret) {
|
|
1015
|
+
require(i < length(a), IndexOutOfRange(i, length(a)));
|
|
1016
|
+
return inco.listSet(a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b)));
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
/// @notice Replaces an element at plaintext index "i" (euint256 variant). Reverts if out of range.
|
|
1020
|
+
/// @param a EList handle to modify element in.
|
|
1021
|
+
/// @param i Index position of element to modify.
|
|
1022
|
+
/// @param b Element value to be changed.
|
|
1023
|
+
/// @return ret A new elist handle
|
|
1024
|
+
function set(elist a, uint16 i, euint256 b) internal returns (elist ret) {
|
|
1025
|
+
require(i < length(a), IndexOutOfRange(i, length(a)));
|
|
1026
|
+
return inco.listSet(a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b)));
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
/// @notice Return hidden element at some hidden position (ebool variant).
|
|
1030
|
+
/// @param a EList handle to get element from.
|
|
1031
|
+
/// @param i Hidden index position to get element at.
|
|
1032
|
+
/// @param defaultValue A default element value returned if index is out of range.
|
|
1033
|
+
/// @return ret A new handle for the element or the defaultValue
|
|
1034
|
+
function getOr(elist a, euint256 i, ebool defaultValue) internal returns (ebool ret) {
|
|
1035
|
+
return ebool.wrap(inco.listGetOr(a, euint256.unwrap(s(i)), ebool.unwrap(s(defaultValue))));
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
/// @notice Return hidden element at some hidden position (euint256 variant).
|
|
1039
|
+
/// @param a EList handle to get element from.
|
|
1040
|
+
/// @param i Hidden index position to get element at.
|
|
1041
|
+
/// @param defaultValue A default element value returned if index is out of range.
|
|
1042
|
+
/// @return ret A new handle for the element or the defaultValue
|
|
1043
|
+
function getOr(elist a, euint256 i, euint256 defaultValue) internal returns (euint256 ret) {
|
|
1044
|
+
return euint256.wrap(inco.listGetOr(a, euint256.unwrap(s(i)), euint256.unwrap(s(defaultValue))));
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
/// @notice Return hidden element at a known position as ebool.
|
|
1048
|
+
/// @param a EList handle to get element from.
|
|
1049
|
+
/// @param i Index position to get element at.
|
|
1050
|
+
/// @return ret Returns a handle for the element.
|
|
1051
|
+
function getEbool(elist a, uint16 i) internal returns (ebool ret) {
|
|
1052
|
+
return ebool.wrap(inco.listGet(a, i));
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
/// @notice Return hidden element at a known position as euint256.
|
|
1056
|
+
/// @param a EList handle to get element from.
|
|
1057
|
+
/// @param i Index position to get element at.
|
|
1058
|
+
/// @return ret Returns a handle for the element.
|
|
1059
|
+
function getEuint256(elist a, uint16 i) internal returns (euint256 ret) {
|
|
1060
|
+
return euint256.wrap(inco.listGet(a, i));
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
/// @notice Inserts a hidden element at a desired hidden position (ebool, hidden index).
|
|
1064
|
+
/// @param a An elist handle to insert into.
|
|
1065
|
+
/// @param i Hidden index position to insert at.
|
|
1066
|
+
/// @param b Element value to be inserted.
|
|
1067
|
+
/// @return ret A new elist handle with length len(a)+1.
|
|
1068
|
+
function insert(elist a, euint256 i, ebool b) internal returns (elist ret) {
|
|
1069
|
+
return inco.listInsert(a, euint256.unwrap(s(i)), ebool.unwrap(s(b)));
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
/// @notice Inserts an ebool element at a known position. Reverts if out of range.
|
|
1073
|
+
/// @param a An elist handle to insert into.
|
|
1074
|
+
/// @param i Index position to insert at.
|
|
1075
|
+
/// @param b Element value to be inserted.
|
|
1076
|
+
/// @return ret A new elist handle with length len(a)+1.
|
|
1077
|
+
function insert(elist a, uint16 i, ebool b) internal returns (elist ret) {
|
|
1078
|
+
require(i < length(a), IndexOutOfRange(i, length(a)));
|
|
1079
|
+
return inco.listInsert(a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b)));
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/// @notice Inserts a hidden element at a desired hidden position (euint256, hidden index).
|
|
1083
|
+
/// @param a An elist handle to insert into.
|
|
1084
|
+
/// @param i Hidden index position to insert at.
|
|
1085
|
+
/// @param b Element value to be inserted.
|
|
1086
|
+
/// @return ret A new elist handle with length len(a)+1.
|
|
1087
|
+
function insert(elist a, euint256 i, euint256 b) internal returns (elist ret) {
|
|
1088
|
+
return inco.listInsert(a, euint256.unwrap(s(i)), euint256.unwrap(s(b)));
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
/// @notice Inserts a euint256 element at a known position. Reverts if out of range.
|
|
1092
|
+
/// @param a An elist handle to insert into.
|
|
1093
|
+
/// @param i Index position to insert at.
|
|
1094
|
+
/// @param b Element value to be inserted.
|
|
1095
|
+
/// @return ret A new elist handle with length len(a)+1.
|
|
1096
|
+
function insert(elist a, uint16 i, euint256 b) internal returns (elist ret) {
|
|
1097
|
+
require(i < length(a), IndexOutOfRange(i, length(a)));
|
|
1098
|
+
return inco.listInsert(a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b)));
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
/// @notice Concatenates two elists into one.
|
|
1102
|
+
/// @param a EList handle to be prepended
|
|
1103
|
+
/// @param b EList handle to be appended
|
|
1104
|
+
/// @return ret A new elist handle with length len(a)+len(b).
|
|
1105
|
+
function concat(elist a, elist b) internal returns (elist ret) {
|
|
1106
|
+
return inco.listConcat(a, b);
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
/// @notice Slices a list from plaintext start to plaintext end.
|
|
1110
|
+
/// @param a EList handle to be sliced
|
|
1111
|
+
/// @param start Starting index (inclusive).
|
|
1112
|
+
/// @param end End index (exclusive). Must be >= start and within bounds.
|
|
1113
|
+
/// @return ret A new sliced list with length "end-start".
|
|
1114
|
+
function slice(elist a, uint16 start, uint16 end) internal returns (elist ret) {
|
|
1115
|
+
require(end >= start, InvalidRange(start, end));
|
|
1116
|
+
require(end <= length(a), SliceOutOfRange(start, end, length(a)));
|
|
1117
|
+
require(start < length(a), SliceOutOfRange(start, end, length(a)));
|
|
1118
|
+
bytes32 defaultValue;
|
|
1119
|
+
if (ETypes.Uint256 == listTypeOf(a)) {
|
|
1120
|
+
defaultValue = euint256.unwrap(asEuint256(0));
|
|
1121
|
+
} else if (ETypes.Bool == listTypeOf(a)) {
|
|
1122
|
+
defaultValue = ebool.unwrap(asEbool(false));
|
|
1123
|
+
} else {
|
|
1124
|
+
revert UnsupportedListType(listTypeOf(a));
|
|
1125
|
+
}
|
|
1126
|
+
return inco.listSlice(a, euint256.unwrap(asEuint256(start)), end - start, defaultValue);
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
/// @notice Slices at a hidden index with a specified length (euint256 default).
|
|
1130
|
+
/// @param a EList handle to be sliced.
|
|
1131
|
+
/// @param start Hidden starting index.
|
|
1132
|
+
/// @param len Length of the desired slice.
|
|
1133
|
+
/// @param defaultValue Default value if out of range.
|
|
1134
|
+
/// @return ret A new sliced list with length "len".
|
|
1135
|
+
function sliceLen(elist a, euint256 start, uint16 len, euint256 defaultValue) internal returns (elist ret) {
|
|
1136
|
+
return inco.listSlice(a, euint256.unwrap(s(start)), len, euint256.unwrap(s(defaultValue)));
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
/// @notice Slices at a hidden index with a specified length (ebool default).
|
|
1140
|
+
/// @param a EList handle to be sliced.
|
|
1141
|
+
/// @param start Hidden starting index.
|
|
1142
|
+
/// @param len Length of the desired slice.
|
|
1143
|
+
/// @param defaultValue Default value if out of range.
|
|
1144
|
+
/// @return ret A new sliced list with length "len".
|
|
1145
|
+
function sliceLen(elist a, euint256 start, uint16 len, ebool defaultValue) internal returns (elist ret) {
|
|
1146
|
+
return inco.listSlice(a, euint256.unwrap(s(start)), len, ebool.unwrap(s(defaultValue)));
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
/// @notice Creates a new list populated with ordered values from within range.
|
|
1150
|
+
/// @param start Start value of the range, inclusive.
|
|
1151
|
+
/// @param end End of the range, exclusive. Must be >= start.
|
|
1152
|
+
/// @return ret A new elist handle with length "end-start"
|
|
1153
|
+
function range(uint16 start, uint16 end) internal returns (elist ret) {
|
|
1154
|
+
return inco.listRange(start, end);
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
/// @notice Deterministically shuffles elements within a list.
|
|
1158
|
+
/// @dev costs the inco fee
|
|
1159
|
+
/// @param a elist handle to be shuffled
|
|
1160
|
+
/// @return ret A new elist handle with elements shuffled
|
|
1161
|
+
function shuffle(elist a) internal returns (elist ret) {
|
|
1162
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.listShuffle.selector, a));
|
|
1163
|
+
return elist.wrap(result);
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
/// @notice A convenience function equivalent to range() followed by shuffle().
|
|
1167
|
+
/// @dev costs the inco fee
|
|
1168
|
+
/// @param start Start value of the range, inclusive.
|
|
1169
|
+
/// @param end End of the range, exclusive. Must be >= start.
|
|
1170
|
+
/// @return ret A new elist handle in random order with length "end-start".
|
|
1171
|
+
function shuffledRange(uint16 start, uint16 end) internal returns (elist ret) {
|
|
1172
|
+
elist rangeList = inco.listRange(start, end);
|
|
1173
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.listShuffle.selector, rangeList));
|
|
1174
|
+
return elist.wrap(result);
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
/// @notice Reverses the order of elements in a list.
|
|
1178
|
+
/// @param a Elist handle to be reversed
|
|
1179
|
+
/// @return ret A new elist handle with elements in reverse order
|
|
1180
|
+
function reverse(elist a) internal returns (elist ret) {
|
|
1181
|
+
return inco.listReverse(a);
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
/// @notice Returns the length of the list in plaintext. Pure function, no gas cost.
|
|
1185
|
+
/// @param a EList handle to read the length from
|
|
1186
|
+
/// @return len The length of the list
|
|
1187
|
+
function length(elist a) internal pure returns (uint16 len) {
|
|
1188
|
+
return inco.lengthOf(elist.unwrap(a));
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
/// @notice verifyEListDecryption verifies elist decryption attestation and commitment proof. Each element can be either a pre-computed hash or a commitment-value pair.
|
|
1192
|
+
/// @param elistHandle The elist handle that was decrypted
|
|
1193
|
+
/// @param proofElements Array of proof elements. Each can provide either pairHash directly, or commitment+value to compute the pairHash
|
|
1194
|
+
/// @param proof The expected proof that should match keccak256 of all concatenated pair hashes
|
|
1195
|
+
/// @param signatures Array of signatures from attesters
|
|
1196
|
+
/// @return bool True if verification succeeds
|
|
1197
|
+
/// @dev For privacy, publish only pairHash. For transparency, publish commitment+value. Can mix both in the same array.
|
|
1198
|
+
function verifyEListDecryption(elist elistHandle, ElementDecryptionProof[] memory proofElements, bytes32 proof, bytes[] memory signatures) internal view returns (bool) {
|
|
1199
|
+
return inco.incoVerifier().isValidEListDecryptionAttestation(elist.unwrap(elistHandle), proofElements, proof, signatures);
|
|
1200
|
+
}
|
|
942
1201
|
}
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
4
|
import {IVerifierAddressGetter} from "../../primitives/interfaces/IVerifierAddressGetter.sol";
|
|
5
|
+
import {IEventCounter} from "../../primitives/interfaces/IEventCounter.sol";
|
|
5
6
|
import {AllowanceProof} from "../AdvancedAccessControl.types.sol";
|
|
6
7
|
|
|
7
|
-
interface IBaseAccessControlList is IVerifierAddressGetter {
|
|
8
|
+
interface IBaseAccessControlList is IVerifierAddressGetter, IEventCounter {
|
|
8
9
|
|
|
9
10
|
function allow(bytes32 handle, address account) external;
|
|
10
11
|
function allowTransient(bytes32 handle, address account) external;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: No License
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
|
-
import {DecryptionAttestation} from "./DecryptionAttester.types.sol";
|
|
4
|
+
import {DecryptionAttestation, ElementDecryptionProof} from "./DecryptionAttester.types.sol";
|
|
5
5
|
import {EIP712Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol";
|
|
6
6
|
import {SignatureVerifier} from "./primitives/SignatureVerifier.sol";
|
|
7
7
|
import {IDecryptionAttester} from "./interfaces/IDecryptionAttester.sol";
|
|
@@ -33,7 +33,7 @@ abstract contract DecryptionAttester is IDecryptionAttester, SignatureVerifier,
|
|
|
33
33
|
/// @param decryption The decryption attestation to validate.
|
|
34
34
|
/// @param signatures Array of signatures from covalidators.
|
|
35
35
|
/// @return True if the attestation has valid signatures from the required covalidators.
|
|
36
|
-
function isValidDecryptionAttestation(DecryptionAttestation memory decryption, bytes[]
|
|
36
|
+
function isValidDecryptionAttestation(DecryptionAttestation memory decryption, bytes[] calldata signatures)
|
|
37
37
|
public
|
|
38
38
|
view
|
|
39
39
|
returns (bool)
|
|
@@ -41,4 +41,40 @@ abstract contract DecryptionAttester is IDecryptionAttester, SignatureVerifier,
|
|
|
41
41
|
return isValidSignature(decryptionAttestationDigest(decryption), signatures);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
/// @notice Validates an elist decryption attestation with commitment proof against covalidator signatures.
|
|
45
|
+
/// @dev Verifies that the attestation was signed by the required threshold of covalidators and validates the proof construction.
|
|
46
|
+
/// Each element can be either a pre-computed hash or a commitment-value pair.
|
|
47
|
+
/// @param elistHandle The elist handle that was decrypted
|
|
48
|
+
/// @param proofElements Array of proved values. Each can provide either pairHash directly, or commitment+value to compute the pairHash
|
|
49
|
+
/// @param proof The expected proof that should match keccak256 of all concatenated pair hashes
|
|
50
|
+
/// @param signatures Array of signatures from covalidators
|
|
51
|
+
/// @return bool True if the attestation has valid signatures and proof verification succeeds
|
|
52
|
+
function isValidEListDecryptionAttestation(
|
|
53
|
+
bytes32 elistHandle,
|
|
54
|
+
ElementDecryptionProof[] calldata proofElements,
|
|
55
|
+
bytes32 proof,
|
|
56
|
+
bytes[] calldata signatures
|
|
57
|
+
) public view override returns (bool) {
|
|
58
|
+
DecryptionAttestation memory attestation = DecryptionAttestation({handle: elistHandle, value: proof});
|
|
59
|
+
|
|
60
|
+
// Verify the provided proof by reconstructing it from the provided value-commitment pairs and/or hashes.
|
|
61
|
+
bytes32[] memory elementHashes = new bytes32[](proofElements.length);
|
|
62
|
+
for (uint256 i = 0; i < proofElements.length; i++) {
|
|
63
|
+
// Use pre-computed hash if provided, otherwise compute from commitment and value
|
|
64
|
+
if (proofElements[i].pairHash != bytes32(0)) {
|
|
65
|
+
elementHashes[i] = proofElements[i].pairHash;
|
|
66
|
+
} else {
|
|
67
|
+
elementHashes[i] = keccak256(abi.encodePacked(proofElements[i].commitment, proofElements[i].value));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Single allocation: encode all hashes at once
|
|
72
|
+
bytes32 computedProof = keccak256(abi.encodePacked(elementHashes));
|
|
73
|
+
if (computedProof != proof) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return isValidDecryptionAttestation(attestation, signatures);
|
|
78
|
+
}
|
|
79
|
+
|
|
44
80
|
}
|
|
@@ -5,3 +5,17 @@ struct DecryptionAttestation {
|
|
|
5
5
|
bytes32 handle;
|
|
6
6
|
bytes32 value; // encoded bool or uint256 // todo switch this to bytes
|
|
7
7
|
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @notice Represents a decrypted elist value that can be either a pre-computed hash or a commitment-value pair
|
|
11
|
+
* @param pairHash Pre-computed keccak256(abi.encodePacked(commitment, value)). If non-zero, this is used directly
|
|
12
|
+
* @param commitment Commitment value. Only used if pairHash is zero
|
|
13
|
+
* @param value Decrypted value (encoded as uint256 in Solidity). Only used if pairHash is zero
|
|
14
|
+
* @dev If pairHash is provided (non-zero), commitment and value are ignored. Otherwise, hash is computed as
|
|
15
|
+
* keccak256(abi.encodePacked(commitment, value)) using Solidity's packed ABI encoding
|
|
16
|
+
*/
|
|
17
|
+
struct ElementDecryptionProof {
|
|
18
|
+
bytes32 pairHash;
|
|
19
|
+
bytes32 commitment;
|
|
20
|
+
uint256 value;
|
|
21
|
+
}
|