投票这个事不管在现实世界还是互联网世界都是很常见的。在现实世界中,大家可以面对面的实名投票,或者使用投票箱混淆投票达到匿名投票的目的。在互联网,为了避免刷票,在投票前,投票应用基本上都会要求获取用户的个人信息, 就算是微信小程序投票,也会获取个人的微信头像,微信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!