# 正文
GMW 协议最早是在论文 How to play any mental game 中由 Goldreich, Micali 和 Wigderson 提出。这是一个可以在算术电路和布尔电路中实现的安全计算协议,也可以比较容易地拓展到多方安全计算的领域。
在 2PC 的场景下,我们假设存在两个安全计算的参与方P1,P2,他们各自持有一个秘密输入x,y。一个需要计算的函数F(x,y),对应了一个布尔电路C。
首先,参与方P1 对于自己秘密x∈{0,1}n 中的每一个比特xi,都选择一个随机比特掩码ri∈R{0,1},计算xi⊕ri 作为自己的新秘密比特,接下来,参与方P1 将自己的掩码比特ri,i∈{1,2,...,n} 发送给参与方P2。
同样的,P2 也进行了类似的操作,选取随机比特掩码r′ 对自己的秘密y 进行异或并将结果作为新的秘密,同时将选取的随机比特掩码发送给参与方P1。
经过了上面这样的过程,两个参与方P1,P2 相当于和对方进行了秘密共享 —— 只有同时得到参与方P1 的秘密份额xi⊕ri 和参与方拥有的秘密份额ri 才能够还原秘密比特xi。
接下来,双方共同计算布尔电路C。
对于电路中某个门电路的输入,在先前的混淆电路中,双方是通过乱码表来实现计算。我们假设一个门电路的输入导线wi,wj 由双方分别持有,导线对应的取值可以是 0 或 1,那么这里就需要构造一个乱码表,并且通过标识置换和不经意传输协议由一方告知另外一方足够的数据以进行计算。
在 GMW 中采用的是一种不同的方式。我们可以假设 GMW 协议需要计算的布尔电路中使用了 XOR,NOT 和 AND 三种门电路。
先看非门,这个简单。
NOT 门对于输入导线的取值wi∈{0,1},输出的结果会是wi。
因为双方实现了秘密共享,也就是说一个原本的秘密wi 被分割为了si1,si2 分别由P1,P2 持有(当然前面只对输入秘密进行了分享,没有对中间过程的导线进行操作,不过先暂且当作已经做过了吧)。这样子的话,我们可以看一下这个等式:
wi=si1⊕si2wk=wi=si1⊕si2=si1⊕si2
也就是说,如果我们需要计算一个非门的输出结果,只需要参与双方各自把自己持有的秘密值取反就行了。
接下来是异或门。
同样的对于异或门的两个输入秘密wi 和wj,我们将它们分别分割成两个秘密份额即wi=si1⊕si2 和wj=sj1⊕sj2。
异或门需要计算的结果就是wk=wi⊕wj=(si1⊕si2)⊕(sj1⊕sj2)=(si1⊕sj1)⊕(si2⊕sj2)。也就是说,参与协议的两方可以各自计算自己两个秘密份额的异或值,得到的结果相当于异或门输出结果的一个份额。
比较复杂的部分在于与门的实现。
我们可以从P1 所持有的数据来看,P1 有的秘密份额是输入导线wi 的份额si1 和输入导线wj 的份额sj1。那么P1 就可以猜测P2 所持有的秘密份额分别是多少,也就是有四种可能: 00, 01, 10, 11
。这样子,P0 可以事先计算出这四种可能的结果S,即:
S=Ssi1,sj1(si2,sj2)=(si1⊕si2)∧(sj1⊕sj2)
其中si2,sj2 是P2 可能持有的秘密份额。
理论上这里P1 和P2 直接通过一个 4 选 1-OT 协议就可以让P2 知道实际的秘密份额,但是这样便会暴露P1 的秘密份额(而且P1 还不知道结果),因此我们需要一个更复杂的方法。
P1 这时候选择一个随机数r,计算S⊕r,一共得到四个结果,也就是:
Ssi1,sj1(0,0)⊕rSsi1,sj1(0,1)⊕rSsi1,sj1(1,0)⊕rSsi1,sj1(1,1)⊕r
这样,双方通过一个 4 选 1-OT 协议,P2 就能够得到秘密份额Ssi1,sj1(si2,sj2)⊕r,而P1 的秘密份额就是r,双方也无法去了解对方的份额是多少(P1 不能知道 OT 选了到底哪一个)。
实际上或门的实现也可以采用类似的方法。
在计算的最后,双方可以向对方披露自己计算的结果的秘密份额,这样就可以还原出计算的结果。
# 参考
[1] David Evans; Vladimir Kolesnikov; Mike Rosulek, A Pragmatic Introduction to Secure Multi-Party Computation , now, 2018.