当前位置: 首页 > 科技观察

用香蕉驱动随机数发生器靠谱吗?_0

时间:2023-03-19 23:00:07 科技观察

是不是觉得随机数都很高级?比如前两天,区块链平台Solana就出现了4个小时的宕机。根据联合创始人AnatolyYakovenko和其他开发人员的说法,该问题是由区块链的持久随机数函数中的错误引起的。Yakovenko表示,这个问题“导致部分网络认为该区块无效”,因此“未能形成共识”。又如,2015年和2017年,工商银行与中国科学技术大学合作,实现了基于量子通信技术的同城和异地数据加密传输,在电子档案和网上等领域开展试点。银行业。去年,工行率先在银行业完成量子随机数场景试点。中国工商银行金融科技部总经理表示:“量子随机数被认为是最安全的随机数,我们利用其随机性、不可预测性和不可重复性,利用量子随机数对重要的金融交易信息进行加密、标记和验证。”,更有效地防止用户身份冒充、交易数据截取和重放等攻击,更好地保证用户意愿的真实性、交易要素的完整性、交易过程的安全性。”但你可能想都没想,要生成随机数,其实只要一根香蕉就够了。这个巧妙的脑洞得到了电子硕士即将毕业的博主ValerioNappi的支持。这个香蕉随机数的原理是什么generator?真的靠谱吗?一起和文摘菌一起来看看吧~我们从问题的根源说起,计算机是确定性系统,换句话说,如果我们总是给它们相同的输入数据,它们总会返回相同的输出值。这正是我们对计算机的期望。但是,确定性和随机性不是兼容的关系,计算机不能随机地做任何事情。为了更好地理解随机数,我们必须明白一组数字是随机数的两个必要条件和不充分条件:每个数字必须与其他每个数字具有相同的出现在列表中的概率(取一个参考区间),并且也就是均匀分布.数字的顺序必须事先不可预测。显然,确定性机器的难点在于回答第2点。在只满足第1点的情况下,很可能生成的是伪随机数,不是真正随机的。但这和香蕉有什么关系呢?当我们为计算机提供随机数时,一个硬件系统是必不可少的,它就是随机数发生器(TRNG)。TRNG的种类很多,但它们的原理都是相似的,就是利用不同的物理随机量,将其转化为数字信息,传输给计算机。最常见的是,利用了电阻器中的热噪声、二极管中的雪崩效应和其他混沌效应等物理现象。如果用香蕉,应该还是放射性衰变。我们知道香蕉中含有大量的钾元素,而自然界中存在的钾元素中有一小部分是具有放射性的,而且所占比例非常高。具体来说,我们谈论的是40K同位素,它在自然界中占钾的0.01%。(与柠檬和糖搭配非常好。)这样看,“由香蕉驱动的随机数生成器”突然变得很有意义了。但仍然存在一个问题:我们如何处理计算机中的随机数?-加密。这也是研究随机数及其与计算机的关系的主要原因。随机数用于生成加密密钥,这是决定加密系统有效性的唯一因素。正如Kerckhoffs原则所述,“密码系统的安全性不应取决于对密码算法的保密,而应仅取决于对密钥的保密”。显然,如果攻击者能够以某种方式预测密钥,我们就有了一个易受攻击的系统。因此,“好的随机数”是一个好的加密系统的基础。用什么来测试“香蕉”为了分析随机数发生器的好坏,我们还需要专门设计的软件工具。目前最流行的两个是ent和dieharder。ent被设计为放射性衰变随机数发生器的轻量级测试,它非常简单和快速,需要的数据很少,但结果仅供参考。Dieharder是一个测试套件,被认为是随机数生成器的黄金标准,测试非常彻底,但需要千兆字节的样本才能运行。当然我们这里选择ent。准备数据,我们使用ent进行第一次测试。数据由生成器写入串口,我们使用cat/dev/ttyACM0>>sampletext.txt将它们保存在linux控制台的文件中,在附加模式下使用bash流重定向命令,因此我们可以停止采集,并稍后恢复采集而不覆盖文件。在两天内收集的样本包含90628个16位数字,每行一个。数字保存为ascii文本文件,但ent分析二进制文件,您可以用C编写一个短程序将它们转换为二进制文件。#include#include#include#includeintmain(intargc,charconst*argv[]){FILE*lettura=fopen("textsample.txt","r");断言(lettura!=NULL);FILE*scrittura=fopen("sample.txt","wb");断言(scrittura!=NULL);uint16_tN=0;//N为16字节charbytes[2];字符缓冲区[6];//5字符+终止符do{fscanf(lettura,"%s",buffer);//将一行放入缓冲区N=atoi(buffer);//从字符数组到整数bytes[0]=(N>>8);//取8msbbytes[1]=(N&0xFF);//取8lsbfwrite(bytes,1,sizeof(bytes),scrittura);//输出原始msb和lsb}while(!feof(lettura));fclose(lettura);fclose(scrittura);return0;}这样做之后,我们就可以第一次运行ent测试了。Ent给出了几个参数:熵:熵是一部分信息所包含的“随机性”的多少。信息论告诉我们,理论上可以压缩而不丢失信息的最小尺寸用熵值来表示。卡方分布:该测试用于了解我们的数值分布服从理论分布的程度。从ent手册来看,这个值应该尽可能接近256,百分比值在10-90%之间。算术平均值:位的简单算术平均值。由于该值介于0和255之间,因此它应该大约等于127。使用蒙特卡洛方法计算π的值:这里更像是一个漂亮的数字而不是一个有用的方法。自相关:表示序列值之间的依赖关系,在最好的情况下必须等于零。香蕉与卡方的关系卡方是统计学中的一个概念,主要用来检验一组值与理论上预测的分布的拟合程度。如果给定数据集,频率是给定数据项出现的次数,自由度是可能值的数量减一。为什么减1?考虑抛硬币的情况,我们有两种可能的结果:正面和反面。但是出现正面的百分比直接取决于出现反面的百分比。那么如果我们考虑一个具有三种可能结果的事件,第三种结果的百分比直接由其他两种结果决定。让我们再次掷骰子作为例子。掷骰子有6种可能的结果,这给了我们五个自由度。那么掷骰子1000次,我们就需要验证统计学中所谓的零假设,或者验证在一定的概率范围内,我们的结果是真正随机的。这些是从实验中得到的数据:所以我们得到实验的卡方值,3068。现实世界的数据极不可能完全反映理论分布,卡方值太接近于零也有嫌疑。另一方面,我们离理论分布越远,分子越大,同时保持分母不变。这导致卡方值增加。这对于卡方值意味着能够拒绝原假设,知道您正在处理的数据不仅仅是随机结果,而是具有一定的意义。然而,这对我们来说是个坏消息,因为这意味着我们的数据分布不均。表中的行代表系统的自由度,在模壳中,有5个自由度。列表示计算值大于表中值的概率水平。还有表示计算值小于的概率的表,这些表称为左尾表,上面显示的表是右尾表。这是因为在一种情况下考虑了图形的右侧,而在另一种情况下考虑了左侧。在chi^2=3.068的情况下,这在90%到25%的情况之间。这足以说明我们可以归类为随机行为的行为没有过度变化。再回到香蕉,以90%和10%作为参考百分比,对于255个自由度,ent对生成器记录的值进行测试,得到的值是498.15,超出了可接受的范围,而ent返回的百分比概率<0.01%。对香蕉的猜测,但人们可能会立即注意到字节1的计数明显低于其他字节,而字节2的计数要多得多。仔细观察,那些“缺失”的计数被分配为2。经过一些测试,我决定将偶数位置的字节与奇数位置的字节分开。这是因为每生成一个16位数字(2个字节),就会生成两个字节,一个在偶数位置,一个在奇数位置。MSB没有报告任何重大问题,但LSB组是问题所在。为了了解问题的根源,我们必须首先了解数字在内部是如何产生的。盖革管通过一个接口电路,当它被辐射击中时,在单片机的引脚2(PB2/INT0)上发送一个信号,引脚2配置为在接收到上升沿时产生中断:attachInterrupt(digitalPinToInterrupt(2),randomCore,RISING);.中断会调用randomCore()函数,其定义如下:调用该函数时,会依次调用单片机的micros()函数。此函数返回一个32位数字,表示自系统打开以来经过的微秒数。作为一个32位无符号数,它会在4294.96秒后溢出,或者说每隔70分钟左右就会溢出。由于微控制器的速度不足以进行更准确的更新,因此micros()以4微秒为增量进行更新,始终将两个最低有效位保持为零。为此,我们将micros()返回的值向右移动两位。所以我们得到一个30位的值。如果我们也使用最低有效位,我们将获得累进数字,直到下一次计时器溢出。在发生溢出的70分钟内,每个数字肯定会比前一个大,也肯定会比下一个小。这绝对不是随机的。所以让我们只保留micros()的前16个字节。该值每262144微秒溢出一次,使得上述情况极不可能发生。注意这个值每4*2^8=1024微秒出现一次,也就是1毫秒左右,这是中断溢出发生后的下一个值。接着我们将目光转向MCU核心的millis()函数的代码。millis()函数通过将TIMER0的预分频器设置为64来工作,对于时钟频率为16MHz的8位定时器,这会导致定时器每1.024毫秒溢出一次。定时器溢出会产生中断,中断向量为TIMER0_OVF。如果Geiger脉冲与TIMER0溢出同时到达,我们将有两个竞争中断:TIMER0_OVF和INT0。这种情况由微控制器的中断优先级系统处理,其优先级顺序在数据表中指明。TIMER0溢出的优先级远低于外部中断,所以有如下猜测:Case1:INT0中断与TIMER0_OVF中断同时到达。由于它具有更高的优先级,因此首先执行外部中断,以millis()为代价,影响函数的准确性,但对生成的数字没有明显影响。情况2:INT0中断比TIMER0_OVF中断在下一个时钟周期到达。由于一个时钟周期已经过去,TIMER0_OVF中断已经在执行。执行结束的时候micros()已经有2的值,所以结果数会被注册为2的值。不过也有可能是使用serial对latency有影响,但还需要进一步调查