随机数检测代码运行
测试步骤
- 1.准备测试数据
使用待测的(伪)随机数发生器,产生足够长度的随机数序列。(样本参数见附录)
- 2.在NIST的测试源码中,添加4个国密特有的测试用例
扑克测试,游程分布测试,二元推导测试,自相关测试
- 
3.编译源码得到测试程序 
 在sts-2.1.2目录下make即可
 ![]() 
- 
4.运行测试程序,选择待测试数据,按照NIST测试用例和测试参数进行设置 
1.执行测试程序,$ ./assess 1000000
2. 输入0,选择从文件读入随机数
3. 输入随机数路径及文件名,例如data/data1.bin
4. 输入0,选择NIST测试模式
5. 输入2,选择测试所有NIST用例
6. 输入0,NIST用例使用默认参数即可(如果需要修改参数输入相应的编号进行修改)
7. 输入1000,选择测试的样本数量
8. 输入1,选择输入的文件类型为二进制(选择0表示全是01的ASCII文件)
9. 按回车即开始测试
- 
5.测试结束之后,分析测试结果,看是否满足预期要求 
- 
6.运行测试程序,选择待测试数据,按照国密规范选择对应测试用例,并进行参数设置 
1.执行测试程序 $ ./assess 1000000
2. 输入0,选择从文件读入随机数
3. 输入随机数路径及文件名,例如data/data1.bin
4. 输入1,选择国密测试模式,固定为国密的测试参数
5. 输入3,选择测试所有GM用例
6. 输入1000,选择测试的样本数量
7. 输入1,选择输入的文件类型为二进制(选择0表示全是01的ASCII文件)
8. 按回车即开始测试
- 7.测试结果之后,分析测试结果,看是否满足预期要求
结果分析
- 1.通过测试的样本比例(NIST标准)
根据样本总个数和显著性水平,计算判定用例通过的最小样本个数
对于样本数为1000,显著性水平为0.01的情况,通过的比例需要在0.98以上
即1000的样本需要有980个通过。
- 2.P值均匀分布(仅NIST)
对每个测试样本的P值结果,按照0.1的区间间隔进行数量统计,计算P值统计结果的P值。
如果最终的P值大于0.0001,则认为是均匀分布的。
| 序号 | 检测项目 | 国密参数 | NIST参数 | 
|---|---|---|---|
| 1 | 块内频数测试 | m=100 | m=128 | 
| 2 | 扑克测试(国密) | m=4; m=8 | / | 
| 3 | 重叠子序列测试 | m=2; m=5 | m=16 | 
| 4 | 块内最长游程测试 | m=10000 | m=10000 | 
| 5 | 二元推导测试(国密) | k=3; k=7 | / | 
| 6 | 自相关测试(国密) | d=1, 2, 8, 16 | / | 
| 7 | 矩阵秩测试 | M=Q=32 | M=Q=32 | 
| 8 | 近似熵测试 | m=2; m=5 | m=10 | 
| 9 | 线性复杂度测试 | m=500 | m=500 | 
| 10 | 非重叠模板测试(NIST) | / | m=9 | 
| 11 | 重叠模板测试(NIST) | / | m=9 | 
| 12 | 通用测试 | L=7,Q=1280 | L=7,Q=1280 | 
| 显著性水平α=0.01 | |||
| 样本参数 | 
| 参数 | 值 | 
|---|---|
| 样本长度 | 10^6 bits | 
| 样本个数 | 1000 | 
随机数样本生成方法
- 1.openssl随机数样本生成方法
openssl rand -out data.openssl 1000000000
- 2.用C语言中rand函数生成随机数样本(glibc版本2.27)
./c_rand 1024 data.c_rand 1000000000
- 3.其中c_rand程序的源码c_rand.c如下
#include <stdlib.h>
#include <stdio.h>
#define buffer 1024
int main(int argc, char *argv[])
{
	int j, r, nbytes;
	unsigned int seed;
	FILE* fp = NULL;
	size_t res = 0;
	if (argc != 4) {
	fprintf(stderr, "Usage: %s <seed> <rand_file> <nbytes>\n", argv[0]);
	return -1;
 	}
	seed = atoi(argv[1]);
	nbytes = atoi(argv[3]);
	srand(seed);
	unsigned char* out = new unsigned char[buffer];
	unsigned char* cur = out;
	if (!(fp = fopen(argv[2], "wb")))
	{
 		printf("file %s open fail!", argv[2]);
 		delete[] out;
 		return -1;
	}
	for (j=0;j<nbytes; ++j) {
		r =  rand()%256;
		*cur++ = *((unsigned char*)(&r));
		if((!(( j + 1 ) % buffer)) || ( j + 1 == nbytes))
		{
			size_t num = j % buffer + 1;
      		res = fwrite(out, 1, num, fp);
      		if (res != num)
      		{
        		fclose(fp);
        		delete[] out;
        		printf("file %s write fail!", argv[2]);
        		return -1;
			}
      			cur = out;
		}
	}
		fclose(fp);
		delete[] out;
		return 0;
}
- 4.采集握手中ClientHello随机数
生成随机数命令:
openssl s_server -engine ./engine.so -cert test/rsa-ext.pem -key test/rsa.key -CAfile ca/rsa-ca.pem -www -accept 8888
./ssl -h 192.168.1.10 -p 8888 -s 128000000 -f binary -o data.handshake -m tls1_2
- 5.采集硬件加密卡生成的随机数样本
前置条件:完成硬件安装,驱动安装,编译openssl 引擎得到engine.so
openssl rand -engine ./engine.so -out data.cryptocard 1000000000
实验结果



总结
本来打算自己尝试编码或者实在不行找一下代码尝试自己修改,最终发现自己暂时还是没那个能力,所以还是使用了NIST的测试源码,在网上查阅博客跟着博客运行了起来。感性认识了一下伪随机数的检测。后面打算找一些论文自己看看,尝试写一篇综述类文章发表。以上就是最近的学习总结,如有不足请老师指正。
 
                    
                

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号