예제 #1
0
def test_reconstruct_shared_model(
    is_remote: bool, model_type: Type[sy.Module], get_clients: Callable[[int], Any]
):
    net = model_type(torch)

    clients = get_clients(2)

    session = Session(parties=clients)
    SessionManager.setup_mpc(session)

    if is_remote:
        model = net.send(clients[0])
    else:
        model = net

    mpc_model = model.share(session=session)
    res = mpc_model.reconstruct()

    assert isinstance(res, sy.Module)

    if is_remote:
        # If the model is remote fetch it such that we could compare it
        model = model.get()

    for name_res, name_expected in zip(res.modules, model.modules):
        assert name_res == name_expected

        module_expected = model.modules[name_expected]
        module_res = res.modules[name_res]

        name_module = type(module_expected).__name__
        assert MAP_TORCH_TO_SYMPC[name_module].eq_close(
            module_expected, module_res, atol=1e-4
        )
예제 #2
0
def run_conv_model(get_clients: Callable[[int], List[Any]]):
    """Create a convolutional network and do a feedforwad.

    Arguments:
        get_clients: Fixture that returns a list of clients
    """
    model = ConvNet(torch)

    clients = get_clients(2)

    session = Session(parties=clients)
    SessionManager.setup_mpc(session)

    mpc_model = model.share(session=session)

    x_secret = torch.randn((1, 1, 28, 28))
    x_mpc = MPCTensor(secret=x_secret, session=session)

    model.eval()

    # For the moment we have only inference
    expected = model(x_secret)

    res_mpc = mpc_model(x_mpc)

    res_mpc.reconstruct()
    expected = expected.detach().numpy()
예제 #3
0
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
            },
        )
예제 #4
0
def test_get_grad_input_padding(get_clients, common_args: List,
                                nr_parties) -> None:
    clients = get_clients(2)
    session = Session(parties=clients)
    SessionManager.setup_mpc(session)

    grad = torch.Tensor([[[[1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0,
                                                              1.0]]]])
    grad_mpc = MPCTensor(secret=grad, session=session)

    input_size, stride, padding, kernel_size, dilation = common_args

    expected_padding = torch.nn.functional.grad._grad_input_padding(
        grad,
        input_size,
        (stride, stride),
        (padding, padding),
        kernel_size,
        (dilation, dilation),
    )

    args = [[el] + common_args + [session] for el in grad_mpc.share_ptrs]
    shares = parallel_execution(GradConv2d.get_grad_input_padding,
                                grad_mpc.session.parties)(args)
    grad_input_padding = MPCTensor(shares=shares, session=grad_mpc.session)
    output_padding_tensor = grad_input_padding.reconstruct()
    output_padding_tensor /= grad_mpc.session.nr_parties
    calculated_padding = tuple(output_padding_tensor.to(torch.int).tolist())

    assert calculated_padding == expected_padding
예제 #5
0
def test_generate_and_transfer_primitive(
    get_clients: Callable,
    nr_parties: int,
    nr_instances: int,
    nr_instances_retrieve: int,
) -> None:
    parties = get_clients(nr_parties)
    session = Session(parties=parties)
    SessionManager.setup_mpc(session)

    g_kwargs = {"nr_parties": nr_parties, "nr_instances": nr_instances}
    CryptoPrimitiveProvider.generate_primitives(
        "test",
        session=session,
        g_kwargs=g_kwargs,
        p_kwargs={},
    )

    for i in range(nr_parties):
        remote_crypto_store = session.session_ptrs[i].crypto_store
        primitives = remote_crypto_store.get_primitives_from_store(
            op_str="test", nr_instances=nr_instances_retrieve).get()
        assert primitives == [
            tuple(ShareTensor(i) for _ in range(PRIMITIVE_NR_ELEMS))
            for _ in range(nr_instances_retrieve)
        ]
예제 #6
0
def test_setup_przs(get_clients):
    """Test _setup_przs method for session."""
    alice_client, bob_client = get_clients(2)
    session = Session(parties=[alice_client, bob_client])
    assert len(session.przs_generators) == 0
    SessionManager._setup_przs(session)
    assert len(session.przs_generators) == 2
예제 #7
0
def test_additional_attributes(get_clients):
    class ConvNet_attr(sy.Module):
        def __init__(self, torch_ref):
            super(ConvNet_attr, self).__init__(torch_ref=torch_ref)
            self.conv1 = self.torch_ref.nn.Conv2d(
                in_channels=2,
                out_channels=6,
                kernel_size=(3, 5),
                stride=(2, 1),
                padding=(2, 1),
                groups=1,
                dilation=2,
            )

        def forward(self, x):
            x = self.conv1(x)
            return x

    model = ConvNet_attr(torch)

    clients = get_clients(2)

    session = Session(parties=clients)
    SessionManager.setup_mpc(session)

    mpc_model = model.share(session=session)
    model = mpc_model.reconstruct()

    assert model.conv1.kernel_size == (3, 5)
    assert model.conv1.padding == (2, 1)
    assert model.conv1.stride == (2, 1)
    assert model.conv1.groups == 1
    assert model.conv1.dilation == (2, 2)
예제 #8
0
def test_setup_mpc(get_clients):
    """Test setup_mpc method for session."""
    alice_client, bob_client = get_clients(2)
    session = Session(parties=[alice_client, bob_client])
    SessionManager.setup_mpc(session)
    assert session.rank == 1
    assert len(session.session_ptrs) == 2
예제 #9
0
def protobuf_session_deserializer(proto: MPCSession_PB) -> Session:
    id_session = UUID(bytes=proto.uuid)
    rank = proto.rank
    conf_dict = Dict._proto2object(proto=proto.config)
    _conf_dict = {key: value for key, value in conf_dict.items()}
    conf = Config(**_conf_dict)
    ring_size = int.from_bytes(proto.ring_size, "big")
    nr_parties = int.from_bytes(proto.nr_parties, "big")
    protocol_deserialized = proto.protocol.decode()

    session = Session(
        config=conf,
        uuid=id_session,
        ring_size=ring_size,
        protocol=protocol_deserialized,
    )
    session.rank = rank
    session.crypto_store = CryptoStore()
    session.nr_parties = nr_parties

    if "session" in globals():
        warning("Overwritting session for MPC")
        globals()["session"] = session

    return session
예제 #10
0
    def __init__(
        self,
        data: Optional[Union[float, int, torch.Tensor]] = None,
        session: Optional[Session] = None,
        encoder_base: int = 2,
        encoder_precision: int = 16,
        ring_size: int = 2**64,
    ) -> None:
        """Initializer for the ShareTensor."""

        if session is None:
            self.session = Session(ring_size=ring_size, )
            self.session.config.encoder_precision = encoder_precision
            self.session.config.encoder_base = encoder_base

        else:
            self.session = session
            encoder_precision = self.session.config.encoder_precision
            encoder_base = self.session.config.encoder_base

        # TODO: It looks like the same logic as above
        self.fp_encoder = FixedPointEncoder(base=encoder_base,
                                            precision=encoder_precision)

        self.tensor: Optional[torch.Tensor] = None

        if data is not None:
            tensor_type = self.session.tensor_type
            self.tensor = self._encode(data).type(tensor_type)
예제 #11
0
def share(_self, **kwargs: Dict[Any, Any]) -> MPCTensor:  # noqa
    session = None

    if "parties" not in kwargs and "session" not in kwargs:
        raise ValueError("Parties or Session should be provided as a kwarg")

    if "session" not in kwargs:
        parties = frozenset({client.id for client in kwargs["parties"]})

        if parties not in PARTIES_TO_SESSION:
            from sympc.session import SessionManager

            session = Session(kwargs["parties"])
            PARTIES_TO_SESSION[parties] = session
            SessionManager.setup_mpc(session)

            for key, val in kwargs.items():
                setattr(session, key, val)
        else:
            session = PARTIES_TO_SESSION[parties]

        kwargs.pop("parties")
        kwargs["session"] = session

    return MPCTensor(secret=_self, **kwargs)
예제 #12
0
def set_up_model(
    get_clients: Callable[[int], List[Any]]
) -> Tuple[sy.Module, sy.Module, MPCTensor]:
    """Create a convolutional network and do a feedforwad.

    Args:
        get_clients: Fixture that returns a list of clients

    Returns:
        A tuple with three items: (origin Model, Syft Model, MPCTensor)
    """
    model = ConvNet(torch)

    clients = get_clients(2)

    session = Session(parties=clients)
    SessionManager.setup_mpc(session)

    mpc_model = model.share(session=session)

    x_secret = torch.randn((1, 1, 28, 28))
    x_mpc = MPCTensor(secret=x_secret, session=session)

    model.eval()

    expected = model(x_secret)

    return (expected, mpc_model, x_mpc)
예제 #13
0
def test_generate_primitive_from_dict_beaver_mul(get_clients) -> None:
    clients = get_clients(2)
    session = Session(parties=clients)
    SessionManager.setup_mpc(session)

    primitive_log = {
        "beaver_mul": [
            (
                {
                    "a_shape": (2, 10),
                    "b_shape": (2, 10)
                },
                {
                    "session": session,
                    "a_shape": (2, 10),
                    "b_shape": (2, 10),
                    "nr_parties": 2,
                },
            ),
            (
                {
                    "a_shape": (1, 5),
                    "b_shape": (1, 5)
                },
                {
                    "session": session,
                    "a_shape": (1, 5),
                    "b_shape": (1, 5),
                    "nr_parties": 2,
                },
            ),
        ]
    }

    CryptoPrimitiveProvider.generate_primitive_from_dict(
        primitive_log=primitive_log, session=session)

    args = primitive_log.popitem()[1]

    for arg in args:
        a_shape = arg[1].get("a_shape")
        b_shape = arg[1].get("b_shape")

        key = f"beaver_mul_{a_shape}_{b_shape}"

        store_client_1 = session.session_ptrs[0].crypto_store.store.get()
        store_client_2 = session.session_ptrs[1].crypto_store.store.get()

        a_shape_client_1 = tuple(store_client_1.get(key)[0][0].shape)
        b_shape_client_1 = tuple(store_client_1.get(key)[0][1].shape)

        assert a_shape == a_shape_client_1
        assert b_shape == b_shape_client_1

        a_shape_client_2 = tuple(store_client_2.get(key)[0][0].shape)
        b_shape_client_2 = tuple(store_client_2.get(key)[0][1].shape)

        assert a_shape == a_shape_client_2
        assert b_shape == b_shape_client_2
예제 #14
0
def test_invalid_mpc_pointer(get_clients) -> None:
    parties = get_clients(3)
    session = Session(parties=parties)
    SessionManager.setup_mpc(session)
    x = MPCTensor(secret=1, session=session)
    # passing sharetensor pointer
    with pytest.raises(ValueError):
        ABY3.truncate(x, session, 2**32, None)
예제 #15
0
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)
예제 #16
0
def test_setup_mpc(get_clients):
    """Test setup_mpc method for session."""
    alice_client, bob_client = get_clients(2)
    session = Session(parties=[alice_client, bob_client])
    SessionManager.setup_mpc(session)
    assert isinstance(session.uuid, UUID)
    assert list(session.rank_to_uuid.keys()) == [0, 1]
    assert all(isinstance(e, UUID) for e in session.rank_to_uuid.values())
예제 #17
0
def test_copy() -> None:
    session = Session()

    copy_session = session.copy()

    assert session.nr_parties == copy_session.nr_parties
    assert session.config == copy_session.config
    assert session.protocol == copy_session.protocol
예제 #18
0
def test_remote_mpc_no_shape(get_clients) -> None:
    alice_client, bob_client = get_clients(2)
    session = Session(parties=[alice_client, bob_client])
    SessionManager.setup_mpc(session)

    x_remote = alice_client.torch.Tensor([1, -2, 0.3])

    with pytest.raises(ValueError):
        MPCTensor(secret=x_remote, session=session)
예제 #19
0
def test_setupmpc_nocall_exception(get_clients) -> None:
    alice_client, bob_client = get_clients(2)
    session = Session(parties=[alice_client, bob_client])

    with pytest.raises(ValueError):
        MPCTensor(secret=42, session=session)

    with pytest.raises(ValueError):
        MPCTensor(secret=torch.Tensor([1, -2]), session=session)
예제 #20
0
def test_invalid_share_class(get_clients) -> None:
    clients = get_clients(2)
    session = Session(parties=clients)
    SessionManager.setup_mpc(session)
    x = torch.tensor([1, 2, 3])
    x_s = MPCTensor(secret=x, session=session)
    x_s.session.protocol.share_class = "invalid"
    with pytest.raises(TypeError):
        x_s + x
예제 #21
0
def test_mpc_len(get_clients) -> None:
    clients = get_clients(2)
    session = Session(parties=clients)
    SessionManager.setup_mpc(session)

    for dim in range(1, 5):
        x_secret = torch.arange(-6, 6).view(dim, -1)
        x = MPCTensor(secret=x_secret, session=session)
        assert len(x_secret) == len(x)
예제 #22
0
def test_eq() -> None:
    """Test __eq__ for Session."""
    session = Session()
    other1 = Session()
    other2 = session

    # Test different instances:
    assert session != 1

    # Test equal sessions:
    assert session == other2

    # Test same sessions (until we call setup mpc):
    assert session == other1

    SessionManager.setup_mpc(session)

    assert session != other1
예제 #23
0
def test_max_multiple_max(get_clients) -> None:
    clients = get_clients(2)
    session = Session(parties=clients)
    SessionManager.setup_mpc(session)

    x = MPCTensor(secret=torch.Tensor([1, 2, 3, -1, 3]), session=session)

    with pytest.raises(ValueError):
        x.argmax()
예제 #24
0
def test_session_manager_init():
    """Test correct initialisation of the SessionManager class."""
    # Test default init
    session = SessionManager()
    assert isinstance(session.uuid, UUID)
    # Test custom init
    uuid = uuid4()
    session = Session(uuid=uuid)
    assert session.uuid == uuid
예제 #25
0
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)
예제 #26
0
def test_remote_mpc_with_shape(get_clients) -> None:
    alice_client, bob_client = get_clients(2)
    session = Session(parties=[alice_client, bob_client])
    SessionManager.setup_mpc(session)

    x_remote = alice_client.torch.Tensor([1, -2, 0.3])
    x = MPCTensor(secret=x_remote, shape=(1, 3), session=session)
    result = x.reconstruct()

    assert np.allclose(x_remote.get(), result, atol=1e-5)
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)
예제 #28
0
def test_exception_value_error(get_clients) -> None:
    clients = get_clients(2)
    session_one = Session(parties=clients)
    SessionManager.setup_mpc(session_one)

    x_secret = torch.Tensor([-2.0, 6.0, 2.0, 3.0, -5.0, -0.5])

    x = MPCTensor(secret=x_secret, session=session_one)

    with pytest.raises(ValueError):
        reciprocal(x, method="exp")
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)
예제 #30
0
def test_exception_conv2d_kernel_mismatch(get_clients):

    clients = get_clients(2)

    model = ConvNet(torch, kernel_size=(5, 4))
    # Setup the session for the computation
    session = Session(parties=clients)
    SessionManager.setup_mpc(session)

    with pytest.raises(ValueError):
        model.share(session=session)