Homomorphic Encryption 101

I was recently exploring methods for improved privacy using various encryption schemes and stumbled upon Homomorphic Encryption that has a huge potential  in that area. I do feel that it has higher barrier to entry considering the complexity and level of maturity it has today. If you’re looking for learning resources/libraries to get started on it take a look at Git repo that I have created for purpose of sharing resources around Homomorphic Encryption.

At a very high level Holomorphic Encryption allows you to perform basic matematical computations (+,-,x,/) on encrypted data (cipher text) without need to have un-encrypted data (plaintext). This ability to perform operations on encrypted data has many high impact use cases.

Just to give you an idea lets say you like to leverage a service hosted by a cloud provider but you don’t want to reveal the data to could provider without it being encrypted.  The biggest challenge today is without access to actual data (in decrypted form) there is very limited useful operations that can be performed on it. However, with Homomorphic Encryption  cloud provider can take your data which in encrypted form then process it without decrypting it and then gives you back the result which is also encrypted. At no point  your data is revealed to the cloud provider in decrypted form.

The biggest beneficiary of this type of encryption is privacy. So, at this point you may ask well if this is so useful why it hasn’t been adopted/used commercially on a wider scale? Well, the short answer is that Homomorphic Encryption is still in its infancy. This article call out some of the challenges that you may want to look into. In short its still being actively worked upon and organization like NIST are working towards its standardization.

Finally, let me leave you with a simple example using Python Paillier library. I will use set of numbers and encrypt them using private key and then use the library (think of it as cloud provider though I’m running everything on my laptop using docker container) perform the mathematical operations (+,-.*,/) on the numbers while they are encrypted. Only thing the library needs is the public key. After the operations  are done the results are provided back which are also encrypted. At the end you decrypt the results using your private key. In short at no point library has access to your un-encrypted data. There is another library that is quite useful for trying Homomorphic Encryption called  SEAL (Simple Encrypted Arithmetic Library) by Microsoft which I also experimented with but going to cover it in a separate post.

As I mentioned earlier, I’m using Docker container image that I created to package the Python Paillier library which is available on DockerHub.


#Launch Docker container and remove it automatically afterwords.
docker run --rm -it rbinrais/python-paillier:1.2.2 bash


xxxxxx@xxxxxxxxxxx:/# python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.

#Import Library
from phe import paillier

#Generate a Private/Public Key Pair
public_key, private_key = paillier.generate_paillier_keypair() 

#Define Numbers 
secret_number_list = [12, 2.89763, -4.6e-12] 

#Encrypt Numbers (Using Public Key)
encrypted_number_list = [public_key.encrypt(x) for x in secret_number_list]

#List Encrypted Numbers
encrypted_number_list
[<phe.paillier.EncryptedNumber object at 0x7efd57c0f630>, <phe.paillier.EncryptedNumber object at 0x7efd57c16358>, <phe.paillier.EncryptedNumber object at 0x7efd553229b0>]

#Decrypt Numbers (Using Private Key)
[private_key.decrypt(x) for x in encrypted_number_list]
[12, 2.89763, -4.6e-12]

#Perform Mathematical Operations 
a, b, c = encrypted_number_list
a_plus_10 = a + 10
a_mins_b = a - b 
b_times_4_7 = b * 4.7 
c_div_33 = c / 33

#Display Encrypted Results 
a_plus_10
<phe.paillier.EncryptedNumber object at 0x7efd57c0f668>

a_mins_b
<phe.paillier.EncryptedNumber object at 0x7efd57c0f5c0>

b_times_4_7
<phe.paillier.EncryptedNumber object at 0x7efd55d03240>

c_div_33 
<phe.paillier.EncryptedNumber object at 0x7efd55d03978>

#Decrypt Results using Private Key
private_key.decrypt(a_plus_10)
22

private_key.decrypt(a_mins_b) 
9.10237

private_key.decrypt(b_times_4_7)
13.618861

private_key.decrypt(c_div_33)   
-1.393939393939394e-13