Repository: OpenMined/PySyft
Pull request #206 (2017-09-02 15:35:58)

Paillier division
This fixes the issue with mine.js that caused the following error found by @anoff :

mine_1     | Traceback (most recent call last):
mine_1     |   File "/usr/bin/syft_cmd", line 4, in <module>
mine_1     |     __import__('pkg_resources').run_script('syft==0.1.0', 'syft_cmd')
mine_1     |   File "/usr/lib/python3.6/site-packages/pkg_resources/__init__.py", line 743, in run_script
mine_1     |     self.require(requires)[0].run_script(script_name, ns)
mine_1     |   File "/usr/lib/python3.6/site-packages/pkg_resources/__init__.py", line 1505, in run_script
mine_1     |     exec(script_code, namespace, namespace)
mine_1     |   File "/usr/lib/python3.6/site-packages/syft-0.1.0-py3.6.egg/EGG-INFO/scripts/syft_cmd", line 141, in <module>
mine_1     |   File "/usr/lib/python3.6/site-packages/numpy/core/fromnumeric.py", line 2909, in mean
mine_1     |     out=out, **kwargs)
mine_1     |   File "/usr/lib/python3.6/site-packages/numpy/core/_methods.py", line 73, in _mean
mine_1     |     ret, rcount, out=ret, casting='unsafe', subok=False)
mine_1     | TypeError: unsupported operand type(s) for /: 'PaillierTensor' and 'int'


Patch:
diff --git a/.travis.yml b/.travis.yml
index 8a1dbf8b5b..0526581950 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,7 +4,7 @@ python:
 
 # install server dependencies
 before_install:
-  - "sudo apt-get -y install musl-dev g++ libgmp3-dev libmpfr-dev ca-certificates libmpc-dev"
+  - "sudo apt-get install musl-dev g++ libgmp3-dev libmpfr-dev libmpc-dev ca-certificates"
 
 # install dependencies
 install:
diff --git a/README.md b/README.md
index 1dbcb5c680..c2475e754b 100755
--- a/README.md
+++ b/README.md
@@ -74,7 +74,7 @@ make test
 
 ## For Contributors
 
-If you are interested in contributing to Syft, first check out our [Contributor Quickstart Guide](https://github.com/OpenMined/Docs/blob/master/contributing/quickstart.md) and then sign into our [Slack Team](https://openmined.slack.com/) channel #team_pysyft to let us know which projects sound interesting to you! (or propose your own!).
+If you are interested in contributing to Syft, first check out our [Contributor Quickstart Guide](https://github.com/OpenMined/Docs/blob/master/contributing/quickstart.md) and then sign into our [Slack Team](https://openmined.slack.com/) channel #syft to let us know which projects sound interesting to you! (or propose your own!).
 
 ## Relevant Literature
 
diff --git a/notebooks/Functional Encryption Prototype.ipynb b/notebooks/Functional Encryption Prototype.ipynb
index fa4274313d..f29aece522 100644
--- a/notebooks/Functional Encryption Prototype.ipynb
+++ b/notebooks/Functional Encryption Prototype.ipynb
@@ -2,59 +2,125 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 1,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "from syft.he.paillier import KeyPair, PaillierTensor\n",
+    "from syft import TensorBase\n",
+    "import unittest\n",
+    "import numpy as np\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "p, s = KeyPair().generate()\n",
+    "\n",
+    "x = PaillierTensor(p, np.array([3., 8., 15., 24., 35.]))\n",
+    "x2 = TensorBase(np.array([3, 4, 5, 6, 7.]))\n",
+    "\n",
+    "y = x / x2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "out = x2.data[0]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
    "metadata": {},
    "outputs": [
     {
-     "ename": "TypeError",
-     "evalue": "'float' object is not iterable",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
-      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
-      "\u001b[0;32m<ipython-input-7-06ca8c63c03f>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mPaillierTensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m5.\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      7\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m40.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
-      "\u001b[0;32m/Users/amberedmundson/anaconda/lib/python3.6/site-packages/syft-0.1.0-py3.6.egg/syft/he/paillier/basic.py\u001b[0m in \u001b[0;36m__add__\u001b[0;34m(self, tensor)\u001b[0m\n\u001b[1;32m     26\u001b[0m         \u001b[0;32mif\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtensor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mTensorBase\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     27\u001b[0m             \u001b[0;31m# try encrypting it\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 28\u001b[0;31m             \u001b[0mtensor\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mTensorBase\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtensor\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencrypt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpublic_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     29\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     30\u001b[0m             \u001b[0;32mreturn\u001b[0m \u001b[0mPaillierTensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpublic_key\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mtensor\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;31mTypeError\u001b[0m: 'float' object is not iterable"
-     ]
+     "data": {
+      "text/plain": [
+       "e"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
     }
    ],
    "source": [
-    "from syft.he.paillier import KeyPair, PaillierTensor\n",
-    "import numpy as np\n",
-    "\n",
-    "p, s = KeyPair().generate()\n",
-    "\n",
-    "x = PaillierTensor(p, np.array([1, 2, 3, 4, 5.]))\n",
+    "x.data[0] * (1/3.0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def __truediv__(self, tensor):\n",
+    "    \"\"\"Performs element-wise division between two tensors\"\"\"\n",
+    "    if self.encrypted:\n",
+    "        return NotImplemented\n",
     "\n",
-    "y = x + 40."
+    "    if(type(tensor) != TensorBase and isinstance(tensor, TensorBase)):\n",
+    "        out = tensor * 0\n",
+    "        out += self\n",
+    "        return out.data / tensor.data\n",
+    "    else:\n",
+    "        tensor = _ensure_tensorbase(tensor)\n",
+    "        return TensorBase(self.data / tensor.data)"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
    "metadata": {},
    "outputs": [
     {
-     "ename": "TypeError",
-     "evalue": "Don't know the precision of type <class 'numpy.int64'>.",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
-      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
-      "\u001b[0;32m<ipython-input-7-e76826d054b1>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mPaillierTensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m5.\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      7\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m40\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
-      "\u001b[0;32m/Users/amberedmundson/anaconda/lib/python3.6/site-packages/syft-0.1.0-py3.6.egg/syft/he/paillier/basic.py\u001b[0m in \u001b[0;36m__add__\u001b[0;34m(self, tensor)\u001b[0m\n\u001b[1;32m     26\u001b[0m         \u001b[0;32mif\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtensor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mTensorBase\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     27\u001b[0m             \u001b[0;31m# try encrypting it\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 28\u001b[0;31m             \u001b[0mtensor\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mTensorBase\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtensor\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencrypt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpublic_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     29\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     30\u001b[0m             \u001b[0;32mreturn\u001b[0m \u001b[0mPaillierTensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpublic_key\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mtensor\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;32m/Users/amberedmundson/anaconda/lib/python3.6/site-packages/syft-0.1.0-py3.6.egg/syft/tensor.py\u001b[0m in \u001b[0;36mencrypt\u001b[0;34m(self, pubkey)\u001b[0m\n\u001b[1;32m     59\u001b[0m             \u001b[0;32mreturn\u001b[0m \u001b[0mNotImplemented\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     60\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 61\u001b[0;31m             \u001b[0;32mreturn\u001b[0m \u001b[0mpubkey\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencrypt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     62\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     63\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mdecrypt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mseckey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;32m/Users/amberedmundson/anaconda/lib/python3.6/site-packages/syft-0.1.0-py3.6.egg/syft/he/paillier/keys.py\u001b[0m in \u001b[0;36mencrypt\u001b[0;34m(self, x, same_type)\u001b[0m\n\u001b[1;32m     53\u001b[0m             \u001b[0;32mif\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencrypted\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0msame_type\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     54\u001b[0m                 \u001b[0;32mreturn\u001b[0m \u001b[0mNotImplemented\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 55\u001b[0;31m             \u001b[0;32mreturn\u001b[0m \u001b[0mPaillierTensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     56\u001b[0m         \u001b[0;32melif\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndarray\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     57\u001b[0m             \u001b[0msh\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;32m/Users/amberedmundson/anaconda/lib/python3.6/site-packages/syft-0.1.0-py3.6.egg/syft/he/paillier/basic.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, public_key, data, input_is_decrypted)\u001b[0m\n\u001b[1;32m     10\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpublic_key\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpublic_key\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     11\u001b[0m         \u001b[0;32mif\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndarray\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0minput_is_decrypted\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpublic_key\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencrypt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     13\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     14\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;32m/Users/amberedmundson/anaconda/lib/python3.6/site-packages/syft-0.1.0-py3.6.egg/syft/he/paillier/keys.py\u001b[0m in \u001b[0;36mencrypt\u001b[0;34m(self, x, same_type)\u001b[0m\n\u001b[1;32m     59\u001b[0m             \u001b[0mout\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     60\u001b[0m             \u001b[0;32mfor\u001b[0m \u001b[0mv\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mx_\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 61\u001b[0;31m                 \u001b[0mout\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mFloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     62\u001b[0m             \u001b[0;32mif\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msame_type\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     63\u001b[0m                 \u001b[0;32mreturn\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msh\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;32m/Users/amberedmundson/anaconda/lib/python3.6/site-packages/syft-0.1.0-py3.6.egg/syft/he/paillier/basic.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, public_key, data)\u001b[0m\n\u001b[1;32m     91\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpublic_key\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpublic_key\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     92\u001b[0m         \u001b[0;32mif\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 93\u001b[0;31m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpublic_key\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpk\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencrypt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     94\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     95\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;32m/Users/amberedmundson/anaconda/lib/python3.6/site-packages/phe/paillier.py\u001b[0m in \u001b[0;36mencrypt\u001b[0;34m(self, value, precision, r_value)\u001b[0m\n\u001b[1;32m    169\u001b[0m             \u001b[0mencoding\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    170\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 171\u001b[0;31m             \u001b[0mencoding\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mEncodedNumber\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mprecision\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    172\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    173\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencrypt_encoded\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mencoding\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mr_value\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;32m/Users/amberedmundson/anaconda/lib/python3.6/site-packages/phe/paillier.py\u001b[0m in \u001b[0;36mencode\u001b[0;34m(cls, public_key, scalar, precision, max_exponent)\u001b[0m\n\u001b[1;32m    602\u001b[0m             \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    603\u001b[0m                 raise TypeError(\"Don't know the precision of type %s.\"\n\u001b[0;32m--> 604\u001b[0;31m                                 % type(scalar))\n\u001b[0m\u001b[1;32m    605\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    606\u001b[0m             \u001b[0mprec_exponent\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfloor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlog\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprecision\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcls\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mBASE\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;31mTypeError\u001b[0m: Don't know the precision of type <class 'numpy.int64'>."
-     ]
+     "data": {
+      "text/plain": [
+       "array([e, e, e, e, e], dtype=object)"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
     }
    ],
-   "source": []
+   "source": [
+    "\n",
+    "def div(self, tensor):\n",
+    "    \"\"\"Performs element-wise addition between two tensors\"\"\"\n",
+    "\n",
+    "    if(isinstance(tensor, TensorBase)):\n",
+    "        if(not tensor.encrypted):\n",
+    "            result = self.data * (1 / tensor.data)\n",
+    "            o = PaillierTensor(self.public_key, result, False)\n",
+    "            return o\n",
+    "        else:\n",
+    "            return NotImplemented\n",
+    "    else:\n",
+    "        return PaillierTensor(self.public_key, self.data * (1 / float(tensor)), False)\n",
+    "y = div(x,x2)\n",
+    "y"
+   ]
   },
   {
    "cell_type": "code",
diff --git a/syft/he/paillier/basic.py b/syft/he/paillier/basic.py
index c0002c7abc..2edf67302a 100644
--- a/syft/he/paillier/basic.py
+++ b/syft/he/paillier/basic.py
@@ -35,7 +35,7 @@ class PaillierTensor(TensorBase):
         return PaillierTensor(self.public_key, self.data + tensor.data, False)
 
     def __sub__(self, tensor):
-        """Performs element-wise addition between two tensors"""
+        """Performs element-wise subtraction between two tensors"""
 
         if(not isinstance(tensor, TensorBase)):
             # try encrypting it
@@ -48,12 +48,12 @@ class PaillierTensor(TensorBase):
         return PaillierTensor(self.public_key, self.data - tensor.data, False)
 
     def __isub__(self, tensor):
-        """Performs element-wise addition between two tensors"""
+        """Performs inline, element-wise subtraction between two tensors"""
         self.data -= tensor.data
         return self
 
     def __mul__(self, tensor):
-        """Performs element-wise addition between two tensors"""
+        """Performs element-wise multiplication between two tensors"""
 
         if(isinstance(tensor, TensorBase)):
             if(not tensor.encrypted):
@@ -65,6 +65,19 @@ class PaillierTensor(TensorBase):
         else:
             return PaillierTensor(self.public_key, self.data * float(tensor), False)
 
+    def __truediv__(self, tensor):
+        """Performs element-wise division between two tensors"""
+
+        if(isinstance(tensor, TensorBase)):
+            if(not tensor.encrypted):
+                result = self.data * (1 / tensor.data)
+                o = PaillierTensor(self.public_key, result, False)
+                return o
+            else:
+                return NotImplemented
+        else:
+            return PaillierTensor(self.public_key, self.data * (1 / float(tensor)), False)
+
     def sum(self, dim=None):
         """Returns the sum of all elements in the input array."""
         if not self.encrypted:
diff --git a/syft/tensor.py b/syft/tensor.py
index 82a38e7fc1..10c9bdd446 100644
--- a/syft/tensor.py
+++ b/syft/tensor.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 import numpy as np
 import syft
 
@@ -158,8 +157,11 @@ class TensorBase(object):
         if self.encrypted:
             return NotImplemented
 
-        tensor = _ensure_tensorbase(tensor)
-        return TensorBase(self.data / tensor.data)
+        if(type(tensor) != TensorBase and isinstance(tensor, TensorBase)):
+            return NotImplemented  # it's not clear that this can be done
+        else:
+            tensor = _ensure_tensorbase(tensor)
+            return TensorBase(self.data / tensor.data)
 
     def __itruediv__(self, tensor):
         """Performs in place element-wise subtraction between two tensors"""
@@ -617,18 +619,3 @@ class TensorBase(object):
             return NotImplemented
         self.data = np.random.lognormal(mean, stdev, self.shape())
         return self
-
-    def view(self, *args):
-        """View the tensor."""
-        if self.encrypted:
-            return NotImplemented
-        else:
-            dt = np.copy(self.data)
-            return TensorBase(dt.reshape(*args))
-
-    def view_as(self, tensor):
-        """ View as another tensor's shape """
-        if self.encrypted:
-            return NotImplemented
-        else:
-            return self.view(tensor.shape())


Test patch:
diff --git a/tests/test_paillier.py b/tests/test_paillier.py
index 8f52aca3df..f8ce2cb37e 100644
--- a/tests/test_paillier.py
+++ b/tests/test_paillier.py
@@ -122,3 +122,33 @@ class MulTests(unittest.TestCase):
 
         x *= 2
         self.assertTrue(s.decrypt(x) == np.array([2., 4., 6., 8., 10.]))
+
+
+class DivTests(unittest.TestCase):
+
+    def testBasic(self):
+        p, s = KeyPair().generate()
+
+        x = PaillierTensor(p, np.array([3., 8., 15., 24., 35.]))
+        x2 = TensorBase(np.array([3, 4, 5, 6, 7.]))
+
+        y = x / x2
+        print(y.decrypt(s))
+        self.assertTrue(y.decrypt(s) == np.array([1., 2., 3., 4., 5.]))
+
+    def testInline(self):
+        p, s = KeyPair().generate()
+
+        x = PaillierTensor(p, np.array([3., 8., 15., 24., 35.]))
+        x2 = TensorBase(np.array([3, 4, 5, 6, 7.]))
+
+        x /= x2
+        self.assertTrue(x.decrypt(s) == np.array([1., 2., 3., 4., 5.]))
+
+    def testScalar(self):
+        p, s = KeyPair().generate()
+
+        x = PaillierTensor(p, np.array([2., 4., 6., 8., 10.]))
+
+        x /= 2
+        self.assertTrue(s.decrypt(x) == np.array([1, 2, 3, 4, 5.]))
diff --git a/tests/test_tensor.py b/tests/test_tensor.py
index 1ba6c36006..148a0258c7 100644
--- a/tests/test_tensor.py
+++ b/tests/test_tensor.py
@@ -11,16 +11,6 @@ class DimTests(unittest.TestCase):
         t = TensorBase(np.array([1, 2, 3]))
         self.assertTrue(t.dim() == 1)
 
-    def testView(self):
-        t = TensorBase([1.0, 2.0, 3.0])
-        self.assertTrue(syft.equal(t.view(-1, 1), TensorBase(np.array([[1], [2], [3]]))))
-
-    def testAsView(self):
-        t = TensorBase(np.array([1.0, 2.0, 3.0]))
-        t1 = t.view([-1, 1])
-        print(t.data.dtype)
-        self.assertTrue(syft.equal(t.view_as(t1), TensorBase(np.array([[1.0], [2.0], [3.0]]))))
-
 
 class AddTests(unittest.TestCase):
     def testSimple(self):