首发于The Wretched
半诚实模型下的姚式混淆电路协议

半诚实模型下的姚式混淆电路协议

最近在学习MPC下的Yao's protocol双方安全计算协议。这篇博客主要记录下自己对Yao's protocol for semi-honest adversary的学习。

博客内容基于:

《Efficient Secure Two Party-Protocols》——Carmit Hazay and Yehuda Lindell
Mike Rosulek 的讲座:【密码学学术讲座】Mike Rosulek教授开讲安全多方计算_哔哩哔哩_bilibili

有关多方安全计算(MPC)

MPC简单来说,就是一堆人想要用自己和别人手上的隐私数据来计算一些东西(比如一个函数),但每一个人都不想让其他人知道自己的隐私数据是什么。

而双方安全(2PC),便是MPC的特殊情况。如下图,其中只有两个人(Alice and Bob)想用自己的隐私数据(x)和对方的隐私数据(y)一起计算一个函数f,同时不想让对方知道自己的数据输入。

半诚实敌手(semi-honest adversary)

依然在双方安全的语境下(后文不特别指出都做此假设),如果有其中一方被腐坏(corrupted),此处假设是y方。在遵守协议的前提下,y会希望能获取到x的输入。这样的一方被称为半诚实敌手。

注意,这样的一方很想获取到对方的输入,但一定会遵守双方的计算协议。

生成混淆电路(garbled circuit)

首先我们设想,对于一个函数,我们能不能用“不真实”的输入,得到真实的结果?

我们可否建立一个这样的映射,对于我们的每个输入,与其使用真实输入参与函数计算,我们为每个输入构造一个“替身”,让这个替身为其完成计算的任务。

想象有天晚上你在酒吧里和朋友喝酒,见到吧台边有一个漂亮的女生,你很想要她的微信。但你是个很害羞的人,于是让你的朋友代你去向那个女生要微信。你的朋友答应了,去向那个女生要了微信,回来给你。于是你在那个女生不知道你是男是女,长什么样的前提下,获取到了她的微信。在这个例子中,我们可以把向女生要微信的过程看成一个要计算的函数,而“你”则是这个函数的真实输入,你的朋友则作为你的“替身”,代替你去完成了要微信的过程,得到了女生的微信——函数的计算结果。

若我们可以为函数构造出类似的计算过程,那么在不暴露我们真实输入的前提下,我们确实可以计算函数,得到真实的结果。

下面我们就来介绍姚期智院士在1986年提出的混淆电路是如何解决这个问题的。

我们知道,任何函数都可以被表示为一个门电路,计算一个函数其实就是计算一个门电路,得到电路输出的过程。一个门电路是由许多个门组成的,我们这里先用只由一个门组成的电路来解释混淆电路的原理。

比如有一个计算两个1 bit数a,b模2加法的函数 f(a,b) ,则我们可以用下面的电路来表示。

函数f对应的电路

这个电路很简单,只有一个异或门,给电路提供两个输入a和b,其输出一个结果c。

下面,我们来基于这个电路(其实只有一个门),来构造一个混淆电路。

首先我们列出这个门的真值表

abc
000
011
101
110

可以看出,电路中有三条线(两条输入线a、b,一条输出线c),我们将其标为 w_1、w_2、w_3

每条线上可能会存在两种逻辑值——0和1,我们想隐藏每条线上真实的逻辑值(不想让别人知道现在是0还是1在这条线上),可以通过以下的步骤来实现。

  1. 首先,为电路中所有线路分配两个分别代表逻辑值0和1的密钥。记一条线路为 w_i ,则为其分配两个密钥记为 k_i^b, b\in \{0,1\} 。b为0则此密钥代表的逻辑值为0,为1则代表的逻辑值为1。
    回到上面那个例子,电路中只有三条线路,则对线路w_1,其有密钥 k_1^0k_1^1 ;对线路 w_2 ,其有密钥 k_2^0k_2^1 ;对线路 w_3 ,其有密钥 k_3^0k_3^1 。(这里提一下,因为 w_3 为输出线路,所以不一定要为其生成密钥,但这里暂时与其他线路保持一致,具体原因后面解释)。
  2. 对电路中的每个门,我们使用上述密钥和门的真值表,对门的输出进行加密。
    我们直接通过上述例子来理解加密步骤。例子中,我们的电路只有一个门,所以只需要对这个门进行加密。我们将上面真值表的a,b,c 换为 w1,w2,w3,以表示这个门对应的三条线路,其中w3为输出线路,我们对其进行加密。


对真值表的每一行,我们将输入线w1和w2的逻辑值替换成对应的密钥值。

用w1和w2的密钥值,对w3的逻辑值对应的密钥值进行加密,将w3替换为该加密值。

如第一行,w1上的0替换为 k_1^0 ,w2上的0替换为 k_2^0 ,w3上的0替换为 k_3^0 后,用k_1^0k_2^0

通过加密算法 Enc 加密得到 Enc_{k_1^0,k_2^0}(k_3^0)

其他三行也是如此操作。最后生成的表如下图的右表格。

​3. 然后,我们将表中的行进行随机置换,打乱原来行的排布。这步非常关键,因为这样一来,行的位置便不包含任何信息。(若不打乱,则我们能知道表的每一行的加密值是由哪两个逻辑值加密而来的)。这一步称为混淆(garbled)。下图的右表格即为混淆后的表。

​​​​4. 最后,取出上表的第三列,得到这个电路最终的混淆表。注意,其实这只是一个门的混淆表,但因为我们这个电路中只有这一个门,所以便也是这个电路的混淆表。若电路中不只有一个门,我们要为电路中的所有门都构造一个不同的混淆表,所有门的混淆表组合而成的才是整个电路的混淆表。

最终的混淆表

注意,因为我们是构造此混淆电路的人,所以我们知道上表的含义(每行的密文代表的是什么输出)。但对于单纯只是拿到此表的人(未参与GC构造的人),对此表每行所代表的信息是一脸懵逼的。

若加密后的输出是7位十进制,外人看起来就是这种感觉

最后,因为我们要为电路的输出提供一个映射表。在这个例子中,w3的输出即为电路的输出。因为w3输出的v仍是密钥值,我们需要提供将其转化为真实值的映射

至此,我们的混淆电路——一个原始电路与电路的混淆表,就构造完毕了。那么我们该怎么来计算混淆电路呢?

计算混淆电路

若我们要计算原始电路,我们需要为电路的每条输入线提供真实的逻辑值0或1,才能得到真实的结果。但现在在混淆电路中,我们要为电路提供的不是真实的逻辑值,而是每条输入线上逻辑值所对应的密钥值!

我们用我们刚刚为计算函数 f 构造的混淆电路(一个异或门与它的混淆表)来解释。为方便展示,左表是未混淆前的表格。

f的电路

此时为了方便理解,我将电路混淆表的符号转化为具体的数字。

w1上的逻辑值0和1分别对应密钥1111和2222;w2上的逻辑值0和1分别对应密钥3333和6666;w3上的逻辑值0和1分别对应密钥10000和20000。而加密算法就是简单的将输入线的值与输出线的值相加。

(注意,真实情况的密钥是随机选取,加密算法也不可能如此retarded,此处是为了简化)

现在,我们将上表混淆(行打乱)后,提取出第三列。

最后,我们定义了输出密文与真实值的映射。有了以下信息,我们就能完成计算。

现在假设输入 a=1111 , b=6666 ,此时a和b是真实输入的密钥值。我们想知道输出 c 是什么。

现在我们有混淆表,而表中的值就是电路输出的密文,我们得通过解密才能还原我们对应输入的真实值。我们知道加密算法是 a+b+c ,则我们可以解密还原出真实值。那么表中的哪个值才是我们应该解密的值呢?很简单,我们遍历表中的四个值进行解密计算,若计算出的值没有意义,则不是我们要的值。

对表中的第一行, 27777-1111-6666=20000 ,对照输出映射表,即对应真实值1,于是我们得到了电路的输出为1。

这里有个点需要特别注意:我们构造混淆电路的加密算法保证混淆表中不会(以很小概率)出现能解密出两个有意义的值的情况!

至此,我们完成了电路的计算,而且我们并没有输入a和b的真实值!

基于半诚实模型的姚式协议(Yao's protocol for semi-honest adversary)

现在,我们可以非形式化的定义姚式协议,基于半诚实模型的2PC协议。

现在假设Alice和Bob想基于姚式协议共同计算一个函数 f(x,y) ,其中 x 是Alice对函数的输入, y 是Bob对函数的输入。协议可以简单的分为三步:

  1. Alice先构造一个计算函数 f 的电路,然后加电路加密混淆,构造出计算函数 f 的混淆电路 C (包括原始电路与混淆表)。假设电路总共有n条输入线,其中i条为Alice的输入,另外n-i条则是Bob的输入。
  2. Alice将电路 C ,以及Alice的电路输入对应的密钥 (k_1^b,k_2^b,...,k_i^b),b \in \{0,1\} 发送给Bob。同时,Alice和Bob运用一种叫不经意传输(Oblivious Transfer)的技术,使得Bob从Alice处获取到电路有关Bob输入对应的密钥(k_{i+1}^b,k_{i+2}^b,...,k_n^b),b \in \{0,1\},并且Alice不知道每个密钥对应的b等于0还是1(即Alice不知道Bob要用的是对应逻辑值0的密钥还是逻辑值1的密钥)。所以Alice并不知道Bob的输入。
  3. Bob将自己的输入密钥和Alice的输入密钥输入进电路 C 中,并得到最终计算结果。因为电路是Alice构造的,所以Bob不知道Alice的输入密钥所对应的逻辑值是什么。所以Bob并不知道Alice的输入。

剩下的问题

在上面的描述中,其实忽略了一些问题没有解决。

A.在加密电路中门的真值表时,我们应该用怎样的加密算法,在保证安全性的同时,满足以下两个条件:

1. 在解密混淆表时,不会出现一对密钥能将多于一个密文解密成有意义的明文。如上面的例子,如果给定我们两个输入密钥a,b,我们遍历混淆表解密时,应该只有一个值是能被正确解密出有意义的门输出的,而其他值是没有意义的。不然我们不知道该用哪个作为门输出继续计算。

2. 同时,我们在遍历混淆表时,需要能高效的辨别这个值是不是能被正确解密的,若不能则跳过。


B. 什么是不经意传输,我们该怎么实现不经意传输?

后文将会解答这两个问题。

发布于 2021-07-26 16:56