安全多方计算 - Yao’s 混淆电路(一) 手动构建
简介
在当今信息时代,数据隐私保护越来越重要。传统的计算方式往往会泄露参与方的隐私信息,例如在联合分析数据时,各方需要共享自己的数据,这可能会导致数据泄露。
安全多方计算 (Secure Multi-party Computation, MPC) 是一种密码学技术,它允许多个参与方在不泄露彼此隐私信息的情况下共同计算某个函数1。Yao’s 混淆电路2是 MPC 中一种重要的实现技术,它可以将计算函数转换为一个混淆电路,使得参与方可以在不泄露彼此隐私信息的情况下共同计算该函数。即使攻击者获得了混淆电路,也无法从中获取任何有用的信息;参与方只共享混淆后的数据,而无需泄露原始数据。
本文将介绍 Yao’s 混淆电路的基本原理和手动构建过程,后续探讨现有优化技术和它在实际场景中的应用。
协议流程及原理
基本定义
《Foundations of Garbled Circuits》中给出了混淆电路的基本定义3:
Components of a garbling scheme G = (Gb, En, De, Ev, ev). Function Gb maps f and k to (F, e, d),
strings encoding the garbled function, the encoding function, and the decoding function.
Possession of e and x lets one compute the garbled input X = En(e, x); having F and X lets one
calculate the garbled output Y = Ev(F, X); and knowing d and Y lets one recover the final output
y = De(d, Y ), which must equal ev(f, x).
混淆电路方案由以下几部分组成:Gb是混淆算法,En是编码算法,Ev是计算算法,De是解码算法。
f
f
f 为将计算函数转换后对应的电路,
F
F
F 为混淆电路;
d
d
d 为解码信息;
X
X
X 为输入编码,通过编码信息
e
e
e 和电路输入
x
x
x 计算得到,
Y
Y
Y 是输出编码,它是对输入编码
X
X
X 和混淆电路
F
F
F 计算得到;最终的电路输出
y
y
y 是通过解码算法
D
e
De
De 对输出编码
Y
Y
Y 解码得到的;
一个基本要求是对电路输入
x
x
x 和电路
f
f
f 执行计算
e
v
(
f
,
x
)
ev(f, x)
ev(f,x) 后得到的结果
y
y
y 与混淆计算之后的
y
y
y 值相同。
有了上面的基本定义后,接下来以Alice和Bob举例说明以上组成部分如何配合完成简单的单个逻辑门电路计算过程。
过程说明
我们要实现以下目标:两个参与方 Alice 和 Bob 在不泄露彼此输入(隐私)信息的情况下计算一个函数。
函数转换为电路的方式有多种,这里不考虑具体的转换方式,我们从转换后的电路开始混淆电路计算过程。Alice 作为混淆方和Bob作为计算方要计算函数
z
=
f
(
x
,
y
)
z = f(x, y)
z=f(x,y)。
f
f
f为函数转换后对应的电路,
x
,
y
x, y
x,y 是两者的输入。
首先 Alice 采用 Gb 混淆算法将原始电路转换为混淆电路。具体来说,她对每条线路和每个电路门进行混淆。
线路混淆:
很多文章中也叫做打"标签"。对于电路
C
C
C 的每一条输入线路
W
i
W_i
Wi,Alice 随机生成两个秘密值(secret value)
w
i
0
,
w
i
1
w_i^0, w_i^1
wi0,wi1,这两个值
w
i
j
w_i^j
wij 就叫做输入线路
W
i
W_i
Wi 对于
j
∈
{
0
,
1
}
j \in \{0, 1\}
j∈{0,1} 的混淆值(garbled value)。这两个混淆值就相当于原来的真值替换成的"标签"。Alice 将这两个值发送给 Bob,但她不会告诉 Bob
w
i
j
w_i^j
wij 的值与
j
j
j 的对应关系,需要 Alice 在生成的时候将它们的对应关系记录下来,用于后续的协议过程。有一点需要注意,当多个门组合成完整电路的时候,前面电路门的输出会作为后面门的输入,即中间线路相当于共享输出作为下一个门的输入,这种线路只需要做一次线路混淆就好了。
门混淆:
Alice 需要为电路
C
C
C 中的每一个门
G
i
G_i
Gi 构建一个混淆的真值表(garbled truth table)
T
i
T_i
Ti。这里的混淆利用输入线路混淆值作为密钥对电路门输出线路混淆值进行加密实现,具体的实现方式可以有多种。以两输入一输出门(如异或门)为例,它的门混淆值有4个。Alice将这个门的混淆值发送给Bob,除了门混淆值与门的对应关系,Alice不会告诉Bob门混淆值与输入的对应关系。
其次,计算方 Bob 从混淆方获得自己输入对应的线路混淆值。Bob 虽然知道自己要输入什么,但这个混淆电路的输入只接受混淆值,而这个混淆值与真值的对应关系(也就是前面提到的 w i j w_i^j wij 与 j j j 的关系)只有 Alice 知道。这种情况下,为了让 Bob 能够得到自己输入对应的混淆值,同时又要避免 Alice 知道 Bob 的输入值,就需要用到 不经意传输OT协议 实现。Alice 还要与 Bob 通过 OT 协议进行交互,将 Bob 输入的每一比特对应的线路混淆值返回给 Bob。关于 不经意传输OT协议 的详细实现,可以查看之前的文章《手动构建 2-选-1 不经意传输OT协议》。
接下来的事情对于Alice来说很简单,她将自己的输入 x x x 对应的线路混淆值(输入编码) X X X 发送给Bob就可以了。
至此,Bob 得到了混淆电路以及双方的输入线路混淆值,可以开始计算整个混淆电路。在计算每一个电路门的时候,Bob会对门混淆值的每一个解密,然后将解密后的结果与该电路门输出线路混淆值进行比较。直到遇到两值相等的,就可以确定这个逻辑门的输出线路混淆值。若电路未结束,则这个输出线路混淆值将作为下一个电路门的输入线路混淆值继续参与计算。
当Bob计算完整个电路后,他拿到的结果 Z Z Z 仍是"混淆"之后的结果,他还需要将这些混淆值发回给Alice。由Alice来对这些混淆值"解密",最后二者共享正确的计算结果。
以上过程划分了混淆方和计算方在混淆电路过程中的角色分工和混淆电路基本工作过程,后来出现了很多的优化方法,这里暂时不进行讨论。
混淆和计算单个电路门
接下来说明单个电路门的混淆和计算过程。
单个电路门
G
G
G 有两个输入线路和一个输出线路。它的两条输入线路分别是
W
0
W_0
W0 和
W
1
W_1
W1,它的输出线路是
W
W
W。对于这三条线路,Alice 需要为它们生成六个随机秘密值:
w
0
0
,
w
0
1
,
w
1
0
,
w
1
1
,
w
0
,
w
1
w_0^0, w_0^1, w_1^0, w_1^1, w^0, w^1
w00,w01,w10,w11,w0,w1。
w
i
j
w_i^j
wij 表示第
i
i
i 条线路上真值为
j
j
j 的时候对应的线路混淆值。
w
0
w^0
w0 表示输出线路上真值为 0 对应的混淆值,
w
1
w^1
w1 表示输出线路上真值为 1 对应的混淆值。
下图表示 AND 电路门计算门混淆值的情况:
以第一行为例,
w
0
0
,
w
1
0
w_0^0, w_1^0
w00,w10 分别表示第 0 条线输入为 0,第 1条线输入为 1。在 AND 门条件下,计算结果是 0 ^ 1 = 0。所以计算门混淆需要以
w
0
0
,
w
1
0
w_0^0, w_1^0
w00,w10 为密钥对
w
0
w^0
w0 进行加密实现。
E
w
0
0
,
w
1
0
(
w
0
)
E_{w_0^0,w_1^0}(w^0)
Ew00,w10(w0) 表示对该 AND 门的输出
w
0
w^0
w0 两次加密,第一次加密密钥为第 1 条线路真值为 0 时候对应的混淆值
w
1
0
w_1^0
w10,第二次加密密钥为第 0 条线路真值为 0 时候对应的混淆值
w
0
0
w_0^0
w00。
Alice 需要根据 AND 门的真值表依次完成剩余的计算。但 Alice 不会按照固定的顺序将混淆值
{
E
w
0
0
,
w
1
0
(
w
0
)
,
E
w
0
0
,
w
1
1
(
w
0
)
,
E
w
0
1
,
w
1
0
(
w
0
)
,
E
w
0
1
,
w
1
1
(
w
0
)
}
\{E_{w_0^0,w_1^0}(w^0), E_{w_0^0,w_1^1}(w^0), E_{w_0^1,w_1^0}(w^0), E_{w_0^1,w_1^1}(w^0)\}
{Ew00,w10(w0),Ew00,w11(w0),Ew01,w10(w0),Ew01,w11(w0)} 发送给 Bob,而是会将这些混淆值顺序置换,使其无法在解密的时候由固定顺序推断出来哪个密文应该被解密。
在计算电路的时候,Bob只知道这个 AND 门的两个确定的线路混淆值作为输入,两个不确定的输出线路混淆值和这个电路门的4个混淆值。Bob 对于它们之间的映射关系一无所知。这种情况下,Bob 需要根据以上信息从这两个不确定的输出线路混淆值中找出真正的输出线路混淆值。
默认情况下Bob需要对每一个逻辑门中的两种输出都计算一下他们的门混淆值 E w 0 , w 1 ( w 0 ) E_{w_0,w_1}(w^0) Ew0,w1(w0) 和 E w 0 , w 1 ( w 1 ) E_{w_0,w_1}(w^1) Ew0,w1(w1),然后与门混淆真值表中的值进行比较,以此得到这个逻辑门运算的输出混淆值。这个输出混淆值继续作为后续计算的门电路输入值或者作为最终输出的一部分。
手动构建
接下来以一个实际的函数为例,对其完成混淆电路计算。这里的函数是 f ( a l i c e _ i n p u t , b o b _ i n p u t ) = a l i c e _ i n p u t + b o b _ i n p u t f(alice\_input, bob\_input) = alice\_input + bob\_input f(alice_input,bob_input)=alice_input+bob_input,Alice和Bob各自输入一个两位二进制数,对二者进行加法计算。
函数转换为电路
可以通过专门的工具将计算函数转换为门电路,这里不作更多说明。我偷了懒儿,直接在网上找了一个转换后的电路4。
这里通过真值表对电路的正确性进行简单验证。Alice 的二进制输入线路为
A
1
A
2
A1A2
A1A2,Bob 的二进制输入线路为
B
1
B
2
B1B2
B1B2,对应的输出结果为
f
(
A
1
A
2
,
B
1
B
2
)
=
C
3
S
2
S
1
f(A1A2, B1B2) = C3S2S1
f(A1A2,B1B2)=C3S2S1。
示例真值表如下:
A1 | A2 | B1 | B2 | result |
---|---|---|---|---|
1 | 0 | 1 | 1 | 101 |
1 | 1 | 1 | 1 | 110 |
… |
接下来开始对电路混淆和计算。
混淆电路
- 线路混淆
对每一个逻辑门进行如下操作,以 A2B2 作为输入的异或门 XOR 为例,它的每一条输入线路都可以是 0 或 1,输出线路也可能是 0 或 1。需要为每一个可能的输入输出真值生成一个随机秘密值作为线路混淆值。
A2 | B2 | A2B2_XOR_Output |
---|---|---|
1:40592 | 0:81912 | 1:78007 |
1:40592 | 1:16059 | 0:57808 |
0:29869 | 0:81912 | 0:57808 |
0:29869 | 1:16059 | 1:78007 |
如图所示,电路中的每一个门的输入、输出线路都将被一个秘密值标记。这个秘密值与真值的对应关系将由Alice记录,不会将这个关系发送给Bob。
- 门混淆
接下来Alice对电路门进行加密混淆,一种混淆方案就是 E k 0 , k 1 ( x ) = E k 0 ( E k 1 ( x ) ) E_{k_0,k_1}(x)=E_{k_0}(E_{k_1}(x)) Ek0,k1(x)=Ek0(Ek1(x))。这里的 k 0 , k 1 k_0, k_1 k0,k1 就是门的输入线路混淆值, x x x 是门的输出线路混淆值。加密采用的算法及参数是双方协商的结果。
以下表第一行为例进行计算,加密结果 5 W m d V 16 z = E 40592 , 81912 ( 78007 ) 5WmdV16z = E_{40592,81912}(78007) 5WmdV16z=E40592,81912(78007) 。
A2 | B2 | A2B2_XOR_Output | 门混淆值 |
---|---|---|---|
1:40592 | 0:81912 | 1:78007 | 5WmdV16z |
1:40592 | 1:16059 | 0:57808 | DBvwcAzp |
0:29869 | 0:81912 | 0:57808 | HPdimDXE |
0:29869 | 1:16059 | 1:78007 | ZtZve80z |
如果知道了任意电路门的两个输入,同时也知道这个电路门的所有的线路混淆值,在使用这两个输入线路混淆值作为key对门混淆值解密之后,就可以通过匹配得到这个逻辑门的输出混淆值。
计算电路
- 单个门电路计算
给到Bob的两个输入值是(40592,16059)、这个逻辑门可能的输出混淆值 {78007, 57808} 和这个逻辑门的门混淆值 {5WmdV16z, DBvwcAzp, HPdimDXE, ZtZve80z},但Bob 是不知道各个值的对应关系的。Bob 在获得两个输入值后,需要对每一个门混淆值进行解密计算,然后与 A2B2_XOR_Output 的值对比,只有一个值在列表中,就是57808。这样,Bob 计算出来这个逻辑门的输出线路混淆值。 - 完整电路计算
接下来是这个电路的完整的计算过程。Alice 输入值为 (0, 1),对应线路 A1A2,Bob 输入值为 (1, 1),对应线路 B1B2。
首先,Alice 将混淆后的电路发送给 Bob,包括自己输入值对应的输入线路混淆值 (80353, 40592)。
然后,Bob 与 Alice 进行通信,依赖不经意传输OT协议,从 Alice 处获得自己的输入值 (1, 1) 对应的输入线路混淆值 (74984, 16059),而 Alice 并不知道 Bob 的真实输入。关于不经意传输OT协议的具体实现过程,请查看我之前的文章《手动构建 2-选-1 不经意传输OT协议》。
接着,Bob开始计算。首先计算第一个逻辑门(XOR),根据输入混淆值 (40592, 16059) 计算得到输出混淆值为 57808,这作为最终输出,将被发送给 Alice,得到 S1 为 0。
第二个逻辑门(AND)根据输入混淆值 (40592, 16059) 计算得到输出混淆值为 56178;第三个逻辑门(XOR)根据输入混淆值 (80353, 74984) 计算得到输出混淆值为 54642;第四个逻辑门(XOR)根据输入混淆值 (54642, 56178) 计算得到输出混淆值为 90803,这也是一位最终结果,将被发送给 Alice,得到 S2 为 0;第五个逻辑门(AND)根据输入混淆值 (54642, 56178) 计算得到输出混淆值为 56208;第六个逻辑门(AND)根据输入混淆值 (80353, 74984) 计算得到输出混淆值为 14595;最后一个逻辑门(OR)根据输入混淆值 (14595, 56208) 计算得到输出混淆值为 35969,这也是一位最终结果,将被发送给 Alice,得到 C1 为 1。
最终 Bob 得到了计算结果为二进制 100,符合 A1A2+B1B2=C1S2S1。
这里的例子是双方计算一个两位加法器,在结果出来后减去各自的输入值就能够算出来对方的输入值。这是因为单纯的加法本身就是可逆计算的,而通常使用混淆电路计算的问题本身就不是可逆的,能够保证对方的输入隐私不被泄露。
小结
混淆电路是一种实现安全多方计算的关键技术,它能够有效保护参与方隐私,同时具备很强的灵活性。本文详细介绍了Yao’s 混淆电路基本原理和手动构建过程,并以计算两方二进制累加函数为例,展示了混淆电路在实际应用中的计算过程。
混淆电路的优势主要体现在以下两个方面:
- 隐私保护: 混淆电路可以有效保护参与方的隐私,计算过程中数据全部以混淆形式呈现,即使面对攻击也能保证数据安全。
- 灵活性: 与其他安全多方计算技术相比,只要函数可以转换为电路形式,混淆电路就能用于计算任意函数,展现很强的灵活性。
然而,混淆电路也存在一些不足之处:
- 计算效率:混淆电路的规模会影响计算效率。对于复杂函数,电路规模可能会变得庞大,导致计算效率下降。
- 计算成本:混淆电路的计算主要依赖加解密运算,而加解密运算成本较高,需要进一步优化。
- 协议依赖:混淆电路依赖不经意传输OT协议保护计算方输入隐私,该协议要求双方在线,OT协议实现是性能瓶颈之一。
在接下来的文章中我将对混淆电路的优化问题进一步对比分析,并探索混淆电路在更多实际场景中的应用。
参考
- 中国信通院,《安全多方计算技术与应用研究报告》
- Yao, Andrew Chi-Chih. 《How to Generate and Exchange Secrets》. 27th Annual Symposium on Foundations of Computer Science (Sfcs 1986), 162–67.
- Bellare, Mihir, Viet Tung Hoang和Phillip Rogaway. 《Foundations of Garbled Circuits》, 2012. Cryptology ePrint Archive.