信不信由你,有可能使用加密数据进行计算。换句话说,可以在程序中对所有变量进行加密的情况下运行该程序!
在本教程中,我们将逐步介绍加密计算的基本工具。特别地,我们将集中于一种流行的方法,称为安全多方计算。在本课程中,我们将学习如何构建一个可以对加密数字执行计算的加密计算器。
作者:
参考文献:
中文版译者:
乍一看,SMPC(Secure Multi-Party Computation,安全多方计算)是一种非常奇怪的“加密”形式。 每个值都被分成多个“共享”,而不是使用公共/私有密钥对变量进行加密,每个共享都像私有密钥一样工作。 通常,这些“份额”将分配给2个或更多owners。 因此,为了解密变量,所有所有者必须同意允许解密。 本质上,每个人都有一个私钥。
因此,假设我们要“加密”变量“x”,可以通过以下方式进行。
加密不使用浮点数或实数,而是在称为整数商环的数学空间中进行,该空间基本上是介于
0
和Q-1
之间的整数 ,其中Q
是质数,并且“足够大”,以便该空间可以包含我们在实验中使用的所有数字。 实际上,给定值x
整数,我们将x%Q
放入环中。 (这就是为什么我们避免使用数字“ 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]:
In [5]:
def decrypt(*shares):
return sum(shares) % Q
In [6]:
a,b,c = encrypt(25)
In [7]:
decrypt(a, b, c)
Out[7]:
重要的是,请注意,如果我们尝试仅使用两个共享进行解密,则解密将不起作用!
In [8]:
decrypt(a, b)
Out[8]:
因此,我们需要所有所有者参与才能解密该值。 通过这种方式,shares
就像私钥一样,所有私钥都必须存在才能解密值。
In [9]:
x = encrypt(25)
y = encrypt(5)
In [10]:
def add(x, y):
z = list()
# 第一个工作机将其共享分片相加
z.append((x[0] + y[0]) % Q)
# 第二个工作机将其共享分片相加
z.append((x[1] + y[1]) % Q)
# 第三个工作机将其共享分片相加
z.append((x[2] + y[2]) % Q)
return z
In [11]:
decrypt(*add(x,y))
Out[11]:
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")
In [13]:
x = torch.tensor([25])
In [14]:
x
Out[14]:
In [15]:
encrypted_x = x.share(bob, alice, bill)
In [16]:
encrypted_x.get()
Out[16]:
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]:
In [20]:
# Alice's share
alices_share = list(alice._objects.values())[0]
alices_share
Out[20]:
In [21]:
# Bill's share
bills_share = list(bill._objects.values())[0]
bills_share
Out[21]:
如果愿意,我们可以使用我们之前讨论的同样的方法解密这些值!!!
In [22]:
(bobs_share + alices_share + bills_share)
Out[22]:
如您所见,当我们调用.share()
时,它只是将值分割成3股,并向每一方发送了一份!
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]:
In [25]:
z = x - y
z.get()
Out[25]:
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]:
而且可以执行矩阵乘法
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]:
私有值之间的私有比较也是可能的。 我们在这里依赖SecureNN协议,其详细信息可以在这里找到。比较的结果也是私有共享张量。
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]:
In [33]:
z = x <= y
z.get()
Out[33]:
In [34]:
z = x == y
z.get()
Out[34]:
In [35]:
z = x == y + 20
z.get()
Out[35]:
您还可以执行求最值操作
In [36]:
x = torch.tensor([2, 3, 4, 1]).share(bob,alice, crypto_provider=crypto_provider)
x.max().get()
Out[36]:
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]:
祝贺您完成本笔记本教程! 如果您喜欢此方法,并希望加入保护隐私、去中心化AI和AI供应链(数据)所有权的运动,则可以通过以下方式做到这一点!
帮助我们的社区的最简单方法是仅通过给GitHub存储库加注星标! 这有助于提高人们对我们正在构建的出色工具的认识。
保持最新进展的最佳方法是加入我们的社区! 您可以通过填写以下表格来做到这一点http://slack.openmined.org
对我们的社区做出贡献的最好方法是成为代码贡献者! 您随时可以转到PySyft GitHub的Issue页面并过滤“projects”。这将向您显示所有概述,选择您可以加入的项目!如果您不想加入项目,但是想做一些编码,则还可以通过搜索标记为“good first issue”的GitHub问题来寻找更多的“一次性”微型项目。
如果您没有时间为我们的代码库做贡献,但仍想提供支持,那么您也可以成为Open Collective的支持者。所有捐款都将用于我们的网络托管和其他社区支出,例如黑客马拉松和聚会!
In [ ]: