前言
投票這個事不管在現實世界還是互聯網世界都是很常見的。在現實世界中,大家可以面對面的實名投票,或者使用投票箱混淆投票達到匿名投票的目的。在互聯網,爲了避免刷票,在投票前,投票應用基本上都會要求獲取用戶的個人信息, 就算是微信小程序投票,也會獲取個人的微信頭像,微信id等個人信息。根據這些信息多半能夠對應的上誰是誰,因爲圈子就這麼大。那有沒有一種方法像使用投票箱一樣達到匿名投票的效果呢?答案是:有!本文將介紹一種去中心化的匿名投票的方法。
一種去中心化的匿名投票的方法
先將問題簡化一下:假如Alice,Bob,Carol 現在就假期要不要外出旅遊的問題進行投票。同意旅遊投yes票,不同意旅遊投no票。2票及2票以上的投票勝出。爲了避免失敗的人的尷尬,這裏採用匿名投票的方式。
假設3人都有一個公開密鑰和一個私人密鑰,每個人還知道其他人的公開密鑰。E 爲加密函數
開始投票:
1、Alice 將自己的投票結果voteA後附加一個隨機字符串R0, 生成
(voteA,R0)
2、Alice用Carol的公開密鑰加密上述結果,生成
Ec(voteA,R0)
3、Alice用Bob的公開密鑰加密上述結果,生成
Eb ( Ec (voteA,R0) )
4、Alice用Alice的公開密鑰加密上述結果,生成
Ea ( Eb ( Ec (voteA,Ro) ) )
5、Alice新生成一個隨機數R1,並用Carol的公開密鑰將上述結果加密,生成
Ec ( Ea(Eb(Ec(voteA,R0) ) ),R1)
6、Alice新生成一個隨機數R2,並用Bob的公開密鑰將上述結果加密,生成
Eb (Ec ( Ea(Eb(Ec(voteA,R0) ) ),R1) , R2)
7、Alice新生成一個隨機數R3,並用Alice的公開密鑰將上述結果加密,生成
Ea ( Eb (Ec ( Ea(Eb(Ec(voteA,R0) ) ),R1) , R2),R3)
Bob,Carol按照上述流程都會生成一個包含了投票的加密數據,並將結果發送個Alice。如下
Ea ( Eb (Ec ( Ea(Eb(Ec(voteB,R0) ) ),R1) , R2),R3)
Ea ( Eb (Ec ( Ea(Eb(Ec(voteC,R0) ) ),R1) , R2),R3) 備註:每個人的隨機數都不相同
開始計票:
現在Alice手中有三個人包含了投票信息的加密數據,開始計票
1、Alice用自己的私鑰對所有選票進行解密,然後去掉R3。現在的結果是這樣的:
Eb (Ec ( Ea(Eb(Ec(voteA,R0) ) ),R1) , R2)
Eb (Ec ( Ea(Eb(Ec(voteB,R0) ) ),R1) , R2)
Eb (Ec ( Ea(Eb(Ec(voteC,R0) ) ),R1) , R2)
Alice將上述結果打亂順序發送給Bob。
2、Bob收到3個數據,但不知道哪個是Alice的,哪個是Carol的。Bob用私鑰解密數據,得到
Ec ( Ea(Eb(Ec(voteA,R0) ) ),R1)
Ec ( Ea(Eb(Ec(voteB,R0) ) ),R1)
Ec ( Ea(Eb(Ec(voteB,R0) ) ),R1)
Bob根據得到的隨機數R2,可以判斷自己的選票在上述結果中,去掉R2,發給Carol。
3、Carol收到3個結果,用私鑰解密。刪除R1,得到
Ea(Eb(Ec(voteA,R0) ) )
Ea(Eb(Ec(voteB,R0) ) )
Ea(Eb(Ec(voteC,R0) ) )
Carol得到3個R1,根據自己的R1可以判斷,自己的選票是否在結果裏。發送給Alice
4、Alice得到上述3個結果,用私鑰解密得到3個結果,同時檢驗自己的選票是否在結果裏。然後簽名所有選票,併發送給Bob,Carol。Bob,Carol得到的結果是這樣的。
SignA(Eb(Ec(voteA,R0) ))
SignA(Eb(Ec(voteB,R0) ))
SignA(Eb(Ec(voteC,R0) ))
此時Bob,Carol 可以根據Alice的公鑰驗證自己的選票是否包含在結果集裏。
5、Bob驗證Alice簽名,並用私鑰對所有選票解密,查看自己的選票是否在選票集中。然後對所有選票簽名,發送給Alice,Carol。 Alice,Carol得到的結果是這樣的。
SignB( Ec(voteA,R0) )
SignB( Ec(voteB,R0) )
SignB( Ec(voteC,R0) )
此時Alice,Carol 可以根據Bob的公鑰驗證自己的選票是否在結果集裏。
6、Carol驗證Bob簽名,並使用私鑰對所有選票解密,檢查自己的選票是否在結果集裏。然後對所有選票簽名併發送給Alice,Bob。 Alice,Bod得到
SignC( VoteA,R0)
SignC( VoteB,R0)
SignC( VoteC,R0)
此時,Carol已經知道3個投票結果,Alice,Bob可以通過Carol的公鑰得到R0,驗證自己的結果是否包含在結果集裏。然後去掉R0,即可得到3個投票voteA,voteB,voteC。但由於數據傳送的過程中,打亂的順序,因此每個人都無法將其餘兩張選票與人員對應起來。
至此,計票結束,3個人得到了同樣的投票結果,voteA,voteB,voteC,而且除了自己的選票外,無法將其餘兩張選票與兩個人對應起來,達到完全匿名的目的。
適用場景
本方法不需要依賴第三方來投票,同時實現了完全匿名。因此適用於對匿名要求度高的場景
優點
去中心化,匿名,適用於人數較少的投票
缺點
不適用於人數較多的投票。當人數較多時,投票和計票的步驟也會相應增加,選票的數據大小也會隨之增加。
擴展
如果參與投票人數較多的情況下,可以將投票分組進行。例如將100人分成10組,每組10人,同時引入一人在每組中都投票以獲取所有人的投票結果,但此人的票不計入總票。
THE END!