隨機數發生器(True Random Number Generator,TRNG)是一種用于生成隨機數的設備,其輸出的隨機數是基于物理隨機現象或過程產生的,這些現象或過程具有固有的隨機性
正如我們在[沿著低成本MCU路漫步]中所談到的,我們開始嘗試用相當低成本的應廣(Padauk0 – PFS154制造隨機數生成器。
我們如何創造“真正的”隨機性?
在我們深入研究實現之前,我們可以更多地研究如何實現真正的隨機性。
如前所述,我們希望:
通過串行通信鏈路吐出真隨機數的設備
我們如何實現這一目標是最棘手的部分。正如我們在[隨機性:它是什么?我們為什么需要它?我們如何創建它?],偽隨機性很容易創建,但真正的隨機性需要更多。這里的關鍵是從物理事物中獲取熵。
有幾種方法(和地點)可以獲取此熵。
也許最常用的是制造一個從硬件中獲取噪聲的系統,例如齊納二極管擊穿、ADC、人體鍵盤時序、鼠標移動、空氣湍流等。
但是我們希望在盡可能少(希望沒有)外部要求的情況下做到這一點,而PFS154沒有ADC模塊,因此不可能從ADC或通過ADC實現隨機性。
有幾個人已經實現了隨機數生成器,它使用2個以不同速度運行的系統時鐘,當其中最慢的時鐘滴答作響時,數據從連接到另一個時鐘的計數器中取出。
通過這樣做,我們可以捕獲時鐘噪聲和抖動(可能接近100%隨機)。
PFS154有兩個時鐘系統,我們認為它們彼此完全獨立。即IHRC和ILRC,其中IHRC是“快速的”,通常運行在16 MHz,而“慢速”/ ILRC運行在~54 kHz。
我們可以將兩個不同的時鐘通過管道傳輸到單獨的計時器中,并在每次觸發“慢速中斷”時從快速計數器中取出一些位。
實施和一些數據
T16中斷只發生在~1.6 Hz,以使兩個時鐘有時間表現不同(IHRC 8位計數器為每個T16中斷封裝約39,000次)。
但這意味著我們每5秒只能獲得一個完整字節的數據!導致一個不那么快的數字生成器…
首先,我們嘗試在每次中斷時取出2位,從而得到驚人的1.25 bps,但結果數據顯然不是隨機的(參見下面的“第1輪”結果)。因此,我們通過每次中斷僅從計數器獲取1位數據來降低速度(來自此的數據稱為“第2輪”)。
這個系統在這兩輪中產生的所有數據都可以在這里和這里下載。
if ( INTRQ & INTRQ_T16 )
{
if ( random_number_index == 0 )
{
random_number = 0;
}
// take out one bit each time
random_number |= ( ( (TM3CT & 0b00000010) >> 1) << random_number_index );
if ( random_number_index >= 7 )
{
random_number_index = 0;
new_number = 1;
}
else
{
random_number_index++;
}
// mark T16 interrupt request processed
INTRQ &= ~INTRQ_T16;
}
_number_index == 0 )
{
random_number = 0;
}
// take out one bit each time
random_number |= ( ( (TM3CT & 0b00000010) >> 1) << random_number_index );
if ( random_number_index >= 7 )
{
random_number_index = 0;
new_number = 1;
}
else
{
random_number_index++;
}
// mark T16 interrupt request processed
INTRQ &= ~INTRQ_T16;
}
為了方便使用,easypdk被修改為將傳入的數據轉儲到二進制文件:
// Changes added to easypdkprog.c line 714+:
FILE *fptr;
if ( dbgd>0 && !first_byte )
{
dbgmsg[dbgd]=0;
printf("%s", dbgmsg);
fptr = fopen("serialdump.bin","ab");
fwrite(&dbgmsg[0], 1, 1, fptr);
fclose(fptr);
}
if ( first_byte )
{
first_byte = false;
}
是隨機的嗎?不。
如果我們從兩輪的分布開始看
你很快就會發現這不是均勻分布的。如果我們觀察這個分布的發展,我們也會發現它缺少幾層“隨機性”:
所以只要快速看一下這些數字我們就知道這不是隨機的。
是的,數據集相當小(第2輪只包含9 189 912位),但我們仍然可以看到這不是“正確”的方式???
為了好玩,我們在《dieharder》中對這個數據集進行了幾次統計測試。結果并不令人驚訝:
$ dieharder -g 201 -f serialdump_round2.bin -a
#=============================================================================#
# dieharder version 3.31.1 Copyright 2003 Robert G. Brown #
#=============================================================================#
rng_name | filename |rands/second|
file_input_raw| serialdump_round2.bin| 4.98e+06 |
#=============================================================================#
test_name |ntup| tsamples |psamples| p-value |Assessment
#=============================================================================#
# The file file_input_raw was rewound 48 times
diehard_birthdays| 0| 100| 100|0.00000000| FAILED
# The file file_input_raw was rewound 396 times
diehard_operm5| 0| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 842 times
diehard_rank_32x32| 0| 40000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 1051 times
diehard_rank_6x8| 0| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 1142 times
diehard_bitstream| 0| 2097152| 100|0.00000000| FAILED
# The file file_input_raw was rewound 1872 times
diehard_opso| 0| 2097152| 100|0.00000000| FAILED
# The file file_input_raw was rewound 2359 times
diehard_oqso| 0| 2097152| 100|0.00000000| FAILED
# The file file_input_raw was rewound 2587 times
diehard_dna| 0| 2097152| 100|0.00000000| FAILED
# The file file_input_raw was rewound 2609 times
diehard_count_1s_str| 0| 256000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 3055 times
diehard_count_1s_byt| 0| 256000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 3063 times
diehard_parking_lot| 0| 12000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 3069 times
diehard_2dsphere| 2| 8000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 3073 times
diehard_3dsphere| 3| 4000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 4199 times
diehard_squeeze| 0| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 4199 times
diehard_sums| 0| 100| 100|0.00000000| FAILED
# The file file_input_raw was rewound 4234 times
diehard_runs| 0| 100000| 100|0.83092807| PASSED
diehard_runs| 0| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 4712 times
diehard_craps| 0| 200000| 100|0.00000000| FAILED
diehard_craps| 0| 200000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 11677 times
marsaglia_tsang_gcd| 0| 10000000| 100|0.00000000| FAILED
marsaglia_tsang_gcd| 0| 10000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 11711 times
sts_monobit| 1| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 11746 times
sts_runs| 2| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 11781 times
sts_serial| 1| 100000| 100|0.00000000| FAILED
sts_serial| 2| 100000| 100|0.00000000| FAILED
sts_serial| 3| 100000| 100|0.00000000| FAILED
sts_serial| 3| 100000| 100|0.00000000| FAILED
sts_serial| 4| 100000| 100|0.00000000| FAILED
sts_serial| 4| 100000| 100|0.00000000| FAILED
sts_serial| 5| 100000| 100|0.00000000| FAILED
sts_serial| 5| 100000| 100|0.00000000| FAILED
sts_serial| 6| 100000| 100|0.00000000| FAILED
sts_serial| 6| 100000| 100|0.00000000| FAILED
sts_serial| 7| 100000| 100|0.00000000| FAILED
sts_serial| 7| 100000| 100|0.00000000| FAILED
sts_serial| 8| 100000| 100|0.00000000| FAILED
sts_serial| 8| 100000| 100|0.00000000| FAILED
sts_serial| 9| 100000| 100|0.00000000| FAILED
sts_serial| 9| 100000| 100|0.00000000| FAILED
sts_serial| 10| 100000| 100|0.00000000| FAILED
sts_serial| 10| 100000| 100|0.00000000| FAILED
sts_serial| 11| 100000| 100|0.00000000| FAILED
sts_serial| 11| 100000| 100|0.00000000| FAILED
sts_serial| 12| 100000| 100|0.00000000| FAILED
sts_serial| 12| 100000| 100|0.00000000| FAILED
sts_serial| 13| 100000| 100|0.00000000| FAILED
sts_serial| 13| 100000| 100|0.00000000| FAILED
sts_serial| 14| 100000| 100|0.00000000| FAILED
sts_serial| 14| 100000| 100|0.00000000| FAILED
sts_serial| 15| 100000| 100|0.00000000| FAILED
sts_serial| 15| 100000| 100|0.00000000| FAILED
sts_serial| 16| 100000| 100|0.00000000| FAILED
sts_serial| 16| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 11851 times
rgb_bitdist| 1| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 11990 times
rgb_bitdist| 2| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 12199 times
rgb_bitdist| 3| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 12478 times
rgb_bitdist| 4| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 12826 times
rgb_bitdist| 5| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 13244 times
rgb_bitdist| 6| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 13731 times
rgb_bitdist| 7| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 14288 times
rgb_bitdist| 8| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 14915 times
rgb_bitdist| 9| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 15611 times
rgb_bitdist| 10| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 16377 times
rgb_bitdist| 11| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 17213 times
rgb_bitdist| 12| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 17283 times
rgb_minimum_distance| 2| 10000| 1000|0.00000000| FAILED
# The file file_input_raw was rewound 17387 times
rgb_minimum_distance| 3| 10000| 1000|0.00000000| FAILED
# The file file_input_raw was rewound 17527 times
rgb_minimum_distance| 4| 10000| 1000|0.00000000| FAILED
# The file file_input_raw was rewound 17701 times
rgb_minimum_distance| 5| 10000| 1000|0.00000000| FAILED
# The file file_input_raw was rewound 17770 times
rgb_permutations| 2| 100000| 100|0.00008615| WEAK
# The file file_input_raw was rewound 17875 times
rgb_permutations| 3| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 18014 times
rgb_permutations| 4| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 18188 times
rgb_permutations| 5| 100000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 18536 times
rgb_lagged_sum| 0| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 19233 times
rgb_lagged_sum| 1| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 20277 times
rgb_lagged_sum| 2| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 21670 times
rgb_lagged_sum| 3| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 23411 times
rgb_lagged_sum| 4| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 25501 times
rgb_lagged_sum| 5| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 27938 times
rgb_lagged_sum| 6| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 30724 times
rgb_lagged_sum| 7| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 33858 times
rgb_lagged_sum| 8| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 37340 times
rgb_lagged_sum| 9| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 41170 times
rgb_lagged_sum| 10| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 45348 times
rgb_lagged_sum| 11| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 49875 times
rgb_lagged_sum| 12| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 54750 times
rgb_lagged_sum| 13| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 59973 times
rgb_lagged_sum| 14| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 65545 times
rgb_lagged_sum| 15| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 71464 times
rgb_lagged_sum| 16| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 77732 times
rgb_lagged_sum| 17| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 84348 times
rgb_lagged_sum| 18| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 91312 times
rgb_lagged_sum| 19| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 98624 times
rgb_lagged_sum| 20| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 106285 times
rgb_lagged_sum| 21| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 114294 times
rgb_lagged_sum| 22| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 122651 times
rgb_lagged_sum| 23| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 131356 times
rgb_lagged_sum| 24| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 140409 times
rgb_lagged_sum| 25| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 149811 times
rgb_lagged_sum| 26| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 159561 times
rgb_lagged_sum| 27| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 169659 times
rgb_lagged_sum| 28| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 180105 times
rgb_lagged_sum| 29| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 190900 times
rgb_lagged_sum| 30| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 202042 times
rgb_lagged_sum| 31| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 213533 times
rgb_lagged_sum| 32| 1000000| 100|0.00000000| FAILED
# The file file_input_raw was rewound 213568 times
rgb_kstest_test| 0| 10000| 1000|0.00000000| FAILED
# The file file_input_raw was rewound 214103 times
dab_bytedistrib| 0| 51200000| 1|0.00000000| FAILED
# The file file_input_raw was rewound 214148 times
dab_dct| 256| 50000| 1|0.00000000| FAILED
Preparing to run test 207. ntuple = 0
# The file file_input_raw was rewound 214541 times
dab_filltree| 32| 15000000| 1|0.00000000| FAILED
dab_filltree| 32| 15000000| 1|0.00000000| FAILED
Preparing to run test 208. ntuple = 0
# The file file_input_raw was rewound 214626 times
由于必須重繞輸入數據文件的次數,diehard -test可能會報告幾個假陰性結果。因此,如果您實際要使用統計測試電池,如硬測試,則需要許多GB的原始數據(與這里的~1 MB相比!)
為什么這不是隨機的?
我們可以清楚地看到,這個數據不是“隨機的”。
但兩個獨立的硬件時鐘應該包含足夠的隨機性和抖動,我們可以提取!
也許他們不像我們想象的那么獨立?
因為當我們校準其中一個時鐘時,另一個時鐘開始表現不同,這意味著某種相互作用發生了。也許Padauk偶爾會用IHRC校準ILRC ?
這不是一件壞事,但請注意,數據表中沒有記錄這種行為,因此很難在PFS154上以這種方式制作TRNG。