星期三, 七月 29日 2020, 1:56 下午

  4.2k 字     19 分钟  

本文介绍了一种实用的安全聚合算法(Secure Aggregation Protocol),主要参考了Google的论文Practical Secure Aggregation for Privacy-Preserving Machine Learning 。

谷歌的Bonawitz等人,在2017年的CCS中提出了一种安全聚合加密方案(SMPC),服务器只能看到聚合完成之后的梯度,不能知道每个用户的私有的真实梯度值。这种方法适用于大规模终端(例如手机)通过一个服务器,共同计算各自输入之和的情形,但是前提是不泄露某个特定的终端的输入,无论是对服务器还是对其他的终端。

在介绍该算法之前,首先介绍几个该算法中需要用的几个算法。

  • 秘密共享(Secret Sharing)

    Shamir算法是秘密共享协议的一种实现,本文使t用的就是这种算法,其基本思想是分发者通过秘密多项式,将秘密s分解为n个秘密分发个持有者,其中任意不少于t个秘密均能恢复密文,而任意少于t个秘密均无法得到密文的任何信息。

    本文使用{(u,su)}uU SS.share (s,t,U),VUVt\left\{\left(u, s_{u}\right)\right\}_{u \in \mathcal{U}} \leftarrow \text { SS.share }(s, t, \mathcal{U}), \mathcal{V} \subseteq \mathcal{U},|\mathcal{V}| \geq t,来表示将秘密s拆分成n份,传入集合U(nn),s,t\mathcal{U}(大小为n,表示n个秘密分发持有者),s,t,针对每一个集合中的每一个u输出它自己那一条拆分后的密文。

    使用 SS.recon ({(u,su)}uV,t)=s\text { SS.recon }\left(\left\{\left(u, s_{u}\right)\right\}_{u \in \mathcal{V}}, t\right)=s来表示恢复密文。

  • 密钥协商(Key Agreement)

    DH密钥交换是一个常用的密钥交换协议,DH密钥交换的目的,是让想要通信的Alice、Bob双方,他们之间能够拥有一个私密的密钥,这个密钥只有A和B两个人知道。DH密钥交换包含如下步骤:

    • 首先,Alice和Bob商量好DH的参数,一个大数素数q\mathcal{q},和zp\mathbb{z}_p上的一个生成元gg(1<gg<q\mathcal{q},一种比较特殊的素数)。这一步我们用公式表示为,KA.param(k)(G,g,q,H)HKA.param(k) \rightarrow \left(\mathbb{G}^{\prime}, g, q, H\right),H为哈希函数

    • 然后通过公共参数生成各自的公钥和私钥:

      KA.gen(G,g,q,H)(x,gx),xgxKA. \operatorname{gen}(G',g,q,H) \rightarrow\left(x, g^{x}\right),x为私钥,g^{x}为生成的公钥

    • Alice和Bob分别将公钥发送给对方

    • 然后双方通过公钥生成一个用于通信的密钥,su,v=H((gxv)xu)s_{u, v}=H\left(\left(g^{x_{v}}\right)^{x_{u}}\right),用公式表示为,KA.agree(xu,gxv)su,vKA.agree\left(x_{u}, g^{x_{v}}\right) \rightarrow s_{u, v}

  • 认证加密(Authenticated Encryption)

    其实就是使用一个key对一段明文进行加密,同时使用相同的key可以进行解密。用公式表示为:

    AE.dec(c,AE.enc(c,x))=x,xckey\operatorname{AE.dec}(c, \operatorname{AE.enc}(c, x))=x,x表示需加密的明文,c表示key

  • 伪随机数生成器(Pseudorandom Generator)

    给定一个随机数种子,生成无关的随机数,使用PRG(seed)PRG(seed)来表示输出的随机数。

  • 数字签名(Signature Scheme )

    对一段明文进行数字签名,以保证其内容没有遭到篡改。

    • 首先输入k,生成一对公钥和私钥,SIG.gen(k)(dPK,dSK)\operatorname{SIG.gen}(k) \rightarrow\left(d^{P K}, d^{S K}\right)
    • 然后通过签名算法对一段消息m用私钥进行签名, SIG.sign(dSK,m)σSIG.sign\left(d^{S K}, m\right) \rightarrow \sigma
    • 然后用公钥进行验证,SIG.ver(dPK,m,σ){0,1}SIG.ver \left(d^{P K}, m, \sigma\right) \rightarrow\{0,1\}

算法具体实现步骤

  1. 初始阶段

    • 首先,每个客户端初始化一个安全参数k用来生成DH的相关参数,ppKAparam(k)p p \leftarrow \mathbf{K A} \cdot \operatorname{param}(k)
    • 规定秘密分享协议中的数值n和阈值t。
    • 规定m为传输数据向量的大小,xux_u为隐私数据向量。
    • 每个客户端和服务器有一个经过身份验证的通道。
    • 客户端u从可信第三方针获得一个私钥,对所有的其他用户v第三方给予一个公钥,(dPK,dSK)\left(d^{P K}, d^{S K}\right)
  2. 第0轮(通知Keys)

    • 对于客户端u:
      • 根据根据pp分别生成两对公钥和私钥,分别为,(cuPK,cuSK)KA.gen(pp)\left(c_{u}^{P K}, c_{u}^{S K}\right) \leftarrow \operatorname{KA.gen}(p p)(suPK,suSK)KAgen(pp)\left(s_{u}^{P K}, s_{u}^{S K}\right) \leftarrow \mathbf{K A} \cdot \operatorname{gen}(p p),然后使用数字签名算法对两个公钥进行签名,生成 σuSIG.sign(duSK,cuPKsuPK)\sigma_{u} \leftarrow \operatorname{SIG.sign}\left(d_{u}^{S K}, c_{u}^{P K} \| s_{u}^{P K}\right)
      • 将生成的两个公钥,连同签名结果即,(cuPKsuPKσu)\left(c_{u}^{P K}\left\|s_{u}^{P K}\right\| \sigma_{u}\right),通过经过验证的通道发送给服务器。
    • 对于服务器端:
      • 检查所有客户端中收集消息数是否小于t,否则中止算法,将收到消息的客户端集合记为U1\mathcal{U}_1
      • U1\mathcal{U}_1中的所有客户端广播其与其他客户端对应的客户端id,两个公钥,以及数字签名的结果,{(v,cvPK,svPK,σv)}vU1\left\{\left(v, c_{v}^{P K}, s_{v}^{P K}, \sigma_{v}\right)\right\}_{v \in \mathcal{U}_{1}}
  3. 第1轮(分享Keys)

    • 对于客户端u:

      • 收到来自服务器的{(v,cvPK,svPK,σv)}vU1\left\{\left(v, c_{v}^{P K}, s_{v}^{P K}, \sigma_{v}\right)\right\}_{v \in \mathcal{U}_{1}},为了验证U1t\left|\mathcal{U}_{1}\right| \geq t是否真的成立,防止服务器伪造客户端来套取客户端数据,先对U1\mathcal{U}_1中的所有客户端进行消息验证,即

        vU1,\forall v \in \mathcal{U}_{1}, SIG.ver (dvPK,cvPKsvPK,σu)=1\left(d_{v}^{P K}, c_{v}^{P K} \| s_{v}^{P K}, \sigma_{u}\right)=1

        由于公钥,私钥是可信第三方分发的,如果服务器伪造客户端,那么这个公式就不成立,那么客户端立即中止算法。

      • 随机抽样一个bub_u,用于PRG(伪随机数生成器)的生成种子。

      • 通过秘密共享算法生成SuPKS_u^{PK}bub_u的分享内容(shares),

        {(v,su,vSK)}vU1\left\{\left(v, s_{u, v}^{S K}\right)\right\}_{v \in \mathcal{U}_{1}} \leftarrow SS.share (suSK,t,U1)\left(s_{u}^{S K}, t, \mathcal{U}_{1}\right){(v,bu,v)}vU1\left\{\left(v, b_{u, v}\right)\right\}_{v \in \mathcal{U}_{1}} \leftarrow SS.share (bu,t,U1)\left(b_u, t, \mathcal{U}_{1}\right)

      • 对于U1\mathcal{U}_{1}中的其他客户端,针对每个客户端使用认证加密技术,使用的密钥是两个客户端经过密钥协商出来的结果,计算一个

        eu,ve_{u, v} \leftarrow AE.enc ( KA.agree (cuSK,cvPK),uvsu,vSKbu,v)\left(\text { KA.agree }\left(c_{u}^{S K}, c_{v}^{P K}\right), u\|v\| s_{u, v}^{S K} \| b_{u, v}\right)

        eu,ve_{u, v}携带了share的信息,这个东西后面就会被传给相应的其他客户端。

      • 将所有eu,ve_{u, v}传输给服务器,这个东西每个都暗中包含了u和v地址数据(大概是客户端id一类的东西)

      • 存储本轮中生成的所有信息和收到的信息。

    • 对于服务器端:

      • 检查所有客户端中收集消息数是否小于t,否则中止算法,将收到消息的客户端集合记为U2\mathcal{U}_2,注意U2U1\mathcal{U}_{2} \subseteq \mathcal{U}_{1}
      • 将收集到的所有eu,ve_{u, v},分别广播给相应的客户端。
  4. 第2轮(收集已经加密过的信息)

    • 对于客户端u:

      • 收集来自服务器端的与其他客户端对应的eu,ve_{u, v},并且得到集合U2\mathcal{U}_2,如果发现大小小于t,则立即中止算法(因为少于t个客户端的信息无法恢复)。

      • 对于每个客户端u,计算他与U2\mathcal{U}_2中其他客户端的共享mask(用来掩盖真实的数据),通过密钥协商得到密钥,su,vKA.agree(suSK,svPK)s_{u, v} \leftarrow KA.agree \left(s_{u}^{S K}, s_{v}^{P K}\right),然后用这个密钥作为种子,送入PRG(伪随机数生成器),生成与隐私数据向量大小相同的m个,作为mask向量。

        pu,v=Δu,vPRG(su,v)\boldsymbol{p}_{u, v}=\Delta_{u, v} \cdot \mathbf{P} \mathbf{R} \mathbf{G}\left(s_{u, v}\right),当 u>v,u>v, Δu,v=1\Delta_{u, v}=1u<vu<vΔu,v=1\Delta_{u, v}=-1(注意 pu,v+pv,u=0uv)\left(\text {注意 } p_{u, v}+p_{v, u}=0, \forall u \neq v\right),定义pu,u=0\boldsymbol{p}_{u, u} = 0

      • 计算每个客户端u的个人mask向量pu=PRG(bu)\boldsymbol{p}_{u} = PRG(b_u),然后计算将隐私数据向量与个人mask向量和共享mask向量的加和,用来mask个人隐私数据,

        yuxu+pu+vU2pu,v(modR)\boldsymbol{y}_{u} \leftarrow \boldsymbol{x}_{u}+\boldsymbol{p}_{u}+\sum_{v \in \mathcal{U}_{2}} \boldsymbol{p}_{u, v}(\bmod R)

      • 如果上述过程中任意操作,例如密钥协商,PRG操作失败,那么直接中止操作,否则将生成的yny_n发送给服务器。

    • 对于服务器端:

      • 检查所有客户端中收集yny_n数量是否小于t,否则中止算法,将收到消息的客户端集合记为U3\mathcal{U}_3,注意U3U2\mathcal{U}_{3} \subseteq \mathcal{U}_{2},将U3\mathcal{U}_3的列表发送给每个用户。
  5. 第3轮(一致性检查,我认为该部分主要是为了防止服务器恶意模拟客户端以套取信息)

    • 对于客户端u:

      • 收集收到的客户端集合U3\mathcal{U}_3,查看U3\mathcal{U}_3的大小是否大于t,小于t直接中止算法。

      • 若大于等于t,那么将U3\mathcal{U}_3使用数字签名进行某种形式的签名,σuSIG.sign(duSK,U3)\sigma_{u}^{\prime} \leftarrow \operatorname{SIG.sign}\left(d_{u}^{S K}, \mathcal{U}_{3}\right),得到一个σu\sigma_{u}^{\prime}

        这个东西主要是为了防止服务器在上一步恶意欺骗大多数客户端以套取信息,因为如果上一步中服务器故意伪造某一个客户端掉线的假象,那么想要套取信息的那个客户端和其他客户端收到的U3\mathcal{U}_3就会是不一样的,这样签名就会出问题,可以被客户端发现服务器端造假。

    • 对于服务器端:

      • 收集所有σu\sigma_{u}^{\prime},确认收到的消息数是否大于t,否则中止,如果大于t,那么将这部分用户记为,U4U3\mathcal{U}_{4} \subseteq \mathcal{U}_{3},对于该集合中的每一个用户,发送对应的签名结果{v,σv}vU4\left\{v, \sigma_{v}^{\prime}\right\}_{v \in \mathcal{U}_{4}}
  6. 第4轮(汇聚信息并解密)

    • 对于客户端u:

      • 收到来自服务器端的签名结果{v,σv}vU4\left\{v, \sigma_{v}^{\prime}\right\}_{v \in \mathcal{U}_{4}},确认U4U3\mathcal{U}_{4} \subseteq \mathcal{U}_{3},且数量大于等于t,然后确认SIG.ver (dPK,U3,σv)=1\left(d^{P K}, \mathcal{U}_{3}, \sigma_{v}^{\prime}\right)=1 对于所有的 vU4v \in \mathcal{U}_{4},这一步主要是防止服务器端故意欺骗客户端以套取客户端信息。如果以上任何环节出问题,直接中止算法。
      • U2\mathcal{U}_{2}中除了u的其他客户端中,对于每个客户端v,可以使用密钥来解密认证加密过的eu,ve_{u, v}vusv,uSKbv,uAE.dec(KA.agree(cuSK,cvPK),ev,u)v^{\prime}\left\|u^{\prime}\right\| s_{v, u}^{S K} \| b_{v, u} \leftarrow \operatorname{AE.dec}\left(\mathrm{KA} . \operatorname{agree}\left(c_{u}^{S K}, c_{v}^{P K}\right), e_{v, u}\right),得到这四个结果,其中前两个首先验证一下是否满足u=uv=vu=u^{\prime} \wedge v=v^{\prime},如果不满足说明发错了,或者信息丢失了,直接中止算法。
      • 将得到的两个share有选择的发送给服务器,对于客户端 vU2\U3v \in \mathcal{U}_{2} \backslash \mathcal{U}_{3},即掉线的客户端,发送Sv,uSKS_{v, u}^{S K} , 对于vU3v \in \mathcal{U}_{3},即正常的客户端,发送bv,ub_{v, u}
    • 对于服务器端:

      • 收集从客户端中收集最少t个信息,这群客户端记为U5\mathcal{U}_{5},否则中止算法

      • 对于客户端 vU2\U3v \in \mathcal{U}_{2} \backslash \mathcal{U}_{3},即掉线的客户端,使用秘密分享中的恢复算法,恢复出suSKs_{u}^{S K},即,suSKSS.recon({su,vSK}vU5,t)s_{u}^{S K} \leftarrow \operatorname{SS.recon}\left(\left\{s_{u, v}^{S K}\right\}_{v \in \mathcal{U}_{5}}, t\right),将它送入PRG计算出针对他和其他客户端的所有pv,up_{v,u}

      • 同理,对于vU3v \in \mathcal{U}_{3},即正常的客户端,使用秘密分享中的恢复算法,恢复出bub_ubuSS.recon({bu,v}vU5,t)b_{u} \leftarrow \operatorname{SS.recon}\left(\left\{b_{u, v}\right\}_{v \in \mathcal{U}_{5}}, t\right),送入PRG计算出自己的pup_u

      • 最后计算出聚合后的结果,即z=uU3xuz=\sum_{u \in \mathcal{U}_{3}} x_{u}

        uU3xu=uU3yuuU3pu+uU3,vU2\U3pv,u\sum_{u \in \mathcal{U}_{3}} x_{u}=\sum_{u \in \mathcal{U}_{3}} y_{u}-\sum_{u \in \mathcal{U}_{3}} p_{u}+\sum_{u \in \mathcal{U}_{3}, v \in \mathcal{U}_{2} \backslash \mathcal{U}_{3}} p_{v, u}

几个需要注意的地方

  • 该算法原理是针对隐私数据向量xux_u,对他进行一个mask的操作,mask主要分为两块,一块是pup_u,另一块是pu,vp_{u,v},这两个mask可以保证隐私数据不被服务器所获取。
  • 服务器是否可以通过欺骗其他客户端以套取某一个客户端的信息?答曰,不行,因为有第3轮的认证加密机制,会在第4轮被客户端发现从而发现发送的客户端集合不一致导致算法中止。
  • 在恢复阶段,诚实用户v不会把关于某个用户u的信息bub_usuSKs_u^{SK}的秘密同时说出去,对于在线的用户u,则会说出bub_u,不在线的用户,会说出suSKs_u^{SK}bub_usuSKs_u^{SK}就是用来生成pup_upu,vp_{u,v}的。
  • 如果没有pup_u,那么如果用户不是真的掉线,而是延迟较大,在服务器已经得到所有的pu,vp_{u,v}时,他就可以恢复出该用户的数据,有了pup_u就难以恢复出数据。

参考资料

1.论文Practical Secure Aggregation for Privacy-Preserving Machine Learning

2.https://blog.csdn.net/qq_37734256/article/details/104223580

3.https://www.cnblogs.com/20189223cjt/p/12529827.html

4.课件:http://jakubkonecny.com/files/2018-01_UW_Federated_Learning.pdf

5.ACM CCS视频:https://www.youtube.com/watch?v=OCy9gPjl-XM&t=1153s



联邦学习     

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

 目录

"觉得赞的话,微信扫一扫赞赏一下吧"



Plugins