nucypher / nufhe

NuCypher fully homomorphic encryption (NuFHE) library implemented in Python
https://nufhe.readthedocs.io/en/latest/
GNU General Public License v3.0
441 stars 53 forks source link

Some detail about TLWE sample #26

Closed zj-rayan closed 3 years ago

zj-rayan commented 3 years ago

I want to verify the correctness of TLWE encryption to better understand the polynomial multiplication, but I find some problem, here is what I do:

Assume a TLWE sample(A,b) whose k =1, degree = 1024, coefficients are in int32 (-2^31~2^31); A tlwekey s is a 1024 degree polynomial whose coefficients are 1/0 . b = <A,s> + noise, this is what I want to verify. I extract (A,b), s, noise by following way:

Getting (A,b): In function ''tgsw_encrypt_int()'' of tgsw.py, there is a line "tgsw_encrypt_zero", and I regard it as creating TGSW samples that encrypts zero, where each column should be an TLWE sample that encrypts zero. I just extract one column, a TLWE sample (A,b), where A,b are both 1024 degree polynomial of coefficient in int32

Getting s: The tlwekey s is obtained by "cloud_key.tgsw_key.tlwe_key.key.coeffs.get()", and it does is a 1024 degree polynomial of coefficients 1/0.

Getting noise: The noise is obtained from function "tlwe_encrypt_zero()" of tlwe.py, there are noises1 and noises2 in the function, the noises1 is exactly A, so I regard noises2 as noise.

Problem: By using the extracted variables above, I find b != <A,s> + noise (mod X^N+1 , mod int32) , I wonder what is the problem, is there any detail that I miss or did wrong ?

Thanks.

fjarri commented 3 years ago

How do you perform the polynomial multiplication to calculate <A, s>? Where do you get "noise (mod X^N+1 , mod int32)" from? It may be better to see that the absolute value of b - <A, s> is small (it should be a Gaussian noise with a pretty narrow variance), because the Gaussian noise used to calculate b is transient and is not saved anywhere.

Could you provide an example code of what you are doing?

Also, it may be easier to experiment with the reference Julia code (https://github.com/nucypher/tfhe.jl), if you're familiar with the language - TFHE is intended to be optimized and as a result it may be too obscure.

zj-rayan commented 3 years ago

This afternoon when I am preparing my test code for you, I find that my calculation of polynomial multiplication was wrong before, and I can now prove the correctness of b = <a,s> + noise. But I still thank you for your patience.

I get the noise by simply adding "numpy.save('noises1',noises1.get())" , "numpy.save('noises2',noises2.get())" in tlwe.py: tlwe_encrypt_zero( ); And get b by adding "numpy.save('bk_encrypt_zero', result.samples.a.coeffs[:].get())" in tgsw.py: tgsw_encrypt_int( ) after "tgsw_encrypt_zero(thr, rng, result, noise, key, perf_params)". Then running the usage demo of main page would save these intermediate results.

Thanks.