@cofhe/mock-contracts 0.0.0-alpha-20260409113701
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +86 -0
- package/README.md +180 -0
- package/contracts/ABITest.sol +99 -0
- package/contracts/MockACL.sol +342 -0
- package/contracts/MockCoFHE.sol +444 -0
- package/contracts/MockTaskManager.sol +676 -0
- package/contracts/MockThresholdNetwork.sol +199 -0
- package/contracts/MockZkVerifier.sol +140 -0
- package/contracts/Permissioned.sol +213 -0
- package/contracts/TestBed.sol +98 -0
- package/dist/index.d.mts +3193 -0
- package/dist/index.d.ts +3193 -0
- package/dist/index.js +2864 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2858 -0
- package/dist/index.mjs.map +1 -0
- package/foundry.toml +10 -0
- package/package.json +65 -0
- package/remappings.txt +5 -0
- package/src/MockACL.ts +620 -0
- package/src/MockTaskManager.ts +1211 -0
- package/src/MockThresholdNetwork.ts +457 -0
- package/src/MockZkVerifier.ts +266 -0
- package/src/TestBed.ts +311 -0
- package/src/index.ts +7 -0
- package/src/typechain-types/MockACL.ts +382 -0
- package/src/typechain-types/MockTaskManager.ts +565 -0
- package/src/typechain-types/MockThresholdNetwork.ts +247 -0
- package/src/typechain-types/MockZkVerifier.ts +205 -0
- package/src/typechain-types/TestBed.ts +172 -0
- package/src/typechain-types/common.ts +92 -0
- package/src/typechain-types/index.ts +8 -0
- package/src/types.ts +14 -0
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
2
|
+
pragma solidity >=0.8.25 <0.9.0;
|
|
3
|
+
|
|
4
|
+
import { Strings } from '@openzeppelin/contracts/utils/Strings.sol';
|
|
5
|
+
import { FHE } from '@fhenixprotocol/cofhe-contracts/FHE.sol';
|
|
6
|
+
import { FunctionId, Utils } from '@fhenixprotocol/cofhe-contracts/ICofhe.sol';
|
|
7
|
+
import { console } from 'hardhat/console.sol';
|
|
8
|
+
|
|
9
|
+
address constant ZK_VERIFIER_SIGNER_ADDRESS = 0x6E12D8C87503D4287c294f2Fdef96ACd9DFf6bd2;
|
|
10
|
+
uint256 constant ZK_VERIFIER_SIGNER_PRIVATE_KEY = 49099792800763675079532137679706322989817545357788440619111868498148356080914;
|
|
11
|
+
|
|
12
|
+
address constant DECRYPT_RESULT_SIGNER_ADDRESS = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8;
|
|
13
|
+
uint256 constant DECRYPT_RESULT_SIGNER_PRIVATE_KEY = 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @dev Mock implementation of the CoFHE coprocessor, used to test FHE ops in isolation.
|
|
17
|
+
* Is inherited by MockTaskManager.
|
|
18
|
+
*
|
|
19
|
+
* It is responsible for storing a map of ctHash -> value
|
|
20
|
+
* and for performing the operations on the values.
|
|
21
|
+
*
|
|
22
|
+
* It is intended as a 1:1 drop-in replacement for the real CoFHE coprocessor, with the following differences:
|
|
23
|
+
* - AsyncCallbacks are called synchronously (with a mock 1-10 second delay).
|
|
24
|
+
* - Unencrypted values are available onchain via the `mockStorage` map.
|
|
25
|
+
*
|
|
26
|
+
* NOTE: This is not used in production
|
|
27
|
+
*/
|
|
28
|
+
abstract contract MockCoFHE {
|
|
29
|
+
// Pulled from TMCommon
|
|
30
|
+
uint256 constant uintTypeMask = (type(uint8).max >> 1); // 0x7f - 7 bits reserved for uint type in the one before last byte
|
|
31
|
+
uint256 constant triviallyEncryptedMask = type(uint8).max - uintTypeMask; //0x80 1 bit reserved for isTriviallyEncrypted
|
|
32
|
+
uint256 constant shiftedTypeMask = uintTypeMask << 8; // 0x7f007 bits reserved for uint type in the one before last byte
|
|
33
|
+
|
|
34
|
+
bool public logOps = true;
|
|
35
|
+
|
|
36
|
+
mapping(uint256 => uint256) public mockStorage;
|
|
37
|
+
mapping(uint256 => bool) public inMockStorage;
|
|
38
|
+
|
|
39
|
+
error InputNotInMockStorage(uint256 ctHash);
|
|
40
|
+
|
|
41
|
+
// Used internally to check if we missed any operations in the mocks
|
|
42
|
+
error InvalidUnaryOperation(string operation);
|
|
43
|
+
error InvalidTwoInputOperation(string operation);
|
|
44
|
+
error InvalidThreeInputOperation(string operation);
|
|
45
|
+
|
|
46
|
+
// OPTIONS
|
|
47
|
+
|
|
48
|
+
function setLogOps(bool _logOps) public {
|
|
49
|
+
logOps = _logOps;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Utils
|
|
53
|
+
|
|
54
|
+
function getUintTypeFromHash(uint256 hash) internal pure returns (uint8) {
|
|
55
|
+
return uint8((hash & shiftedTypeMask) >> 8);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function getUtypeStringFromHash(uint256 hash) internal pure returns (string memory) {
|
|
59
|
+
uint8 inputType = getUintTypeFromHash(hash);
|
|
60
|
+
if (inputType == Utils.EBOOL_TFHE) return 'ebool';
|
|
61
|
+
if (inputType == Utils.EUINT8_TFHE) return 'euint8';
|
|
62
|
+
if (inputType == Utils.EUINT16_TFHE) return 'euint16';
|
|
63
|
+
if (inputType == Utils.EUINT32_TFHE) return 'euint32';
|
|
64
|
+
if (inputType == Utils.EUINT64_TFHE) return 'euint64';
|
|
65
|
+
if (inputType == Utils.EUINT128_TFHE) return 'euint128';
|
|
66
|
+
if (inputType == Utils.EUINT256_TFHE) return 'euint256';
|
|
67
|
+
if (inputType == Utils.EADDRESS_TFHE) return 'eaddress';
|
|
68
|
+
return 'unknown';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function getUtypeBits(uint256 hash) internal pure returns (uint256) {
|
|
72
|
+
uint8 inputType = getUintTypeFromHash(hash);
|
|
73
|
+
if (inputType == Utils.EBOOL_TFHE) return 8;
|
|
74
|
+
if (inputType == Utils.EUINT8_TFHE) return 8;
|
|
75
|
+
if (inputType == Utils.EUINT16_TFHE) return 16;
|
|
76
|
+
if (inputType == Utils.EUINT32_TFHE) return 32;
|
|
77
|
+
if (inputType == Utils.EUINT64_TFHE) return 64;
|
|
78
|
+
if (inputType == Utils.EUINT128_TFHE) return 128;
|
|
79
|
+
if (inputType == Utils.EUINT256_TFHE) return 256;
|
|
80
|
+
if (inputType == Utils.EADDRESS_TFHE) return 160;
|
|
81
|
+
return 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function getUtypeMask(uint256 hash) internal pure returns (uint256) {
|
|
85
|
+
uint256 bits = getUtypeBits(hash);
|
|
86
|
+
unchecked {
|
|
87
|
+
return (1 << bits) - 1;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function removeFirstLetter(string memory str) public pure returns (string memory) {
|
|
92
|
+
bytes memory strBytes = bytes(str);
|
|
93
|
+
if (strBytes.length == 0) return '';
|
|
94
|
+
bytes memory result = new bytes(strBytes.length - 1);
|
|
95
|
+
for (uint i = 1; i < strBytes.length; i++) {
|
|
96
|
+
result[i - 1] = strBytes[i];
|
|
97
|
+
}
|
|
98
|
+
return string(result);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function getIsBoolTypeFromHash(uint256 hash) internal pure returns (bool) {
|
|
102
|
+
uint8 inputType = getUintTypeFromHash(hash);
|
|
103
|
+
return (inputType ^ Utils.EBOOL_TFHE) == 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function strEq(string memory _a, string memory _b) internal pure returns (bool) {
|
|
107
|
+
return keccak256(abi.encodePacked(_a)) == keccak256(abi.encodePacked(_b));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function opIs(string memory op, FunctionId fid) internal pure returns (bool) {
|
|
111
|
+
return strEq(op, Utils.functionIdToString(fid));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function sliceString(string memory str, uint start, uint length) public pure returns (string memory) {
|
|
115
|
+
bytes memory strBytes = bytes(str);
|
|
116
|
+
require(start + length <= strBytes.length, 'Out of bounds');
|
|
117
|
+
|
|
118
|
+
bytes memory result = new bytes(length);
|
|
119
|
+
for (uint i = 0; i < length; i++) {
|
|
120
|
+
result[i] = strBytes[start + i];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return string(result);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function logCtHash(uint256 ctHash) internal view returns (string memory) {
|
|
127
|
+
string memory hashStr = Strings.toString(ctHash);
|
|
128
|
+
uint256 length = bytes(hashStr).length;
|
|
129
|
+
if (length <= 6) {
|
|
130
|
+
return hashStr;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
bool stored = inMockStorage[ctHash];
|
|
134
|
+
uint256 value = mockStorage[ctHash];
|
|
135
|
+
bool isBool = getIsBoolTypeFromHash(ctHash);
|
|
136
|
+
|
|
137
|
+
string memory valueString = isBool ? (value == 1 ? 'true' : 'false') : Strings.toString(value);
|
|
138
|
+
|
|
139
|
+
string memory truncated = string.concat(
|
|
140
|
+
getUtypeStringFromHash(ctHash),
|
|
141
|
+
'(',
|
|
142
|
+
sliceString(hashStr, 0, 4),
|
|
143
|
+
'..',
|
|
144
|
+
sliceString(hashStr, length - 4, 4),
|
|
145
|
+
')[',
|
|
146
|
+
stored ? valueString : 'EMPTY',
|
|
147
|
+
']'
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
return truncated;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
string constant LOG_PREFIX = unicode'├ ';
|
|
154
|
+
string constant LOG_DIVIDER = unicode' | ';
|
|
155
|
+
|
|
156
|
+
function padRight(string memory input, uint256 length, bytes1 padChar) internal pure returns (string memory) {
|
|
157
|
+
bytes memory inputBytes = bytes(input);
|
|
158
|
+
if (inputBytes.length >= length) return input;
|
|
159
|
+
|
|
160
|
+
bytes memory padded = new bytes(length);
|
|
161
|
+
uint256 i = 0;
|
|
162
|
+
for (; i < inputBytes.length; i++) {
|
|
163
|
+
padded[i] = inputBytes[i];
|
|
164
|
+
}
|
|
165
|
+
for (; i < length; i++) {
|
|
166
|
+
padded[i] = padChar;
|
|
167
|
+
}
|
|
168
|
+
return string(padded);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function logOperation(string memory operation, string memory inputs, string memory output) internal view {
|
|
172
|
+
if (logOps)
|
|
173
|
+
console.log(string.concat(LOG_PREFIX, padRight(operation, 16, ' '), LOG_DIVIDER, inputs, ' => ', output));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function logAllow(string memory operation, uint256 ctHash, address account) internal view {
|
|
177
|
+
if (logOps)
|
|
178
|
+
console.log(
|
|
179
|
+
string.concat(
|
|
180
|
+
LOG_PREFIX,
|
|
181
|
+
padRight(operation, 16, ' '),
|
|
182
|
+
LOG_DIVIDER,
|
|
183
|
+
logCtHash(ctHash),
|
|
184
|
+
' -> ',
|
|
185
|
+
Strings.toHexString(account)
|
|
186
|
+
)
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Storage functions
|
|
191
|
+
|
|
192
|
+
function _set(uint256 ctHash, uint256 value, bool log) internal {
|
|
193
|
+
mockStorage[ctHash] = value;
|
|
194
|
+
inMockStorage[ctHash] = true;
|
|
195
|
+
|
|
196
|
+
if (log) logOperation('set', '', logCtHash(ctHash));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function _set(uint256 ctHash, uint256 value) internal {
|
|
200
|
+
uint256 mask = getUtypeMask(ctHash);
|
|
201
|
+
_set(ctHash, value & mask, false);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function _set(uint256 ctHash, bool value) internal {
|
|
205
|
+
_set(ctHash, value ? 1 : 0);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function _get(uint256 ctHash) internal view returns (uint256) {
|
|
209
|
+
if (!inMockStorage[ctHash]) revert InputNotInMockStorage(ctHash);
|
|
210
|
+
|
|
211
|
+
uint256 mask = getUtypeMask(ctHash);
|
|
212
|
+
return mockStorage[ctHash] & mask;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Public functions
|
|
216
|
+
|
|
217
|
+
function MOCK_setInEuintKey(uint256 ctHash, uint256 value) public {
|
|
218
|
+
_set(ctHash, value);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Mock Log
|
|
222
|
+
|
|
223
|
+
function MOCK_logAllow(string memory operation, uint256 ctHash, address account) public view {
|
|
224
|
+
logAllow(operation, ctHash, account);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Mock functions
|
|
228
|
+
|
|
229
|
+
function MOCK_verifyKeyInStorage(uint256 ctHash) internal view {
|
|
230
|
+
if (!inMockStorage[ctHash]) revert InputNotInMockStorage(ctHash);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function MOCK_unaryOperation(uint256 ctHash, string memory operation, uint256 input) internal {
|
|
234
|
+
if (opIs(operation, FunctionId.random)) {
|
|
235
|
+
_set(ctHash, uint256(blockhash(block.number - 1)));
|
|
236
|
+
logOperation('FHE.random', '', logCtHash(ctHash));
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
if (opIs(operation, FunctionId.cast)) {
|
|
240
|
+
_set(ctHash, _get(input));
|
|
241
|
+
logOperation('FHE.cast', logCtHash(input), logCtHash(ctHash));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (opIs(operation, FunctionId.not)) {
|
|
245
|
+
bool inputIsTruthy = _get(input) == 1;
|
|
246
|
+
_set(ctHash, !inputIsTruthy);
|
|
247
|
+
logOperation('FHE.not', logCtHash(input), logCtHash(ctHash));
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
if (opIs(operation, FunctionId.square)) {
|
|
251
|
+
unchecked {
|
|
252
|
+
_set(ctHash, _get(input) * _get(input));
|
|
253
|
+
}
|
|
254
|
+
logOperation('FHE.square', string.concat(logCtHash(input), ' * ', logCtHash(input)), logCtHash(ctHash));
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
revert InvalidUnaryOperation(operation);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function MOCK_twoInputOperation(uint256 ctHash, string memory operation, uint256 input1, uint256 input2) internal {
|
|
261
|
+
if (opIs(operation, FunctionId.sub)) {
|
|
262
|
+
unchecked {
|
|
263
|
+
_set(ctHash, _get(input1) - _get(input2));
|
|
264
|
+
}
|
|
265
|
+
logOperation('FHE.sub', string.concat(logCtHash(input1), ' - ', logCtHash(input2)), logCtHash(ctHash));
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (opIs(operation, FunctionId.add)) {
|
|
269
|
+
unchecked {
|
|
270
|
+
_set(ctHash, _get(input1) + _get(input2));
|
|
271
|
+
}
|
|
272
|
+
logOperation('FHE.add', string.concat(logCtHash(input1), ' + ', logCtHash(input2)), logCtHash(ctHash));
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (opIs(operation, FunctionId.xor)) {
|
|
276
|
+
unchecked {
|
|
277
|
+
_set(ctHash, _get(input1) ^ _get(input2));
|
|
278
|
+
}
|
|
279
|
+
logOperation('FHE.xor', string.concat(logCtHash(input1), ' ^ ', logCtHash(input2)), logCtHash(ctHash));
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (opIs(operation, FunctionId.and)) {
|
|
283
|
+
unchecked {
|
|
284
|
+
_set(ctHash, _get(input1) & _get(input2));
|
|
285
|
+
}
|
|
286
|
+
logOperation('FHE.and', string.concat(logCtHash(input1), ' & ', logCtHash(input2)), logCtHash(ctHash));
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (opIs(operation, FunctionId.or)) {
|
|
290
|
+
unchecked {
|
|
291
|
+
_set(ctHash, _get(input1) | _get(input2));
|
|
292
|
+
}
|
|
293
|
+
logOperation('FHE.or', string.concat(logCtHash(input1), ' | ', logCtHash(input2)), logCtHash(ctHash));
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
if (opIs(operation, FunctionId.div)) {
|
|
297
|
+
uint256 cleartext2 = _get(input2);
|
|
298
|
+
if (cleartext2 == 0) {
|
|
299
|
+
_set(ctHash, type(uint256).max);
|
|
300
|
+
} else {
|
|
301
|
+
unchecked {
|
|
302
|
+
_set(ctHash, _get(input1) / cleartext2);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
logOperation('FHE.div', string.concat(logCtHash(input1), ' / ', logCtHash(input2)), logCtHash(ctHash));
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (opIs(operation, FunctionId.rem)) {
|
|
309
|
+
unchecked {
|
|
310
|
+
_set(ctHash, _get(input1) % _get(input2));
|
|
311
|
+
}
|
|
312
|
+
logOperation('FHE.rem', string.concat(logCtHash(input1), ' % ', logCtHash(input2)), logCtHash(ctHash));
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
if (opIs(operation, FunctionId.mul)) {
|
|
316
|
+
unchecked {
|
|
317
|
+
_set(ctHash, _get(input1) * _get(input2));
|
|
318
|
+
}
|
|
319
|
+
logOperation('FHE.mul', string.concat(logCtHash(input1), ' * ', logCtHash(input2)), logCtHash(ctHash));
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
if (opIs(operation, FunctionId.shl)) {
|
|
323
|
+
unchecked {
|
|
324
|
+
_set(ctHash, _get(input1) << _get(input2));
|
|
325
|
+
}
|
|
326
|
+
logOperation('FHE.shl', string.concat(logCtHash(input1), ' << ', logCtHash(input2)), logCtHash(ctHash));
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
if (opIs(operation, FunctionId.shr)) {
|
|
330
|
+
unchecked {
|
|
331
|
+
_set(ctHash, _get(input1) >> _get(input2));
|
|
332
|
+
}
|
|
333
|
+
logOperation('FHE.shr', string.concat(logCtHash(input1), ' >> ', logCtHash(input2)), logCtHash(ctHash));
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
if (opIs(operation, FunctionId.gte)) {
|
|
337
|
+
_set(ctHash, _get(input1) >= _get(input2));
|
|
338
|
+
logOperation('FHE.gte', string.concat(logCtHash(input1), ' >= ', logCtHash(input2)), logCtHash(ctHash));
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
if (opIs(operation, FunctionId.lte)) {
|
|
342
|
+
_set(ctHash, _get(input1) <= _get(input2));
|
|
343
|
+
logOperation('FHE.lte', string.concat(logCtHash(input1), ' <= ', logCtHash(input2)), logCtHash(ctHash));
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
if (opIs(operation, FunctionId.lt)) {
|
|
347
|
+
_set(ctHash, _get(input1) < _get(input2));
|
|
348
|
+
logOperation('FHE.lt', string.concat(logCtHash(input1), ' < ', logCtHash(input2)), logCtHash(ctHash));
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (opIs(operation, FunctionId.gt)) {
|
|
352
|
+
_set(ctHash, _get(input1) > _get(input2));
|
|
353
|
+
logOperation('FHE.gt', string.concat(logCtHash(input1), ' > ', logCtHash(input2)), logCtHash(ctHash));
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
if (opIs(operation, FunctionId.min)) {
|
|
357
|
+
uint256 min;
|
|
358
|
+
unchecked {
|
|
359
|
+
min = _get(input1) < _get(input2) ? _get(input1) : _get(input2);
|
|
360
|
+
}
|
|
361
|
+
_set(ctHash, min);
|
|
362
|
+
|
|
363
|
+
logOperation(
|
|
364
|
+
'FHE.min',
|
|
365
|
+
string.concat('min(', logCtHash(input1), ', ', logCtHash(input2), ')'),
|
|
366
|
+
logCtHash(ctHash)
|
|
367
|
+
);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
if (opIs(operation, FunctionId.max)) {
|
|
371
|
+
uint256 max;
|
|
372
|
+
unchecked {
|
|
373
|
+
max = _get(input1) > _get(input2) ? _get(input1) : _get(input2);
|
|
374
|
+
}
|
|
375
|
+
_set(ctHash, max);
|
|
376
|
+
|
|
377
|
+
logOperation(
|
|
378
|
+
'FHE.max',
|
|
379
|
+
string.concat('max(', logCtHash(input1), ', ', logCtHash(input2), ')'),
|
|
380
|
+
logCtHash(ctHash)
|
|
381
|
+
);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
if (opIs(operation, FunctionId.eq)) {
|
|
385
|
+
_set(ctHash, _get(input1) == _get(input2));
|
|
386
|
+
|
|
387
|
+
logOperation('FHE.eq', string.concat(logCtHash(input1), ' == ', logCtHash(input2)), logCtHash(ctHash));
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (opIs(operation, FunctionId.ne)) {
|
|
391
|
+
_set(ctHash, _get(input1) != _get(input2));
|
|
392
|
+
|
|
393
|
+
logOperation('FHE.ne', string.concat(logCtHash(input1), ' != ', logCtHash(input2)), logCtHash(ctHash));
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
if (opIs(operation, FunctionId.rol)) {
|
|
397
|
+
unchecked {
|
|
398
|
+
_set(ctHash, _get(input1) << _get(input2));
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
logOperation('FHE.rol', string.concat(logCtHash(input1), ' << ', logCtHash(input2)), logCtHash(ctHash));
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (opIs(operation, FunctionId.ror)) {
|
|
405
|
+
unchecked {
|
|
406
|
+
_set(ctHash, _get(input1) >> _get(input2));
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
logOperation('FHE.ror', string.concat(logCtHash(input1), ' >> ', logCtHash(input2)), logCtHash(ctHash));
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
revert InvalidTwoInputOperation(operation);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function MOCK_threeInputOperation(
|
|
416
|
+
uint256 ctHash,
|
|
417
|
+
string memory operation,
|
|
418
|
+
uint256 input1,
|
|
419
|
+
uint256 input2,
|
|
420
|
+
uint256 input3
|
|
421
|
+
) internal {
|
|
422
|
+
if (opIs(operation, FunctionId.trivialEncrypt)) {
|
|
423
|
+
_set(ctHash, input1);
|
|
424
|
+
|
|
425
|
+
logOperation(
|
|
426
|
+
string.concat('FHE.asE', removeFirstLetter(getUtypeStringFromHash(ctHash))),
|
|
427
|
+
string.concat(removeFirstLetter(getUtypeStringFromHash(ctHash)), '(', Strings.toString(input1), ')'),
|
|
428
|
+
logCtHash(ctHash)
|
|
429
|
+
);
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
if (opIs(operation, FunctionId.select)) {
|
|
433
|
+
_set(ctHash, _get(input1) == 1 ? _get(input2) : _get(input3));
|
|
434
|
+
|
|
435
|
+
logOperation(
|
|
436
|
+
'FHE.select',
|
|
437
|
+
string.concat(logCtHash(input1), ' ? ', logCtHash(input2), ' : ', logCtHash(input3)),
|
|
438
|
+
logCtHash(ctHash)
|
|
439
|
+
);
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
revert InvalidThreeInputOperation(operation);
|
|
443
|
+
}
|
|
444
|
+
}
|