五个同事决定计算他们的平均工资,在大家互相不告诉薪水的情况下,如何才能做到这一点?

论坛 期权论坛 期权     
爱的用户   2020-6-14 01:27   8862   10
由于提问者绑定了「数学」话题,可以合理推测问题有隐含条件:不借助第六人。
更进一步,应当要求所选择的方法有一定防止作弊和少数人串通的能力。
分享到 :
0 人收藏

10 个回复

倒序浏览
2#
热心小回应  16级独孤 | 2020-6-14 01:27:07
每个人把自己的工资随意拆成四个数的和,分别把四个数字告诉自己以外的四个人;每个人手里收到四个数字,加起来,报出;五个人的数字相加,即可得到五个人的总收入,除以5得到平均工资。
记得这是一个挺古老的解决方案?
———————————————————————————————————————————
5/23 19:40千赞留念。没想到昨天吃晚饭时随手回答的一个问题得到了这么多的赞同
有评论说我说的不够清楚,那可以这么再严格地叙述一下:
设这五个人的工资分别为
,第
个人告诉第
个人的数字为
,那么有
;
现在得到一个矩阵:

第二步就相当于计算每一列的和,然后第三步把它们加起来再除以五。总体上就是说矩阵所有元素的和等于各行和之和,也等于各列和之和。
总结一下评论区一些讨论:
  • 如果考虑剩余四个人抱团的情况,四个人可以采用同样的办法,在互相不告诉薪水的情况下得知四人的总薪水,从而得知第五人的薪水。
  • 每个人把工资分成五份,自己留一个数字只能让其余四个人不能直接把手里的关于他的数字相加得到他的薪水,对防御四人抱团的情况没有帮助。
  • 拆分的数字可以取负数,从而让其余人失去了薪水的一个下界的信息。
这个方法不是我原创的,应该是近几年在某一本书上看的,但是翻了翻没找到;也有可能是数学建模或者密码学课上老师提到过。
———————————————————————————————————————————
5/24 12:40 两千赞留念。因为这个回答关注我的各位……可能会比较失望?我在社区上主要回答魔方话题下的问题,以及给大佬们点赞……
3#
热心小回应  16级独孤 | 2020-6-14 01:27:08
哈哈这事儿我刚入职时干过。找个计算器,叫第一个人输入一个巨大的不规则的数,然后把自己的收入加上去,之后依次传给其他人,每人都把自己的收入加上之前的数。最后传回第一个人。

第一个人再把最后的总和减去Ta选中的那个不规则数,然后除以人数,即可得到大家的平均。

我的老板听说以后警告我们说:这么做是fireable offence,叫我们以后别再这么干了。
4#
热心小回应  16级独孤 | 2020-6-14 01:27:09
找一个计算器,把屏幕封起来,每个人输自己的工资,5个人都输完后,再把屏幕打开。
…………………………………………………………………………
这么简单的回答收到好多赞,十分惊讶
5#
热心小回应  16级独孤 | 2020-6-14 01:27:10
作为一个密码学学渣,这个问题引起了我极大的兴趣,想从相对专业一点的角度聊一聊。答案较长,分为以下几个部分:第一部分介绍一些基本概念和讨论的大前提,第二部分分析目前知友们提出的方案,第三部分基于一位知友的答案进行改进,第四部分讨论几何均值的情况,第五部分总结。
[h1]一、介绍[/h1]在一个有信息需要保密的过程中,我们应该如何考虑消息的安全性?主要分为两个方面:
第一是消息的保密性。也就是说,要尽量保证不该知道这个消息的人不能知道与消息相关的信息(注意是信息而非内容。内容是指完整地掌握所有的信息,而信息则是与之相关的东西,比如最后一个比特,二进制中 1 的个数等等。这些信息的泄露也是需要避免的)。
第二是消息的可靠性。也就是说,A 收到了 B 发出的消息,他应该有办法验证这条消息确实是 B 发出的,而不是中间人掉包后的消息。
在研究一个协议的安全性时,我们经常构造一个“游戏(game)”,游戏中有两方:敌手和挑战者。挑战者进行保密通信,而敌手则需要窃取秘密或破坏通信。根据不同的假设,我们给予敌手一些能力,同时对通信中消息的保密性和可靠性做一些要求。最后,我们考虑在面对有这种能力的敌手时,需要的保密性和可靠性是否能够达到要求。
具体到这个问题中,我们先讨论一些大前提,再讨论其他知友给出的方案的安全性,构造一些攻击,最后提出一个相对来说安全性较高的方案。为了一般性,我们直接讨论 n 个人的情况。
大前提1:所有的节点必须是诚实的。也就是说,每个人提供自己的工资信息时不能撒谎。
说明:这是一个很不现实但又必须做的假设。原因很简单:如果有且只有一个节点撒谎,那么他将获得其他四个人的平均工资,同时其他四个人不知道五个人的平均工资,且完全无法验证;如果有至少两个人撒谎,那么没有人可以同时知道所有人的平均工资。无论如何,整个协议将变得没有意义。
大前提2:最坏的情况下只有 n-2 个节点进行合谋,攻击其余两个节点。
因为如果 n-1 个节点攻击另外一个节点,无论如何都一定成功。(注: n-1 个节点如果可以合谋,可以在这 n-1 个节点不泄露自己工资的情况下得到剩下一个人的工资,这是一个递归的过程。简单起见,我们不允许这样的攻击。虽然 @Pegasus 的答案讨论了这样的攻击)
大前提3:他们只能靠互相交流信息来获得答案。
也就是说,没有一个可信第三方来帮助计算。这个要求否决了找会计等答案。
[h1]二、方案分析[/h1]下面我们分析一些知友提出的方案的安全性。
1. 扑克牌/麻将/大富翁钞票
在这些知友的方案中,每个人通过扑克牌等将自己的工资信息拆分,之后混在一起加起来求平均。由于这些牌是扣起来混合的,因此不可能知道其他人的工资。
分析:这个方法在大多数情况下可以保证自己的工资不被其他人所知,但一定会有信息泄露。比如说我们用红桃代表千位,你看到翻开后的牌里有一个红桃九,而你自己的工资只有一千多,矛盾是不是就产生了?但是如果是理想情况,你只能知道最后的平均工资,而不能知道每一个人工资的任何信息。
由于这个方案泄露了大家工资的信息,因此不可靠。
2.第一个人加上一个随机数,最后减掉这个答案
这样的方式是符合最基本的安全要求的。也就是说,如果每个人都只知道自己的工资和传来的数字,没有人可以知道其他人的工资。
分析:这个方案几乎没有直接泄露的信息,但少数人合谋可以对某个人的工资数进行攻击。如果第一个人知道了第三个人收到的数字,他就可以知道第二个人的工资;2 号知道了 4 号收到的数字,就知道 3 号的工资……对于任意一个 n ,只需要知道前后的数字就可以算出一个人的工资,这个协议还是比较脆弱的。
3.每个人拆分自己的工资并发给其他人这个答案
在这种情况下,任意 n-2 个人合谋也只能得到其余两人的平均工资,无法获得更多的信息。这是目前最好的方案。
但是注意,这个方案我们进行了一些假设:每个人发给其他人的信息不会被这 n 个人之外的敌手窃听,也不会被篡改。但实际中并不是这样。我们的方案应该能防止这些事情的发生。
下面,我们提出这个问题中的敌手能力和安全性要求,并对方案 3 做出改进来满足我们提出的要求。
三、方案改进
现在我们假设这 n 个人不在一起,彼此之间只能通过计算机发送信息。而通信的信道是不可靠的,也就是说我们不能验证这条消息是不是对方发来的、没有被篡改过的,传输的信息也会被敌手得到。
而我们的要求包括两方面。第一,这 n 个人中即使有 n-2 个人合谋,也只能知道剩下 2 人的平均工资,不能获得更多的信息;第二,敌手即使可以获得所有的通信消息,也可以进行篡改。在这种情况下,敌手不能获得关于工资的任何信息,也不能篡改通信内容而不被发现。
在这里我们还要再做两点补充。第一是敌手的计算能力是有限的,这允许我们进行公钥加密和签名(这两个概念马上会具体介绍);第二是公开信息是可靠的,也就是说,我可以公开一个字符串作为我的一个“公钥”,这个公钥没有保密性,任何人都可以看到。而这种情况下这个字符串是无法伪造的,也就是所有人都可以确定我确实公开的是这段字符串。

下面我们分别介绍公钥加密和数字签名。在传输中的消息是会被敌手看到的,所以要对消息进行加密。但如果使用传统的加密方式,需要加密者和解密者拥有共同的密钥,在这种情况下是做不到的(不考虑密钥交换……这个过程还是用公钥思想实现的)。因此我们需要使用另一种加密方式:加密密钥是公开的,每个人都可以看到并使用;但解密密钥是保密的,只有消息的接受者持有。这样,当 Alice 想给 Bob 发送一条保密消息时,他只需要使用 Bob 的公钥对消息进行加密再发给 Bob ,Bob 使用解密密钥进行解密即可。
这种加密方式需要一个困难问题,大家把困难问题理解为一个敌手和挑战者都无法进行的计算问题即可。比如说离散对数问题:在一个群 G 中,
,给出群 G 和
的值,求
。这里的对数和我们之前讨论的不同,是在群中的。实数中的对数是容易计算的,而一般情况下,群里的离散对数是难以计算的。
另外,我们还要做一个假设(CDH 假设):在群 G 中,给出
,计算
是困难的。
这样,我们就可以构造一个公钥加密体制,也就是著名的 ELGamal :
1.Bob 找一个群(比如
)和一个生成元
,私钥为
,公开
,保密
.2.Alice 先随机选择一个数
,然后分别计算

,将其发送给 Bob.3.Bob 计算
,可以验证其等于
,解密成功。(这里的描述不是很严谨,大家理解意思即可)
下面我们介绍数字签名。在现实生活中,我们经常需要对文件进行签名,证明我们已经阅读并认可该文件。类似地,在数字世界中,我们也需要对文件进行签名。签名可以防止信息的伪造:因为我们提到了,每个人可以公开一个字符串,这个字符串是可靠的,所有人都可以验证它属于你。类比公钥,你把一个消息用你的私钥进行处理,得到的值任何人都可以用你的公钥进行验证,这就达到了目的。
类似地,ELGamal 同样可以进行签名的构造。比如 Alice 要对消息 m 进行签名:
sAlice 随机选择 k 计算

dsis
Bob 验证
(公式显示不出来的话可自行搜索相关内容)
其实具体的方法不重要,大家只要知道有一种方法,可以验证一条消息是不是由某个人发送的就行了。

好了,下面我们完整地过一遍:
1.每个人的工资分别记为
2.每个人将工资随机地分解为 n 个数之和,记为
等等
3.每个人在自己分解的 n 个数随机排序,将第
个数用第
个人的公钥加密(如果是给自己的则省略),用自己的私钥对加密后的消息进行签名,然后将消息与加密结果一起发送给第
个人
4.每个人验证签名后用自的私钥解密其余 n-1 条消息,将其与自己留下的一个数共 n 个数求和
5.把求和结果用其余 n-1 个人的公钥分别加密,并对结果签名,将加密后的消息与对应的签名发送给对应的人
6.每个人验证签名后解密所有消息,计算平均值即可

四、几何均值
在第三部分最后,我们已经给出了所有人算术平均值的方案,可以证明在加密算法和签名算法安全的情况下,这种方案也是足够安全的。下面我们讨论求几何均值的情况。
如果用类似的方法,我们需要把每个数分解为若干个数的乘积,这是很难做到的。一方面,对整数进行素因子分解本身就不是一件容易的事情;另一方面,有些整数没有足够的素因子,将 1 作为因数之一并不是一个好办法。
看来只有另寻出路了。注意到 ELGamal 加密算法中的消息是作为一个因子的,这给了我们一个提示。构造这样的算法:
1. 其中任何一个人公开一个群
和一个生成元
,每个人选取一个私钥
和一个随机数
,公开所有
2. 第一个人计算
,传给第二个人
3.第二个人计算
,以此类推,直到第
个人计算完毕,将结果
交给第一个人
4.第一个人计算
,交给第二个人
5.第二个人计算
,交给第三个人,以此类推,直到第
个人计算完毕。公布结果,即为所有人工资的乘积
6.别忘了这里的乘积是对
取模的,因此要得到最终答案还需要一点数学技巧:选取
个不同的大素数
,重复上述过程,我们就得到了
个数的乘积对不同的
取模的值。用中国剩余定理,我们可以算出这个乘积对所有的
乘积的模值。注意到后者大于前者,因此取模并不影响,该数字就是这
个数的乘积,开
次方即为答案。
关于可靠性只需要再加一个签名即可,不再赘述。

五、总结
这个看起来很简单的问题,深究起来竟然涉及如此多的密码学知识,连我都有些惊讶。这也是我们思考问题的方式:假设每个环节都有泄密或被篡改的可能,然后逐个去排除,让协议更加安全可靠。
第二部分第三个方案是一个很不错的方案,不仅泄露的信息最少,而且很容易类比到任意人数的情况。因此很容易想到在此基础上进行修正。而第四部分纯粹是我突然想到的,画蛇添足了。
事实上,问题本身是一个最简单的安全多方计算问题,有兴趣的朋友可以顺着这个关键词查阅相关的资料。
最后我想说,密码学真的很好玩~
6#
热心小回应  16级独孤 | 2020-6-14 01:27:11
看了下目前的回答,有两类方案,一类是 @消失的苦猫 的传递数据时加随机数最后再减掉,另一类是 @呜呼啦呼 的拆数方法,这两种方案对于原命题来说都是有效的解。
现在更有趣的问题(加强版问题)是:是否存在不借助机器或第六个人帮助且满足任意四人在不泄露自己工资的情况下不能合作得出另一个人工资的方案?并尝试对人数为任意大于等于2的正整数的情况考虑这个问题。

人数为N时的方案记为P[N]。
首先P[2]显然不存在,P[3]用方案一、二都可以(因为如果算出了第三个人的工资,那么这两个人也就知道了对方的工资,也就是泄露了自己的工资),N=3时修改后的命题与原命题等价。
考虑P[4],假设存在,则任意三人P[3]不存在(见注),这导出矛盾,那么P[4]不存在。
考虑P[5],在原问题基础上需要额外满足任意四人在不泄露自己工资的情况下不能合作得出另一个人工资,这至少需要P[4]不存在(满足),但这只是一个必要条件,这N个人手中还有P[5]进行时产生的部分数据,所以还有可能有其他的方法求出另一个人的工资,所以P[5]不一定存在。
这样归纳下去可以得出,P[3]存在,P[4]不存在,N为大于等于5的奇数时,P[N]不一定存在,如果存在那么P[N+1]不存在。

注:当N个人合作试图求出另外一个人的工资时他们有两种途径,一种是用已经进行过的方案留下的信息,另一种是在这N个人中用方案P[N],求出N人工资总和,用N+1人的工资和减就得出另外一个人的工资了。

*******************
我对条件的修改是基于两个假设
1.所有人都绝对不想让别人知道自己的工资
2.所有人都极其想知道别人的工资
并且首先满足1
对解的要求是不借助其他人或机器
(在现实中当然可以进行某些额外的给定类型的操作,比如n-1人合作时额外用p算n-1个人总工资的情况,而且并不是所有的pn都是有解的,所以我的考虑不是平凡的。其实本来想搞个递推,做出来类似奇数人都有解,偶数人都无解的结果,但没做到。感觉还可能继续探讨,看看有没有大神构造出P[5]吧。)
********************
(*接下来的讨论更细致,而且和上面的讨论不太一样。*)

其实还可以接着往下想,有没有发现我这两个假设很像一些常见的“博弈”问题,比如海盗分金,先求保命再求多金。那么在这个意义上会发生些什么?让我们再加一个假设,让它更像一个博弈问题。
3.假设所有人都足够聪明。
讨论:对于人数为N的情况,我们已经有了不止一种当且仅当N-1人合作时才能求出另外一人工资的方法,那么按我们之前的分析,N-1人合作算另一个人工资的情况总会发生,这样N会越来越小,直到N=3,一定会停止这种八卦行为,否则自己的工资就会暴露。
但是否一定会进行到N=3的程度呢?
其实一定不会,因为对于那N-4个伙同三人算计第N个人工资的人,他们最终也被其他人合伙算计了,这是他们不愿意看到的(违背假设1),而避免这种情况发生只需要他们不参与计算第N个人的工资,换句话说,就是只要有两人坚定立场,不参与计算别人工资的行为,就一定可以保证他们的工资不被别人猜出,否则,他们很可能被别人以同样的方式“背叛”,而暴露工资。考虑N=4时的情况,所有人都在担心另三个人合起伙来算他的工资,此时的最优策略就是和另一个人结盟(形成联盟),约定绝不参与和其他人合伙算计对方的行为,这样可以绝对地避免自己工资泄露,而当有第三个人愿意加入联盟时就可以合伙算出第四个人的工资了。N更大时情况略有不同,首先所有人都会立刻找别人构成二人联盟,接下来最重要的问题是联盟合并问题,是否所有的联盟都愿意和其他联盟合并或者吸纳新人?如果为了满足假设2,当然希望自己的联盟越大越好,当达到N-1人时就可以合伙算出另一个人的工资了,称这N-1人的联盟为极大联盟,但风险在于,这件事的完成宣告了联盟的瓦解(变成了一个N-1人的问题,所有人在同一个联盟里,等同于没有联盟),所有人都必须重新建立联盟,如果我们假设
4.合并前的联盟比合并后的联盟更牢固(联盟之间具有层次关系,在更大的下层联盟瓦解后,更牢靠的上层联盟自然成立)
5.没有背叛自己的联盟投靠他人联盟的背叛者
那么除非极大联盟是由N-2人联盟加入一个新人形成的,这个八卦行为就会因为无法构成极大联盟而停止。
这个“除非”说明所有未结盟的人都更愿意组成新联盟(二人联盟)而非加入已有联盟。(否则可能在极大联盟瓦解后成为落单者)以及联盟合并也是非常欢迎的(因为只要我的二人联盟不瓦解,我的工资就不会泄露,我当然希望能尽量形成极大联盟)。
有了这个结论,看似复杂的结盟、联盟合并与加入新人的多种选择会呈现一个有序的发生情况,就是当总人数为偶数人时,所有的人都会找到他的二人联盟伙伴,所以,不会形成极大联盟,也就不用担心有人被别人合伙计算工资。当总人数为奇数时,那么一定有一个人形成不了二人联盟,而显然所有的二人联盟都会选择形成极大联盟而拒绝加入这个落单者,那么如果P[N]不存在,这个落单者的工资一定会被泄露,并且在计算出落单者工资后,八卦行为就会终止。

这个结论说明在承认五个假设的前提下,在总人数为偶数人时,任意原问题的解都是加强版问题的解,而人数(N)为奇数人时如果P[N]不存在,一定有且只有一个人被其他人合伙算出工资。
7#
热心小回应  16级独孤 | 2020-6-14 01:27:12
一个简单的做法就是A想一个随机数,加上自己的工资发给B,然后B再加上自己的工资,发给C,以此类推,直到E把算出来的数发给A。A用收到的数减去自己的随机数,就能得到工资总和。而其他人如果不做额外的通信的话,也是得不到别人的工资信息的。
8#
热心小回应  16级独孤 | 2020-6-14 01:27:13
每个人把自己工资分成三个以上数的和。比如5000元,可以是2000+2000+1000,也可以是4000+100+100+100+100+100……
出于不愿意让别人知道的考虑,一般不会有人写4998+1+1……
然后同样的纸条,打印,扔到一个盒子里。再把盒子里的总数除以5。
9#
热心小回应  16级独孤 | 2020-6-14 01:27:14
如果要想保护每个人的工资隐私,不被其他人知道,可以用密码学的方法。楼上 @metaseq 提到的全同态加密方案是一种方法。但是题主的这个问题还不需要全同态这个这么强大的工具。题主只是想要计算平均工资,其实等价于计算这五个人工资的总和。这样的话,我们只需要加法同态的加密方案就可以了。现今广用的加法同态加密方案是Paillier 加密方案。但是我们在使用Paillier 方案之前,还需要一个小小的处理,就是将解密密钥分成五份,每个人保存其中一份。这种方案也就是threshold version of Paillier encryption。
相关文章链接A Generalisation, a Simpli.cation and Some Applications of Paillier's Probabilistic Public-Key System 以及Sharing Decryption in the Context of Voting or Lotteries
有了这种方案其实就很容易构造出题主想要的protocol了,这里就省略掉了。

其实题主这个问题就是密码学里一个非常常见的研究问题:multi-party computation 。这类问题当今主要的解决技术有三种,一个是Yao提出的Garbled Circuit,一个是Shamir 提出的secret sharing,还有一种就是使用Homomorphic Encryption。第三种技术构造的multi-party computation protocol一般比较直观,容易理解。
10#
热心小回应  16级独孤 | 2020-6-14 01:27:15
工具:计算器、纸、笔

第一步:每人先拿一张纸,在上面写上自己的工资,然后写上一个自己随机想到的加密代码。

A工资1000 加密代码 11 加密工资 1011
B工资1500 加密代码 9 加密工资 1509
C工资1200 加密代码 33 加密工资 1233
D工资900 加密代码 27 加密工资927
E工资1234 加密代码 12 加密工资 1246

第二步:ABCDE依次输入自己的加密工资,并相加,得到加密工资总和。

第三步:ABCDE依次减去自己的加密代码,得到纯净的总工资。

第四步:除以5,得到平均值。

由于他们互相之间并不知道原始工资以及加密代码,所以即使从“加密总和”之中减去加密代码,互相之间也不知道原始工资的具体数字。
11#
热心小回应  16级独孤 | 2020-6-14 01:27:16
简单,搓一桌麻将,万为千,筒为百,条为十,各自选好后,背面朝上出牌,再搓掉,最后总数相加。
扑克以花色区分,也可达到类似效果。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:342608
帖子:68643
精华:1
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP