1、传统彩票
以美国大乐透为例,它们具有以下优点:
缺点是:
-
开奖号码不是
真随机数
。
-
彩票中心贪腐案件层出不穷,名声不佳。
参考资料:
-
菲律宾总统下令无限期关闭全国彩票店理由是涉嫌大规模腐败
http://finance.jrj.com.cn/2019/07/30100627902612.shtml
2. Insiderwho scammed $14.3m lottery ‘win’ pleads guilty
https://nakedsecurity.sophos.com/2017/07/14/insider-who-scammed-14-3m-lottery-win-pleads-guilty/
参考资料:
-
互联网彩票大起底:“黑彩”“吃票”“倍投”,三个黑幕让你倾家荡产!
http://www.sohu.com/a/273021811_100288264
-
吃票——彩票“销售”的诈骗花样
http://blog.sina.com.cn/s/blog_c204b0d50102yen4.html
针对传统彩票这些无可避免的缺陷,能否用密码学方法,设计一个真正可信的彩票系统呢?在正式开始之前,我们需要先学习贯穿本文始终的一点点预备知识——哈希算法。
2、哈希算法简介
哈希算法即哈希函数(又称散列函数或者杂凑函数),是把任意长度的输入数据,通过该函数创建一个对应的固定长度的输出,这个短输出称之为
哈希值
(又称散列值、摘要或者数据指纹),哈希值相当于是对输入数据的一种背书,它承诺了一个对应的原始数据。
图2-1哈希函数
哈希算法具有以下特点:
根据输入数据在有限的时间和资源内很容易计算出哈希值,这称为
正向快速
。而根据哈希值,完全无法推断出原始输入数据,这称之为
不可逆
(或者单向性)。输入数据只需要发生最微小的改变,哈希值也会彻底不同,这称之为
雪崩效应
(或输入敏感)。
对于同一个哈希函数,相同的输入数据会有相同的哈希值,若哈希值不同,那么输入数据一定不同,这称之为哈希函数的
确定性
。另一方面,若两个不同的输入数据,得到了相同的哈希值,这种情况称为“杂凑碰撞(collision)”。只应选用当前还无法人为刻意制造出“杂凑碰撞”的哈希函数,目前MD5、SHA-1等函数已不再安全,本文示例中使用SHA3-256函数。
3、可信彩票模型简介
要使一个彩票系统真正可信,开奖号码应该是真正意义上的随机数;彩票涉及的所有数据和开奖方法应对所有人透明可查;透过公开的数据和算法,任何人都可以验证最终开奖号码,证明其不受任何秘密的隐藏因素的影响。
可信彩票系统的操作流程如图6-1彩票模型B所示,首先对彩票购买截止时间点内的所有售出的彩票号码数据排序,立即公开和公证该数据的哈希值(参见2、哈希算法简介),并在随后提供原始数据的下载。
然后,把上一步计算得到的哈希值作为输入,使用一个可以消耗特定时间长度的公开算法(参见5、确定性时延算法),得到最终的开奖号码。对于这个开奖算法来说,开奖号码由彩票池原始数据唯一确定。
4、彩票模型A
4.1、对彩票池原始数据进行哈希
所有彩票号码的购买记录构成了一个集合,为了防止二义性,对其排序可以得到唯一确定的结果,我们把排序后的彩票号码交易记录称之为
彩票池原始数据
。为了及时固定彩票池原始数据,应立即计算其哈希值并公开和公证。(注意,需要确保在临近截止时间点之前有彩票购买记录。)
为了方便演示,下面用模拟器生成了10条福彩双色球销售记录并对其进行了排序(真实数据可能有上亿条),每条记录包含6个红球号码、1个篮球号码和每张彩票对应的附加码。其中第6、7条彩票号码相同,附加码不同,表示不同的人购买了同一个号码。若彩票号码不同但附加码相同,表示这两个号码属于同一张彩票(一张彩票上可以买多个号码或者复式投注)。
把lottery_model.data作为输入数据,使用SHA3-256计算其哈希值(参见6.1公式①)。
该示例计算时间不到2纳秒,哈希函数SHA3-256输出64个16进制数(等于256位二进制数),这里的'7ee4d882……'就是该输入数据对应的哈希值,立即在网上公开这个值使人们可以查看,并在随后提供lottery_model.data文件下载。
4.2、Alice的疑惑
现在假设有彩民Alice对彩票中心并不信任,Alice通过网络或者电视直播在第一时间查看到了'7ee4d882……'这个值,并在晚些时候才下载lottery_model.data这个文件。通过标准的哈希算法她计算得到了'7ee4d882……'这个值,经过对比发现这个值与之前彩票中心公开的那个值一致。在lottery_model.data文件中Alice根据她手上的彩票的附加码找到了她购买的两个彩票号码:
Alice因此可以推论她下载到的lottery_model.data确实是彩票中心之前公开申明的文件。在这个过程中,哈希值起到了对原始数据的承诺作用。
Alice想了一下,把自己购买的号码球08改成09,重新计算lottery_model.data的哈希值得到:
她惊奇的发现,虽然仅仅只改变了一个号码,其结果哈希值却被彻底改变了,这是因为哈希算法的雪崩效应所致。因此Alice明白,每个彩民选择的彩票号码,都会彻底的影响最终的开奖号码。
(想一想)如果现在我们就把'7ee4d882……'这个值立即映射到一组开奖号码(参见6.1公式③),这就已经是一个具有内禀随机性的彩票模型了——我们且称之为
彩票模型A
。
图4-1彩票模型A
但是——
4.3、Eve对彩票模型A的攻击
Eve是彩票中心的一名技术人员,他负责计算彩票池原始数据的哈希值以及向外公开这些数据的工作。设想Eve首先通过正常渠道购买了1000张号码各不相同的彩票,当临近彩票购买截止时间点12:00时,Eve已经收集到了所有彩票的销售记录,但他并不立即对外公开这些原始数据,而是在彩票池原始数据中新增加一条虚假的彩票号码FakeNumber记录。
Eve用一个程序自动试算FakeNumber的值,因为哈希函数正向快速的特点,利用彩票模型A的开奖算法立即计算出了一个开奖号码。程序会检查这个开奖号码是否在Eve事先购买的这1000个号码之中,如果不在,就改变FakeNumber中的数字,再次重复以上过程。大约经过20000次这样的尝试计算之后,Eve几乎必然可以找到一组特定的FakeNumber的值,能使最终的开奖号码落入他事先购买的1000张彩票号码之中。
因为计算彩票模型A的开奖号码非常简单,速度很快,大约在不到0.01秒的时间之内,程序就可以计算好了这一切。现在时间为12:00,Eve把这个添加了FakeNumber号码的彩票池数据,作为“原始数据”对外公开其哈希值以及提供数据下载。Eve通过精心的设计,修改了彩票池原始数据,最终以1001张彩票的代价,让自己获得了大奖。
5、确定性时延算法
彩票模型A可以被操控的根本原因在于,从彩票池原始数据映射到开奖号码的算法十分简单。通过测试在原始数据中添加不同数字得到的开奖号码,在极短时间之内就可以进行上亿次这样的试算,通过篡改彩票池原始数据,就可以让自己中奖。
幸运的是,有方法可以迫使在计算开奖之前,必须消耗一段符合我们期望长度的时间,我们把该算法称之为
确定性时延算法
。
根据哈希函数不可逆的特点,我们对任意数据进行哈希计算,可以得到一个无法事先预知的哈希值。比如,我们对字符串数据'something_1'进行哈希计算可以得到一个哈希值7c8bbe46d8aa1b364e2867f08f6c8f8d5bae8ce156610bad492629cd396f4921,如果我们想要找到一个字符串,要求它的哈希值是以'0'开头,应该怎么办呢?只存在唯一的方法,就是计算不同输入数据的哈希值,只要尝试的次数足够多,从概率上来说,在这些结果中就一定能找到满足要求的值。为方便起见,下面的示例通过在'something_'后面添加自然数n来改变输入数据字符串。
当输入数据为'something_11'的时候,我们看到其哈希值'0996c9ed……' 满足我们之前设想的要求。
如果要求是以'00'开头的哈希值呢?
我们就不得不进行更多次数的尝试。
当输入数据为'something_540'的时候,发现其哈希值'0037891b……'满足要求。
我们把要求的'0'的个数表示为DIFFICULTY值,随着DIFFICULTY值减小,找到合适输入值的计算量呈指数迅速增加,下面要求的DIFFICULTY值为'0000000F',程序经过2505014次哈希计算才找到一个满足要求的对应的输入值,这在我的计算机上花了79秒。