Closed Ritian-Li closed 1 year ago
The function rescale is a little confusing, I tried your code:
parms = EncryptionParameters(scheme_type.ckks)
poly_modulus_degree = 8192
parms.set_poly_modulus_degree(poly_modulus_degree)
parms.set_coeff_modulus(CoeffModulus.Create(poly_modulus_degree, [ 60, 40, 40, 60 ]))
scale = 2.0 ** 40
context = SEALContext(parms)
ckks_encoder = CKKSEncoder(context)
slot_count = ckks_encoder.slot_count()
print_parameters(context)
keygen = KeyGenerator(context)
public_key = keygen.create_public_key()
secret_key = keygen.secret_key()
relin_keys = keygen.create_relin_keys()
gal_keys = keygen.create_galois_keys()
encryptor = Encryptor(context, public_key)
evaluator = Evaluator(context)
decryptor = Decryptor(context, secret_key)
print(f'slot_count: {slot_count}')
data = [2.] * slot_count
plain = ckks_encoder.encode(data, scale)
cipher = encryptor.encrypt(plain)
data1 = [3.] * slot_count
plain1 = ckks_encoder.encode(data1, scale)
cipher1 = encryptor.encrypt(plain1)
r1 = evaluator.sub(cipher1, cipher)
r2 = evaluator.multiply(r1, cipher1)
r2 = evaluator.relinearize(r2, relin_keys)
r2 = evaluator.rescale_to_next(r2)
cipher = evaluator.mod_switch_to(cipher, r2.parms_id())
r3 = evaluator.multiply(r2, cipher)
r3 = evaluator.relinearize(r3, relin_keys)
r3 = evaluator.rescale_to_next(r3)
r3.scale(2.0 ** 40)
print(math.log2(r3.scale()))
r4 = evaluator.mod_switch_to(cipher1, r3.parms_id())
print(math.log2(r4.scale()))
res = evaluator.sub(r3, r4)
plain_res = decryptor.decrypt(res)
result = ckks_encoder.decode(plain_res)
print(result)
# [3.00000483 3.00000483 3.00000482 ... 3.00000483 3.00000482 3.00000483]
Sorry, the code sent before is the result of my encapsulation. The following code can reproduce the problem I mentioned. @Huelse
import math
from seal import *
poly_modulus_degree = 8192
coeff = [60, 40, 40, 60]
scale = 2.0 ** (4*10)
params = EncryptionParameters(scheme_type.ckks)
params.set_poly_modulus_degree(poly_modulus_degree)
params.set_coeff_modulus(CoeffModulus.Create(poly_modulus_degree, coeff))
context = SEALContext(params)
encoder = CKKSEncoder(context)
keygen = KeyGenerator(context)
secret_key = keygen.secret_key()
public_key = keygen.create_public_key()
relin_key = keygen.create_relin_keys()
encryptor = Encryptor(context, public_key)
decryptor = Decryptor(context, secret_key)
evaluator = Evaluator(context)
slot_count = encoder.slot_count()
data1 = 2.
data2 = 3.
enc1 = encryptor.encrypt(encoder.encode([data1] * slot_count, scale))
enc2 = encryptor.encrypt(encoder.encode([data2] * slot_count, scale))
print("3 - 2 = 1")
res1 = evaluator.sub(enc2, enc1)
print("1 * 3 = 3")
res2 = evaluator.multiply(res1, enc2)
res2 = evaluator.relinearize(res2, relin_key)
print("3 * 2 = 6")
res3 = evaluator.multiply(res2, enc1)
print("Before rescale", math.log2(res3.scale()))
res3 = evaluator.relinearize(res3, relin_key)
res3 = evaluator.rescale_to_next(res3)
res3 = evaluator.rescale_to_next(res3)
res3.scale(scale)
res4 = evaluator.mod_switch_to(enc2, res3.parms_id())
print("After rescale", math.log2(res3.scale()))
print("6 - 3 = 3")
res4 = evaluator.sub(res4, enc2)
And I also tried your code, and it can success run. This makes me very confused
I found the reason, the result of evaluator.mod_switch_to() is the enc2.
I'm sorry for encountering some issues again. Based on the code you provided, I can continue to subtract r3 and r2. But if you multiply r3 and r2, an 'scale out of bounds'error will be reported. So I checked their scale, and they are already the initial scale. I would like to know if this situation can be further calculated? It can only be decrypted and re encrypted for calculation. Thank you for your answer!!
print(math.log2(r3.scale())) # => 40.0
print(math.log2(r2.scale())) # => 80.0
r2 = evaluator.rescale_to_next(r2)
r2.scale(scale)
r2 = evaluator.mod_switch_to(r2, r3.parms_id())
print(math.log2(r2.scale())) # => 40.0
# evaluator.sub(r3, r2) # => [3.00000443, 3.00000442, 3.00000443, ..., 3.00000444, 3.00000442, 3.00000442]
evaluator.multiply(r3, r2) # => ValueError: scale out of bounds
scale out of bounds
means your noise is out of budget, need to enlarge the poly_modulus_degree
and coeff_modulus
.
The examples is a good start.
Thanks for your answer! : )
Hi, I am trying to use CKKS to calculate a series of mathematical operations. I noticed that after performing multiplication operations, a relinear operation is required, and at the same time, a rescale operation is required between multiplication and addition calculations. I successfully scaled the scale after multiplication, but the following error occurred during the subtraction operation. How can I obtain the correct calculation results
Descripe
Here is the log: