def test_select_shares_exception_ring(get_clients) -> None: parties = get_clients(3) falcon = Falcon() session = Session(parties=parties, protocol=falcon, ring_size=2**32) SessionManager.setup_mpc(session) val = MPCTensor(secret=1, session=session) with pytest.raises(ValueError): Falcon.select_shares(val, val, val)
def test_select_shares_exception_shape(get_clients) -> None: parties = get_clients(3) falcon = Falcon() session = Session(parties=parties, protocol=falcon) SessionManager.setup_mpc(session) val = MPCTensor(secret=1, session=session) rst = val.share_ptrs[0].get_copy() rst.ring_size = 2 val.share_ptrs[0] = rst.send(parties[0]) val.shape = None with pytest.raises(ValueError): Falcon.select_shares(val, val, val)
def test_eq(): aby = ABY3() falcon1 = Falcon(security_type="malicious") falcon2 = Falcon() other2 = aby # Test equal protocol: assert aby == other2 # Test different protocol security type assert aby != falcon1 # Test different protocol objects assert aby != falcon2
def test_private_compare_exception(get_clients) -> None: parties = get_clients(3) falcon = Falcon() session = Session(parties=parties, protocol=falcon) SessionManager.setup_mpc(session) x = MPCTensor(secret=1, session=session) r = torch.tensor([1]) # Expection for not passing input tensor values as list. with pytest.raises(ValueError): Falcon.private_compare(x, r) # Exception for not passing a public value(torch.Tensor). with pytest.raises(ValueError): Falcon.private_compare([x], x)
def test_prime_mul_private(get_clients, security): parties = get_clients(3) protocol = Falcon(security) session = Session(protocol=protocol, parties=parties) SessionManager.setup_mpc(session) ring_size = PRIME_NUMBER prime_op = ReplicatedSharedTensor.get_op(ring_size, "mul") sh1 = torch.tensor([[32, 12, 23], [17, 35, 7]], dtype=torch.uint8) sh2 = torch.tensor([[45, 66, 47], [19, 57, 2]], dtype=torch.uint8) shares1 = [sh1, sh1, sh1] shares2 = [sh2, sh2, sh2] rst_list1 = ReplicatedSharedTensor.distribute_shares(shares=shares1, session=session, ring_size=ring_size) rst_list2 = ReplicatedSharedTensor.distribute_shares(shares=shares2, session=session, ring_size=ring_size) tensor1 = MPCTensor(shares=rst_list1, session=session) tensor1.shape = sh1.shape tensor2 = MPCTensor(shares=rst_list2, session=session) tensor2.shape = sh2.shape secret1 = ReplicatedSharedTensor.shares_sum(shares1, ring_size) secret2 = ReplicatedSharedTensor.shares_sum(shares2, ring_size) result = operator.mul(tensor1, tensor2) expected_res = prime_op(secret1, secret2) assert (result.reconstruct(decode=False) == expected_res).all()
def test_bin_mul_private(get_clients, security): parties = get_clients(3) protocol = Falcon(security) session = Session(protocol=protocol, parties=parties) SessionManager.setup_mpc(session) ring_size = 2 bin_op = ReplicatedSharedTensor.get_op(ring_size, "mul") sh1 = torch.tensor([[0, 1, 0], [1, 0, 1]], dtype=torch.bool) sh2 = torch.tensor([[1, 1, 0], [0, 1, 1]], dtype=torch.bool) shares1 = [sh1, sh1, sh1] shares2 = [sh2, sh2, sh2] rst_list1 = ReplicatedSharedTensor.distribute_shares(shares=shares1, session=session, ring_size=ring_size) rst_list2 = ReplicatedSharedTensor.distribute_shares(shares=shares2, session=session, ring_size=ring_size) tensor1 = MPCTensor(shares=rst_list1, session=session) tensor1.shape = sh1.shape tensor2 = MPCTensor(shares=rst_list2, session=session) tensor2.shape = sh2.shape secret1 = ReplicatedSharedTensor.shares_sum(shares1, ring_size) secret2 = ReplicatedSharedTensor.shares_sum(shares2, ring_size) result = operator.mul(tensor1, tensor2) expected_res = bin_op(secret1, secret2) assert (result.reconstruct(decode=False) == expected_res).all()
def test_session_ring_xor(get_clients, security, bit) -> None: parties = get_clients(3) protocol = Falcon(security) session = Session(protocol=protocol, parties=parties) SessionManager.setup_mpc(session) ring_size = session.ring_size tensor_type = session.tensor_type config = Config(encoder_base=1, encoder_precision=0) x_sh1 = torch.tensor([[927021, 3701]], dtype=tensor_type) x_sh2 = torch.tensor([[805274, 401]], dtype=tensor_type) x_sh3 = torch.tensor([[-1732294, -4102]], dtype=tensor_type) bit_sh_1, bit_sh_2, bit_sh_3 = bit b_sh1 = torch.tensor([bit_sh_1], dtype=tensor_type) b_sh2 = torch.tensor([bit_sh_2], dtype=tensor_type) b_sh3 = torch.tensor([bit_sh_3], dtype=tensor_type) shares_x = [x_sh1, x_sh2, x_sh3] shares_b = [b_sh1, b_sh2, b_sh3] rst_list_x = ReplicatedSharedTensor.distribute_shares(shares=shares_x, session=session, ring_size=ring_size, config=config) rst_list_b = ReplicatedSharedTensor.distribute_shares(shares=shares_b, session=session, ring_size=ring_size, config=config) x = MPCTensor(shares=rst_list_x, session=session, shape=x_sh1.shape) b = MPCTensor(shares=rst_list_b, session=session, shape=b_sh1.shape) secret_x = ReplicatedSharedTensor.shares_sum(shares_x, ring_size) secret_b = ReplicatedSharedTensor.shares_sum(shares_b, ring_size) result = operator.xor(x, b) expected_res = secret_x ^ secret_b assert (result.reconstruct(decode=False) == expected_res).all()
def test_bin_xor(get_clients, bit, security) -> None: parties = get_clients(3) protocol = Falcon(security) session = Session(protocol=protocol, parties=parties) session.ring_size = 2 SessionManager.setup_mpc(session) ring_size = 2 sh_x = torch.tensor([[0, 1, 0], [1, 0, 1]], dtype=torch.bool) shares_x = [sh_x, sh_x, sh_x] rst_list_x = ReplicatedSharedTensor.distribute_shares(shares=shares_x, session=session, ring_size=ring_size) x = MPCTensor(shares=rst_list_x, session=session) x.shape = sh_x.shape sh_b = torch.tensor([bit], dtype=torch.bool) shares_b = [sh_b, sh_b, sh_b] rst_list_b = ReplicatedSharedTensor.distribute_shares(shares=shares_b, session=session, ring_size=ring_size) b = MPCTensor(shares=rst_list_b, session=session) b.shape = sh_b.shape secret_x = ReplicatedSharedTensor.shares_sum(shares_x, ring_size) secret_b = ReplicatedSharedTensor.shares_sum(shares_b, ring_size) result = operator.xor(x, b) expected_res = secret_x ^ secret_b assert (result.reconstruct(decode=False) == expected_res).all()
def test_ops_prime_public_xor(get_clients, security, bit) -> None: parties = get_clients(3) protocol = Falcon(security) session = Session(protocol=protocol, parties=parties) SessionManager.setup_mpc(session) ring_size = PRIME_NUMBER sh1 = torch.tensor([[17, 44], [8, 20]], dtype=torch.uint8) sh2 = torch.tensor([[8, 51], [27, 52]], dtype=torch.uint8) sh3 = torch.tensor([[42, 40], [32, 63]], dtype=torch.uint8) shares = [sh1, sh2, sh3] rst_list = ReplicatedSharedTensor.distribute_shares(shares=shares, session=session, ring_size=ring_size) tensor = MPCTensor(shares=rst_list, session=session) tensor.shape = sh1.shape secret = ReplicatedSharedTensor.shares_sum(shares, ring_size) value = torch.tensor([bit], dtype=torch.uint8) result = operator.xor(tensor, value) expected_res = secret ^ value assert (result.reconstruct(decode=False) == expected_res).all()
def test_rst_invalid_triple(get_clients) -> None: parties = get_clients(3) falcon = Falcon("malicious") session = Session(parties, protocol=falcon) SessionManager.setup_mpc(session) shape_x = (1, ) shape_y = (1, ) # create an inconsistent sharing,invoke a prrs first session.session_ptrs[0].prrs_generate_random_share(shape_x) with pytest.raises(ValueError): CryptoPrimitiveProvider.generate_primitives( "beaver_mul", session=session, g_kwargs={ "session": session, "a_shape": shape_x, "b_shape": shape_y, "nr_parties": session.nr_parties, }, p_kwargs={ "a_shape": shape_x, "b_shape": shape_y }, )
def test_rst_distribute_reconstruct_float_secret(get_clients, parties, security) -> None: parties = get_clients(parties) protocol = Falcon(security) session = Session(protocol=protocol, parties=parties) SessionManager.setup_mpc(session) secret = 43.2 a = MPCTensor(secret=secret, session=session) assert np.allclose(secret, a.reconstruct(), atol=1e-3)
def test_bit_injection_exception(get_clients) -> None: parties = get_clients(3) falcon = Falcon() session = Session(parties=parties, protocol=falcon) SessionManager.setup_mpc(session) x = MPCTensor(secret=1, session=session) with pytest.raises(ValueError): ABY3.bit_injection(x, session, 2**64)
def test_share_distribution_number_shares(get_clients, parties): parties = get_clients(parties) protocol = Falcon("semi-honest") session = Session(protocol=protocol, parties=parties) SessionManager.setup_mpc(session) shares = MPCTensor.generate_shares(100.42, len(parties)) share_ptrs = ReplicatedSharedTensor.distribute_shares(shares, session) for RSTensor in share_ptrs: assert len(RSTensor.get_shares().get()) == (len(parties) - 1)
def test_prrs_rs_tensor_pointer(get_clients) -> None: clients = get_clients(3) falcon = Falcon(security_type="malicious") session = Session(protocol=falcon, parties=clients) SessionManager.setup_mpc(session) party1 = session.session_ptrs[0] share_ptr = party1.prrs_generate_random_share(shape=(1, 2)) assert share_ptr.class_name.endswith("UnionPointer") share = share_ptr.get() assert isinstance(share, ReplicatedSharedTensor)
def test_prrs_rst_union_resolve(get_clients) -> None: clients = get_clients(3) protocol = Falcon("semi-honest") session = Session(protocol=protocol, parties=clients) SessionManager.setup_mpc(session) share_pt0 = session.session_ptrs[0].prrs_generate_random_share(shape=(1, 2)) resolved_share_pt0 = share_pt0.resolve_pointer_type() share_pt_name = type(resolved_share_pt0).__name__ assert share_pt_name == "ReplicatedSharedTensorPointer"
def test_rst_distribute_reconstruct_tensor_secret(get_clients, parties, security) -> None: parties = get_clients(parties) protocol = Falcon(security) session = Session(protocol=protocol, parties=parties) SessionManager.setup_mpc(session) secret = torch.Tensor([[1, -2.0, 0.0], [3.9, -4.394, -0.9], [-43, 100, -0.4343], [1.344, -5.0, 0.55]]) a = MPCTensor(secret=secret, session=session) assert np.allclose(secret, a.reconstruct(), atol=1e-3)
def test_private_compare(get_clients, security) -> None: parties = get_clients(3) falcon = Falcon(security_type=security) session = Session(parties=parties, protocol=falcon) SessionManager.setup_mpc(session) base = session.config.encoder_base precision = session.config.encoder_precision fp_encoder = FixedPointEncoder(base=base, precision=precision) secret = torch.tensor([[358.85, 79.29], [67.78, 2415.50]]) r = torch.tensor([[357.05, 90], [145.32, 2400.54]]) r = fp_encoder.encode(r) x = MPCTensor(secret=secret, session=session) x_b = ABY3.bit_decomposition_ttp(x, session) # bit shares x_p = [] # prime ring shares for share in x_b: x_p.append(ABY3.bit_injection(share, session, PRIME_NUMBER)) tensor_type = get_type_from_ring(session.ring_size) result = Falcon.private_compare(x_p, r.type(tensor_type)) expected_res = torch.tensor([[1, 0], [0, 1]], dtype=torch.bool) assert (result.reconstruct(decode=False) == expected_res).all()
def test_invalid_malicious_reconstruction(get_clients, parties): parties = get_clients(parties) protocol = Falcon("malicious") session = Session(protocol=protocol, parties=parties) SessionManager.setup_mpc(session) secret = 42.32 tensor = MPCTensor(secret=secret, session=session) tensor.share_ptrs[0][0] = tensor.share_ptrs[0][0] + 4 with pytest.raises(ValueError): tensor.reconstruct()
def test_rst_resolve_pointer(get_clients) -> None: clients = get_clients(3) protocol = Falcon("semi-honest") session = Session(protocol=protocol, parties=clients) SessionManager.setup_mpc(session) secret = torch.randn(1, 2) tensor = MPCTensor(secret=secret, session=session) share_pt0 = tensor.share_ptrs[0] resolved_share_pt0 = share_pt0.resolve_pointer_type() share_pt_name = type(resolved_share_pt0).__name__ assert share_pt_name == "ReplicatedSharedTensorPointer"
def test_rst_reconstruct_zero_share_ptrs(get_clients, security) -> None: parties = get_clients(3) protocol = Falcon(security) session = Session(protocol=protocol, parties=parties) SessionManager.setup_mpc(session) secret = torch.Tensor([[1, -2.0, 0.0], [3.9, -4.394, -0.9], [-43, 100, -0.4343], [1.344, -5.0, 0.55]]) a = MPCTensor(secret=secret, session=session) a.share_ptrs = [] with pytest.raises(ValueError): a.reconstruct()
def test_select_shares(get_clients, security) -> None: parties = get_clients(3) falcon = Falcon(security) session = Session(parties=parties, protocol=falcon) SessionManager.setup_mpc(session) sh = torch.tensor([[1, 0], [0, 1]], dtype=torch.bool) shares = [sh, sh, sh] ptr_lst = ReplicatedSharedTensor.distribute_shares(shares, session, ring_size=2) b = MPCTensor(shares=ptr_lst, session=session, shape=sh.shape) x_val = torch.tensor([[1, 2], [3, 4]]) y_val = torch.tensor([[5, 6], [7, 8]]) x = MPCTensor(secret=x_val, session=session) y = MPCTensor(secret=y_val, session=session) z = Falcon.select_shares(x, y, b) expected_res = torch.tensor([[5.0, 2.0], [3.0, 8.0]]) assert (expected_res == z.reconstruct()).all()
def test_invalid_malicious_reconstruction(get_clients, parties): parties = get_clients(parties) protocol = Falcon("malicious") session = Session(protocol=protocol, parties=parties) SessionManager.setup_mpc(session) secret = torch.Tensor([[1, -2.0, 0.0], [3.9, -4.394, -0.9], [-43, 100, -0.4343], [1.344, -5.0, 0.55]]) tensor = MPCTensor(secret=secret, session=session) tensor.share_ptrs[0][0] = tensor.share_ptrs[0][0] + 4 with pytest.raises(ValueError): tensor.reconstruct()
def test_mul_private_exception_nothreeparties(get_clients, parties): parties = get_clients(parties) protocol = Falcon("semi-honest") session = Session(protocol=protocol, parties=parties) SessionManager.setup_mpc(session) secret1 = torch.tensor([[-100, 20, 30], [-90, 1000, 1], [1032, -323, 15]]) secret2 = 8 tensor1 = MPCTensor(secret=secret1, session=session) tensor2 = MPCTensor(secret=secret2, session=session) with pytest.raises(ValueError): tensor1 * tensor2
def test_eq(): falcon = Falcon() aby1 = ABY3(security_type="malicious") aby2 = ABY3() other2 = falcon # Test equal protocol: assert falcon == other2 # Test different protocol security type assert falcon != aby1 # Test different protocol objects assert falcon != aby2
def test_send_get(get_clients, precision=12, base=4) -> None: client = get_clients(1)[0] protocol = Falcon("semi-honest") session = Session(protocol=protocol, parties=[client]) SessionManager.setup_mpc(session) share1 = torch.Tensor([1.4, 2.34, 3.43]) share2 = torch.Tensor([1, 2, 3]) share3 = torch.Tensor([1.4, 2.34, 3.43]) session_uuid = session.rank_to_uuid[0] x_share = ReplicatedSharedTensor(shares=[share1, share2, share3], session_uuid=session_uuid) x_ptr = x_share.send(client) result = x_ptr.get() assert result == x_share
def test_ops_public_mul_matrix(get_clients, security, base, precision): parties = get_clients(3) protocol = Falcon(security) config = Config(encoder_base=base, encoder_precision=precision) session = Session(protocol=protocol, parties=parties, config=config) SessionManager.setup_mpc(session) secret = torch.Tensor([[0.125, 1001, 4.82, -1.25], [-4.25, 0.217, 3301, 4]]) value = torch.Tensor([[4.5, 9.25, 3.47, -2.5], [50, 3.17, 5.82, 2.25]]) tensor = MPCTensor(secret=secret, session=session) result = tensor * value expected_res = secret * value assert np.allclose(result.reconstruct(), expected_res, atol=1e-3)
def test_hook_property(get_clients) -> None: clients = get_clients(3) protocol = Falcon("semi-honest") session = Session(protocol=protocol, parties=clients) SessionManager.setup_mpc(session) x = torch.randn(1, 3) y = torch.randn(1, 3) shares = [x, y] rst = ReplicatedSharedTensor() rst.shares = shares assert (rst.T.shares[0] == x.T).all() assert (rst.T.shares[1] == y.T).all()
def test_private_matmul(get_clients, security): parties = get_clients(3) protocol = Falcon(security) session = Session(protocol=protocol, parties=parties) SessionManager.setup_mpc(session) secret1 = torch.tensor([ [[-100.25, 20.3, 30.12], [-50.1, 100.217, 1.2], [1032.15, -323.56, 15.15]], [[-0.25, 2.3, 3012], [-5.01, 1.00217, 1.2], [2.15, -3.56, 15.15]], ]) secret2 = torch.tensor([[-1, 0.28, 3], [-9, 10.18, 1], [32, -23, 5]]) tensor1 = MPCTensor(secret=secret1, session=session) tensor2 = MPCTensor(secret=secret2, session=session) result = tensor1 @ tensor2 expected_res = secret1 @ secret2 assert np.allclose(result.reconstruct(), expected_res, atol=1e-3)
def test_mul_private(get_clients, security, base, precision): parties = get_clients(3) protocol = Falcon(security) config = Config(encoder_base=base, encoder_precision=precision) session = Session(protocol=protocol, parties=parties, config=config) SessionManager.setup_mpc(session) secret1 = torch.tensor([[-100.25, 0.29, 30.45], [-90.82, 1000, 0.18], [1032.45, -323.18, 15.15]]) secret2 = 8 tensor1 = MPCTensor(secret=secret1, session=session) tensor2 = MPCTensor(secret=secret2, session=session) result = tensor1 * tensor2 expected_res = secret1 * secret2 assert np.allclose(result.reconstruct(), expected_res, atol=1e-3)
def test_przs_rst_ring_size(get_clients) -> None: clients = get_clients(3) falcon = Falcon() session = Session(protocol=falcon, parties=clients) SessionManager.setup_mpc(session) for ring_size in RING_SIZE_TO_TYPE.keys(): rst_pt0 = session.session_ptrs[0].przs_generate_random_share( shape=(1, 2), ring_size=str(ring_size)) share = rst_pt0.get_copy() assert share.ring_size == ring_size assert share.shares[0].dtype == RING_SIZE_TO_TYPE[ring_size] if ring_size == PRIME_NUMBER: assert torch.max(torch.cat(share.shares)) <= PRIME_NUMBER - 1 assert torch.min(torch.cat(share.shares)) >= 0