There are ways of determining greater than or less in the example but how do we determine equality when we introduce random error
If you write a circuit/look-up table only using LWE ciphertexts in an exact scheme such as FHEW, you can check equality. If you want to achieve this through an intermediate conversion through an approximate scheme such as CKKS, then you can only achieve equality up to some precision, because by definition CKKS has approximation errors. In the latter case, you could compute |x - y| <= eps instead of x==y.
If I use TFHE, can I calculate the difference between two values and then use that to create a LUT?
Because the function parameter type is NativeInteger, I’m not sure if can determine it as 0.
m = x-y;
auto fp = (NativeInteger m, NativeInteger p1) → NativeInteger {
if (m == 0)
return 1;
else
return 0;
};
// Generate LUT from function f(x)
auto lut = cc.GenerateLUTviaFunction(fp, p);
The problem is that it doesn’t work when the difference is very large.
int p = cc.GetMaxPlaintextSpace().ConvertToInt(); // Obtain the maximum plaintext space
// Initialize Function f(x) = x^3 % p
auto fp = [](NativeInteger m, NativeInteger p1) -> NativeInteger {
if (m == 0)
return 1;
else
return 0;
};
// Generate LUT from function f(x)
auto lut = cc.GenerateLUTviaFunction(fp, p);
auto ct1 = cc.Encrypt(sk, 1024, FRESH, p);
auto ct2 = cc.Encrypt(sk, 0, FRESH, p);
cc.GetLWEScheme()->EvalSubEq(ct1, ct2);
auto ct_cube = cc.EvalFunc(ct1, lut);
LWEPlaintext result;
cc.Decrypt(sk, ct_cube, &result, 2);
std::cout << "Evaluated = " << result << std::endl;
It works correctly with cc.Decrypt(sk, ct_cube, &result, p). Also recall that you are computing x - y % p, so if for instance, p = 8, then the expected result is 1 for x = 1024 and y = 0.
Is the value of p modifiable? The documentation on GitHub says that it can be supported up to 8 using the LUT method.
It is the same answer as in your previous question Is there a way to make the plaintext modulus greater than 8 in GenerateLUTviaFunction?.
I apologize for taking so long, but I still have a question.
If judged by the form of the circuit, it is required that each bit of the plaintext be the same, is the same operation required for the ciphertext as well? How can the XNOR operation be directly performed on two LWECipertexts, or is some function required to extract the bits one by one?
If you have several ciphertexts encoding the bits of the input, then you should apply the XNOR (or whatever binary gate you have in your circuit) on each ciphertext. If your ciphertext encodes a the whole message, then you only apply the LUT on that ciphertext. Finally, if your message is broken up in pieces up to p, then you write your circuit in terms of LUTs accordingly, and apply them on the respective ciphertexts.