國密隨機數檢測--2/15 塊內頻數檢測


最近研究隨機數檢測,主要學習了一下NIST和國密檢測,這里整理了國密15項檢測規項目的原理,數學表達式以及python源碼。

15項檢測項目分別為單比特頻數檢測、塊內頻數檢測、撲克檢測、重疊子序列檢測、游程總數檢測、游程分布檢測、塊內最大“1”游程檢測、二元推導檢測、自相關檢測、矩陣秩檢測、累加和檢測、近似熵檢測、線性復雜度檢測、 Maurer通用統計檢測、離散傅立葉檢測。

規定了商用密碼應用中的隨機性檢測指標和檢測方法,適用於對隨機數發生器產生的二元序列的隨機性檢測。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2/15 塊內頻數檢測

a) 將待檢序列 ε 分成 N = |n/m| 個長度為 m 的非重疊子序列,將多余的比特舍棄。本規范取m =100

b) 計算每個子序列中1所占的比例

 

 

 c) 計算統計量

 

 d) 計算

igamc 為不完全伽馬函數。

 

e) 如果 P-value  ≥ α , 則認為待檢序列通過塊內頻數檢測。 

 

 

原理:

塊內頻數檢測用來檢測待檢序列的m位子序列中1的個數是否接近m/2。對隨機序列來說,其任意長度為m位中子序列中1的個數都應該接近m/2。

 

參數要求:

n>=100; m>=20

 

不通過分析:

m位子序列0、1分布不均衡

 

測試demo

import math
from fractions import Fraction
#from scipy.special import gamma, gammainc, gammaincc
from gamma_functions import *

#ones_table = [bin(i)[2:].count('1') for i in range(256)]
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 frequency_within_block_test(bits):
    # Compute number of blocks M = block size. N=num of blocks
    # N = floor(n/M)
    # miniumum block size 20 bits, most blocks 100
    n = len(bits)
    M = 20
    N = int(math.floor(n/M))
    if N > 99:
        N=99
        M = int(math.floor(n/N))
    
    if len(bits) < 100:
        print ("Too little data for test. Supply at least 100 bits")
        #return (FAIL,1.0,None)
    
    print ("  n = %d" % len(bits))
    print ("  N = %d" % N)
    print ("  M = %d" % M)
    
    num_of_blocks = N
    block_size = M #int(math.floor(len(bits)/num_of_blocks))
    #n = int(block_size * num_of_blocks)
    
    proportions = list()
    for i in range(num_of_blocks):
        block = bits[i*(block_size):((i+1)*(block_size))]
        zeroes,ones= count_ones_zeroes(block)
        proportions.append(Fraction(ones,block_size))

    chisq = 0.0
    for prop in proportions:  #
        chisq += 4.0*block_size*((prop - Fraction(1,2))**2)
    
    p = gammaincc((num_of_blocks/2.0),float(chisq)/2.0)
    success = (p >= 0.01)
    return success,p,None
    


if __name__ == "__main__":
    #bit2='0111011010111101111101010000110100011000111011000101010111110001010100010011110110100111010000101010111000101'
    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] 
    s1,s2,s3= frequency_within_block_test(bits)
    print(s1)
    print("p value is %s" %s2)
    

 

 


 

 


免責聲明!

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



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