def ckks_test(): ctx = ts.context(ts.SCHEME_TYPE.CKKS, 8192, coeff_mod_bit_sizes=[60, 40, 40, 60]) l, r = gen_values(200) scale = 2**40 return ts.ckks_vector(ctx, scale, l), ts.ckks_vector(ctx, scale, r)
def test(): ## Make some fake data to regress to scale = 10**3 N = 100 beta_0 = 1 learning_rate = 0.005 learning_scale = np.sqrt(2 * learning_rate / N) x = np.tile(np.arange(10, dtype=float), 10) #10*10=N=100 y = learning_scale * (beta_0 * x + np.random.normal(size=N, scale=0.8)) x = learning_scale * x plt.scatter(x, y) plt.show() x_list = x.tolist() y_list = y.tolist() ## Encrypt context = ts.context(ts.SCHEME_TYPE.CKKS, poly_modulus_degree=8192 * 2, coeff_mod_bit_sizes=[60, 40, 40, 40, 40, 40, 40, 60]) context.generate_galois_keys() context.global_scale = 2**40 enc_x = ts.ckks_vector(context, x_list) enc_y = ts.ckks_vector(context, y_list) #lin_regressor = EncryptedLinReg(enc_x, enc_y, context, scale=10**3) lin_regressor = EncryptedLinReg(x, y, context) beta_g = lin_regressor.predict() return beta_g
def test_add(vec1, vec2, precision, duplicate): context = ckks_context() first_vec = ts.ckks_vector(context, vec1) first_vec = duplicate(first_vec) second_vec = ts.ckks_vector(context, vec2) # replicate for operation between n-sized and 1-sized vectors if len(vec2) == 1: # needed for replicating the first slot in the encrypted vector context.generate_galois_keys() expected = [v1 + v2 for v1, v2 in zip(vec1, vec2 * len(vec1))] else: expected = [v1 + v2 for v1, v2 in zip(vec1, vec2)] result = first_vec + second_vec result = duplicate(result) # Decryption decrypted_result = result.decrypt() assert _almost_equal(decrypted_result, expected, precision), "Addition of vectors is incorrect." assert _almost_equal(first_vec.decrypt(), vec1, precision), "Something went wrong in memory." assert _almost_equal(second_vec.decrypt(), vec2, precision), "Something went wrong in memory."
def ckks_test(input_size, n_threads=None): ctx = ckks_context(n_threads) l, r = [np.random.randn(input_size), np.random.randn(input_size)] scale = 2**40 return ts.ckks_vector(ctx, l, scale), ts.ckks_vector(ctx, r, scale)
def test_sanity_keys_regeneration(duplicate, vec1, vec2, encryption_type): orig_context = ctx(encryption_type) orig_context.global_scale = pow(2, 40) orig_context.generate_relin_keys() orig_context.generate_galois_keys() precision = 1 context = duplicate(orig_context) assert isinstance(context.relin_keys(), RelinKeys), "Relin keys should be set" assert isinstance(context.galois_keys(), GaloisKeys), "Galois keys should be set" first_vec = ts.ckks_vector(context, vec1) second_vec = ts.ckks_vector(context, vec2) result = first_vec.dot(second_vec) expected = [sum([v1 * v2 for v1, v2 in zip(vec1, vec2)])] # Decryption decrypted_result = result.decrypt() assert almost_equal(decrypted_result, expected, precision), "Dot product of vectors is incorrect." assert almost_equal(first_vec.decrypt(), vec1, precision), "Something went wrong in memory." assert almost_equal(second_vec.decrypt(), vec2, precision), "Something went wrong in memory."
def test_mul_inplace(context, scale): first_vec = ts.ckks_vector(context, scale, [66, 73, 81, 90]) second_vec = ts.ckks_vector(context, scale, [2, 3, 4, 5]) first_vec *= second_vec # Decryption decrypted_result = first_vec.decrypt() assert _almost_equal(decrypted_result, [132, 219, 324, 450], 1), "Multiplication of vectors is incorrect." assert _almost_equal(second_vec.decrypt(), [2, 3, 4, 5], 1), "Something went wrong in memory."
def test_sub_inplace(context, scale): first_vec = ts.ckks_vector(context, scale, [1, 2, 3, 4]) second_vec = ts.ckks_vector(context, scale, [4, 3, 2, 1]) first_vec -= second_vec # Decryption decrypted_result = first_vec.decrypt() assert _almost_equal(decrypted_result, [-3, -1, 1, 3], 1), "Substraction of vectors is incorrect." assert _almost_equal(second_vec.decrypt(), [4, 3, 2, 1], 1), "Something went wrong in memory."
def test_add_inplace(context, scale, vec1, vec2): first_vec = ts.ckks_vector(context, scale, vec1) second_vec = ts.ckks_vector(context, scale, vec2) first_vec += second_vec expected = [v1 + v2 for v1, v2 in zip(vec1, vec2)] # Decryption decrypted_result = first_vec.decrypt() assert _almost_equal(decrypted_result, expected, 1), "Addition of vectors is incorrect." assert _almost_equal(second_vec.decrypt(), vec2, 1), "Something went wrong in memory."
def test_add(context, scale): first_vec = ts.ckks_vector(context, scale, [1, 2, 3, 4]) second_vec = ts.ckks_vector(context, scale, [4, 3, 2, 1]) result = first_vec + second_vec # Decryption decrypted_result = result.decrypt() assert _almost_equal(decrypted_result, [5, 5, 5, 5], 1), "Addition of vectors is incorrect." assert _almost_equal(first_vec.decrypt(), [1, 2, 3, 4], 1), "Something went wrong in memory." assert _almost_equal(second_vec.decrypt(), [4, 3, 2, 1], 1), "Something went wrong in memory."
def test_dot_product_inplace(context, vec1, vec2, precision): context.generate_galois_keys() first_vec = ts.ckks_vector(context, vec1) second_vec = ts.ckks_vector(context, vec2) first_vec.dot_(second_vec) expected = [sum([v1 * v2 for v1, v2 in zip(vec1, vec2)])] # Decryption decrypted_result = first_vec.decrypt() assert _almost_equal(decrypted_result, expected, precision), "Dot product of vectors is incorrect." assert _almost_equal(second_vec.decrypt(), vec2, precision), "Something went wrong in memory."
def test_mul(context, scale, vec1, vec2): first_vec = ts.ckks_vector(context, scale, vec1) second_vec = ts.ckks_vector(context, scale, vec2) result = first_vec * second_vec expected = [v1 * v2 for v1, v2 in zip(vec1, vec2)] # Decryption decrypted_result = result.decrypt() assert _almost_equal(decrypted_result, expected, 1), "Multiplication of vectors is incorrect." assert _almost_equal(first_vec.decrypt(), vec1, 1), "Something went wrong in memory." assert _almost_equal(second_vec.decrypt(), vec2, 1), "Something went wrong in memory."
def test_sub(context, vec1, vec2): first_vec = ts.ckks_vector(context, vec1) second_vec = ts.ckks_vector(context, vec2) result = first_vec - second_vec expected = [v1 - v2 for v1, v2 in zip(vec1, vec2)] # Decryption decrypted_result = result.decrypt() assert _almost_equal(decrypted_result, expected, 1), "Substraction of vectors is incorrect." assert _almost_equal(first_vec.decrypt(), vec1, 1), "Something went wrong in memory." assert _almost_equal(second_vec.decrypt(), vec2, 1), "Something went wrong in memory."
def test_vec_plain_matrix_mul_inplace(context, vec, matrix, precision): context.generate_galois_keys() ct = ts.ckks_vector(context, vec) ct.mm_(matrix) expected = (np.array(vec) @ np.array(matrix)).tolist() assert _almost_equal(ct.decrypt(), expected, precision), "Matrix multiplciation is incorrect."
def test_negate_inplace(context, plain_vec, precision): ckks_vec = ts.ckks_vector(context, plain_vec) expected = [-v for v in plain_vec] ckks_vec.neg_() decrypted_result = ckks_vec.decrypt() assert _almost_equal(decrypted_result, expected, precision), "Decryption of vector is incorrect"
def do(ct_size: int, batch_size: int) -> None: # third party import numpy as np import tenseal as ts # syft absolute import syft as sy sy.load("tenseal") sy.logger.add(sys.stderr, "ERROR") duet = sy.launch_duet(loopback=True, network_url=f"http://127.0.0.1:{PORT}/") duet.requests.add_handler(action="accept") context = ts.context(ts.SCHEME_TYPE.CKKS, 8192, coeff_mod_bit_sizes=[60, 40, 40, 60], n_threads=1) context.global_scale = pow(2, 40) data = np.random.uniform(-10, 10, 100) enc = [] for i in range(ct_size): enc.append(ts.ckks_vector(context, data)) start = time.time() _ = context.send(duet, pointable=True) for chunk in chunks(enc, batch_size): _ = sy.lib.python.List(chunk).send(duet, pointable=True) sys.stderr.write( f"[{ct_size}][{batch_size}] DO sending took {time.time() - start} sec\n" ) sy.core.common.event_loop.loop.run_forever()
def test_vec_plain_matrix_mul_depth2(context, vec, matrix1, matrix2): context.generate_galois_keys() ct = ts.ckks_vector(context, vec) result = ct @ matrix1 @ matrix2 expected = (np.array(vec) @ np.array(matrix1) @ np.array(matrix2)).tolist() assert _almost_equal(result.decrypt(), expected, 1), "Matrix multiplication is incorrect."
def test_ckks_encryption_decryption_with_global_scale(plain_vec): context = ts.context(ts.SCHEME_TYPE.CKKS, 8192, coeff_mod_bit_sizes=COEFF_MOD_BIT_SIZES) context.global_scale = pow(2, 40) ckks_vec = ts.ckks_vector(context, plain_vec) decrypted_vec = ckks_vec.decrypt() assert _almost_equal(decrypted_vec, plain_vec, 1), "Decryption of vector is incorrect"
def test_square_inplace(context, plain_vec, precision): ckks_vec = ts.ckks_vector(context, plain_vec) expected = [np.power(v, 2) for v in plain_vec] ckks_vec.square_() decrypted_result = ckks_vec.decrypt() assert _almost_equal(decrypted_result, expected, precision), "Decryption of vector is incorrect"
def test_ckks_empty_encryption(plain_vec): context = ts.context(ts.SCHEME_TYPE.CKKS, 8192, coeff_mod_bit_sizes=COEFF_MOD_BIT_SIZES) scale = pow(2, 40) with pytest.raises(ValueError) as e: ckks_vec = ts.ckks_vector(context, plain_vec, scale) assert str(e.value) == "Attempting to encrypt an empty vector"
def test_ckks_encryption_decryption(): context = ts.context(ts.SCHEME_TYPE.CKKS, 8192, coeff_mod_bit_sizes=[60, 40, 40, 60]) scale = pow(2, 40) plain_vec = [73, 81, 90] ckks_vec = ts.ckks_vector(context, scale, plain_vec) decrypted_vec = ckks_vec.decrypt() assert _almost_equal(decrypted_vec, plain_vec, 1), "Decryption of vector is incorrect"
def test_polynomial(context, data, polynom, precision): ct = ts.ckks_vector(context, data) expected = [np.polyval(polynom[::-1], x) for x in data] result = ct.polyval(polynom) decrypted_result = result.decrypt() assert _almost_equal(decrypted_result, expected, precision), "Polynomial evaluation is incorrect."
def test_mul_without_global_scale(vec1, vec2, precision): context = ts.context(ts.SCHEME_TYPE.CKKS, 8192, coeff_mod_bit_sizes=[60, 40, 40, 60]) scale = 2**40 first_vec = ts.ckks_vector(context, vec1, scale=scale) second_vec = ts.ckks_vector(context, vec2, scale=scale) result = first_vec * second_vec expected = [v1 * v2 for v1, v2 in zip(vec1, vec2)] # Decryption decrypted_result = result.decrypt() assert _almost_equal(decrypted_result, expected, precision), "Multiplication of vectors is incorrect." assert _almost_equal(first_vec.decrypt(), vec1, precision), "Something went wrong in memory."
def test_ckks_vector_sanity(plain_vec, precision, duplicate): context = ckks_context() orig = ts.ckks_vector(context, plain_vec) ckks_tensor = duplicate(orig) decrypted = ckks_tensor.decrypt() assert _almost_equal(decrypted, plain_vec, precision), "Decryption of vector is incorrect"
def test_sub_plain_inplace(context, scale): first_vec = ts.ckks_vector(context, scale, [1, 2, 3, 4]) second_vec = [4, 3, 2, 1] first_vec -= second_vec # Decryption decrypted_result = first_vec.decrypt() assert _almost_equal(decrypted_result, [-3, -1, 1, 3], 1), "Substraction of vectors is incorrect."
def test_polynomial_rescale_off(context, data, polynom): context = ts.context(ts.SCHEME_TYPE.CKKS, 8192, 0, [60, 40, 40, 60]) context.global_scale = 2**40 context.auto_rescale = False ct = ts.ckks_vector(context, data) with pytest.raises(ValueError) as e: result = ct.polyval(polynom) assert str(e.value) == "scale mismatch"
def test_sum_inplace(context, vec1, precision): context.generate_galois_keys() first_vec = ts.ckks_vector(context, vec1) result = first_vec.sum() expected = [sum(vec1)] # Decryption decrypted_result = result.decrypt() assert _almost_equal(decrypted_result, expected, precision), "Sum of vector is incorrect."
def test_add_plain_inplace(context, scale): first_vec = ts.ckks_vector(context, scale, [1, 2, 3, 4]) second_vec = [4, 3, 2, 1] first_vec += second_vec # Decryption decrypted_result = first_vec.decrypt() assert _almost_equal(decrypted_result, [5, 5, 5, 5], 1), "Addition of vectors is incorrect."
def test_vec_plain_matrix_mul(context, vec, matrix, precision): context.generate_galois_keys() ct = ts.ckks_vector(context, vec) result = ct.mm(matrix) expected = (np.array(vec) @ np.array(matrix)).tolist() assert _almost_equal(result.decrypt(), expected, precision), "Matrix multiplciation is incorrect." assert _almost_equal(ct.decrypt(), vec, precision), "Something went wrong in memory."
def test_mul_plain_inplace(context, scale): first_vec = ts.ckks_vector(context, scale, [66, 73, 81, 90]) second_vec = [2, 3, 4, 5] first_vec *= second_vec # Decryption decrypted_result = first_vec.decrypt() assert _almost_equal(decrypted_result, [132, 219, 324, 450], 1), "Multiplication of vectors is incorrect."
def test_square(context, plain_vec, precision): ckks_vec = ts.ckks_vector(context, plain_vec) expected = [np.power(v, 2) for v in plain_vec] new_vec = ckks_vec.square() decrypted_result = new_vec.decrypt() assert _almost_equal(decrypted_result, expected, precision), "Decryption of vector is incorrect" assert _almost_equal(ckks_vec.decrypt(), plain_vec, precision), "Something went wrong in memory."