Beispiel #1
0
def deserialize_paillier(struct, pub=None):
    # Case 1: dict recursion
    if isinstance(struct, dict):
        pub = PaillierPublicKey(n=int(struct['n']))
        child = [
            deserialize_paillier(substruct, pub)
            for substruct in struct['values']
        ]
        # Building Paillier Tensor
        tensor = PaillierTensor()
        tensor.child = array(child)
        tensor.pubkey = pub
        return tensor.wrap()

    # Case 2: list recursion
    elif isinstance(struct, list):
        return [deserialize_paillier(substruct, pub) for substruct in struct]

    # Case 3: Tuple deserialization
    elif isinstance(struct, tuple):
        return EncryptedNumber(pub, int(struct[0]), int(struct[1]))

    # Case 4: Unknown type
    else:
        raise TypeError(type(struct))
Beispiel #2
0
    def encrypt(self, protocol="mpc", **kwargs):
        """
        This method will encrypt each value in the tensor using Multi Party
        Computation (default) or Paillier Homomorphic Encryption

        Args:
            protocol (str): Currently supports 'mpc' for Multi Party
                Computation and 'paillier' for Paillier Homomorphic Encryption
            **kwargs:
                With Respect to MPC accepts:
                    workers (list): Parties involved in the sharing of the Tensor
                    crypto_provider (syft.VirtualWorker): Worker responsible for the
                        generation of the random numbers for encryption
                    requires_grad (bool): If true, whenever the remote value of this tensor
                        will have its gradient updated (for example when calling .backward()),
                        a call will be made to set back the local gradient value.
                    no_wrap (bool): If True, wrap() is called on the created pointer
                    Keyword Args: To be parsed as kwargs for the .fix_prec() method

                With Respect to Paillier accepts:
                    public_key (phe.paillier.PaillierPublicKey): Can be obtained using
                        ```public_key, private_key = sy.frameworks.torch.he.paillier.keygen()```
        Returns:
            An encrypted version of the Tensor following the protocol specified

        Raises:
            NotImplementedError: If protocols other than the ones mentioned above are queried

        """
        if protocol.lower() == "mpc":
            workers = kwargs.pop("workers")
            crypto_provider = kwargs.pop("crypto_provider")
            requires_grad = kwargs.pop("requires_grad", False)
            no_wrap = kwargs.pop("no_wrap", False)
            kwargs_fix_prec = kwargs  # Rest of kwargs for fix_prec method

            x_shared = self.fix_prec(**kwargs_fix_prec).share(
                *workers,
                crypto_provider=crypto_provider,
                requires_grad=requires_grad,
                no_wrap=no_wrap,
            )
            return x_shared

        elif protocol.lower() == "paillier":
            public_key = kwargs.get("public_key")

            x = self.copy()
            x_encrypted = PaillierTensor().on(x)  # Instantiate the class
            x_encrypted.child.encrypt_(
                public_key)  # Perform Homomorphic Encryption

            return x_encrypted

        else:
            raise NotImplementedError(
                "Currently the .encrypt() method only supports Paillier Homomorphic "
                "Encryption and Secure Multi-Party Computation")
Beispiel #3
0
    def encrypt(self, public_key):
        """This method will encrypt each value in the tensor using Paillier
        homomorphic encryption.

        Args:
            *public_key a public key created using
                syft.frameworks.torch.he.paillier.keygen()
        """

        x = self.copy()
        x2 = PaillierTensor().on(x)
        x2.child.encrypt_(public_key)
        return x2
Beispiel #4
0
def to_paillier(element, public_key):
    if isinstance(element, torch.Tensor) and isinstance(
            element.child, PaillierTensor):
        element.child.pubkey = public_key
        child = element.child.child
        if isinstance(child, ndarray):
            return element
        elif isinstance(child, EncryptedNumber):
            element.child.child = array([child])
            return element
        else:
            raise Exception(
                "The tensor does not have an EncryptedNumber or a np.ndarray as child"
            )
    elif isinstance(element, PaillierTensor):
        element.pubkey = public_key
        return element.wrap()
    elif isinstance(element, ndarray):
        tensor = PaillierTensor()
        tensor.child = element
        tensor.pubkey = public_key
        return tensor.wrap()
    elif isinstance(element, list):
        tensor = PaillierTensor()
        tensor.child = array(element)
        tensor.pubkey = public_key
        return tensor.wrap()
    elif isinstance(element, EncryptedNumber):
        tensor = PaillierTensor()
        tensor.child = array([element])
        tensor.pubkey = public_key
        return tensor.wrap()
    else:
        raise TypeError(type(element))
Beispiel #5
0
    def encrypt(self, protocol="mpc", inplace=False, **kwargs):
        """
        This method will encrypt each value in the tensor using Multi Party
        Computation (default) or Paillier Homomorphic Encryption

        Args:
            protocol (str): Currently supports the following crypto protocols:
                - 'snn' for SecureNN
                - 'fss' for Function Secret Sharing (see AriaNN paper)
                - 'mpc' (Multi Party Computation) defaults to most standard protocol,
                    currently 'snn'
                - 'paillier' for Paillier Homomorphic Encryption

            inplace (bool): compute the operation inplace (default is False)

            **kwargs:
                With respect to Fixed Precision accepts:
                    precision_fractional (int)
                    dtype (str)

                With Respect to MPC accepts:
                    workers (list): Parties involved in the sharing of the Tensor
                    crypto_provider (syft.VirtualWorker): Worker responsible for the
                        generation of the random numbers for encryption
                    requires_grad (bool): If true, whenever the remote value of this tensor
                        will have its gradient updated (for example when calling .backward()),
                        a call will be made to set back the local gradient value.
                    no_wrap (bool): If True, wrap() is called on the created pointer
                    Keyword Args: To be parsed as kwargs for the .fix_prec() method

                With Respect to Paillier accepts:
                    public_key (phe.paillier.PaillierPublicKey): Can be obtained using
                        ```public_key, private_key = sy.frameworks.torch.he.paillier.keygen()```
        Returns:
            An encrypted version of the Tensor following the protocol specified

        Raises:
            NotImplementedError: If protocols other than the ones mentioned above are queried

        """
        protocol = protocol.lower()

        if protocol in {"mpc", "snn", "fss"}:
            if protocol == "mpc":
                protocol = "snn"
            workers = kwargs.pop("workers")
            crypto_provider = kwargs.pop("crypto_provider")
            requires_grad = kwargs.pop("requires_grad", False)
            no_wrap = kwargs.pop("no_wrap", False)
            dtype = kwargs.get("dtype")
            kwargs_fix_prec = kwargs  # Rest of kwargs for fix_prec method
            kwargs_share = dict(
                crypto_provider=crypto_provider,
                requires_grad=requires_grad,
                no_wrap=no_wrap,
                protocol=protocol,
                dtype=dtype,
            )

            if not inplace:
                x_shared = self.fix_prec(**kwargs_fix_prec).share(
                    *workers, **kwargs_share)
                return x_shared
            else:
                self.fix_prec_(**kwargs_fix_prec).share_(
                    *workers, **kwargs_share)
                return self

        elif protocol == "paillier":
            public_key = kwargs.get("public_key")

            x = self.copy()
            x_encrypted = PaillierTensor().on(x)  # Instantiate the class
            x_encrypted.child.encrypt_(
                public_key)  # Perform Homomorphic Encryption

            return x_encrypted

        else:
            raise NotImplementedError(
                "Currently the .encrypt() method only supports Paillier Homomorphic "
                f"Encryption and Secure Multi-Party Computation, but {protocol} was given"
            )
Beispiel #6
0
    AutogradTensor:
    get_child,
    LoggingTensor:
    get_child,
    PaillierTensor:
    get_child,
}

backward_func = {
    TorchTensor: lambda i, **kwargs: i.wrap(**kwargs),
    torch.Tensor: lambda i, **kwargs: i.wrap(**kwargs),
    torch.nn.Parameter: lambda i, **kwargs: torch.nn.Parameter(data=i),
    AutogradTensor:
    lambda i, **kwargs: AutogradTensor(data=i).on(i, wrap=False),
    LoggingTensor: lambda i, **kwargs: LoggingTensor().on(i, wrap=False),
    PaillierTensor: lambda i, **kwargs: PaillierTensor().on(i, wrap=False),
}

if dependency_check.crypten_available:
    import crypten

    type_rule[crypten.mpc.MPCTensor] = one
    forward_func[crypten.mpc.MPCTensor] = (
        lambda i: i.child
        if hasattr(i, "child") else ().throw(PureFrameworkTensorFoundError))
    backward_func[crypten.mpc.MPCTensor] = lambda i, **kwargs: i.wrap(**kwargs)

# Methods or functions whose signature changes a lot and that we don't want to "cache", because
# they have an arbitrary number of tensors in args which can trigger unexpected behaviour
ambiguous_methods = {
    "__getitem__",
Beispiel #7
0
    else (_ for _ in ()).throw(PureFrameworkTensorFoundError),
    torch.nn.Parameter: lambda i: i.child
    if hasattr(i, "child")
    else (_ for _ in ()).throw(PureFrameworkTensorFoundError),
    AutogradTensor: get_child,
    LoggingTensor: get_child,
    PaillierTensor: get_child,
}

backward_func = {
    TorchTensor: lambda i: i.wrap(),
    torch.Tensor: lambda i: i.wrap(),
    torch.nn.Parameter: lambda i: torch.nn.Parameter(data=i),
    AutogradTensor: lambda i: AutogradTensor(data=i).on(i, wrap=False),
    LoggingTensor: lambda i: LoggingTensor().on(i, wrap=False),
    PaillierTensor: lambda i: PaillierTensor().on(i, wrap=False),
}

ambiguous_methods = {
    "__getitem__",
    "_getitem_public",
    "__setitem__",
    "view",
    "permute",
    "add_",
    "sub_",
    "new",
    "chunk",
    "reshape",
}