随机数检测(一)

1 概述

随机数发生器设计完成后,使用随机数发生器的产品需对其执行测试,防止应用过程中产生不合规的随机数。对于密码产品而言,对随机数发生器输出数据的检测一般称为随机数自测试。这里的随机数自测试为使用过程的自测试,注意与随机数发生器设计时的自测试区分开来。

确定密码产品需执行的随机数自测试项目前,应首先按照GM/T 0062确定产品所属类型。对应不同类型的密码产品,应执行不同阶段的检测项目。检测项目的实现方式在GM/T 0005中定义。
如果商用密码产品认证中遇到问题,欢迎加微信symmrz沟通。

2 产品形态划分和检测项目

按照GM/T0062要求,密码产品可分为ABCDE五种类型。依据所属类型确定随机数自测试的检测项。

类型划分依据典型产品
A类不能独立作为功能产品使用随机数发生器芯片等
B类用时上电,随机数检测处理能力有限,对上电响应速度有严格要求IC卡
C类用时上电,随机数检测处理能力有限,对上电响应速度没有严格要求USBKey
D类长期加电,随机数检测处理能力有限,对上电响应速度没有严格要求POS机
E类长期上电,较强的随机数检测处理能力,对上电响应速度没有严格要求服务器

随机数检测包括送样检测、出厂检测、上电检测、周期检测和单次检测。其中:
1) 送样检测在检测机构对产品测试时执行。产品自身无需关注。
2) 出厂检测在产品出厂前执行。
3) 上电检测在产品加点时自动执行。
4) 周期检测按照一定时间周期自动执行。
5) 单次检测在每次使用随机数前自动执行。
实际上多数系统类产品都属于E类产品。以E类产品为例,各测试阶段的检测项如下图。
E类要求1
E类要求2

3 测试方式

3.1 概述

GM/T 0005-2021为最新的随机性检测规范,可以在实践中代替GB/T 32915。GM/T 0005-2021规定了15中随机性检测方法:单比特频数检测方法、块内频数检测方法、扑克检测方法、重叠子序列检测方法、游程总数检测方法、游程分布检测方法、块内最大游程检测方法、二元推导检测方法、自相关检测方法、矩阵秩检测方法、 累加和检测方法、近似熵检测方法、线性复杂度检测方法、Maurer通用统计检测方法、离散傅里叶检测方法。

规范定义的样本通过率显著性水平α=0.01。样本分布均匀性检测的显著性水平αT=0.0001,子区间数量k=10。

3.2 单比特频数检测方法

单比特频数检测方法

以下实现代码供参考。

def monobitFrequency(epsilon:bitarray):
    sn = epsilon.count(1) - epsilon.count(0)
    #2021version make change
    V = sn/sqrt(len(epsilon))
    pvalue = math.erfc(abs(V)/sqrt(2))
    qvalue = math.erfc(V/sqrt(2))/2
    return {'p':pvalue, 'q':qvalue} 

#test case
if __name__ == '__main__':
    # input = bitarray('11001100000101010110110001001100111000000000001001001101010100010001001111010110100000001101011111001100111001101101100010110010')
    input = readInputFile('.\\pi\\data.pi')
    ret = monobitFrequency(input)
    print('pvalue:', ret['p'])
    print('qvalue:', ret['q'])

3.3块内频数检测方法

块内频数检测方法

以下实现代码供参考。

def blockFrequency(epsilon:bitarray,m):
    # m = getblockFrequencyM(len(epsilon))
    N = int(len(epsilon)/m)
    epsilonList = epsilon.tolist()
    sumOfPi = 0
    for i in range(N):
        pi = sum(epsilonList[i*m:(i+1)*m:1])/m
        sumOfPi += (pi - 0.5)**2
    V = 4*m*sumOfPi
    pvalue = scipy.special.gammaincc(N/2, V/2)
    qvalue = pvalue
    return {'p':pvalue, 'q':qvalue}

test case
if __name__ == '__main__':
    input = bitarray('1100100100001111110110101010001000100001011010001100001000110100110001001100011001100010100010111000')
    # input = readInputFile('.\\pi\\data.pi')
    ret = blockFrequency(input,10)
    print('pvalue:', ret['p'])
    print('qvalue:', ret['q'])
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值