narger-ef / LowMemoryFHEResNet20

Source code for the paper "Encrypted Image Classification with Low Memory Footprint using Fully Homomorphic Encryption"
https://eprint.iacr.org/2024/460
MIT License
24 stars 7 forks source link

Question about downsample related functions? #17

Closed damionfan closed 2 days ago

damionfan commented 3 weeks ago

Hi/ In the downsample-related function, it first changes the original ciphertext slots from 16384 to 32768, then multiplying it with the mask plaintext.

And my question is that the original ciphertext is packed by 16384 and its plain message is placed as "aabbccddeeffgg...."; while the mask plaintext is placed as "111111000000..."; And I think multiplying these cannot select the required message "abcdefg...."

c1->SetSlots(32768);
c2->SetSlots(32768);
num_slots = 16384*2;
Ctxt fullpack = add(mult(c1, mask_first_n(16384, c1->GetLevel())), mult(c2, mask_second_n(16384, c2->GetLevel())));

Therefore, can you teach me why this code can select the required message? Or give me some advice to learn how to select the required message from the sparse packing ciphertext?

narger-ef commented 3 weeks ago

Hello,

thank you for your question!

Actually, increasing the number of slots is done in order to lighten computations. In fact, a sparse ciphertext contains repetitions of the message, so when the number of slots is increased, you end up with something like:

msg (4 slots) : [A, B, C, D]

msg (8 slots) : [A, B, C, D, A, B, C, D]

Having said that, notice that the input of the downsampling function is composed of two ciphertexts (16384 slots each).

They represent the "sx" and the "dx" part of the convolution. If you check this image, you will notice that the fourth block (i.e., the first of the second layer, since each layer is composed of three blocks), there are two branches. So, convolutions are performed in the "sx" and in the "dx".

My trick to increase the number of slots is done in order to compute both branches in parallel, without doing it in two different ciphertexts (thus, with twice runtime).

Let me know if it is clearer!

damionfan commented 3 weeks ago

In the OpenFHE code, the CKKSPackedEncoding::Encode() function, along with its helper FitToNativeVector function, is used to encode sparse slots into a specific format. The "a0b0c0d0" format. How to convert the "a0b0c0dd" into "abcdabcd"? or which function?

narger-ef commented 3 weeks ago

At what part of the code you are referring to?

damionfan commented 3 weeks ago

In the OpenFHE code, located at ser/pke/lib/encoding/ckkspackedencoding.cpp, the functions CKKSPackedEncoding::Encode() and FitToNativeVector

narger-ef commented 2 weeks ago

I'm sorry, but this is not an issue related to my code, is it?

damionfan commented 2 weeks ago

yes, but I do not understand how to extract the required slots in the ciphertext, as it is not encoded in 'abcdabcd' format.

narger-ef commented 1 week ago

Usually this is done by using binary masks encoded in plaintexts

minnow54426 commented 5 days ago

Hello, I think you may confused of sparse encoding of CKKS, you can refer to https://openfhe.discourse.group/t/openfhe-setslots-method-what-is-the-usage-scenario/620/8 for more details. Section 4.4 of this paper maybe helpful too: Bootstrapping for Approximate Homomorphic Encryption.