Huelse / SEAL-Python

Microsoft SEAL 4.X For Python
MIT License
319 stars 66 forks source link

question about the result after two-time encryption #97

Closed Ten000hours closed 1 year ago

Ten000hours commented 2 years ago

Type I have a question about the result after two-time encryption

Descripe Hi,

I have a question about the result after the encryption for ciphertext two times using CKKS scheme. The whole process of what I did is: encrypt an numpy array --> ciphertext multi_plain with plaintext(numpy array) --> decrypt the result ciphertext --> re-encrypt the result --> ciphertext multi_plain plaintext --> decrypt for getting result. The reason for two times encryption is to refresh the noise budget. Everything works well until I get the result after the second multi_plain. Here is the question:

if I choose a relatively small value, like 400, for the plaintext part(the variable kenel in the following code), it will produce the correct result after two-time multiplication. But when I choose a value like 4000 for plaintext, it outputs the wrong result.

result for choosing 4000 for b ( wrong for 001 : should equal to 4000 4000 1) image

result for choosing 400 for b( correct for 001 : 400 400 1 ) image

The main code is following:

input_message.append(np.arange(0, 64).reshape(8, 8))
slot_count, scale, encryptor, evaluator, decryptor, galois_keys, ckks_encoder,relin_key,context = Setup()
a =  encryptor.encrypt(ckks_encoder.encode(input_message[0].flatten(), scale)
kenel = np.full((3,3),483)
b=ckks_encoder.encode(kenel.flatten(), scale)    
---------first multi-------------
evaluator.multiply_plain_inplace(a, b)

-------re-encrypt--------------
input = ckks_encoder.decode(decryptor.decrypt(a))
slot_count, scale, encryptor, evaluator, decryptor, galois_keys, ckks_encoder, relin_key, context = Setup()
plain_matrix1 = ckks_encoder.encode(input, scale)
a = encryptor.encrypt(plain_matrix1)    
b=ckks_encoder.encode(kenel.flatten(), scale)
--------------second multi-----------------
evaluator.multiply_plain_inplace(a, b)
--------decrypt--------    
check_res = ckks_encoder.decode(decryptor.decrypt(a))

The CKKS setup code:

parms = EncryptionParameters(scheme_type.ckks)
poly_modulus_degree = 4096
parms.set_poly_modulus_degree(poly_modulus_degree)
parms.set_coeff_modulus(CoeffModulus.Create(
    poly_modulus_degree, [36,37,36])) #36,36,37
scale = 2.0**30
context = SEALContext(parms)
print_parameters(context)
Huelse commented 2 years ago

I guess you have run out of the cipher space budget, which means you should set larger a poly_modulus_degree and coeff_modulus, and notice the ckks scheme will lose precision. recommend you read these encryptionparams.h or 3_levels.cpp