carloscn / blog

My blog
Apache License 2.0
132 stars 38 forks source link

2.0_Security_随机数(伪随机数) #136

Open carloscn opened 2 years ago

carloscn commented 2 years ago

2.0_Security_随机数(伪随机数)

密码学安全伪随机数生成器(亦作密码学伪随机数生成器,英文:Cryptographically secure pseudo-random number generator,通称CSPRNG),是一种能够通过运算得出密码学安全伪随机数伪随机数生成器。相较于统计学伪随机数生成器和更弱的伪随机数生成器,CSPRNG所生成的密码学安全伪随机数具有额外的伪随机属性。

在对称加密的流密码算法和块密码算法中,都需要生成随机的密钥流,明文通过密钥加密得到密文,所以随机数生成算法显得十分重要,它决定加密密钥,密钥决定了加密算法的安全性。

随机数的类型分有三种,伪随机数生成器,密码学伪随机数生成器和真正的随机数生成器,前两者生成随机数通过软件实现,真正的随机数生成器通过硬件实现。

1、伪随机数生成器:软件实现,随机性。 2、密码学伪随机数生成器:软件实现,随机性,不可预测性。 3、真正的随机数生成器:硬件实现,随机性,不可预测性,不可重现性。

伪随机数生成器(PRNG)

PRNG是从某个初始熵(种子)开始,并通过某种计算来计算下一个随机数的函数,而这些计算在不知道种子的情况下是无法预测的。这种计算称为伪随机函数。

伪随机函数内部会维护一个状态(internal state)。首先,通过初始种子初始化状态。当生成下一个随机数时,它是从内部状态(使用某种计算或公式)计算出来的,然后更改伪随机函数的内部状态(使用某种计算或公式)。当生成下一个随机数时,将再次根据函数的内部状态进行计算,并再次更改此状态,依此类推。以最简单的形式可以执行以下过程:

伪随机数生成

如果每次熵(或种子)是一样的,生成的随机数也是相同的,所以熵(或种子)对于随机数生成器非常重要。

好的随机数生成器应该是快速的,并且应该具有统计随机性(请参阅Diehard测试),即在一段时间内所有数字的生成机会均应相同。而CSPRNG有更高的要求,还要求不可预测性和不可重现性。所谓不可重现性(unrepeat)就是不管经过多长时间,不会产生完全相同的随机数。当然,在软件层面不可能生成完全不一样的随机数,在一定周期内,密码学随机数算法最终会生成两个完全相同的随机数,只是周期长短的问题,在密码学中应该尽量使用周期相对长的随机数。

初始熵(种子)

为了安全起见,PRNG应该从真正随机的初始种子开始,这绝对是不可预测的。如果种子是可预测的,它将生成可预测的随机数序列,并且整个随机生成过程将是不安全的。这就是为什么在开始时拥有不可预测的随机性(安全种子)非常重要的原因。

如何以安全的方式初始化伪随机生成器?答案很简单:收集随机性(熵)。

在计算机科学中,“熵”是指不可预测的随机性,通常以位为单位进行度量。例如,如果您移动计算机的鼠标,它将生成一些难以预测的事件,例如鼠标光标的开始位置和结束位置。如果我们假设鼠标在 [0 ... 255] 像素范围内更改了位置,则从此鼠标移动收集的熵应约为8位(因为2 ^ 8 = 255)。另一个示例:如果要求用户考虑一个[0 ... 1000]范围内的数字,则该数字将会是大约 9-10 位的熵(因为 2 ^ 10 = 1024)。为了收集256位的熵(例如安全地生成256位的整数),您将需要考虑一系列此类事件的序列(例如用户的鼠标移动和键盘输入)。

收集熵

我们可以从计算机中许多难以预测的事件中收集熵:键盘点击、鼠标移动、网络活动、相机、麦克风输入等,以及它们发生的时间。初始随机性的收集通常是由操作系统(OS)在内部执行的,操作系统提供了标准 API 来访问它(例如,从 Linux 中的 /dev/random 文件读取)。

应用软件也可以通过要求用户移动鼠标、在键盘上键入内容、在麦克风上说某些内容或在相机前面移动一会儿来明确地收集熵。一个很好的例子是bitaddress.org钱包应用程序,该应用程序将鼠标移动与键盘事件结合在一起以收集熵:

https://www.bitaddress.org/bitaddress.org-v3.3.0-SHA256-dec17c07685e1870960903d8f58090475b25af946fe95a734f88408cef4aa194.html

CSPRNG(密码学安全随机数生成器)

根据定义,CSPRNG是一种伪随机数发生器(PRNG),要使PRNG成为CSPRNG,有两个主要要求:

操作系统中的熵通常数量有限,并且等待更多的熵是缓慢且不切实际的。大多数密码应用程序使用CSPRNG,CSPRNG会将来自操作系统的可用熵“扩展”到更多位,这是加密目的所必需的,并且符合上述CSPRNG要求。

大多数CSPRNG结合使用来自操作系统和高质量PRNG生成器的熵,它们经常“重置”,这意味着当新的熵来自操作系统时(例如,来自用户输入、系统中断、磁盘 I/O 或硬件随机产生),基础 PRNG 根据即将到来的新熵位来更改其内部状态。随着时间的推移,这种不断的播种使CSPRNG变得非常难以预测和分析。

通常,现代 OS CSPRNG API 将来自环境的不断收集的熵与其内置伪随机算法的内部状态结合起来,并进行连续重新播种,以确保生成的随机性具有最大的不可预测性,同时具有高速和无阻塞行为。

硬件随机发生器

硬件随机发生器,称为真随机数发生器(True Random Number Generator,TRNG),通常捕获物理过程或现象,例如光的可见光谱、环境的热噪声、大气噪声等。物理环境的随机性是通过专门的传感器收集,然后由设备进行放大和处理,最后通过USB、PCI Express或其他标准接口传输到计算机。

现代微处理器(CPU)提供了内置的硬件随机发生器,可通过特殊的CPU指令 RdRand 访问该发生器,该指令将随机整数返回到CPU寄存器之一。

如今,大多数加密应用程序都不需要硬件随机数生成器,因为操作系统中的熵对于常规加密目的而言足够安全。对于具有较高安全性要求的系统(例如银行和金融应用程序、证书颁发机构和大额付款处理等),需要使用TRNG。

DRBG质量评估参数影响

改变DRBG的参数来评估随机数质量。

有关于DRBG随机数测试标准如表1-1所示,NIST和SM测试项目中有重叠部分。本文中基于NIST和SM两种不同的标准对DRBG数据进行测试,用以参考NIST和SM两种标准下的性能。

表1-1 测试标准

TEST CASE NIST* SM*
monobit frequency test Y Y
frequency test with a block Y Y
poker test N Y
serial test Y Y
runs test Y Y
runs distribution test N Y
test for the longest run of ones in a block Y Y
binary derivative test N Y
autocorrelation test N Y
binary matrix rank test Y Y
cumulative test Y Y
appoximate entropy test Y Y
linear complexity test Y Y
maurer's universal test Maurer Y Y
discrete fourier transform test FFT Y Y
Non-overlapping template matching test Y N
overlapping template matching test Y N
random excursions test Y N
random excursions variant test Y N
1. NIST: nist 800-2 2. SM:国标 GM/T 0005-2012 GB/T 32915-2016

数据集合及通过率

Items Data Name Single Data Size Groups Num SM
2020/5/24 | seed file: norand_seed | reseed: 1MB | test cmd :> python nist.py 1048576‬ 100
ctr ctr_drbg_13107200 13.1MB (104,857,600 bits) 100 13 0.87
hash hash_sha1_drbg 13.1MB (104,857,600 bits) 100 6 0.94
hash hash_sha224_drbg 13.1MB (104,857,600 bits) 100 7 0.93
hash hash_sha256_drbg 13.1MB (104,857,600 bits) 100 5 0.95
hash hash_sha384_drbg 13.1MB (104,857,600 bits) 100 7 0.93
hash hash_sha512_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hmac hmac_sha1_drbg 13.1MB (104,857,600 bits) 100 5 0.95
hmac hmac_sha224_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hmac hmac_sha256_drbg 13.1MB (104,857,600 bits) 100 10 0.9
hmac hmac_sha384_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hmac hmac_sha512_drbg 13.1MB (104,857,600 bits) 100 8 0.92
2020/5/24 | seed file: trng_seed_v8 | reseed: 1MB | test cmd :> python nist.py 1048576‬ 100
ctr ctr_drbg_13107200 13.1MB (104,857,600 bits) 100 4 0.96
hash hash_sha1_drbg 13.1MB (104,857,600 bits) 100 11 0.89
hash hash_sha224_drbg 13.1MB (104,857,600 bits) 100 10 0.9
hash hash_sha256_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hash hash_sha384_drbg 13.1MB (104,857,600 bits) 100 6 0.94
hash hash_sha512_drbg 13.1MB (104,857,600 bits) 100 11 0.89
hmac hmac_sha1_drbg 13.1MB (104,857,600 bits) 100 5 0.95
hmac hmac_sha224_drbg 13.1MB (104,857,600 bits) 100 9 0.91
hmac hmac_sha256_drbg 13.1MB (104,857,600 bits) 100 14 0.86
hmac hmac_sha384_drbg 13.1MB (104,857,600 bits) 100 12 0.88
hmac hmac_sha512_drbg 13.1MB (104,857,600 bits) 100 12 0.88
2020/5/24 | seed file: drbg hmac | reseed: 1MB | test cmd :> python nist.py 1048576‬ 100
ctr ctr_drbg_13107200 13.1MB (104,857,600 bits) 100 8 0.92
hash hash_sha1_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hash hash_sha224_drbg 13.1MB (104,857,600 bits) 100 4 0.96
hash hash_sha256_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hash hash_sha384_drbg 13.1MB (104,857,600 bits) 100 7 0.93
hash hash_sha512_drbg 13.1MB (104,857,600 bits) 100 5 0.95
hmac hmac_sha1_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hmac hmac_sha224_drbg 13.1MB (104,857,600 bits) 100 7 0.93
hmac hmac_sha256_drbg 13.1MB (104,857,600 bits) 100 7 0.93
hmac hmac_sha384_drbg 13.1MB (104,857,600 bits) 100 10 0.9
hmac hmac_sha512_drbg 13.1MB (104,857,600 bits) 100 4 0.96
2020/5/25 | seed file: norand_seed | reseed: 100KB | test cmd :> python nist.py 1048576‬ 100
ctr ctr_drbg_13107200 13.1MB (104,857,600 bits) 100 3 0.97
hash hash_sha1_drbg 13.1MB (104,857,600 bits) 100 9 0.91
hash hash_sha224_drbg 13.1MB (104,857,600 bits) 100 2 0.98
hash hash_sha256_drbg 13.1MB (104,857,600 bits) 100 10 0.9
hash hash_sha384_drbg 13.1MB (104,857,600 bits) 100 5 0.95
hash hash_sha512_drbg 13.1MB (104,857,600 bits) 100 4 0.96
hmac hmac_sha1_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hmac hmac_sha224_drbg 13.1MB (104,857,600 bits) 100 5 0.95
hmac hmac_sha256_drbg 13.1MB (104,857,600 bits) 100 6 0.94
hmac hmac_sha384_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hmac hmac_sha512_drbg 13.1MB (104,857,600 bits) 100 5 0.95
2020/5/25 | seed file: trng | reseed: 100KB | test cmd :> python nist.py 1048576‬ 100
ctr ctr_drbg_13107200 13.1MB (104,857,600 bits) 100 5 0.95
hash hash_sha1_drbg 13.1MB (104,857,600 bits) 100 10 0.9
hash hash_sha224_drbg 13.1MB (104,857,600 bits) 100 10 0.9
hash hash_sha256_drbg 13.1MB (104,857,600 bits) 100 9 0.91
hash hash_sha384_drbg 13.1MB (104,857,600 bits) 100 4 0.96
hash hash_sha512_drbg 13.1MB (104,857,600 bits) 100 9 0.91
hmac hmac_sha1_drbg 13.1MB (104,857,600 bits) 100 10 0.9
hmac hmac_sha224_drbg 13.1MB (104,857,600 bits) 100 5 0.95
hmac hmac_sha256_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hmac hmac_sha384_drbg 13.1MB (104,857,600 bits) 100 6 0.94
hmac hmac_sha512_drbg 13.1MB (104,857,600 bits) 100 7 0.93
2020/5/25 | seed file: drbg | reseed: 100KB | test cmd :> python nist.py 1048576‬ 100
ctr ctr_drbg_13107200 13.1MB (104,857,600 bits) 100 6 0.94
hash hash_sha1_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hash hash_sha224_drbg 13.1MB (104,857,600 bits) 100 9 0.91
hash hash_sha256_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hash hash_sha384_drbg 13.1MB (104,857,600 bits) 100 4 0.96
hash hash_sha512_drbg 13.1MB (104,857,600 bits) 100 5 0.95
hmac hmac_sha1_drbg 13.1MB (104,857,600 bits) 100 7 0.93
hmac hmac_sha224_drbg 13.1MB (104,857,600 bits) 100 6 0.94
hmac hmac_sha256_drbg 13.1MB (104,857,600 bits) 100 5 0.95
hmac hmac_sha384_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hmac hmac_sha512_drbg 13.1MB (104,857,600 bits) 100 6 0.94
2020/5/26 | seed file: drbg | reseed: 10KB | test cmd :> python nist.py 1048576‬ 100
ctr ctr_drbg_13107200 13.1MB (104,857,600 bits) 100 9 0.91
hash hash_sha1_drbg 13.1MB (104,857,600 bits) 100 10 0.9
hash hash_sha224_drbg 13.1MB (104,857,600 bits) 100 5 0.95
hash hash_sha256_drbg 13.1MB (104,857,600 bits) 100 7 0.93
hash hash_sha384_drbg 13.1MB (104,857,600 bits) 100 6 0.94
hash hash_sha512_drbg 13.1MB (104,857,600 bits) 100 6 0.94
hmac hmac_sha1_drbg 13.1MB (104,857,600 bits) 100 10 0.9
hmac hmac_sha224_drbg 13.1MB (104,857,600 bits) 100 7 0.93
hmac hmac_sha256_drbg 13.1MB (104,857,600 bits) 100 9 0.91
hmac hmac_sha384_drbg 13.1MB (104,857,600 bits) 100 5 0.95
hmac hmac_sha512_drbg 13.1MB (104,857,600 bits) 100 7 0.93
2020/5/26 | seed file: trng | reseed: 10KB | test cmd :> python nist.py 1048576‬ 100
ctr ctr_drbg_13107200 13.1MB (104,857,600 bits) 100 12 0.88
hash hash_sha1_drbg 13.1MB (104,857,600 bits) 100 5 0.95
hash hash_sha224_drbg 13.1MB (104,857,600 bits) 100 9 0.91
hash hash_sha256_drbg 13.1MB (104,857,600 bits) 100 10 0.9
hash hash_sha384_drbg 13.1MB (104,857,600 bits) 100 9 0.91
hash hash_sha512_drbg 13.1MB (104,857,600 bits) 100 4 0.96
hmac hmac_sha1_drbg 13.1MB (104,857,600 bits) 100 10 0.9
hmac hmac_sha224_drbg 13.1MB (104,857,600 bits) 100 7 0.93
hmac hmac_sha256_drbg 13.1MB (104,857,600 bits) 100 5 0.95
hmac hmac_sha384_drbg 13.1MB (104,857,600 bits) 100 7 0.93
hmac hmac_sha512_drbg 13.1MB (104,857,600 bits) 100 5 0.95
2020/5/26 | seed file: norand | reseed: 10KB | test cmd :> python nist.py 1048576‬ 100
ctr ctr_drbg_13107200 13.1MB (104,857,600 bits) 100 10 0.9
hash hash_sha1_drbg 13.1MB (104,857,600 bits) 100 7 0.93
hash hash_sha224_drbg 13.1MB (104,857,600 bits) 100 12 0.88
hash hash_sha256_drbg 13.1MB (104,857,600 bits) 100 9 0.91
hash hash_sha384_drbg 13.1MB (104,857,600 bits) 100 11 0.89
hash hash_sha512_drbg 13.1MB (104,857,600 bits) 100 9 0.91
hmac hmac_sha1_drbg 13.1MB (104,857,600 bits) 100 10 0.9
hmac hmac_sha224_drbg 13.1MB (104,857,600 bits) 100 9 0.91
hmac hmac_sha256_drbg 13.1MB (104,857,600 bits) 100 9 0.91
hmac hmac_sha384_drbg 13.1MB (104,857,600 bits) 100 8 0.92
hmac hmac_sha512_drbg 13.1MB (104,857,600 bits) 100 9 0.91

通过率计算方法

在NIST测试中,有两种情况认为随机数没有通过测试,第一种情况为数据序列本身不够随机,没有通过统计算法;另一种情况为数据序列已经通过统计算法,但最终P-Value值不服从Chi方分布。我们认定两种情况没有必然联系,即为独立事件,设定发生第一种情况的事件概率为$P{1}$, 设发生第二种情况的概率时间为$P{2}$,因此,最终的通过率为:

$$P{pass} = {1 - P}{1}*P_{2}$$

在SM测试中存在比NIST测试更丰富的测试项目,如:Poker Test,在这些测试项目标准中,仅存在数据序列是否通过统计算法的唯一一种情况,故我们将SM和NIST中重叠的算法中两种情况合并为一种,设定SM中独有的算法通过概率为$P_{3}$,那么,通过SM测试的通过率为:

$$P{pass} = {1 - P}{1}P_{2}P_{3}$$

本文准备100个13.5MB的数据样本进行算法的测试,故本文中的数据误差容忍限度为$\varepsilon{0} = 0.01$,在计算均值或其他算法时,误差$\varepsilon < \varepsilon{0} = 0.01$,在统计上可以忽略不计。

DRBG算法性能影响

NIST测试结果

利用NIST测试套件,对drbg数据进行测试。为了对比三种算法总体性能,本文产生三种reseed数据,分别是1M、100KB和10KB,对数据中HMAC所有的子算法与数据中所有HASH子算法进行累积求和并取平均数,得到如图1-1所示的直方图。

图 1-1 DRBG的三类算法的通过率直方图

从图1-1中可以观察到,在总体上,DRBG三种算法的通过率的累积量相差无几,HASH的均值性能要高于HMAC再高于CTR。在数据中不排除HASH和HMAC的子算法某个过高或者过低的情况,故还需进一步分析。

图1-2为测试结果,直方图中绿色为DRBG_CTR算法,红色为DRBG_HASH算法,蓝色为DRBG_HMAC算法。为了对比不同种子对DRBG性能的影响,故生成的DRBG数据分别采用了不同的熵源数据,数据来源为,第一,DRBG_HMAC产生的随机数作为熵源;第二,由Chariot FPGA主板生成的TRNG数据;第三,采集高斯白噪声作为熵源。本节考虑到对DRBG算法本身性能的探究,故在生成DRBG数据时,播种间隔选择较大的参数,以降低熵源数据对的影响成分,即固定为1MB大小,因此,在本文生成13.5MB的DRBG数据时,共重新播种14次。

A screenshot of a cell phone Description automatically generated A screenshot of a cell phone Description automatically generated
(a)DRBG as Seed (b)TRNG as Seed
A screenshot of a cell phone Description automatically generated A screenshot of a cell phone Description automatically generated
(c)GaussNoise as Seed (d)Average above all

图 1-2 Reseed-1MB下不同熵源下的DRBG算法的性能

在误差$\varepsilon_{0}$范围内,从图1-2中(a)(b)(c)从趋势上可以看出,HASH所有算法子算法的均值通过率要优于HMAC。为了比较DRBG的综合性能,将三种不同熵源的算法取均值如图1-2(d)所示,综合通过率分数最高的为HASH算法,其次是HMAC,最后为CTR;在直方图中,峰值最高为HASH-SHA256子算法。除图(b)以外,在DRBG和GaussNoise作为熵源时CTR的性能最差,图(b)中CTR通过率高达94%,同样有为野值的可能性,因此,还需要补充数据对于CTR性能进行论证。

(a)DRBG as Seed (b)TRNG as Seed
(c)GaussNoise as Seed (d)Average above all

图 1-3 Reseed-10KB下不同熵源下的DRBG算法的性能

将Reseed参数设定为10KB,即生成10KB的DRBG数据时则将重新播种,此时,影响DRBG性能因素除了DRBG子算法本身,熵源的质量影响权重进一步加大,但本节仅作为图1-2的CTR算法的补充性证明。在此情况下对CTR数据进行分析,除图1-3(c)外,CTR算法性能最差,从图(d)的平均数中也可以得到该结论。另外,图(d)再一次证明了上一节的结论,综合通过率分数最高的为HASH算法但峰值最高的为HASH-SHA384

SM测试结果

按照表1-1中SM测试的要求对三种reseed参数的数据1M、100KB和10KB重新统计。同样对数据中HMAC所有的子算法与数据中HASH所有的子算法的数据样本进行累积求和并取平均数,得到如图1-4所示DRBG总体通过率的直方图。

图 1-4 DRBG的三类算法的通过率直方图

从图1-4中可以观察到,在总体上,DRBG三种算法的通过率在不同的参数下最后的平均数相差无几,差别精度仅为0.001级别,超过本文收集样本的精度为0.01,故差异可以忽略,因此,DRBG三种算法通过率具备一定的稳定性。在数据中不排除HASH和HMAC的子算法某个过高或者过低的情况,故还需进一步分析。

图1-5为测试结果,直方图中绿色为DRBG_CTR算法,红色为DRBG_HASH算法,蓝色为DRBG_HMAC算法。与上一节NIST测试相同,本节考虑到对DRBG算法本身性能的探究,故在生成DRBG数据时,固定为1MB大小,共重新播种14次,播种长度最高448字节。

(a)DRBG as Seed (b)TRNG as Seed
(c)GaussNoise as Seed (d)Average above all

图 1-2 Reseed-1MB下不同熵源下的DRBG算法的性能

在误差$\varepsilon_{0}$范围内,从图1-5中(a)(b)(c)从趋势上可以看出,HASH所有算法子算法的均值通过率要优于HMAC。但为了比较DRBG的综合性能,将三种不同熵源的算法取均值如图1-5(d)所示,综合通过率分数最高的为HASH算法,其次为CTR,最后为HMAC;在直方图中,峰值最高为HMAC-SHA1子算法。除图(b)以外,在DRBG和GaussNoise作为熵源时CTR的性能最差,在TRNG作为熵源时图(b)中CTR通过率高达97%,有为野值的可能性,故还需要进一步讨论。

(a)DRBG as Seed (b)TRNG as Seed
(c)GaussNoise as Seed (d)Average above all

图 1-6 Reseed-10KB下不同熵源下的DRBG算法的性能

将Reseed参数设定为10KB,即生成10KB的DRBG数据时则将重新播种,此时,影响DRBG性能因素除了DRBG子算法本身,熵源的因数影响权重进一步加大,但本节仅作为图1-2的CTR算法的补充性证明。在此情况下对CTR数据进行分析,CTR算法的结果在三种不同的熵源下维持相对较低的水平。另外,图(d)HMAC表现出高于HASH,但两者通过率|0.9206 – 0.9219| \< 0.01误差精度,故可认为HASH和HMAC平均通过率持平,因此,在HASH子算法与HMAC在性能持平,算法峰值在HASH-512。本报告会在后续小节中,对DRBG_HASH子算法进行讨论。

DRBG吞吐量

图 1-7 DRBG产生吞吐量对比

利用Linux的time工具测量drbg_tool在播种间隔为1MB时产生13.5MB数据的速度如图1-7所示,单位为兆每秒(MB/s),从图中可以看出,CTR产生的速度明显最快,优于基于hash运算的HMAC和HASH中最快的约43%。在理论上,HASH和HMAC算法的实现离不开hash运算,而hash运算中含有大量的取余运算,故生成HASH和HMAC的DRBG速度较慢。HASH和HMAC其子算法的生成速度的均值为1.173s和1.2456s,其均值结果相差不大。在吞吐量层面,CTR最优,HASH其次,HMAC最差。

综上,可以得出结论,对于CTR/HASH/HMAC三种算法,在通过率的层面,HASH > HMAC > CTR;在吞吐量层面,CTR > HASH > HMAC。

NIST-DRBG子算法性能探究

如图1-8 使用NIST的统计率对三种reseed的数据样本中HASH和HMAC的子算法进行均值计算。在误差范围内,HASH和HMAC的通过率较为稳定,均值都在0.92,且偏移度仅为0.2,没有数据偏移较大。NIST测试给出的结果是,HASH中的SHA256和SHA384性能最佳,在HMAC中的SHA384和SHA512最佳。

A screenshot of a cell phone Description automatically generated A screenshot of a cell phone Description automatically generated
(c)HASH SM Pass Rate (d)HMAC SM Pass Rate

图 1-8 SM与NIST子算法性能对比

SM-DRBG子算法性能探究

如图1-9,对三种reseed的数据样本中HASH和HMAC的子算法进行均值计算。整体上,HASH和HMAC的通过率较为稳定,均值都在0.92,没有数据偏移较大。在误差精度内,HASH中的SHA384和SHA512性能最佳,HMAC中的SHA224和SHA512最佳。

(c)HASH SM Pass Rate (d)HMAC SM Pass Rate

图 1-9 HASH与HMAC子算法性能对比

综上,从NIST和SM的两种角度来看,在HASH-DRBG中,HASH-SHA384具有最高的通过率;在HMAC-DRBG中,HMAC-SHA512具有较高的通过率

熵源对随机数的影响

在数据样本中,本文选择了三种不同的reseed参数,分别为1MB、100KB和10KB,为了探究熵源因数的影响,故本文使用reseed间隔较小数据,使之种子影响因数权重增大,reseed间隔为10KB,那么在产生DRBG数据过程中,每产生10K的DRBG数据,就会从种子文件中读取新的熵源数据。

本文选择不同的熵源对DRBG进行探究,分别来源于:

  1. Norand:高斯白噪声数据 (差)

  2. Drbg:DRBG-HMAC数据 (优)

  3. Trng:由Chariot FPGA板子生成的TRNG数据("sample_div": 100) (优)

(a)SM Pass Rate (b)NIST Pass Rate

图 1-10 熵源参数影响

我们将不同熵源下所有算法的通过率叠加,得到如图1-10所示的统计直方图,在总体上可以看到熵源对随机数质量的影响,在(a)中显示为SM测试角度,在DRBG作为熵源的时DRBG随机数通过率较高,其次是TRNG,最差的是在高斯白噪声的情况下;图(b)NIST测试角度也同样可以得到相同的结论,但是熵源最好的是TRNG,其次是DRBG,最后是高斯白噪声。

因此,在本小节可以得到结论,熵源的质量是影响产生DRBG随机数的质量的,但这样的影响不是致命的,相差在0.1\~0.2个百分点,这也同样证明,DRBG算法对熵源数据不敏感

reseed间隔对熵源的影响

不同reseed间隔(1M/100K/10K)和不同熵源及不同算法的通过率图如1-11表示,从总体趋势上来看,不论是SM还是NIST测试,都有一个总体的规律,低熵源低播种间隔生成DRBG随机数的质量是最差的,如高斯白噪声熵源,在10K的reseed间隔下均值线最低,在SM测试中为90%,在NIST测试中约为86%,然而高熵源和较大的reseed间隔,无法得到规律,故需要具体讨论。

A close up of a map Description automatically generated A close up of a map Description automatically generated
(a)SM Pass Rate (b)NIST Pass Rate

图 1-11 SM与NIST性能对比

如图1-11(a)所示,为三种熵源(DRBG/TRBG/高斯)对reseed的抗干扰程度,从均值数值上可以得到,DRBG熵源对reseed抵抗性较强。较高熵源对reseed大小依赖不是很大

A screenshot of a cell phone Description automatically generated
(a)SM Pass Rate (b)NIST Pass Rate

图 1-12 SM与NIST性能对比

在reseed上,使用低质量熵源时,建议增大播种间隔,熵源质量高时,reseed影响成分不大。