NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

隐私 AI 框架中的数据流动与工程实现

  • 2020-11-03
  • 本文字数:6809 字

    阅读完需:约 22 分钟

隐私AI框架中的数据流动与工程实现

上一篇文章中,我们介绍了,对于安全技术开发者,如何快速的基于 Rosetta 等隐私 AI 框架所提供的一系列接口,将自己的安全协议集成落地到上层的 AI 应用中来。在这一篇文章中,我们将介绍为了保护用户的隐私数据,在隐私 AI 框架的计算任务全流程中,数据是如何以密文形式流动,同时仍正确完成加法、乘法等计算步骤的。


隐私 AI 系统存在的目的就是赋能 AI,使得各种 AI 场景下对用户隐私数据的使用都是安全的。那么,这样的系统就需要提供充分的保障,从理论到工程实现的每一个阶段都应该是经得起推敲、抵抗得住各种攻击的。不能简单的认为只需要各方先在本地自己的数据上计算出一个模型,然后将模型结果交换一下计算下其模型参数的平均值,就不会泄露各方的隐私数据了。现代密码学(Cryptography)是建立在严格的数学定义、计算复杂度假设和证明基础之上的,其中 MPC (Multi-Party Computation)方向是专门研究多个参与方如何正确、安全的进行联合计算的子领域, RosettaTF Encrypted 等隐私 AI 框架都采用了 MPC 技术以提供可靠的安全性。下面我们就结合具体案例看的看下在 Rosetta 中隐私数据是如何得到安全保护的。

案例

Alice, Bob 和 Charley 三人最近需要在他们的 AI 系统中引入对数据的隐私保护能力。他们很重视安全性,所以他们想通过一个简单的例子 —— 乘法(multiply),来验证下隐私 AI 框架是否真正做到了隐私安全。


他们约定:Alice 的输入为 1.2345;Bob 的输入为 5.4321;而 Charley 拿到相乘的结果。


他们按照 Rosetta 提供的教程,快速编写了如下代码(脚本名为 rosetta-mul.py):


#!/usr/bin/env python3import latticex.rosetta as rttimport tensorflow as tf
rtt.activate("SecureNN")x = tf.Variable(rtt.private_console_input(0, shape=(1,))) # Alice's inputy = tf.Variable(rtt.private_console_input(1, shape=(1,))) # Bob's inputz = tf.multiply(x, y) # z = x * y
with tf.Session() as sess: sess.run(tf.global_variables_initializer()) res = sess.run(rtt.SecureReveal(z, receive_party=4)) # 'b0100' means Charley print('z:', res)
rtt.deactivate()
复制代码


接着,他们各自打开一个终端,分别进行如下操作:


Alice (P0) 在终端敲下如下命令行,并根据提示输入自己的私有数据:


$ python ./rosetta-mul.py --party_id=0please input the private data (float or integer): 1.2345
复制代码


Bob (P1) 执行同样的操作,输入的也是只有自己才知晓的私有数据:


$ python ./rosetta-mul.py --party_id=1please input the private data (float or integer): 5.4321
复制代码


Charley (P2) 在终端敲下如下命令行,等一会儿就可以得到所期望的计算结果:


$ python ./rosetta-mul.py --party_id=2z: [b'6.705910']
复制代码


注:

  • 对于 Charley 来说,由于没有数据,故不会提示输入。

  • Alice 和 Bob 的本地输出都会是 z: [b'0.000000'], 而不会拿到正确的结果。


可以看出,Charley 拿到的最终结果与逻辑上明文结果(6.70592745)相比,误差(0.00001745)可以忽略不计。系统的正确性得到了验证。


如果想让误差更小,可以通过配置提升精度,或使用 128-bit 的数据类型。具体操作可以参考文档


上面短短的几行代码,虽然结果是正确的,但是他们三人对于系统安全性方面仍有一些困惑:


  • Alice、Bob 的私有输入会不会被另外两方知道?

  • Charley 拿到的结果会不会被 Alice 、 Bob 知道?

  • 整个程序运行过程中,有没有其他数据的泄漏?

  • 如果前几问的回答都是否定的,那 Charley 又是如何得到明文?


在回答这些问题之前,为简化描述、突出本质,我们需要简单介绍一下 MPC 实际落地中常用的安全假设。


假定系统中有 3 个节点,P0/P1/P2,其中 P0/P1 为数据参与方,而P2 是辅助节点,用于随机数生成。


  • 只考虑半诚实(Semi-Honest)安全模型,即三方都会遵守协议执行的流程,并且其中诚实者占多数(Honest-Majority),也就是说三个节点中只会有一个“坏人”。更为复杂的恶意(Malicious)模型等安全场景可参考其他相关论文。

  • 内部数据类型为 64 位无符号整型,即 uint64_t (这在理论上对应着在环 )。


下面我们就按照 输入–计算–输出 的顺序,详细介绍 Rosetta 中数据的表示与流动,以及所用到相关技术与算法在工程上的优化实现。

隐私数据的输入

隐私计算问题,首先要解决的是隐私数据的输入。


在上述案例中,是通过如下两行代码来完成私有数据的安全输入的:


x = tf.Variable(rtt.private_console_input(0, shape=(1,))) # Alice's inputy = tf.Variable(rtt.private_console_input(1, shape=(1,))) # Bob's input
复制代码


如代码所示,rtt.private_console_input 是 Rosetta 众多 API 之一,Rosetta 还提供了 rtt.private_inputrtt.PrivateDataset 等 API,用来处理隐私数据的输入。


这里发生了什么?x,y 的值会是什么?


在进入剖析之前,先来了解一个重要的概念 —— 秘密分享

秘密分享

什么是 秘密分享(Secret Sharing)[1]?先来看一种简单的两方 additive 的构造:


给定一个数 x,定义 share(x) = (x0, x1) = (x − r, r),其中 r 是随机数,并且与 x 独立。可以看到,x = x0 + x1 = x -r + r。原始数据 x 的秘密分享值 (x0, x1) 将会由两个数据参与方 (P0, P1) 各自保存。


在秘密分享的方案中,所有的数据,包括中间数值都会分享在两个参与方之间。直观的看,参与的两方不会得到任何的明文信息。理论上,只需要在环 上支持加法和乘法,就可以进一步通过组合来支持上层各种更复杂的函数。下文我们会看到关于乘法的详细解析,读者可以回过头来再看这段话。


那工程上是如何处理的呢?假设 P0 有一个私有数据 x,三方之间可以简单交互一下实现:


方案 1: P2 生成一个随机数 r,发送给 P0/P1。然后 P0 本地设置 x0 = x - rP1 本地设置 x1 = r。此时 share(x) = (x0, x1) = (x - r, r),与上面的定义一致。


这是方案之一,后文基于这个方案进行讲解。在本文最后,我们会提一下实际落地时的进一步优化方案。


回到主线,结合 方案 1,我们以 Alice 的输入值 x = 1.2345 为例看下具体过程。


第一步,浮点数转定点数。


对于有数据输入的一方,需要先将真实的浮点数转成定点数。


浮点数转定点数:即浮点数乘以一个固定的缩放因子(scale,一般为)使其变成定点数(取其整数部分,舍弃小数部分)。当最后需要还原真实的原始浮点数时,用定点数除以缩放因子即可。


我们先选定一个缩放因子,这里取 scale =


经过缩放后,得到 x = 1.2345 * (1<<18) = 323616.768,取整数部分即 323616,用于后续计算。


这里是有精度损失的,但在精度允许的范围内,不会影响后面的计算。


第二步,生成随机数 r 也叫掩码(Masking value),用来隐藏真实值。


P2 生成一个随机数 r,是一个 64-bit 空间的无符号整数。(如,r =​ fdad72ecbfbefeb9。这里用十六进制表示,下同)


P2r 发送给 P0,P1。此时,P0,P1 都拥有一个相同的随机数 r 了。


第三步,设置秘密分享值。


按秘密分享 方案 1 的定义,P0 本地设置 x0 = x - rP1 本地设置 x1 = r。所以有:


P0x0 = 4f020 - fdad72ecbfbefeb9 = 2528d134045f167


P1x1 = fdad72ecbfbefeb9


4f020 是 323616 的十六进制表示。

如果计算结果大于 64 bit 的空间范围,需要对结果取模(64 位空间)。下同。


至此,我们获得了关于 x 的分享值,share(x) = (x0, x1) = (x - r, r) = (2528d134045f167, fdad72ecbfbefeb9)。


感兴趣的读者朋友可以验证一下 (x0 + x1) mod


同理,我们对 Bob 的输入值进行一样的处理。


上面三步,其实就是 private_console_input 的工作机制与过程。经过处理后,各方本地都存储着如下值:


P0P1P2
X02528d134045f167X1fdad72ecbfbefeb9X20
Y0d8e19bd0a532750Y1f271e642f5c29328Y20


我们用 Xi,Yi 表示 X,YPi 的分享值。(下同)

P2 为何是 0 呢?在本方案中 P2 作为一个辅助节点,不参与真正的逻辑计算。


我们可以看到,在处理隐私数据输入的整个过程中,P0 无法知道 y 值,P1 无法知道 x 值,P2 无法知道 xy 值。


最后,我们总结一下这三个主要阶段:


密文上的协同计算

这是计算的核心。


上一步,我们保证了输入的安全,没有信息的泄漏,各方无法单独拿到其他节点的私有输入。


接下来,看一下计算的代码,只有一行:


z = tf.multiply(x, y) # z = x * y
复制代码


在这个计算的过程中发生了什么?下面结合乘法(Multiply) 算子原理进行实例讲解。

Multiply 算子原理

乘法相对较为复杂,我们结合经典的 Beaver Triple 方法[2]加以介绍。该方法是由密码学家 Donald Beaver 在 1991 年提出,主要思想是通过乘法。协议基本原理如下:


输入: P0 拥有 X,Y 的秘密分享值 X0,Y0P1 拥有 X,Y 的秘密分享值 X1,Y1


这里有 share(X) = (X0, X1),share(Y) = (Y0, Y1)。在此案例中,这里的输入,就对接上一节所述的"隐私输入"的输出结果。


计算步骤:


  1. P2 本地生成一组随机数 A,B,C,且满足 C = A * B


A,B,C 的生成步骤:P2 随机生成 A0,A1,B0,B1,C0,令 A = A0 + A1, B = B0 + B1,得到 C = A * B, C1 = C - C0其中 Ai,Bi,CiA,B,C 的分享值。 这些都是在 P2 本地完成的。这也就是 P2 做为辅助节点的作用(用于随机数生成)。


这里 A,B,C 一般被称为三元组(Beaver’s Triple)。


比如,某次生成的随机数如下:


A02373edde1a0e5dcdA1ad483b77e4e5db41
B0d81a4646be1c0cb8B178222aff7dcc1ae8
C062a175e20f9a1542C1483498026c6ab57e


感兴趣的读者朋友可以验证一下。如 A = A0 + A1 = 2373edde1a0e5dcd + ad483b77e4e5db41 = d0bc2955fef4390e。这个 A 是个随机数


  1. P2 将上一步生成的随机数的秘密分享值分别发送给 P0,P1


即将 A0,B0,C0 发送给 P0;将 A1,B1,C1 发送给 P1


此时,P0,P1 拥有如下值:


P0P1
A02373edde1a0e5dcdA1ad483b77e4e5db41
B0d81a4646be1c0cb8B178222aff7dcc1ae8
C062a175e20f9a1542C1483498026c6ab57e


  1. P0 计算 E0F0P1 计算 E1F1。并交换 Ei,Fi


P0 本地计算 E0 = X0 - A0, F0 = Y0 - B0


P1 本地计算 E1 = X1 - A1, F1 = Y1 - B1


此时,P0,P1 拥有如下值:


P0P1
E0dede9f352637939aE150653774dad92378
F03573d3764c371a98F17a4fbb4377f67840


交换 Ei,Fi


P0E0,F0 发送给 P1P1E1,F1 发送给 P0。此时,P0,P1 都拥有 E0,F0,E1,F1


  1. P0,P1 本地计算 得到EF


P0,P1 各自本地计算 E = E0 + E1, F = F0 + F1


P0P1
E2f43d6aa0110b712E2f43d6aa0110b712
Fafc38eb9c42d92d8Fafc38eb9c42d92d8


  1. P0 本地计算 Z0P1 本地计算 Z1


现在,P0 已经拥有 A0,B0,C0,E,FP1 已经拥有 A1,B1,C1,E,F。有了这些就可以计算出 Z = X * Y 的秘密分享值 Z0,Z1 了。 即:


P0 本地计算 Z0 = E * B0 + A0 * F + C0


P1 本地计算 Z1 = E * B1 + A1 * F + C1 + E * F


P0P1
Z01db35d14c12aZ1ffffe24ca30611b0


正确性可以通过以下恒等式加以验证:


输出: P0,P1 分别持有 Z = X * Y 的秘密分享值 Z0,Z1


我们可以看到,从输入到计算再到输出,整个过程中,没有泄漏任何隐私数据。


整个算子计算结束时, P0 单独拥有 X0,Y0,A0,B0,C0,E0,F0,E1,F1,E,F,Z0P1 单独拥有 X1,Y1,A1,B1,C1,E0,F0,E1,F1,E,F,Z1P2 单独拥有 A0,B0,C0,A1,B1,C1,三方都无法单独得到 XYZ


最后,我们总结一下(1~5 对应着上面的步骤):


获取明文结果

输入到计算再到输出,各节点只能看到本地所单独拥有的秘密分享值(一些毫无规律的 64 位随机数),从上文也可以看到,节点是无法独自得到任何隐私数据的。那么,当计算结束后,如果想得到结果的明文,怎么获取呢?


Rosetta 提供了一个恢复明文的接口,使用很简单。


res = sess.run(rtt.SecureReveal(z, receive_party=4)) # 'b0100' means Charleyprint('z:', res)
复制代码


那这个 rtt.SecureReveal 是如何工作的呢?


其实非常简单:如果本方想要知道明文,只需要对方把他的秘密分享值发给我,然后本地相加即可。


比如,上一节结尾处,我们知道了各方 (P0/P1/P2) 的分享值如下:


P0P1P2
Z01db35d14c12aZ1ffffe24ca30611b0Z20


结合实例,Charley (P2) 想要获取结果明文,那么,P0,P1 将各自的分享值 Z0,Z1 发给 P2,然后 P2 本地相加即可。即: 1db35d14c12a + ffffe24ca30611b0 = 1ad2da (1757914)。我们将此值进一步再转换为浮点数,就可以得到我们想要的用户态的明文值了: 1757914 / (1 << 18)= 6.7059097

效率优化

上面介绍的 秘密分享multiply 算子 都是基于最基本的算法原理,在时间上和通信上的开销还是比较大的,在实际工程实现中,还可以进一步进行优化以提升性能。在介绍优化方案之前,先了解一下 什么是 PRF


PRF[3],Pseudo-Random Function。 简单来说,即给定一个随机种子 key,一个计数器 counter,执行 PRF(key, counter) ,会得到一个相同的随机数


补充说明一下。例如,P0,P1 执行 PRF(key01, counter01),会产生一个相同的随机数。这里的 key01counter01 对于 P0,P1 来说是一致的。程序会维护这两个值,对使用者来说是透明的。

关于秘密分享

来看看优化版本(假设: P0 有一个私有数据 x)。


  • 方案 2(优化版): P0,P1 使用 PRF(key01, counter) 本地同时生成一个相同的随机数 r。然后 P0 本地设置 x0 = x - rP1 本地设置 x1 = r。此时 share(x) = (x0, x1) = (x - r, r),与定义一致。此版本无需 P2 的参与。没有通信开销。


目前 Rosetta 开源版本中使用的正是此方案。


  • 方案 3(优化版): P0 设置 x0 = xP1 设置 x1 = 0 即可。此时 share(x) = (x, 0)此版本无需 P2 的参与。没有通信开销,也没有计算开销。


上述各个版本(包括方案 1),都是可行且安全的。可以看到P1/P2 并不知道 P0 的原始输入值。

关于 Multiply 算子

Multiply 算子中输入,输出部分没有变化,主要是计算步骤中的第 1 步与第 2 步有些许变化,以减少通信量。这里也只描述这两步,其余与前文相同。


在上文的描述中,我们知道 P2 生成三元组后,需要将其分享值发送给 P0,P1。当我们有了 PRF 后,可以这么做:


  1. P0,P2 使用 PRF(key02, counter02) 同时生成 A0,B0,C0P0,P1 使用 PRF(key12, counter12) 同时生成 A1,B1

  2. 然后,P2A = A0 + A1, B = B0 + B1,得到 C = A * B, C1 = C - C0P2C1 发送给 P1P2 的任务完成。

  3. 目前 Rosetta 开源版本中使用的是此方案。


相比于原始版本,优化版本只需要发送 C1,不用再发送 A0,A1,B0,B1,C0


在 Rosetta 中,我们还针对具体的各个不同的算子进行了一系列的算法、工程优化,欢迎感兴趣的读者来进一步了解。

小结

安全性是隐私 AI 框架的根本,在本篇文章中,我们结合隐私数据输入的处理和密文上乘法的实现,介绍了“随机数” 形式的密文是如何在多方之间流动,同时“神奇”的仍能保证计算逻辑的正确性的。我们这里对于安全性的说明是直观上的描述,而实际上,这些算法的安全性都是有严格数学证明的。感兴趣的读者可以进一步去探索相关的论文。


Rosetta 将持续集成安全可靠的密码学算法协议作为“隐私计算引擎”到框架后端中,也欢迎广大开发者参与到隐私 AI 的生态建设中来。

参考文献

[1] 秘密共享,https://en.wikipedia.org/wiki/Secret_sharing


[2] Beaver, Donald. “Efficient multiparty protocols using circuit randomization.” Annual International Cryptology Conference. Springer, Berlin, Heidelberg, 1991.


[3] PRF 的一个简单介绍,https://crypto.stanford.edu/pbc/notes/crypto/prf.html


作者介绍:


Rosetta 技术团队,一群专注于技术、玩转算法、追求高效的工程师。Rosetta 是一款基于主流深度学习框架 TensorFlow 的隐私 AI 框架,作为矩阵元公司大规模商业落地的重要引擎,它承载和结合了隐私计算、区块链和 AI 三种典型技术。目前 Rosetta 已经在 Github 开源(https://github.com/LatticeX-Foundation/Rosetta) ,欢迎关注并参与到 Rosetta 社区中来。


系列文章:


隐私 AI 工程技术实践指南:整体介绍


面向隐私AI的TensorFlow深度定制化实践


隐私AI框架中MPC协议的快速集成


公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2020-11-03 10:302181

评论

发布
暂无评论
发现更多内容

交易所开发源码,数字货币永续合约交易平台搭建

V\TG【ch3nguang】

交易所开发

区块链交易所开发, 币币交易系统搭建

V\TG【ch3nguang】

哈希游戏开发、哈希尾数、单双竞猜游戏开发

西安链酷科技

哈希算法 区块链游戏 web3

企业大数据传输的四类方式及镭速解决方案

镭速

大数据传输

通过一流的NFT开发提升您的数字形象

区块链软件开发推广运营

数字藏品开发 dapp开发 区块链开发 链游开发 NFT开发

木鱼一敲烦恼丢掉,一个恢复内心平静的赛博空间

荣耀开发者服务平台

小程序 前端 安卓 组件 服务卡片

亚信科技AntDB数据库携“U8C+AntDB联合产品”亮相“2023全球商业创新大会”,开启生态合作新篇章

亚信AntDB数据库

数据库 AntDB AntDB数据库

跨平台.NET IDE集成开发 Rider 激活码破解版

mac大玩家j

开发环境 Mac软件

安全大文件传输对行业重要性

镭速

大文件传输 传输大文件 安全大文件传输

OpenAI 函数调用教程

3D建模设计

openai ChatGPT

低代码实现软件的快速交付与部署

互联网工科生

软件开发 低代码 企业级低代码平台

Zookeeper简述

数新网络官方账号

zookeeper 后端 ZooKeeper原理

“银河护卫队总部”放大招!Milvus 核心组件再升级,主打就是一个低延迟、高准确度

Zilliz

非结构化数据 Milvus Zilliz 向量数据库

公链项目开发 哪条公链生态好

西安链酷科技

DAPP智能合约交易系统开发 DAPP系统开发 开发软件

国际顶会SC23收录唯一区块链论文,微众银行技术实力受学术界认可

新消费日报

人工智能的优势:使用 GPT 和扩散模型生成图像

3D建模设计

人工智能 生成式AI

Masks Person面具人MAR现在值得参与吗

币离海

使用 WebGL 为 HTML5 游戏创建逼真的地形

3D建模设计

WebGL 地形

Linux 可执行文件瘦身指令 strip 使用示例

互联网工科生

Linux 资源

华为主题十周年共创海报还能这么玩?

最新动态

dapp软件开发需要多少钱

西安链酷科技

DAPP智能合约交易系统开发 链游开发

数据库顶会 VLDB 2023 论文解读:字节跳动如何解决超大规模流式任务运维难题

字节跳动云原生计算

flink 流式计算 VLDB

你折腾一天都装不上的插件,函数计算部署 Stable Diffusion 都内置了

Serverless Devs

Serverless 模型

开发一条以太坊公链需要多久

西安链酷科技

区块链技术开发 公链开发 联盟链开发 公链团队

文心一言 VS 讯飞星火 VS chatgpt (87)-- 算法导论8.2 4题

福大大架构师每日一题

福大大架构师每日一题

堆叠大陆 Stacklands for Mac(卡牌游戏)v1.3.4中文原生版

mac

堆叠大陆 苹果mac 村庄建设游戏 Stacklands 卡牌游戏

Solr数据迁移ES

腾讯云大数据

ES

解锁项目管理神器——低代码开发平台

力软低代码开发平台

Python 套接字编程完整指南

3D建模设计

Python

选择正确的框架:探索 Spring Cloud 和 Dubbo

Liam

程序员 微服务 Spring Cloud dubbo 后端

2023年中国信通院铸基计划“文本图像篡改检测系统技术规范”研讨会成功召开

合合技术团队

中国信通院 文本 合合信息 研讨会 图像篡改

隐私AI框架中的数据流动与工程实现_AI&大模型_Rosetta技术团队_InfoQ精选文章