五個同事決定計算他們的平均工資,在大家互相不告訴薪水的情況下,如何才能做到這一點?
由於提問者綁定了「數學」話題,可以合理推測問題有隱含條件:不藉助第六人。
更進一步,應當要求所選擇的方法有一定防止作弊和少數人串通的能力。
每個人把自己的工資隨意拆成四個數的和,分別把四個數字告訴自己以外的四個人;
每個人手裡收到四個數字,加起來,報出;
五個人的數字相加,即可得到五個人的總收入,除以5得到平均工資。
記得這是一個挺古老的解決方案?
———————————————————————————————————————————
5/23 19:40千贊留念。沒想到昨天吃晚飯時隨手回答的一個問題得到了這麼多的贊同
有評論說我說的不夠清楚,那可以這麼再嚴格地敘述一下:
設這五個人的工資分別為 ,第 個人告訴第 個人的數字為 ,那麼有 ;
現在得到一個矩陣:
第二步就相當於計算每一列的和,然後第三步把它們加起來再除以五。總體上就是說矩陣所有元素的和等於各行和之和,也等於各列和之和。
總結一下評論區一些討論:
- 如果考慮剩餘四個人抱團的情況,四個人可以採用同樣的辦法,在互相不告訴薪水的情況下得知四人的總薪水,從而得知第五人的薪水。
- 每個人把工資分成五份,自己留一個數字只能讓其餘四個人不能直接把手裡的關於他的數字相加得到他的薪水,對防禦四人抱團的情況沒有幫助。
- 拆分的數字可以取負數,從而讓其餘人失去了薪水的一個下界的信息。
這個方法不是我原創的,應該是近幾年在某一本書上看的,但是翻了翻沒找到;也有可能是數學建模或者密碼學課上老師提到過。
———————————————————————————————————————————
5/24 12:40 兩千贊留念。因為這個回答關注我的各位……可能會比較失望?我在知乎上主要回答魔方話題下的問題,以及給大佬們點贊……
哈哈這事兒我剛入職時干過。找個計算器,叫第一個人輸入一個巨大的不規則的數,然後把自己的收入加上去,之後依次傳給其他人,每人都把自己的收入加上之前的數。最後傳回第一個人。
第一個人再把最後的總和減去Ta選中的那個不規則數,然後除以人數,即可得到大家的平均。
我的老闆聽說以後警告我們說:這麼做是fireable offence,叫我們以後別再這麼幹了。
看了下目前的回答,有兩類方案,一類是 @消失的苦貓 的傳遞數據時加隨機數最後再減掉,另一類是 @嗚呼啦呼 的拆數方法,這兩種方案對於原命題來說都是有效的解。
現在更有趣的問題(加強版問題)是:是否存在不藉助機器或第六個人幫助且滿足任意四人在不泄露自己工資的情況下不能合作得出另一個人工資的方案?並嘗試對人數為任意大於等於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]不存在,一定有且只有一個人被其他人合夥算出工資。
找一個計算器,把屏幕封起來,每個人輸自己的工資,5個人都輸完後,再把屏幕打開。
…………………………………………………………………………
這麼簡單的回答收到好多贊,十分驚訝
作為一個密碼學學渣,這個問題引起了我極大的興趣,想從相對專業一點的角度聊一聊。答案較長,分為以下幾個部分:第一部分介紹一些基本概念和討論的大前提,第二部分分析目前知友們提出的方案,第三部分基於一位知友的答案進行改進,第四部分討論幾何均值的情況,第五部分總結。
一、介紹
在一個有信息需要保密的過程中,我們應該如何考慮消息的安全性?主要分為兩個方面:
第一是消息的保密性。也就是說,要盡量保證不該知道這個消息的人不能知道與消息相關的信息(注意是信息而非內容。內容是指完整地掌握所有的信息,而信息則是與之相關的東西,比如最後一個比特,二進位中 1 的個數等等。這些信息的泄露也是需要避免的)。
第二是消息的可靠性。也就是說,A 收到了 B 發出的消息,他應該有辦法驗證這條消息確實是 B 發出的,而不是中間人掉包後的消息。
在研究一個協議的安全性時,我們經常構造一個「遊戲(game)」,遊戲中有兩方:敵手和挑戰者。挑戰者進行保密通信,而敵手則需要竊取秘密或破壞通信。根據不同的假設,我們給予敵手一些能力,同時對通信中消息的保密性和可靠性做一些要求。最後,我們考慮在面對有這種能力的敵手時,需要的保密性和可靠性是否能夠達到要求。
具體到這個問題中,我們先討論一些大前提,再討論其他知友給出的方案的安全性,構造一些攻擊,最後提出一個相對來說安全性較高的方案。為了一般性,我們直接討論 n 個人的情況。
大前提1:所有的節點必須是誠實的。也就是說,每個人提供自己的工資信息時不能撒謊。
說明:這是一個很不現實但又必須做的假設。原因很簡單:如果有且只有一個節點撒謊,那麼他將獲得其他四個人的平均工資,同時其他四個人不知道五個人的平均工資,且完全無法驗證;如果有至少兩個人撒謊,那麼沒有人可以同時知道所有人的平均工資。無論如何,整個協議將變得沒有意義。
大前提2:最壞的情況下只有 n-2 個節點進行合謀,攻擊其餘兩個節點。
因為如果 n-1 個節點攻擊另外一個節點,無論如何都一定成功。(註: n-1 個節點如果可以合謀,可以在這 n-1 個節點不泄露自己工資的情況下得到剩下一個人的工資,這是一個遞歸的過程。簡單起見,我們不允許這樣的攻擊。雖然 @Pegasus 的答案討論了這樣的攻擊)
大前提3:他們只能靠互相交流信息來獲得答案。
也就是說,沒有一個可信第三方來幫助計算。這個要求否決了找會計等答案。
二、方案分析
下面我們分析一些知友提出的方案的安全性。
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.別忘了這裡的乘積是對 取模的,因此要得到最終答案還需要一點數學技巧:選取 個不同的大素數 ,重複上述過程,我們就得到了 個數的乘積對不同的 取模的值。用中國剩餘定理,我們可以算出這個乘積對所有的 乘積的模值。注意到後者大於前者,因此取模並不影響,該數字就是這 個數的乘積,開 次方即為答案。
關於可靠性只需要再加一個簽名即可,不再贅述。
五、總結
這個看起來很簡單的問題,深究起來竟然涉及如此多的密碼學知識,連我都有些驚訝。這也是我們思考問題的方式:假設每個環節都有泄密或被篡改的可能,然後逐個去排除,讓協議更加安全可靠。
第二部分第三個方案是一個很不錯的方案,不僅泄露的信息最少,而且很容易類比到任意人數的情況。因此很容易想到在此基礎上進行修正。而第四部分純粹是我突然想到的,畫蛇添足了。
事實上,問題本身是一個最簡單的安全多方計算問題,有興趣的朋友可以順著這個關鍵詞查閱相關的資料。
最後我想說,密碼學真的很好玩~
工具:計算器、紙、筆
第一步:每人先拿一張紙,在上面寫上自己的工資,然後寫上一個自己隨機想到的加密代碼。
A工資1000 加密代碼 11 加密工資 1011
B工資1500 加密代碼 9 加密工資 1509
C工資1200 加密代碼 33 加密工資 1233
D工資900 加密代碼 27 加密工資927
E工資1234 加密代碼 12 加密工資 1246
第二步:ABCDE依次輸入自己的加密工資,並相加,得到加密工資總和。
第三步:ABCDE依次減去自己的加密代碼,得到純凈的總工資。
第四步:除以5,得到平均值。
由於他們互相之間並不知道原始工資以及加密代碼,所以即使從「加密總和」之中減去加密代碼,互相之間也不知道原始工資的具體數字。一個簡單的做法就是A想一個隨機數,加上自己的工資發給B,然後B再加上自己的工資,發給C,以此類推,直到E把算出來的數發給A。A用收到的數減去自己的隨機數,就能得到工資總和。而其他人如果不做額外的通信的話,也是得不到別人的工資信息的。
說明一下,題目設置五人互不能知道工資的要求可以說就是要絕對保護隱私,即通過答案不能得出任何一人的工資。
所以之前那些回答之所以會被指出四人抱團情況是指這個回答有漏洞,在互不知道工資的情況下依舊可以推斷出其中一個人的工資。
評論里所提到的方法如四人串通就可以互相通報等是不符題意的,不然五人隨機報團推算剩餘一人,還不如直說,這個題目根本沒有意義。
還有就是提到的可以用同樣的方法求四人的工資平均值,以此推算第五人,這種方法同樣可以三人報團,導致四人中有一人工資被暴露,以此類推,所以如果你是那五人之一,絕不會同意此方案,因此根本行不通。
。。。。。。。。。。。。。。。。。。。。
原回答
看了一下回答,被質疑最多的就是如何防止報團的問題,即方案如何只能在五個人中可行而四人及其以下則不可行的問題
有一位答主提到過的一個挺老的方法,將工資拆分為四個數,告訴其他四個人,最後每人報出手裡的四個數之和,再相加計算平均數,這個解法其實將工資拆分成2--5個數都行得通,不一定為4,而如果要去除報團因素,那麼其實拆為五份才是最優解。
這裡要加一個條件,就是每人將工資值分為五份後,寫在同樣的紙上,各自均是通過抓鬮的方式抽取一份數值,這樣抽到的數值都是隨機的,就算是有四個人想要抱團,也無法區分數值是屬於誰,而他們如果互相通報,則是他們四個人的工資數額也都能得出,不可行和 @劉天任 討論後發現下面這個做法應該可以通過三人合謀拆掉。大家就別贊了,留這當一個踩過的坑好了……
===================
五個人坐成一圈,每人拿一張紙。
每個人首先傳給下家k+1個數,其中一個是自己的真實工資,另外k個都是假數。下家再寫上k個假數。如此這麼傳五次,每人手上的紙上都寫了5k+1個數字。分別是自己的真實工資和桌上五個人各自報的k個假數字。
大家把每人手裡數字的和報出來,加到一塊,這樣就得到了5個真數和25k個假數的和。
每個人再把自己五輪裡面寫上的5k個假數的和報出來,從前面的和里減掉,就剩下了5個真數的和。
只要k&>=1就能成立,不過好像是第一個人加隨機數方法的變種。
假設存在一種方法使五個人在不被別人知道自己工資的情況下算出平均工資
那麼同樣的方法可以套用在四個人上,算出四個人平均工資
只要四個人抱團,用同樣方法就可以算出剩下一人的工資
簡單,搓一桌麻將,萬為千,筒為百,條為十,各自選好後,背面朝上出牌,再搓掉,最後總數相加。
撲克以花色區分,也可達到類似效果。
最簡單的辦法:拿個黑箱子,弄一大把珠子,每人掙多少錢就往裡放多少顆珠子,最後數。簡單安全有效,就是累點……
之所以使用一塊錢一個珠子,而不是用多種面值的珠子的方法,是考慮到條件概率。首先,假設每人都寫自己的工資進去,那所有人都可以知道別人的工資了(雖然對不上號);其次,任何一個人如果像高票那樣把工資分成幾個數告訴別人,那麼所有人都可以(1)知道其他人的工資不會小於他告訴自己的數,(2)對其他人的工資做估計(乘以4),所以告訴別人的數額和自己的實際工資並不是條件獨立的;第三,同理,假如使用帶面值的道具,那麼就至少有一個人擁有比出現的最大面值更多的工資,考慮到一個10000和四個100這種情況,這樣的策略也是有問題的。所以說,將信息的粒度變到最小才最可以降低條件概率帶來的影響。
每個人把自己工資分成三個以上數的和。比如5000元,可以是2000+2000+1000,也可以是4000+100+100+100+100+100……
出於不願意讓別人知道的考慮,一般不會有人寫4998+1+1……
然後同樣的紙條,列印,扔到一個盒子里。再把盒子里的總數除以5。
很好的問題,如何對數據脫敏,同時得到有效的運算結果。
這個問題其實有一個更廣義的情況,就是一共有n個數,能否加密後對他們進行四則運算,獲得他們的最終運算結果,卻過程中不暴露n個數本身的數值。
廣義的情況的終極解決辦法就是同態加密(Homomorphic encryption),2009年Marten van Dijk、Craig Gentry 、Shai Halevi、Vinod Vaikuntanathan的論文《Fully Homomorphic encryption over the Integers》實現了對整型的全同態加密,既加密後的整型在四則運算可以解密後得到真實的數值。後人優化的二代演算法,github上shaih/HElib 這開源的庫直接就能使用。
以同事的這個為舉例,有四個工資數值a,b,c,d,和一個同態加密演算法F和其對應的解密演算法f。那麼最終的平均值為f(F(a)+F(b)+F(c)+F(d))/4
以另外一個例子舉例,有四個人分別知道且知道一個電商網站的流量,付費轉化率,客單價和每月經營成本a,b,c,d。那麼最終電商網站的利潤就是f(F(a)*F(b)*F(c)-F(d))
這件事情的巨大價值在於,很多敏感的數據也可以開始放到第三方的雲平台去進行計算了,反正平台做了一堆加減法乘除法,卻依然不知道數值對應什麼。
參考:如何匿名統計平均收入
在《蟻跡尋蹤及其他數學探索》的第四章討論了這個問題並給出了結論:
1. 假設每個人的收入是一定範圍內的整數,那麼任何統計變數都存在少數人-保隱私演算法。這裡少數人-保隱私演算法 是指只要參與合謀的人低於總人數的一半,那麼合謀以外的人的信息就不會被泄露。
2. 平均數以及可以表示為平均數的函數的統計量,是唯一存在多數人-保隱私演算法的統計量。即對於中位數、最大值這樣的統計量,只要多數人參與合謀,其它人的信息就會暴露。
這是一個有名的密碼學問題,叫做密碼學家的晚餐問題。本質是如何匿名的共享信息,思路是通過XOR操作,實現信息的混淆和共享。
見wiki https://en.m.wikipedia.org/wiki/Dining_cryptographers_problem剛剛翻了一下答案,發現 @徐凱恩 已經提過了,他提的比我早!厲害,感謝,贊
RSA就有同態特性,可以用這種方法:
1. 第一個人構造一對公私鑰,並公布公鑰(e,N),把 用公鑰加密, ,並傳給下一個人
2. 其後的每個人都乘以 的e次方,最後得到
3. 最後由第一個人去用私鑰解密,即執行 ,即可求得所有人工資之和
上述演算法全部取模N,如果取log後數字過小,可以公開乘以一個公用的數,然後取整
本質上是加隨機數的方法的一種擴展。由於採用了公私鑰演算法,所以第一個人的隱私得到保護。
基於標準的流程,解答如下:
①每個人隨機生成一個隨機數。
②每個人把自己的工資與隨機數求和,(記為和A1~A5),加上上一個人傳遞過來的數。從第一個人傳遞至第五個人。1-&>2-&>3-&>4-&>5
③算得總數後,私密地交給第3個人,按3-&>1-&>4-&>2-&>5的順序傳遞。每個人減去自己的隨機數再傳遞給下一個人。
④總數除以5就是平均數。
現在,假定我們想攻擊得第4個人的工資,他的工資=A4 - 隨機數4
要求得A4,在第②步時第3人和第5人串通即可。(第5人收到的數)減去(第3人給第4人的數)即可求得A4。
要求得隨機數4,在第③步時第1人和第2人串通即可。(第2人收到的數)減去(第1人給第4人的數)即可求得隨機數4。
所以必須要第1、2、3、5人全體串通才能獲知4的工資。但這還需要這麼麻煩嗎?他們這麼多人直接拿平均數x5減去4個人的總工資就有了。
所以這個方案實現了最大的保密性。
同態加密,因為只需要算工資總和,所以通過log運算把加法轉換成乘法,用一個滿足乘同態的半同態加密演算法即可。很多經典加密演算法都滿足乘同態,比如RSA、ElGamal、Paillier等等。對各人工資算2^x之後分別加密,加密結果乘積進行解密取2為底的對數。
這麼複雜?
我提供一個不用數學方法的抖機靈吧。
取一個不透明容器,稱出容器重,每個人把自己的工資換成水的毫升數,倒入容器,然後稱出總重,減去容器重,除五,搞定。
防止抱團很簡單,在每個人倒水的時候,其他人都不在場,而總重到最後才能稱。
其實,這個容器就是一個自動求和的黑箱。
推薦閱讀:
※在心理學研究中,我們用自己的思維來研究自己的思維,會不會受到自己思維的局限?
※如何分析問題?可以有哪些特殊的分析角度?
※邏輯學中,前提為假而命題為真的推論如何解釋?
※古往今來世界上有哪些著名的或者常見的強盜邏輯?
※邏輯推理有哪些局限性?用邏輯解釋社會現象和人際關係問題是否有局限性?