一种去中心化的匿名投票方案

前言

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章