最近研究隨機數檢測,主要學習了一下NIST和國密檢測,這里整理了國密15項檢測規項目的原理,數學表達式以及python源碼。
15項檢測項目分別為單比特頻數檢測、塊內頻數檢測、撲克檢測、重疊子序列檢測、游程總數檢測、游程分布檢測、塊內最大“1”游程檢測、二元推導檢測、自相關檢測、矩陣秩檢測、累加和檢測、近似熵檢測、線性復雜度檢測、 Maurer通用統計檢測、離散傅立葉檢測。
規定了商用密碼應用中的隨機性檢測指標和檢測方法,適用於對隨機數發生器產生的二元序列的隨機性檢測。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1/15 單比特頻數檢測 monobit frequency test
a) 將待檢序列ε 中的 0 和 1 分別轉換成-1 和 1, X i = 2εi -1 (1 ≤ i n ≤ )。
b) 對其累加求和得
c) 計算統計值
d) 計算
erfc為余誤差函數。
e) 如果
則認為待檢測序列通過但比特數檢測。
原理:
單比特頻數檢測是最基本的檢測,用來檢測一個二元序列中0和1的個數是否相近。也就是說,若已知一個長度為n的二元序列,檢測改序列是否有較好的0、1平衡性。令n0、n1分別表示該序列中0和1的數目。對一個隨機序列,當其長度充分大時,其統計值V應該服從正態分布
參數要求:
n>100
不通過分析:
0或1個數太小
測試demo
import math def count_ones_zeroes(bits): ones = 0 zeroes = 0 for bit in bits: if (bit == 1): ones += 1 else: zeroes += 1 return (zeroes,ones) def monobit_test(bits): n = len(bits) zeroes,ones = count_ones_zeroes(bits) s = abs(ones-zeroes) print (" Ones count = %d" % ones) print (" Zeroes count = %d" % zeroes) p = math.erfc(float(s)/(math.sqrt(float(n)) * math.sqrt(2.0))) success = (p >= 0.1) return (success,p,None) bits=[1,1,0,1,0,0,1,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,1,1,1,1, 0,1,1,1,1,1,0,0,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0, 0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,1,0,0,0,0,1,0,1,0, 0,1,1,0,0,0,1,1,1,0,1,0,0,0,0,1,0,0,1,0,1,0,1,0,0,1,1, 0,0,0,1,1,0,1,0,1,1,1,0,0,1,1,1,1,1,0,0,0] if __name__ == "__main__": s1,s2,s3= monobit_test(bits) print(s1) print("p value is %s" %s2)