Beispiel #1
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)
Beispiel #2
0
    def private_compare(x: List[MPCTensor], r: torch.Tensor) -> MPCTensor:
        """Falcon Private Compare functionality which computes(x>r).

        Args:
            x (List[MPCTensor]) : shares of bits of x in Zp.
            r (torch.Tensor) : Public value r.

        Returns:
            result (MPCTensor): Returns shares of bits of the operation.

        Raises:
            ValueError: If input shares is not a list.
            ValueError: If input public value is not a tensor.

        (if (x>=r) returns 1 else returns 0)
        """
        if not isinstance(x, list):
            raise ValueError(
                f"Input shares for Private Compare: {x} must be a list")

        if not isinstance(r, torch.Tensor):
            raise ValueError(
                f"Value r:{r} must be a torch tensor for private compare")

        shape = x[0].shape
        session = x[0].session

        ptr_list: List[ReplicatedSharedTensor] = [
            session_ptr.prrs_generate_random_share(shape=shape, ring_size="2")
            for session_ptr in session.session_ptrs
        ]

        beta_2 = MPCTensor(shares=ptr_list, session=session,
                           shape=shape)  # shares of random bit
        beta_p = ABY3.bit_injection(
            beta_2, session, PRIME_NUMBER)  # shares of random bit in Zp.
        m = Falcon._random_prime_group(session, shape)

        nr_shares = len(x)
        u = [0] * nr_shares
        c = [0] * nr_shares

        w = 0

        for i in range(len(x) - 1, -1, -1):
            r_i = (r >> i) & 1  # bit at ith position
            u[i] = (1 - 2 * beta_p) * (x[i] - r_i)
            c[i] = u[i] + 1 + w
            w += x[i] ^ r_i

        d = m * math.prod(c)

        d_val = d.reconstruct(decode=False)  # plaintext d.
        d_val[d_val != 0] = 1  # making all non zero values as 1.

        beta_prime = d_val

        return beta_2 + beta_prime
Beispiel #3
0
    def select_shares(x: MPCTensor, y: MPCTensor, b: MPCTensor) -> MPCTensor:
        """Returns either x or y based on bit b.

        Args:
            x (MPCTensor): input tensor
            y (MPCTensor): input tensor
            b (MPCTensor): input tensor which is shares of a bit used as selector bit.

        Returns:
            z (MPCTensor):Returns x (if b==0) or y (if b==1).

        Raises:
            ValueError: If the selector bit tensor is not of ring size "2".
        """
        ring_size = int(b.share_ptrs[0].get_ring_size().get_copy())
        shape = b.shape
        if ring_size != 2:
            raise ValueError(
                f"Invalid {ring_size} for selector bit,must be of ring size 2")
        if shape is None:
            raise ValueError(
                "The selector bit tensor must have a valid shape.")
        session = x.session

        # TODO: Should be made to generate with CryptoProvider in Preprocessing stage.
        c_ptrs: List[ReplicatedSharedTensor] = []
        for session_ptr in session.session_ptrs:
            c_ptrs.append(
                session_ptr.prrs_generate_random_share(
                    shape=shape, ring_size=str(ring_size)))

        c = MPCTensor(shares=c_ptrs, session=session,
                      shape=shape)  # bit random share
        c_r = ABY3.bit_injection(
            c, session, session.ring_size)  # bit random share in session ring.

        tensor_type = get_type_from_ring(session.ring_size)
        mask = (b ^ c).reconstruct(decode=False).type(tensor_type)

        d = (mask - (c_r * mask)) + (c_r * (mask ^ 1))

        # Order placed carefully to prevent re-encoding,should not be changed.
        z = x + (d * (y - x))

        return z
Beispiel #4
0
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()
Beispiel #5
0
def test_bit_injection_prime(get_clients, security_type) -> None:
    parties = get_clients(3)
    falcon = Falcon(security_type=security_type)
    session = Session(parties=parties, protocol=falcon)
    SessionManager.setup_mpc(session)
    ring_size = PRIME_NUMBER

    bin_sh = torch.tensor([[1, 1], [0, 0]], dtype=torch.bool)

    shares = [bin_sh, bin_sh, bin_sh]
    ptr_lst = ReplicatedSharedTensor.distribute_shares(shares,
                                                       session,
                                                       ring_size=2)
    x = MPCTensor(shares=ptr_lst, session=session, shape=bin_sh.shape)

    xbit = ABY3.bit_injection(x, session, ring_size)

    ring0 = int(xbit.share_ptrs[0].get_ring_size().get_copy())
    result = xbit.reconstruct(decode=False)
    exp_res = bin_sh.type(torch.uint8)

    assert (result == exp_res).all()
    assert ring_size == ring0