Hello, sorry to bother for such a silly question. I knew how to do it 6 months ago, but during those days fatigue is overwhelming.
Say I have two ciphertexts encrypting only 1 bit each. For now I used u64 , I know it’s overkill but I’ll refine later. They are low level lwe ciphertexts, that is they are created like that:
plaintext = Plaintext( bit <<63);
vector.push(allocate_and_encrypt_new_lwe_ciphertext(
lwe_secret_key,
plaintext,
lwe_noise_distribution,
ciphertext_modulus,
encryption_generator,
));
And I just want to multiply two of them. I know I need to create a LUT, I would say using a multivariate PBS with the function |(x,y)|, r = x*y; I just no longer find it, it’s unbelievable.
Something like that except I need no carry at all and 1 bit. Ideally that’s an AND for boolean but I also want a wrapping add and I am not sure you use wrapping add for the booleans. Last time I tried a xor with two booleans it took much more time than a wrapping add.
So what you will likely encounter now are questions around the “padding bit”
essentially in the encoding you need to have the top most bit set to 0, meaning that if you add booleans together you could overflow on that top most bit
example:
padding bit | message bit
0 |1
if you add two such ciphertexts together then you get
padding bit | message bit
1 |0
and TFHE-rs is built today to have the padding bit be 0, you can manage this manually but then you may need to manage lookup tables by hand to be “negacyclic” i.e. work with that padding bit set to 1.
So the only way to do what you want while preserving the padding bit seems to be to apply a Lookup Table using a programmable bootstrap for the AND and for the XOR to guarantee that padding bit is 0, otherwise you can choose to only do linear operations but then you don’t have the possibility to compute an AND I believe
Sorry I was not clear. For now, I have several lwe ciphertexts, which I believe have 0 padding bits because I just encode one bit on the MSB.
I created a struct to make polynomials which are essentially vectors of those lwe ciphertexts. I can add them together to get a xor on each bit, which is what I want, I am happy with the overflowing behavior, this is what I want.
I can search in the code which function generates the one you showed at a lower level, but it is a bit tedious as I no longer have the architecture in mind.
EDIT: I think I need
unchecked_evaluate_bivariate_function_assign(
Thanks