コード例 #1
0
ファイル: mpc_tensor_test.py プロジェクト: NiWaRe/SyMPC
def test_generate_shares() -> None:
    precision = 12
    base = 4

    x_secret = torch.Tensor([5.0])

    # test with default values
    x_share = ShareTensor(data=x_secret)

    shares_from_share_tensor = MPCTensor.generate_shares(x_share, nr_parties=2)
    shares_from_secret = MPCTensor.generate_shares(x_secret,
                                                   nr_parties=2,
                                                   config=Config())

    assert sum(shares_from_share_tensor).tensor == sum(
        shares_from_secret).tensor

    x_share = ShareTensor(data=x_secret,
                          config=Config(encoder_precision=precision,
                                        encoder_base=base))

    shares_from_share_tensor = MPCTensor.generate_shares(x_share, 2)
    shares_from_secret = MPCTensor.generate_shares(
        x_secret,
        2,
        config=Config(encoder_precision=precision, encoder_base=base))

    assert sum(shares_from_share_tensor).tensor == sum(
        shares_from_secret).tensor
コード例 #2
0
ファイル: beaver.py プロジェクト: jmaunon/SyMPC
def _get_triples(
    op_str: str, nr_parties: int, a_shape: Tuple[int], b_shape: Tuple[int]
) -> Tuple[Tuple[ShareTensor, ShareTensor, ShareTensor]]:
    """
    The Trusted Third Party (TTP) or Crypto Provider should provide this triples
    Currently, the one that orchestrates the communication provides those triples.
    """

    a_rand = torch.empty(size=a_shape, dtype=torch.long).random_(
        generator=ttp_generator
    )
    a = ShareTensor(data=a_rand, encoder_precision=0)
    a_shares = MPCTensor.generate_shares(a, nr_parties, torch.long)

    b_rand = torch.empty(size=b_shape, dtype=torch.long).random_(
        generator=ttp_generator
    )
    b = ShareTensor(data=b_rand, encoder_precision=0)
    b_shares = MPCTensor.generate_shares(b, nr_parties, torch.long)

    cmd = getattr(operator, op_str)

    c_val = cmd(a_rand, b_rand)
    c = ShareTensor(data=c_val, encoder_precision=0)
    c_shares = MPCTensor.generate_shares(c, nr_parties, torch.long)

    return a_shares, b_shares, c_shares
コード例 #3
0
def test_generate_shares_config(get_clients) -> None:
    x_secret = torch.Tensor([5.0])
    x_share = ShareTensor(data=x_secret)

    shares_from_share_tensor = MPCTensor.generate_shares(x_share, 2)
    shares_from_secret = MPCTensor.generate_shares(
        x_secret, 2, config=Config(encoder_base=2, encoder_precision=16)
    )

    assert sum(shares_from_share_tensor) == sum(shares_from_secret)
コード例 #4
0
ファイル: mpc_tensor_test.py プロジェクト: jmaunon/SyMPC
def test_generate_shares_session(get_clients) -> None:
    clients = get_clients(2)
    session = Session(parties=clients)
    SessionManager.setup_mpc(session)

    x_secret = torch.Tensor([5.0])
    x_share = ShareTensor(data=x_secret, session=session)

    shares_from_share_tensor = MPCTensor.generate_shares(x_share, 2)
    shares_from_secret = MPCTensor.generate_shares(x_secret, 2, session=session)

    assert sum(shares_from_share_tensor) == sum(shares_from_secret)
コード例 #5
0
ファイル: mpc_tensor_test.py プロジェクト: jmaunon/SyMPC
def test_reconstruct(get_clients) -> None:
    clients = get_clients(2)
    session = Session(parties=clients)
    SessionManager.setup_mpc(session)

    a_rand = 3
    a = ShareTensor(data=a_rand, encoder_precision=0)
    a_shares = MPCTensor.generate_shares(a, 2, torch.long)

    a_shares_copy = MPCTensor.generate_shares(a_rand, 2, torch.long)

    x_secret = torch.Tensor([1, -2, 3.0907, -4.870])
    x = MPCTensor(secret=x_secret, session=session)
    x = x.reconstruct()

    assert torch.allclose(x_secret, x)
コード例 #6
0
def count_wraps_rand(
    nr_parties: int, shape: Tuple[int]
) -> Tuple[List[ShareTensor], List[ShareTensor]]:
    """Count wraps random.

    The Trusted Third Party (TTP) or Crypto provider should generate:

    - a set of shares for a random number
    - a set of shares for the number of wraparounds for that number

    Those shares are used when doing a public division, such that the
    end result would be the correct one.

    Args:
        nr_parties (int): Number of parties
        shape (Tuple[int]): The shape for the random value

    Returns:
        List[List[List[ShareTensor, ShareTensor]]: a list of instaces with the shares
        for a random integer value and shares for the number of wraparounds that are done when
        reconstructing the random value
    """
    rand_val = torch.empty(size=shape, dtype=torch.long).random_(
        generator=ttp_generator
    )

    r_shares = MPCTensor.generate_shares(
        secret=rand_val,
        nr_parties=nr_parties,
        tensor_type=torch.long,
        encoder_precision=0,
    )
    wraps = count_wraps([share.data for share in r_shares])

    theta_r_shares = MPCTensor.generate_shares(
        secret=wraps, nr_parties=nr_parties, tensor_type=torch.long, encoder_precision=0
    )

    # We are always creating only an instance
    primitives_sequential = [(r_shares, theta_r_shares)]

    primitives = list(
        map(list, zip(*map(lambda x: map(list, zip(*x)), primitives_sequential)))
    )

    return primitives
コード例 #7
0
def test_reconstruct(get_clients) -> None:
    clients = get_clients(2)
    session = Session(parties=clients)
    SessionManager.setup_mpc(session)

    a_rand = 3
    a = ShareTensor(data=a_rand, config=Config(encoder_precision=0))
    MPCTensor.generate_shares(secret=a, nr_parties=2, tensor_type=torch.long)

    MPCTensor.generate_shares(
        secret=a_rand, nr_parties=2, config=Config(), tensor_type=torch.long
    )

    x_secret = torch.Tensor([1, -2, 3.0907, -4.870])
    x = MPCTensor(secret=x_secret, session=session)
    x = x.reconstruct()

    assert np.allclose(x_secret, x)
コード例 #8
0
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)
コード例 #9
0
def test_share_tensor(get_clients) -> None:
    assert FSS.share_class == ShareTensor

    session = Session(parties=get_clients(3))
    SessionManager.setup_mpc(session)

    secret = torch.tensor([-1, 0, 1])
    shares = MPCTensor.generate_shares(secret, nr_parties=3)

    distributed_shares = FSS.distribute_shares(shares, session=session)

    assert all(ispointer(share_ptr) for share_ptr in distributed_shares)
コード例 #10
0
ファイル: beaver.py プロジェクト: jmaunon/SyMPC
def count_wraps_rand(
    nr_parties: int, shape: Tuple[int]
) -> Tuple[List[ShareTensor], List[ShareTensor]]:
    """
    The Trusted Third Party (TTP) or Crypto Provider should generate
    - a set of shares for a random number
    - a set of shares for the number of wraparounds for that number

    Those shares are used when doing a public division, such that the
    end result would be the correct one.
    """
    rand_val = torch.empty(size=shape, dtype=torch.long).random_(
        generator=ttp_generator
    )
    r = ShareTensor(data=rand_val, encoder_precision=0)

    r_shares = MPCTensor.generate_shares(r, nr_parties, torch.long)
    wraps = count_wraps([share.data for share in r_shares])

    theta_r = ShareTensor(data=wraps, encoder_precision=0)
    theta_r_shares = MPCTensor.generate_shares(theta_r, nr_parties, torch.long)

    return r_shares, theta_r_shares
コード例 #11
0
def _get_triples(
    op_str: str,
    nr_parties: int,
    a_shape: Tuple[int],
    b_shape: Tuple[int],
    **kwargs: Dict[Any, Any]
) -> List[Tuple[Tuple[ShareTensor, ShareTensor, ShareTensor]]]:
    """Get triples.

    The Trusted Third Party (TTP) or Crypto Provider should provide this triples Currently,
    the one that orchestrates the communication provides those triples.".

    Args:
        op_str (str): Operator string.
        nr_parties (int): Number of parties
        a_shape (Tuple[int]): Shape of a from beaver triples protocol.
        b_shape (Tuple[int]): Shape of b part from beaver triples protocol.
        kwargs: Arbitrary keyword arguments for commands.


    Returns:
        List[List[3 x List[ShareTensor, ShareTensor, ShareTensor]]]:
        The generated triples a,b,c for each party.
    """
    a_rand = torch.empty(size=a_shape, dtype=torch.long).random_(
        generator=ttp_generator
    )
    a_shares = MPCTensor.generate_shares(
        secret=a_rand,
        nr_parties=nr_parties,
        tensor_type=torch.long,
        encoder_precision=0,
    )

    b_rand = torch.empty(size=b_shape, dtype=torch.long).random_(
        generator=ttp_generator
    )
    b_shares = MPCTensor.generate_shares(
        secret=b_rand,
        nr_parties=nr_parties,
        tensor_type=torch.long,
        encoder_precision=0,
    )

    if op_str == "conv2d":
        cmd = torch.conv2d
    else:
        cmd = getattr(operator, op_str)

    c_val = cmd(a_rand, b_rand, **kwargs)
    c_shares = MPCTensor.generate_shares(
        secret=c_val, nr_parties=nr_parties, tensor_type=torch.long, encoder_precision=0
    )

    # We are always creating an instance
    triple_sequential = [(a_shares, b_shares, c_shares)]

    """
    Example -- for n_instances=2 and n_parties=2:
    For Beaver Triples the "res" would look like:
    res = [
        ([a0_sh_p0, a0_sh_p1], [b0_sh_p0, b0_sh_p1], [c0_sh_p0, c0_sh_p1]),
        ([a1_sh_p0, a1_sh_p1], [b1_sh_p0, b1_sh_p1], [c1_sh_p0, c1_sh_p1])
    ]

    We want to send to each party the values they should hold:
    primitives = [
        [[a0_sh_p0, b0_sh_p0, c0_sh_p0], [a1_sh_p0, b1_sh_p0, c1_sh_p0]], # (Row 0)
        [[a0_sh_p1, b0_sh_p1, c0_sh_p1], [a1_sh_p1, b1_sh_p1, c1_sh_p1]]  # (Row 1)
    ]

    The first party (party 0) receives Row 0 and the second party (party 1) receives Row 1
    """
    triple = list(map(list, zip(*map(lambda x: map(list, zip(*x)), triple_sequential))))
    return triple
コード例 #12
0
def _get_triples(
    op_str: str,
    nr_parties: int,
    a_shape: Tuple[int],
    b_shape: Tuple[int],
    session: Session,
    ring_size: Optional[int] = None,
    config: Optional[Config] = None,
    **kwargs: Dict[Any, Any],
) -> List[Tuple[Tuple[ShareTensor, ShareTensor, ShareTensor]]]:
    """Get triples.

    The Trusted Third Party (TTP) or Crypto Provider should provide this triples Currently,
    the one that orchestrates the communication provides those triples.".

    Args:
        op_str (str): Operator string.
        nr_parties (int): Number of parties
        a_shape (Tuple[int]): Shape of a from beaver triples protocol.
        b_shape (Tuple[int]): Shape of b part from beaver triples protocol.
        session (Session) : Session to generate the triples for.
        ring_size (int) : Ring Size of the triples to generate.
        config (Config) : The configuration(base,precision) of the shares to generate.
        kwargs: Arbitrary keyword arguments for commands.

    Returns:
        List[List[3 x List[ShareTensor, ShareTensor, ShareTensor]]]:
        The generated triples a,b,c for each party.

    Raises:
        ValueError: If the triples are not consistent.
        ValueError: If the share class is invalid.
    """
    from sympc.protocol import Falcon

    config = Config(encoder_precision=0)
    if op_str in ["conv2d", "conv_transpose2d"]:
        cmd = getattr(torch, op_str)
    else:
        cmd = getattr(operator, op_str)

    if session.protocol.share_class == ShareTensor:
        a_rand = torch.empty(size=a_shape,
                             dtype=torch.long).random_(generator=ttp_generator)
        a_shares = MPCTensor.generate_shares(
            secret=a_rand,
            nr_parties=nr_parties,
            tensor_type=torch.long,
            config=config,
        )

        b_rand = torch.empty(size=b_shape,
                             dtype=torch.long).random_(generator=ttp_generator)
        b_shares = MPCTensor.generate_shares(
            secret=b_rand,
            nr_parties=nr_parties,
            tensor_type=torch.long,
            config=config,
        )

        c_val = cmd(a_rand, b_rand, **kwargs)
        c_shares = MPCTensor.generate_shares(secret=c_val,
                                             nr_parties=nr_parties,
                                             tensor_type=torch.long,
                                             config=config)
    elif session.protocol.share_class == ReplicatedSharedTensor:

        if ring_size is None:
            ring_size = session.ring_size
        if config is None:
            config = session.config

        a_ptrs: List = []
        b_ptrs: List = []
        for session_ptr in session.session_ptrs:
            a_ptrs.append(
                session_ptr.prrs_generate_random_share(a_shape,
                                                       str(ring_size)))
            b_ptrs.append(
                session_ptr.prrs_generate_random_share(b_shape,
                                                       str(ring_size)))

        a = MPCTensor(shares=a_ptrs, session=session, shape=a_shape)
        b = MPCTensor(shares=b_ptrs, session=session, shape=b_shape)
        c = Falcon.mul_semi_honest(a,
                                   b,
                                   session,
                                   op_str,
                                   ring_size,
                                   config,
                                   reshare=True,
                                   **kwargs)

        a_shares = [share.get_copy() for share in a.share_ptrs]
        b_shares = [share.get_copy() for share in b.share_ptrs]
        c_shares = [share.get_copy() for share in c.share_ptrs]

        shares_sum = ReplicatedSharedTensor.shares_sum
        a_val = shares_sum([a_shares[0].shares[0]] + a_shares[1].shares,
                           ring_size)
        b_val = shares_sum([b_shares[0].shares[0]] + b_shares[1].shares,
                           ring_size)
        c_val = shares_sum([c_shares[0].shares[0]] + c_shares[1].shares,
                           ring_size)

        op = ReplicatedSharedTensor.get_op(ring_size, op_str)

        if (c_val != op(a_val, b_val)).all():
            raise ValueError("Computation aborted:Invalid Triples")
    else:
        raise ValueError("Invalid share class.")

    # We are always creating an instance
    triple_sequential = [(a_shares, b_shares, c_shares)]
    """
    Example -- for n_instances=2 and n_parties=2:
    For Beaver Triples the "res" would look like:
    res = [
        ([a0_sh_p0, a0_sh_p1], [b0_sh_p0, b0_sh_p1], [c0_sh_p0, c0_sh_p1]),
        ([a1_sh_p0, a1_sh_p1], [b1_sh_p0, b1_sh_p1], [c1_sh_p0, c1_sh_p1])
    ]

    We want to send to each party the values they should hold:
    primitives = [
        [[a0_sh_p0, b0_sh_p0, c0_sh_p0], [a1_sh_p0, b1_sh_p0, c1_sh_p0]], # (Row 0)
        [[a0_sh_p1, b0_sh_p1, c0_sh_p1], [a1_sh_p1, b1_sh_p1, c1_sh_p1]]  # (Row 1)
    ]

    The first party (party 0) receives Row 0 and the second party (party 1) receives Row 1
    """

    triple = list(
        map(list, zip(*map(lambda x: map(list, zip(*x)), triple_sequential))))

    return triple