def test_evaluator_galois(): parms = sealapi.EncryptionParameters(sealapi.SCHEME_TYPE.BFV) parms.set_poly_modulus_degree(8) parms.set_plain_modulus(257) coeff = sealapi.CoeffModulus.Create(8, [40, 40]) parms.set_coeff_modulus(coeff) ctx = sealapi.SEALContext(parms, False, sealapi.SEC_LEVEL_TYPE.NONE) keygen = sealapi.KeyGenerator(ctx) public_key = sealapi.PublicKey() keygen.create_public_key(public_key) secret_key = keygen.secret_key() galois_keys = sealapi.GaloisKeys() keygen.create_galois_keys([1, 3, 5], galois_keys) decryptor = sealapi.Decryptor(ctx, secret_key) encryptor = sealapi.Encryptor(ctx, public_key) evaluator = sealapi.Evaluator(ctx) plain = sealapi.Plaintext("1x^2") encrypted = sealapi.Ciphertext(ctx) encryptor.encrypt(plain, encrypted) evaluator.apply_galois_inplace(encrypted, 1, galois_keys) decryptor.decrypt(encrypted, plain) assert plain.to_string() == "1x^2" out = sealapi.Ciphertext(ctx) evaluator.apply_galois(encrypted, 3, galois_keys, out) decryptor.decrypt(out, plain) assert plain.to_string() == "1x^6"
def test_util_galois(): with pytest.raises(BaseException): util.GaloisTool(0) gtool = util.GaloisTool(3) assert gtool.get_elt_from_step(0) == 15 assert gtool.get_elts_from_steps([0, 1, -3, 2, -2, 3, -1]) == [15, 3, 3, 9, 9, 11, 11] assert gtool.get_elts_all() == [15, 3, 11, 9, 9] poly_modulus_degree = 8 parms = sealapi.EncryptionParameters(sealapi.SCHEME_TYPE.CKKS) parms.set_poly_modulus_degree(poly_modulus_degree) coeff = sealapi.CoeffModulus.Create(poly_modulus_degree, [17]) parms.set_coeff_modulus(coeff) ctx = sealapi.SEALContext(parms, False, sealapi.SEC_LEVEL_TYPE.NONE) gtool = ctx.key_context_data().galois_tool() assert gtool.apply_galois([0, 1, 2, 3, 4, 5, 6, 7], 3, sealapi.Modulus(17), poly_modulus_degree - 1)[:8] == [0, 14, 6, 1, 13, 7, 2, 12] assert gtool.apply_galois_ntt([0, 1, 2, 3, 4, 5, 6, 7], 3, poly_modulus_degree - 1)[:8] == [ 4, 5, 7, 6, 1, 0, 2, 3, ] assert 7 == util.GaloisTool.GetIndexFromElt(15)
def test_context_scheme_bfv_sanity(sec_level): poly_modulus_degree = 8192 plaintext_modulus = 1032193 parms = sealapi.EncryptionParameters(sealapi.SCHEME_TYPE.BFV) parms.set_poly_modulus_degree(poly_modulus_degree) parms.set_plain_modulus(plaintext_modulus) coeff = sealapi.CoeffModulus.Create(poly_modulus_degree, [32, 32]) parms.set_coeff_modulus(coeff) sealctx = sealapi.SEALContext(parms, True, sec_level) assert sealctx.parameters_set() is True coeff = sealapi.CoeffModulus.BFVDefault(poly_modulus_degree, sec_level) parms.set_coeff_modulus(coeff) sealctx = sealapi.SEALContext(parms, True, sec_level) context_asserts(sealctx, sec_level, sealapi.SCHEME_TYPE.BFV)
def test_evaluator_rotate_vector(): testcase = [complex(i, i) for i in range(4)] slot_size = len(testcase) delta = 1 << 30 parms = sealapi.EncryptionParameters(sealapi.SCHEME_TYPE.CKKS) poly_modulus = 2 * slot_size parms.set_poly_modulus_degree(poly_modulus) parms.set_plain_modulus(0) coeff = sealapi.CoeffModulus.Create(poly_modulus, [40, 40, 40, 40]) parms.set_coeff_modulus(coeff) ctx = sealapi.SEALContext(parms, False, sealapi.SEC_LEVEL_TYPE.NONE) ctx = helper_context_ckks() keygen = sealapi.KeyGenerator(ctx) galois_keys = sealapi.GaloisKeys() keygen.create_galois_keys(galois_keys) pk = sealapi.PublicKey() keygen.create_public_key(pk) decryptor = sealapi.Decryptor(ctx, keygen.secret_key()) encryptor = sealapi.Encryptor(ctx, pk) evaluator = sealapi.Evaluator(ctx) encoder = sealapi.CKKSEncoder(ctx) plain = sealapi.Plaintext() encoder.encode(testcase, ctx.first_parms_id(), delta, plain) encrypted = sealapi.Ciphertext(ctx) encryptor.encrypt(plain, encrypted) # inplace steps = 1 evaluator.rotate_vector_inplace(encrypted, steps, galois_keys) decryptor.decrypt(encrypted, plain) decoded = encoder.decode_complex(plain)[:slot_size] for idx in range(slot_size): off = (idx + steps) % slot_size assert abs(testcase[off].real - decoded[idx].real) < 0.1 assert abs(testcase[off].imag - decoded[idx].imag) < 0.1 # to another ciphertext steps = -steps out = sealapi.Ciphertext(ctx) evaluator.rotate_vector(encrypted, steps, galois_keys, out) decryptor.decrypt(out, plain) decoded = encoder.decode_complex(plain)[:slot_size] for idx in range(slot_size): assert abs(testcase[idx].real - decoded[idx].real) < 0.1 assert abs(testcase[idx].imag - decoded[idx].imag) < 0.1
def test_context_scheme_ckks_sanity(sec_level): poly_modulus_degree = 8192 plaintext_modulus = 1032193 parms = sealapi.EncryptionParameters(sealapi.SCHEME_TYPE.CKKS) parms.set_poly_modulus_degree(poly_modulus_degree) coeff = sealapi.CoeffModulus.Create(poly_modulus_degree, [60, 40, 40, 60]) parms.set_coeff_modulus(coeff) sealctx = sealapi.SEALContext(parms, True, sealapi.SEC_LEVEL_TYPE.TC128) assert sealctx.parameters_set() is True context_asserts(sealctx, sec_level, sealapi.SCHEME_TYPE.CKKS)
def helper_context_invalid(): parms = sealapi.EncryptionParameters(sealapi.SCHEME_TYPE.BFV) return sealapi.SEALContext(parms, True, sealapi.SEC_LEVEL_TYPE.TC128)
def helper_context_ckks(poly_modulus_degree=8192): return sealapi.SEALContext( helper_params_ckks(poly_modulus_degree), True, sealapi.SEC_LEVEL_TYPE.TC128 )
def helper_context_bfv(poly_modulus_degree=4096, plain_modulus=1032193): return sealapi.SEALContext( helper_params_bfv(poly_modulus_degree, plain_modulus), True, sealapi.SEC_LEVEL_TYPE.TC128 )
def test_evaluator_rotate_bfv(): parms = sealapi.EncryptionParameters(sealapi.SCHEME_TYPE.BFV) parms.set_poly_modulus_degree(8) parms.set_plain_modulus(257) coeff = sealapi.CoeffModulus.Create(8, [40, 40]) parms.set_coeff_modulus(coeff) ctx = sealapi.SEALContext(parms, False, sealapi.SEC_LEVEL_TYPE.NONE) keygen = sealapi.KeyGenerator(ctx) galois_keys = sealapi.GaloisKeys() keygen.create_galois_keys(galois_keys) public_key = sealapi.PublicKey() keygen.create_public_key(public_key) decryptor = sealapi.Decryptor(ctx, keygen.secret_key()) encryptor = sealapi.Encryptor(ctx, public_key) evaluator = sealapi.Evaluator(ctx) encoder = sealapi.BatchEncoder(ctx) testcase = [1, 2, 3, 4, 5, 6, 7, 8] # Input # 1, 2, 3, 4, # 5, 6, 7, 8 plain = sealapi.Plaintext() encoder.encode(testcase, plain) encrypted = sealapi.Ciphertext(ctx) encryptor.encrypt(plain, encrypted) evaluator.rotate_columns_inplace(encrypted, galois_keys) decryptor.decrypt(encrypted, plain) # Rotate columns # 5, 6, 7, 8, # 1, 2, 3, 4 assert encoder.decode_int64(plain) == [5, 6, 7, 8, 1, 2, 3, 4] evaluator.rotate_rows_inplace(encrypted, -1, galois_keys) decryptor.decrypt(encrypted, plain) # Shift rows -1 # 8, 5, 6, 7, # 4, 1, 2, 3, assert encoder.decode_int64(plain) == [8, 5, 6, 7, 4, 1, 2, 3] cout = sealapi.Ciphertext(ctx) evaluator.rotate_rows(encrypted, 2, galois_keys, cout) decryptor.decrypt(cout, plain) # Shift rows +2 # 6, 7, 8, 5, # 2, 3, 4, 1, assert encoder.decode_int64(plain) == [6, 7, 8, 5, 2, 3, 4, 1] evaluator.rotate_columns(cout, galois_keys, encrypted) decryptor.decrypt(encrypted, plain) # Rotate columns # 2, 3, 4, 1, # 6, 7, 8, 5, assert encoder.decode_int64(plain) == [2, 3, 4, 1, 6, 7, 8, 5]
def test_context_failure(scheme, sec_level): parms = sealapi.EncryptionParameters(scheme) sealctx = sealapi.SEALContext(parms, True, sec_level) assert sealctx.parameters_set() is False