1 介绍

本文是谷歌团队发在CCS2017上的文章,旨在解决联邦学习中安全聚合的问题。

安全聚合:多方参与者将信息传递给聚合者,聚合者除了知道这个信息的总和不能知道任何一个特定参与者的信息。

在这篇文章中,谷歌将用户手机作为联邦学习的客户端媒介,从而提出了联邦学习下安全聚合需要做到:

  • 通信:希望对参数进行安全处理后相比直接发送参数不超过两倍的通信开销

  • 掉线:手机作为客户端可能经常掉线,协议需要抵抗掉线

也提出了联邦学习下安全聚合协议的要求:

  • 能在高维向量下进行运算

  • 通信高效,即使每次实例化都有一组新的用户集合

  • 对用户掉线鲁棒

  • 在以服务器为中介、未经身份验证的网络模型的约束下提供了最强的安全性

2 预备知识

本文提出的安全聚合协议需要一定的密码学知识,好消息是文章中给出了这些预备知识。

2.1 秘密分享

\(\text{Shamir}\)秘密分享:用户将秘密\(s\)分成\(n\)份,任意\(t\)份可以重建秘密,但任意\(< t\)份的秘密得不到秘密的任何信息。

首先定义一个有限域\(F\),大小\(l>2^k\),\(k\)是安全参数

在有限域中有\(n\)个元素可以来表示\(1,\cdots,n\)(代表\(n\)个参与方)

  • 分享(share)算法:\(\text{SS.share}(s,t,U)\rightarrow \lbrace (u,s_u)\rbrace_{u\in U}\),输入是秘密\(s\),集合\(U\)有\(n\)个元素表示\(n\)个参与方的userID,阈值\(t\leq|U|\)。输出是每个参与方得到的秘密分享\(s_u\)。

  • 重建算法:\(\text{SS.recon}(\lbrace (u,s_u)\rbrace_{u\in V},t)\rightarrow s\),输入阈值\(t\),以及全局\(U\)的一个子集\(V\)中各个元素的分享\(s_u\),这里要求子集\(V\)大小\(|v|\ge t\)。输出是秘密\(s\)。

2.2 密钥协商

密钥协商由算法元组\((\text{KA.param,KA.gen,KA.agree})\)组成。

  • \(\text{KA.param}\):\(\text{KA.param(k)}\rightarrow pp\),由\(k\)生成一些公共参数\(pp\)

  • \(\text{KA.gen}\):\(\text{KA.gen}(pp)\rightarrow (s_u^{SK},s_u^{PK})\),用公共参数\(pp\)为参与方\(u\)生成私钥-公钥对。

  • \(\text{KA.agree}\):\(\text{KA.agree}(s_u^{SK},s_u^{PK})\rightarrow s_{u,v}\),允许用户\(u\)将其私钥\(s_u^{SK}\)和任何用户\(v\)的公钥\(s_v^{PK}\)组合,获得两者之间私有的共享密钥\(s_{u,v}\)。这里不同用户的私钥和公钥都是用相同的\(pp\)生成的。

2.3 \(\text{Diffie-Hellman}\)密钥协商算法

假设用户\(u,v\)协商一个密钥:

(1)首先\(u,v\)共享一个素数\(p\)以及素数的原根\(g\),\(g<p\)。这两个数的发送可以不加密。

原根: 对于\(i\neq j,1\leq i,j\leq p-1\),有\(g^i \space \text{mod}\space p\neq g^j \space \text{mod}\space p\),则\(g\)为\(p\)的原根。

(2)\(u\)产生一个私有随机数\(A\),满足\(1\leq A \leq p-1\),计算\(X=g^A \space \text{mod}\space p\)并发送给\(v\);同样地,\(v\)产生一个私有随机数\(B\),满足\(1\leq B\leq p-1\),计算\(Y=g^B \space \text{mod}\space p\)并发送给\(v\)。

随后,\(u\)可以通过\(K_u=Y^A\space \text{mod}\space p\)得到密钥,\(v\)可以通过\(K_v=X^B\space \text{mod}\space p\)得到密钥。显然,两者的计算结果都是\(K=g^{A\times B}\space \text{mod}\space p\)

介绍完\(\text{Diffie-Hellman}\),再来看本文具体使用的密钥协商

这里采用的密钥协商与Diffie-Hellman相似:

  • \(\text{KA.param}\):\(\text{KA.param(k)}\rightarrow (G^{'},g,q,H)\),由\(k\)生成公共参数:素数阶\(q\)的群\(G^{'}\)(阶表示群元素个数),原根\(g\)和一个哈希函数\(H\)。

  • \(\text{KA.gen}\):\(\text{KA.gen}(G^{'},g,q,H)\rightarrow (x,g^x)\),从\(Z_q\)采样一个\(x\)当做私钥\(s_u^{SK}\),将\(g^x\)当做其公钥\(s_u^{PK}\)。这里\(Z_q\)表示\(q\)的整数环,即包含了\(0-q-1\)的整数。根据原根的定义,当私钥不同,公钥也不同。

  • \(\text{KA.agree}\):\(\text{KA.agree}(x_u,g^{x_v})\rightarrow s_{u,v}\),其中\(s_{u,v}=H((g^{x_v})^{x_u})\)。即用户\(u\)将其私钥\(x_u\)和用户\(v\)的公钥\(g^{x_v}\)组合,经过哈希得到共享密钥。可以看出,当用户\(v\)获得了\(u\)的公钥,能计算出一样的共享密钥。

2.4 认证加密

由3个算法组成:

  • 密钥生成算法:输出私钥

  • 加密算法\(\text{AE.enc}\):输入明文和密钥,输出密文

  • 解密算法\(\text{AE.dec}\):输入密文和密钥,输出明文或者特殊的错误标志符

2.5 签名机制

本文协议依赖标准UF-CMA安全签名机制。

  • 密钥生成算法:\(\text{SIG.gen}(k)\rightarrow (d^{PK},d^{SK})\),输入安全参数,输出私钥\(d^{SK}\)和公钥\(d^{PK}\)

  • 签名算法:\(\text{SIG.sign}(d^{SK},m)\rightarrow \sigma\),输入私钥和信息,输出签名

  • 验签算法:\(\text{SIG.ver}(d^{PK},m,\sigma)\rightarrow \lbrace0,1\rbrace\),输入公钥,信息和签名,输出签名是否有效的结果

2.6 公钥基础设施

每一方\(u\)可以注册\((u,d_u^{PK})\)作为身份信息,基础设施能根据身份对消息进行签名,使得其他方可以验证但无法冒充签名。这样做使得攻击方无法冒充诚实方。

3 技术直觉

为了保护用户的数据\(x_i\),最开始的方案是使用一次mask操作,即用户\(u\)和\(v\)协商得到一个随机数\(s_{u,v}\),然后用该随机数对真实数据\(x_i\)进行扰动,得到扰动后的结果\(y_i\)

\[y_u=x_u+\sum\limits_{v\in U:u<v}s_{u,v}-\sum\limits_{v\in U:u>v}s_{v,u}(\text{mod} \space R)
\]

各客户端会将扰动后的数据\(y_i\)发送给服务器,服务器随后可以进行计算:

\[\begin{aligned}
z&=\sum_{u\in U} y_u \\
&=\sum_{u\in U} y_u(x_u+\sum\limits_{v\in U:u<v}s_{u,v}-\sum\limits_{v\in U:u>v}s_{v,u}) \\
&=\sum_{u\in U} x_u (\text{mod} \space R) \\
\end{aligned}
\]

我们可以对单次mask举例方便理解。假设有3个客户端,那么依据上述扰动方法,他们交给服务器的数据分别为:

\[y_1=x_1+s_{12}+s_{13}
\]
\[y_2=x_2-s_{12}+s_{23}
\]
\[y_3=x_3-s_{13}-s_{23}
\]

服务器进行求和:\(y_1+y_2+y_3=x_1+x_2+x_3\)

这个方案可以让服务器在不知道各方数据\(x_i\)的情况下得到总和\(\sum x_i\),但有一些问题:

  • 通信开销过大

  • 扰动值\(s_{uv}\)若通过服务器分发,那么服务器直接得到了扰动值

  • 如果有用户掉线,那么扰动值无法在总和中被消去

4 问题解决

4.1 通信开销大

直接发送扰动值\(s_{uv}\)的通信开销较大,因此可以改变为发送\(\text{PRG}\)的种子,让客户端自己使用\(\text{PRG}\)对种子进行扩展来得到扰动值。该方法也能回答为什么需要使用一次mask进行扰动而不是直接采用

安全的方法分发数据\(x_i\),因为\(x_i\)可能是维数很大的数据。

4.2 扰动值保护

为了防止服务器直接获得扰动值,采用密钥协商的方法传递。那么各客户端本地持有密钥协商生成的私钥,仅通过服务器传递公钥,服务器无法用公钥获取扰动值。

4.3 用户掉线

我们假设有3个客户端,此时客户端3掉线,那么服务器求和为:

\[y_1+y_2=x_1+x_2+s_{13}+s_{23}
\]

为了消去上式的多余项,想法是让服务器去客户端1处获得\(s_{13}\),去客户端2处获得\(s_{23}\)。然而这时又诞生两个新问题:

  • 若服务器还未获得扰动值,客户端1或3又掉线,那么无法获得扰动值。在真实场景中客户端数量众多,可能每次获取扰动值都有新的掉线用户。我们姑且称这种情况为循环掉线

  • 若\(y_3\)实际上是延迟到达而非掉线。若在服务器获得扰动值后,\(y_3\)延迟到达,那么服务器可以计算\(y_3+s_{13}+s_{23}\)求出\(x_3\),即得到了真实数据

5 最终方案

5.1 循环掉线

使用上面介绍过的秘密分享方法。当把扰动值\(s_{uv}\)当做秘密分享出去,那么只要最后的在线客户端数量大于等于门限值\(t\),就能把扰动值恢复。

5.2 double-masking

对每个数据\(x_i\),为其再加入一个掩码\(b_i\),然后再加入之前的扰动值,即:

\[\begin{aligned}
y_u=x_u&+\text{PRG}(b_u) \\
&+\sum\limits_{v\in U:u<v} \text{PRG}(s_{u,v}) \\
&-\sum\limits_{v\in U:u>v} \text{PRG}(s_{v,u}) \\
\end{aligned}
\]

此时的流程变为:

  • 用户\(u\)将扰动\(s\)和\(b\)都以秘密分享的形式分发出去

  • 在恢复的一轮,对于诚实的用户\(v\):若用户\(u\)掉线,\(v\)会将\(s_{uv}\)的share上传给服务器;若\(u\)在线,\(v\)会将\(b_u\)的share上传给服务器

服务器收集了在线用户的\(b\)的share,可以减去\(\sum \text{PRG}(b_u)\);收集了掉线用户相关的扰动的share,可以安全地按一次mask掉线那样消去扰动。

6 总流程

注:红色表示应对主动攻击者需要采取的措施

翻译与解读:


\(\text{setup}\):

 - 所有参与方获得安全参数\(k\),用户总数\(n\)和阈值\(t\),诚实生成公共参数\(pp\leftarrow \text{KA.gen}(k)\)、\(m,R\)用来规定输入采样空间\(Z_R^m\),秘密分享的域\(F\)。所有参与方都有和server交互的私密通道。

 - 用户\(u\)从可信第三方处获得签名密钥\(d_u^{SK}\),同时获得对\(v\)进行验签的公钥\(d_v^{PK}\)


\(\text{Round 0}\):

 用户\(u\):

 - 生成两对公私钥\((c_u^{PK},c_u^{SK})\leftarrow \text{KA.gen}(pp),(s_u^{PK},s_u^{SK})\leftarrow \text{KA.gen}(pp)\),并生成签名\(\sigma_u \leftarrow \text{SIG.sign}(d_u^{SK},c_u^{PK}||s_u^{PK})\)(\(PS\):\(c\)用来做后面加密时的密钥,\(s\)用来做扰动值)

 - 将\((c_u^{PK}||s_u^{PK}||\sigma_u)\)发送给server,移至下轮

 server:

 - 收集至少\(t\)份信息(收集到的集合为\(U_1\))。否则终止

 - 对\(U_1\)中所有用户广播集合用户信息\(\lbrace (v,c_v^{PK},s_v^{PK},\sigma_v)\rbrace_{v\in U_1}\)


\(\text{Round 1}\):

 用户\(u\):

 - 收到信息\(\lbrace (v,c_v^{PK},s_v^{PK},\sigma_v)\rbrace_{v\in U_1}\)。判断\(|U_1|\ge t\),且所有公钥是不同的,并进行验签\(\forall v\in U_1,\text{SIG.ver}(d_v^{PK},c_v^{PK}||s_v^{PK},\sigma_u)=1\)

 - 从\(F\)中随机采样一个\(b_u\)

 - 生成share \(s_u^{SK}:\lbrace(v,s_{u,v}^{SK})_{v\in u_1}\rbrace\leftarrow \text{SS.share}(s_u^{SK},t,U_1)\)

 - 生成share \(b_u:\lbrace(v,b_{u,v})_{v\in u_1}\rbrace\leftarrow \text{SS.share}(b_u,t,U_1)\) (\(PS\):这里生成share,但没有直接分发)

 - 对每个\(v\in U_1 \backslash \lbrace u\rbrace\),计算\(e_{u,v}\leftarrow \text{AE.enc}(\text{KA.agree}(c_u^{SK},c_v^{PK}),u||v||s_{u,v}^{SK}||b_{u,v})\)

 - 若上述有步骤失败,则终止

 - 所有密文\(e_{u,v}\)发给服务器

 - 存储本轮生成所有的信息,并移至下轮

 server:

 - 从至少\(t\)个用户处收集密文(收集到的集合为\(U_2 \subseteq U_1\) )

 - 给\(U_2\)中每个用户\(u\)发送密文\(\lbrace e_{u,v}\rbrace_{v\in U_2}\),移至下轮


\(\text{Round 2}\):

 用户\(u\):

 - 从服务器处收集并存储密文信息\(\lbrace e_{u,v}\rbrace_{v\in U_2}\),并推断出集合\(U_2\)。如果大小小于\(t\),终止

 - 对每个\(v\in U_2 \backslash \lbrace u\rbrace\),计算\(s_{u,v}\leftarrow \text{KA.agree}(s_u^{SK},s_v^{PK})\),并使用PRG将这个值扩展为一个随机向量\(p_{u,v}=\Delta_{u,v}\cdot \text{PRG}(s_{u,v})\),其中若\(u>v\)则\(\Delta_{u,v}=1\),若\(u<v\)则\(\Delta_{u,v}=-1\)。且定义\(p_{u,u}=0\)(\(PS\):\(s_u^{SK}\)是\(u\)自己持有的,\(s_v^{PK}\)在\(\text{Round 1}\)收到,密钥协商生成的\(s_{u,v}\)就是扰动值的种子)

 - 计算用户自己的私有掩码向量\(p_u=\text{PRG}(b_u)\)。然后计算输入\(y_u\leftarrow x_u+p_u+\sum_{v\in U_2}p_{u,v}\)

 - 若上述有步骤失败,则终止。否则将\(y_u\)发送给服务器并移至下轮

 server:

 - 从至少\(t\)个用户处收集\(y_u\)(收集到的集合为\(U_3 \subseteq U_2\) )。给\(U_3\)中每个用户发送\(U_3\)用户列表


\(\text{Round 3}\):

 用户\(u\):

 - 从服务器收集用户列表\(U_3 \subseteq U_2\)(包括自身),若\(U_3\)大小小于\(t\),终止

 - 将自己的签名\(\sigma_u^{'}\leftarrow \text{SIG.sign}(d_u^{SK},U_3)\)发送给服务器

 server:

 - 从至少\(t\)个用户处收集\(\sigma_u^{'}\)(收集到的集合为\(U_4\subseteq U_3\))。给\(U_4\)中每个用户发送集合\(\lbrace v, \sigma_v^{'}\rbrace_{v\in U_4}\)


\(\text{Round 4}\):

 用户\(u\):

 - 从服务器处得到列表\(\lbrace v, \sigma_v^{'}\rbrace_{v\in U_4}\)。验证\(U_4 \subseteq U_3,|U_4|\ge t,\text{SIG.ver}(d^{PK},U_3,\sigma_v^{'})=1\)。如果验证失败则终止

 - 对于用户\(v\in U_2 \backslash \lbrace u\rbrace\), 解密密文得到\(v^{'}||u^{'}||s_{v,u}^{SK}||b_{v,u}\leftarrow \text{AE.dec}(\text{KA.agree}(c_u^{SK},c_v^{PK}),e_{v,u})\),并验证\(u=u^{'},v=v^{'}\)(PS:解密后各方才得到share)

 - 如果有解密操作失败,终止

 - 给服务器发送shares,发送的内容包括:对用户\(v\in U_2 \backslash U_3\)发送\(s_{v,u}^{SK}\),对用户\(v\in U_3\)发送\(b_{v,u}\)(PS:\(U_3\)在Round 2被告知,这里可以看出在Round 2结束时必须明确哪些是掉线用户哪些是在线用户)

 server:

 - 从至少\(t\)个用户处收集回复(收集到的集合为\(U_5\))

 - 对每个用户\(u\in U_2\backslash U_3\),重建\(s_u^{SK}\leftarrow \text{SS.recon}(\lbrace s_{u,v}^{SK}\rbrace_{v\in U_5},t)\),并使用该值和PRG,来计算和\(U_3\)中用户\(v\)组成的扰动\(p_{v,u}\)

 - 对每个用户\(u\in U_3\),重建\(b_u \leftarrow \text{SS.recon}(\lbrace b_{u,v}\rbrace_{v\in U_5},t)\),并使用PRG计算\(p_u\)

 - 计算输出\(z=\sum_{u\in {U_3}}x_u=\sum_{u\in {U_3}}y_u-\sum_{u\in {U_3}}p_u+\sum_{u\in {U_3},v\in U_2 \backslash U_3}p_{v,u}\)


原文链接:https://dl.acm.org/doi/10.1145/3133956.3133982

Practical Secure Aggregation for Privacy-Preserving Machine Learning的更多相关文章

  1. Federated Machine Learning: Concept and Applications

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! Qiang Yang, Yang Liu, Tianjian Chen, and Yongxin Tong. 2019. Federate ...

  2. Machine Learning for Developers

    Machine Learning for Developers Most developers these days have heard of machine learning, but when ...

  3. (转)Is attacking machine learning easier than defending it?

    转自:http://www.cleverhans.io/security/privacy/ml/2017/02/15/why-attacking-machine-learning-is-easier- ...

  4. How do I learn machine learning?

    https://www.quora.com/How-do-I-learn-machine-learning-1?redirected_qid=6578644   How Can I Learn X? ...

  5. Practical Machine Learning For The Uninitiated

    Practical Machine Learning For The Uninitiated Last fall when I took on ShippingEasy's machine learn ...

  6. Lessons learned developing a practical large scale machine learning system

    原文:http://googleresearch.blogspot.jp/2010/04/lessons-learned-developing-practical.html Lessons learn ...

  7. Practical Black-Box Attacks against Machine Learning

    目录 概 主要内容 Jacobian-based Dataset Augmentation Note Papernot N, Mcdaniel P, Goodfellow I, et al. Prac ...

  8. [C2P2] Andrew Ng - Machine Learning

    ##Linear Regression with One Variable Linear regression predicts a real-valued output based on an in ...

  9. 【机器学习Machine Learning】资料大全

    昨天总结了深度学习的资料,今天把机器学习的资料也总结一下(友情提示:有些网站需要"科学上网"^_^) 推荐几本好书: 1.Pattern Recognition and Machi ...

  10. [Machine Learning & Algorithm]CAML机器学习系列2:深入浅出ML之Entropy-Based家族

    声明:本博客整理自博友@zhouyong计算广告与机器学习-技术共享平台,尊重原创,欢迎感兴趣的博友查看原文. 写在前面 记得在<Pattern Recognition And Machine ...

随机推荐

  1. fabric基本使用

    fabric简介 ​ Fabric 是一个 Python 的库,同时它也是一个命令行工具.它提供了丰富的同 SSH 交互的接口,可以用来在本地或远程机器上自动化.流水化地执行 Shell 命令.使用 ...

  2. Quartz集群增强版_01.集群及缺火处理(ClusterMisfireHandler)

    Quartz集群增强版_01.集群及缺火处理(ClusterMisfireHandler) 转载请著名出处 https://www.cnblogs.com/funnyzpc/p/18542452 主要 ...

  3. 通过squid将本地作为代理让不可联网的远端服务器联网

    一种方法 https://unix.stackexchange.com/questions/116191/give-server-access-to-internet-via-client-conne ...

  4. 关于 java.util.concurrent.RejectedExecutionException

    遇到java.util.concurrent.RejectedExecutionException 目前看来,最主要有2种原因. 第一: 你的线程池ThreadPoolExecutor 显示的shut ...

  5. Java GC 调试手记

    摘要 本文记录GC调试的一次实验过程和结果. GC知识要点回顾 问题1:为什么要调试GC参数?在32核处理器的系统上,10%的GC时间导致75%的吞吐量损失.所以在大型系统上,调试GC是以小博大的不错 ...

  6. Java基础总结大纲(一)

    1.JVM.JRE.和JDK的区别: JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性.说明:java是跨平台的而JVM不是跨平台的,正对的不同的语言 ...

  7. golang类型转换模块之gconv

    gf框架提供了非常强大的类型转换包gconv,可以实现将任何数据类型转换为指定的数据类型,对常用基本数据类型之间的无缝转换,同时也支持任意类型到struct对象的属性赋值.由于gconv模块内部大量使 ...

  8. Golang之工作区workspace

    快速开始 创建工作区 写一个最简单的基础项目实际演练一下 Go workspace. 首先,创建 workspace 工作区. $: mkdir workspace $: cd workspace $ ...

  9. Vite项目无法通过IP+端口的方式访问开发服务

    前情 最近要新开一个项目,技术栈由自己安排,于是就想到使用vue3+vite来做,体验一把新技术栈 坑位 vite开发体验极佳,但是在项目完成的时候,想通过本地服务提前发给产品确认UI.交互等细节的时 ...

  10. Node开发规范v1.0

    一.空格与格式 (一)缩进 采用2个空格缩进,而不是tab缩进. 空格在编辑器中与字符是等宽的,而tab可能因编辑器的设置不同.2个空格会让代码看起来更紧凑.明快. 变量声明 永远用var声明变量,不 ...