Huelse / SEAL-Python

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

Not able to perform multiplication beyond depth 3 #35

Closed tremblerz closed 4 years ago

tremblerz commented 4 years ago

The code following performs multiplication over a, b, c, and d. Till a, b, and c, I get correct results but then it doesn't work. I do apply relinearization keys in order to keep the noise budget in control but that doesn't seem to help.

from seal import *

def print_h(hex_string):
  print(int(hex_string, 16))

parms = EncryptionParameters(scheme_type.BFV)

poly_modulus_degree = 4096
parms.set_poly_modulus_degree(poly_modulus_degree)
parms.set_coeff_modulus(CoeffModulus.BFVDefault(poly_modulus_degree))
parms.set_plain_modulus(256)

context = SEALContext.Create(parms)

keygen = KeyGenerator(context)
public_key = keygen.public_key()
secret_key = keygen.secret_key()

relin_keys = keygen.relin_keys()

encryptor = Encryptor(context, public_key)
evaluator = Evaluator(context)
decryptor = Decryptor(context, secret_key)

a = Plaintext("2")
b = Plaintext("5")
c = Plaintext("1")
d = Plaintext("1")

a_enc = Ciphertext()
b_enc = Ciphertext()
c_enc = Ciphertext()
d_enc = Ciphertext()

ab = Plaintext()
abc = Plaintext()
abcd = Plaintext()

ab_enc = Ciphertext()
abc_enc = Ciphertext()
abcd_enc = Ciphertext()

encryptor.encrypt(a, a_enc)
encryptor.encrypt(b, b_enc)
encryptor.encrypt(c, c_enc)
encryptor.encrypt(d, d_enc)

evaluator.multiply(a_enc, b_enc, ab_enc)
evaluator.relinearize_inplace(ab_enc, relin_keys)
decryptor.decrypt(ab_enc, ab)
print_h(ab.to_string())

evaluator.multiply(ab_enc, c_enc, abc_enc)
evaluator.relinearize_inplace(abc_enc, relin_keys)
decryptor.decrypt(abc_enc, abc)
print_h(abc.to_string())

evaluator.multiply(abc_enc, d_enc, abcd_enc)
evaluator.relinearize_inplace(abcd_enc, relin_keys)
decryptor.decrypt(abcd_enc, abcd)
print_h(abcd.to_string())

Output -

10
10
Traceback (most recent call last):
  File "custom_test.py", line 62, in <module>
    print_h(abcd.to_string())
  File "custom_test.py", line 4, in print_h
    print(int(hex_string, 16))
ValueError: invalid literal for int() with base 16: '20x^4095 + 20x^4094 + 20x^4093 + 20x^4092 + 20x^4091 + 20x^4090 + 20x^4089 + 20x^4088 + 20x^4087 + 20x^4086 + 20x^4085 + 20x^4084 + 20x^4083 + 20x^4082 + 20x^4081 + 20x^4080 + 20x^4079 + 20x^4078 + 2
Huelse commented 4 years ago

poly_modulus_degree = 8192 will work

Huelse commented 4 years ago

You can read the MS example's notes. 1_bfv_basics.cpp

Understand the meaning of the print(CoeffModulus.MaxBitCount(poly_modulus_degree)) is necessary.

tremblerz commented 4 years ago

Thanks! Need to do some reading here.