microsoft / SEAL

Microsoft SEAL is an easy-to-use and powerful homomorphic encryption library.
https://www.microsoft.com/en-us/research/group/cryptography-research/
MIT License
3.62k stars 711 forks source link

How to use an array to build a Ciphertext? #708

Closed cipeizheng closed 6 days ago

cipeizheng commented 1 month ago

I am trying to use the GPU etc. to compute Ciphertext. I have used for_each_n() function and iterators to extract Dynarray's elements ( I think they are coefficients of ciphertext polynomials) in Ciphertext and computed them. But I am confusing with how to use the results (In my case they are vector<uint64_t>) to build a Ciphertext object.

I tried copy() function, but it works in a weird way: If I copy an extracted data to its original Ciphertext, it works well in decryption and decode, but in another case I get wrong results. So is there a way to use an array to build a Ciphertext? Do I have to use Deserialization?

kimlaine commented 3 weeks ago

I would just use the SEAL iterators to write the ciphertext data. It's kind of impossible to say what might be going wrong without a lot more details. Can you debug and check at least that the ciphertext data is what you think it should be after you write it?

cipeizheng commented 3 weeks ago

Thanks for your reply! I have tried adding some output in Decryptor::bfv_decrypt to trace the decryption process, and I think the problem maybe happening in rns_tool()->decrypt_scale_and_round().

Here is what I did: In main.cpp I extract data, and copied it like this:

ConstCoeffIter operand1 = encrypted1.data();
ConstCoeffIter operand2 = encrypted2.data();

vector<uint64_t> data1, data2;

for_each_n(iter(operand1, operand2), coeff_count * coeff_modulus_size, [&](auto I){
    data1.push_back(get<0>(I));
    data2.push_back(get<1>(I));
});

copy(data2.begin(), data2.end(), encrypted1.data()); 

In decryptor.cpp I added output before and after the call to rns_tool()->decrypt_scale_and_round(). After decrypting both encrypted1 and encrypted2, I noticed that the two tmp_dest_modqs are same, but the two destination values were different. In my opinion, since the parameters passed to decrypt_scale_and_round() are the same, this discrepancy is quite confusing.

Besides, could you help me understand how to use SEAL iterators to properly write ciphertext data? Thanks a lot!

cipeizheng commented 6 days ago

After I learned about SEAL iterators, I found the problem is not how I store data to a Ciphertext. It the way I READ it. Due to my lack of knowledge of BFV, I miscalculated the size of the ciphertext, so the ciphertext I read was incomplete, which led to incomplete coverage of the data and caused the error. I changed

for_each_n(iter(operand1, operand2), coeff_count * coeff_modulus_size, [&](auto I)

to

for_each_n(iter(operand1, operand2), 2 * coeff_count * coeff_modulus_size, [&](auto I)

and the problem is solved.

I will mark this issue to close.