隨機數檢測代碼運行


測試步驟

  • 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的測試源碼,在網上查閱博客跟着博客運行了起來。感性認識了一下偽隨機數的檢測。后面打算找一些論文自己看看,嘗試寫一篇綜述類文章發表。以上就是最近的學習總結,如有不足請老師指正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM