Part 9 - Intro to Encrypted Programs

You believe or you no believe, he dey possible to compute with encrypted data. Make I talk am another way sey he dey possible to run program where ALL of the variables in the program dey encrypted!

For this tutoria we go learn basic tools of encrypted computation. In particular, we go focus on one popular approach called Secure Multi-Party Computation. We go build encrypted calculator wey fit perform calculations on encrypted numbers for this lesson.

Person wey write am:

Reference wey you fit use:

Person wey translate am:

Step 1: Encryption Using Secure Multi-Party Computation

SMPC na strange form of "encryptioon". Instead make we use public/private key to encrypt a variable, we go split each value into multiple shares, each of dem operates like a private key. Typically, we go distribute these shares amongst 2 or more owners. Thus, to decrypt the variable, all owners must agree sey make we decryt am. In essence, everyone go get private key.

Encrypt()

So, let's say we wan "encrypt" a variable x, we fit do am in the following way. So, let's say we wanted to "encrypt" a variable x, we could do so in the following way.

Encryption no dey use floats or real numbers but he dey happen in a mathematical space called integer quotient ring wey be the integer wey dey between 0 and Q-1, where Q na prime and "big enough" so that the space can contain all the numbers that we use in our experiments. In practice, given a value x integer, we do x % Q to fit in the ring. (That's why we dey avoid to use number x' > Q).


In [1]:
Q = 1234567891011

In [2]:
x = 25

In [3]:
import random

def encrypt(x):
    share_a = random.randint(-Q,Q)
    share_b = random.randint(-Q,Q)
    share_c = (x - share_a - share_b) % Q
    return (share_a, share_b,  share_c)

In [4]:
encrypt(x)


Out[4]:
(890804432397, -2305631655, 346069090294)

As you dey see am, we don split our variable x into 3 different shares, wey we go send to 3 different owners.

Decrypt()

If you wan decrypt these 3 shares, we go just sum them togeda and then we go take the modulus of the result (mod Q)


In [5]:
def decrypt(*shares):
    return sum(shares) % Q

In [6]:
a,b,c = encrypt(25)

In [7]:
decrypt(a, b, c)


Out[7]:
25

Importantly, notice sey if we try to decrypt with only two shares, the decryption no dey work!


In [8]:
decrypt(a, b)


Out[8]:
778460474681

We go need all of the owners to participate if we wan decrypt value. Na like this shares dey act like private keys, everytin must to dey before we go fit decrypt a value.

Step 2: Basic Arithmetic Using SMPC

The extraordinary property of Secure Multi-Party Computation na him ability to perform computation while the variables are still encrypted. Make we demonstrate simple addition as he dey below.


In [9]:
x = encrypt(25)
y = encrypt(5)

In [10]:
def add(x, y):
    z = list()
    # the first worker adds their shares together
    z.append((x[0] + y[0]) % Q)
    
    # the second worker adds their shares together
    z.append((x[1] + y[1]) % Q)
    
    # the third worker adds their shares together
    z.append((x[2] + y[2]) % Q)
    
    return z

In [11]:
decrypt(*add(x,y))


Out[11]:
30

Success!!!

And there you get am! If each worker (separately) add their shares togeda, the resulting shares go decrypt to the correct vallues (25 + 5 == 30).

As he dey so, SMPC protocols exist go allow make this encrypted computation fit do the following operations:

  • addition (which we've just seen)
  • multiplication
  • comparison

If we use these basic underlying primitives, we go fit perform arbitrary computation!!!

In the next section, we go learn how we fit use PySyft library to perform these operations!

Step 3: SMPC Using PySyft

In the previous sections, we talk about some intuition wey dey around SMPC if he go work. However, we no wan use hand write everi primitive operations ourselves when we fit write our encrypted programs. So, for this section we go studi the basics of how we go do encrypted computation using PySyft. Particularly, we go focus on how to do 3 primitives wey we mention before: addition, multiplication, and comparison.

First, we go first create few Virtual Worker (wey you don dey familiar as you don study our previous tutorials).


In [12]:
import torch
import syft as sy
hook = sy.TorchHook(torch)

bob = sy.VirtualWorker(hook, id="bob")
alice = sy.VirtualWorker(hook, id="alice")
bill = sy.VirtualWorker(hook, id="bill")

Basic Encryption/Decryption

Encryption na simple way of taking PySyft tensor and calling .share(). Decryption na simple way of calling .get() on shared variable.


In [13]:
x = torch.tensor([25])

In [14]:
x


Out[14]:
tensor([25])

In [15]:
encrypted_x = x.share(bob, alice, bill)

In [16]:
encrypted_x.get()


Out[16]:
tensor([25])

Introspecting the Encrypted Values

If you look Bob, Alice and Bill's workers wella, we go see the shares we done create!


In [17]:
bob._objects


Out[17]:
{}

In [18]:
x = torch.tensor([25]).share(bob, alice, bill)

In [19]:
# Bob's share
bobs_share = list(bob._objects.values())[0]
bobs_share


Out[19]:
tensor([3212861001891376707])

In [20]:
# Alice's share
alices_share = list(alice._objects.values())[0]
alices_share


Out[20]:
tensor([61371170032936135])

In [21]:
# Bill's share
bills_share = list(bill._objects.values())[0]
bills_share


Out[21]:
tensor([1337453846503075087])

If we want, we fit decrypt these values if we use the SAME approach we don talk about before now!!!


In [22]:
Q = x.child.field

(bobs_share + alices_share + bills_share) % Q


Out[22]:
tensor([25])

Look am wella, as we call .share() he just split value into 3 shares ans he come send one share go each parties!

Encrypted Arithmetic

We fit perform arithmetic on the underlying values! API dey constructed on to sey make we perform arithmetic liek the one wey we do with normal PyTorch tensors.


In [23]:
x = torch.tensor([25]).share(bob,alice)
y = torch.tensor([5]).share(bob,alice)

In [24]:
z = x + y
z.get()


Out[24]:
tensor([30])

In [25]:
z = x - y
z.get()


Out[25]:
tensor([20])

Encrypted Multiplication

For multiplication we go need an additional party who go dey responsible to dey consistently generate random numbers (he no go collude with any other parties). We dey call this person "crypto provider". For all intensive purposes, the crypto provider na just additional VirtualWorker, but he go dey important to acknowledge sey crypto provider no be "owner" onto sey he/she no get him own shares but na someone wey we need to trust make he no go collude with ani existing shareholders.


In [26]:
crypto_provider = sy.VirtualWorker(hook, id="crypto_provider")

In [27]:
x = torch.tensor([25]).share(bob,alice, crypto_provider=crypto_provider)
y = torch.tensor([5]).share(bob,alice, crypto_provider=crypto_provider)

In [28]:
# multiplication

z = x * y
z.get()


Out[28]:
tensor([125])

You fit do matrix multiplication


In [29]:
x = torch.tensor([[1, 2],[3,4]]).share(bob,alice, crypto_provider=crypto_provider)
y = torch.tensor([[2, 0],[0,2]]).share(bob,alice, crypto_provider=crypto_provider)

In [30]:
# matrix multiplication

z = x.mm(y)
z.get()


Out[30]:
tensor([[2, 4],
        [6, 8]])

Encrypted comparison

He dey possible to private compare private values. We go rely on SecureNN protocol, we fit find the details here. The result of the comparison na private shared tensor.


In [31]:
x = torch.tensor([25]).share(bob,alice, crypto_provider=crypto_provider)
y = torch.tensor([5]).share(bob,alice, crypto_provider=crypto_provider)

In [32]:
z = x > y
z.get()


Out[32]:
tensor([1])

In [33]:
z = x <= y
z.get()


Out[33]:
tensor([0])

In [34]:
z = x == y
z.get()


Out[34]:
tensor([0])

In [35]:
z = x == y + 20
z.get()


Out[35]:
tensor([1])

You fit perform max operations


In [36]:
x = torch.tensor([2, 3, 4, 1]).share(bob,alice, crypto_provider=crypto_provider)
x.max().get()


Out[36]:
tensor([4])

In [37]:
x = torch.tensor([[2, 3], [4, 1]]).share(bob,alice, crypto_provider=crypto_provider)
max_values, max_ids = x.max(dim=0)
max_values.get()


Out[37]:
tensor([4, 3])

Congratulations!!! - Oya Join the Community!

Clap for una sef as you don finish this notebook tutorial! If you enjoy am and you wan join the movement towards privacy preserving, decentralized ownership of AI and the AI supply chain (data), follow the steps wey dey below.

Star PySyft on GitHub

The easiset way to helep our community na to star the GitHub repos! This go helep raise awareness of the tools we dey build.

Join our Slack!

To follow up bumper to bumper on how latest advancements, join our community! You can do so by filling out the form at http://slack.openmined.org

Join a Code Project!

The best way to contribute to our community na to become code contributor! You fit go to PySyft GitHub Issues page and filter for "Projects". E go show you all the top level Tickets giving an overview of what projects you fit join! If you no wan join any project, but you wan code small, you fit look for more "one off" mini-projects by searching for GitHub issues marked "good first issue"

If you no get time to contribute to our codebase, but still like to lend support, you fit be a Backer on our Open Collective. All donations wey we get na for our web hosting and other community expenses such as hackathons and meetups! meetups!

OpenMined's Open Collective Page


In [ ]: