Repository: OpenMined/PySyft

Issue:
Call decrypt() without specifying the protocol
**Is your feature request related to a problem? Please describe.**
When we call decrypt on a tensor, we don't want to always provide the protocol if it can be known otherwise.

**Describe the solution you'd like**
I think that the current protocol that encrypted the tensor can be checked by looking at the child's type.


Discussion:
I'll take this up!
It would be great if you can wait till the CKKSTensor is merged to avoid any merge conflict
Sure 😊

Resolving patch:
diff --git a/syft/frameworks/torch/tensors/interpreters/native.py b/syft/frameworks/torch/tensors/interpreters/native.py
--- a/syft/frameworks/torch/tensors/interpreters/native.py
+++ b/syft/frameworks/torch/tensors/interpreters/native.py
@@ -1,5 +1,6 @@
 from typing import Union, List
 import weakref
+import warnings
 
 import torch
 
@@ -1033,14 +1034,12 @@ def encrypt(self, protocol="mpc", **kwargs):
                 "Encryption and Secure Multi-Party Computation"
             )
 
-    def decrypt(self, protocol="mpc", **kwargs):
+    def decrypt(self, **kwargs):
         """
         This method will decrypt 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:
                     None
@@ -1049,19 +1048,23 @@ def decrypt(self, protocol="mpc", **kwargs):
                     private_key (phe.paillier.PaillierPrivateKey): Can be obtained using
                         ```public_key, private_key = sy.frameworks.torch.he.paillier.keygen()```
         Returns:
-            An decrypted version of the Tensor following the protocol specified
+            An decrypted version of the Tensor following the protocol guessed from its type
 
         Raises:
             NotImplementedError: If protocols other than the ones mentioned above are queried
 
         """
 
-        if protocol.lower() == "mpc":
+        protocol = kwargs.get("protocol", None)
+        if protocol:
+            warnings.warn("protocol should no longer be used in decrypt")
+
+        if isinstance(self.child, (syft.FixedPrecisionTensor, syft.AutogradTensor)):
             x_encrypted = self.copy()
             x_decrypted = x_encrypted.get().float_prec()
             return x_decrypted
 
-        elif protocol.lower() == "paillier":
+        elif isinstance(self.child, PaillierTensor):
             # self.copy() not required as PaillierTensor's decrypt method is not inplace
             private_key = kwargs.get("private_key")
             return self.child.decrypt(private_key)


Test patch:
diff --git a/test/torch/tensors/test_tensor.py b/test/torch/tensors/test_tensor.py
--- a/test/torch/tensors/test_tensor.py
+++ b/test/torch/tensors/test_tensor.py
@@ -7,3 +7,18 @@ def test_init():
     tensor_extension = torch.Tensor()
     assert tensor_extension.id is not None
     assert tensor_extension.owner is not None
+
+
+def test_decrypt_mpc(workers):
+    alice = workers.get("alice")
+    bob = workers.get("bob")
+    cp = workers.get("charlie")
+    t = torch.tensor(73)
+    # without grad
+    t_encrypted = t.encrypt(protocol="mpc", workers=[alice, bob], crypto_provider=cp)
+    assert t_encrypted.decrypt() == t
+    # with grad
+    t_encrypted = t.encrypt(
+        protocol="mpc", workers=[alice, bob], crypto_provider=cp, requires_grad=True
+    )
+    assert t_encrypted.decrypt() == t