-
Notifications
You must be signed in to change notification settings - Fork 706
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Encrypted comparison #162
Comments
There is a huge difference between doing equality check (is encrypted number equal to zero) and comparison (is the encrypted number positive). How these might be done depends strongly on the encryption scheme you use (SEAL implements BFV and CKKS). BFV allows encrypting modular integers where comparison is very challenging to do but equality test is reasonable. For equality, you can subtract two encrypted integers (or vectors of them); the result is zero mod CKKS allows encrypting fixed-precision real numbers where the comparison function can be approximated (see e.g. https://eprint.iacr.org/2019/1234). This is probably not very practical if you need high-precision comparison near zero. |
So will the server alone never be able to branch based off of an encrypted equality check or comparison? Will the server always have to return the encrypted result to the client, where the client can decrypt the result and than make a branching decision? |
Right. It's impossible to truly branch on encrypted data; otherwise the branch would leak information about the encrypted data, which is not supposed to be the case. What is possible though, is evaluating both branches and filtering out the desired one. This is used for example in https://arxiv.org/abs/1909.08362. |
Ah, thanks for the insights! |
Hello @kimlaine @lastmjs , I need help to understand the equality check technique between two encrypted integers. I want to quote your statement :
I have two encrypted integer |
It does not yield true or false. The equality check result is in encrypted form. One equality check algorithm, subtraction, gives encrypted zero (equal) or encrypted non-zero (unequal). The other algorithm, Fermat's little theorem, gives encrypted zero (equal) or encrypted one (unequal). Subtraction algorithm: Ciphertext encrypted_a, encrypted_b, encrypted_equality;
Evaluator::sub(encrypted_a, encrypted_b, encrypted_equality);
Plaintext equality;
Decryptor::decrypt(encrypted_equality, equality); Now Fermat's little theorem (following the above code block): Evaluator::exponentiate_inplace(encrypted_equality, plaintext_modulus - 1, relin_keys);
Plaintext new_equality;
Decryptor::decrypt(encrypted_equality, new_equality); Now |
@WeiDaiWD Thank you for your great example and I am clear. I am working on genome data. Actually based on this equality result I will perform another computation. So I just want to know if I decrypt the new_equality variable to get the equality check result on the server-side. is it mean that I provide my secret key to the cloud side? Because I want to keep encrypted the individual's genome data on the cloud during the analysis. After analysis individuals will receive the encrypted result and able to see the result using the secret key that I can make sure a secure analysis of sensitive data. Hope your feedback will be a solution to my misunderstanding or guidelines to go ahead. |
If you share the secret key with the server, there is no point to encryption anything at the beginning. And we don't recommend to have the client decrypt that and send it back to server. What you want to do is computing |
@WeiDaiWD Thank you very much for your support and guidelines |
Is it possible to apply the Fermat's little theorem to a vector in order to batch encrypted comparison? |
|
Thanks a lot for a quick response! |
Vectorization is done at the ciphertext layer. Each |
Thanks for a thorough response. I've made it work all the way until the |
What I meant by "implement a different |
@WeiDaiWD I am trying your suggestion with Fermat's little theorem but it does not work as expected. I am setting #include <iostream>
#include <fstream>
#include "examples.h"
using namespace seal;
using namespace std;
int main(int argc, char** argv) {
EncryptionParameters parms(scheme_type::bfv);
size_t poly_modulus_degree = 4096, plaintext_modulus = 1024;
parms.set_poly_modulus_degree(poly_modulus_degree);
parms.set_coeff_modulus(CoeffModulus::BFVDefault(poly_modulus_degree));
parms.set_plain_modulus(plaintext_modulus);
SEALContext context(parms);
print_parameters(context);
KeyGenerator keygen(context);
SecretKey secret_key = keygen.secret_key();
PublicKey public_key;
RelinKeys relin_keys;
keygen.create_public_key(public_key);
keygen.create_relin_keys(relin_keys);
Encryptor encryptor(context, public_key);
Evaluator evaluator(context);
Decryptor decryptor(context, secret_key);
Ciphertext equality_enc, x_enc, y_enc, z_enc;
Plaintext plain_x("13"), plain_y("14"), plain_z("13");
Plaintext decrypted_result;
encryptor.encrypt(plain_x, x_enc);
encryptor.encrypt(plain_y, y_enc);
encryptor.encrypt(plain_z, z_enc);
// Check x_enc == y_enc
evaluator.sub(x_enc, y_enc, equality_enc); // equality_enc = x_enc - y_enc
evaluator.exponentiate_inplace(equality_enc, plaintext_modulus - 1, relin_keys);
decryptor.decrypt(equality_enc, decrypted_result);
cout << "x == y? : 0x" << decrypted_result.to_string() << endl;
// Check x_enc == z_enc
evaluator.sub(x_enc, z_enc, equality_enc); // equality_enc = x_enc - z_enc
evaluator.exponentiate_inplace(equality_enc, plaintext_modulus - 1, relin_keys);
decryptor.decrypt(equality_enc, decrypted_result);
cout << "x == z? : 0x" << decrypted_result.to_string() << endl;
return EXIT_SUCCESS;
} In decrypt, I would expect to get
I appreciate your help! |
@jimouris You are evaluating a ciphertext to its 1023-th power. The best algorithm will require 10 multiplicative depth. |
@WeiDaiWD Awesome, thank you for the quick response! |
Sorry, I'm new to this. Is the above implying that encrypted comparison is not possible with SEAL? As in, do I absolutely have to look elsewhere for this type of functionality?
Given a simple example, like sending two encrypted numbers to a server and subtracting them, would I somehow be able to know if the encrypted result was equal to 0 without decrypting it on the server? One way that I could think of doing this is by sending an encrypted 0 from the client, and then doing the comparison on the server. Am I thinking about this correctly?
The text was updated successfully, but these errors were encountered: