適用於任何FPGA(甚至 ASIC)的小型且獨立於平台的真隨機數產生器。
neoTRNG 的目標是成為一個小型且與平台無關的真隨機數產生器 (TRNG),可以針對任何目標技術(FPGA 甚至 ASIC)進行合成。它基於簡單的自由運行環形振盪器,透過特殊技術對其進行了增強,以便可以針對任何平台進行合成。對自由運行的環形振盪器進行取樣時出現的相位雜訊被用作物理熵源。
該項目是 NEORV32 RISC-V 處理器的“衍生項目”,其中 neoTRNG 作為預設 SoC 模組實現。
主要特點
警告
內部/外部訊號/事件與產生的隨機數之間可能至少存在一些互相關性。因此,根本無法保證neoTRNG 提供完美的甚至加密安全的隨機數!查看提供的評估結果或(更好)自行測試。此外,還沒有可用的篡改檢測機製或線上健康監控來檢查產生的隨機資料的完整性/品質。
警告
保持 neoTRNG永久啟用會增加動態功耗,也可能導致晶片局部發熱(使用非常大的配置時)。此外,設計可能會發出額外的電磁幹擾 (EMI)。
整個設計作為單一 VHDL 檔案rtl/neoTRNG.vhd
實現,完全沒有依賴項(如特殊庫、套件或子模組)。
entity neoTRNG is
generic (
NUM_CELLS : natural range 1 to 99 := 3 ; -- number of ring-oscillator cells
NUM_INV_START : natural range 3 to 99 := 5 ; -- number of inverters in first cell, has to be odd
SIM_MODE : boolean := false -- enable simulation mode (no physical random if enabled!)
);
port (
clk_i : in std_ulogic ; -- module clock
rstn_i : in std_ulogic ; -- module reset, low-active, async, optional
enable_i : in std_ulogic ; -- module enable (high-active)
valid_o : out std_ulogic ; -- data_o is valid when set (high for one cycle)
data_o : out std_ulogic_vector ( 7 downto 0 ) -- random data byte output
);
end neoTRNG ;
neoTRNG 使用由clk_i
訊號驅動的單一時脈域。模組的重設訊號rstn_i
是可選的(如果未使用,則連接至'1'
)。隨機資料是透過使用簡單的資料/有效介面獲得的:每當有新的有效隨機位元組可用時, valid_o
輸出將在一個週期內保持高電平,因此使用者邏輯可以對data_o
輸出進行取樣。
enable_i
訊號用於初始化和啟動 TRNG。在使用 TRNG 之前,此訊號應保持低電平至少 100 個時脈週期(取決於配置),以確保內部移位暫存器的所有位元再次被清除。當設定了enable_i
並且設定了valid_o
時,TRNG第一次運行。停用 TRNG 也要求enable_i
在相同數量的時脈週期內保持低電平。當enable_i
變低時,所有環形振盪器將停止,減少動態開關活動和功耗。
提供了三個泛型來配置 neoTRNG。 NUM_CELLS
定義熵單元的總數。 NUM_INV_START
定義第一個單元中的反相器數量(= 環形振盪器的長度)。這兩個泛型將在下面的架構部分中進一步描述。最後一個通用SIM_MODE
可以設定為允許在普通 RTL 模擬中模擬 TRNG。
neoTRNG 是基於可配置數量 ( NUM_CELLS
) 的熵單元。每個單元提供一個簡單的環形振盪器(“RO”),它是使用奇數個逆變器構建的。 RO 的振盪頻率由環內元件的傳播延遲定義。此頻率不是靜態的,因為它受到熱噪聲電子散粒噪聲引起的最小波動的影響。 RO 最後一個反相器的狀態透過使用靜態時脈 ( clk_i
) 採樣到觸發器中。由於 RO 的頻率隨時間混亂而變化,採樣資料的固有相位雜訊被用作實際的熵源。
每個熵單元產生 1 位元隨機資料流。在透過簡單的隨機性提取器對流進行去偏壓之前,使用寬異或閘混合所有單元的輸出。採樣單元對幾個去偏壓位元進行採樣/去串行化,以提供位元組範圍的隨機數。採樣單元也應用簡單的後處理,以改善隨機數的頻譜分佈。
每個熵單元由一個環形振盪器組成,該環形振盪器由奇數個反相鎖存器建構而成。第一個熵單元中環的長度由NUM_INV_START
泛型定義。每個額外的熵單元都會在這個初始鍊長度上再增加 2 個反相器。因此,每個額外的熵單元以比之前更低的頻率振盪。
像環形振盪器這樣的非同步元件很難以獨立於平台的方式實現,因為它們通常需要使用特定於平台/技術的原語、屬性或綜合設定。為了提供真正的目標不可知架構,可以針對任何目標技術進行綜合,應用了一種特殊技術:RO 內的每個反相器後面都有一個鎖存器,該鎖存器提供全域重設以及用於切換的單獨鎖存使能將鎖存器設定為透明模式。
各個鎖存器使能由長移位暫存器控制,該暫存器為 RO 鏈中的每個鎖存器提供不同的 FF。當 TRNG 使能時,此移位暫存器開始填入 1。因此,鎖存器是逐一單獨啟用的,使得綜合工具不可能從 RO 鏈中修剪任何邏輯/元件,因為每個鎖存器的啟動狀態(理論上)可以由外部邏輯監控。所有熵單元的啟用移位暫存器均以菊花鏈方式連接,以在整個熵陣列上繼續此啟動過程。
下圖顯示了第一個熵單元的簡化原理圖,該熵單元由用於環形振盪器的5 個反相器鎖存器元件、用於使能移位暫存器的5 個觸發器以及用於同步器的另外2 個觸發器組成。
此處可以看到顯示 FPGA 第一個熵單元的映射結果(由 Intel Quartus Prime 產生)的圖像。它顯示環形振盪器鏈的所有鎖存器+反相器元件均已成功地對應到各個 LUT4。
一旦設定了熵單元菊花鏈使能移位暫存器的最後一位,去偏壓單元就會啟動。該單元實作了一個簡單的「約翰·馮·諾依曼隨機性提取器」來對所獲得的隨機資料流進行去偏。提取器實現了一個 2 位元移位暫存器,用於對來自熵單元陣列的異或隨機位元進行取樣。在每個第二個週期中,擷取器都會評估兩個取樣位,以檢查非重疊位對的邊緣。
每當偵測到邊緣時,就會將「有效」訊號傳送到後續取樣單元。上升沿( 01
)發出1
資料位,下降沿( 10
)發出0
資料位。因此,去偏壓單元需要至少兩個時脈週期來產生單一隨機位元。如果未偵測到邊緣( 00
或11
),則有效訊號保持低電平且取樣單元停止。
採樣單元實現了一個8位移位元暫存器,將串列去偏位元流轉換為位元組寬度的隨機數。此外,樣本單元提供了簡單的後處理,以改善所獲得的隨機樣本的光譜分佈。
為了產生一個位元組的隨機數據,取樣單元將其內部移位暫存器重設為全零,並開始消耗 64 位元的去偏壓隨機流。移位暫存器被實作為線性回授移位暫存器(LFSR),它將輸入流與暫存器的最後一位進行異或,以進一步加擾和混合隨機位元流。
neoTRNG 作為 NEORV32 處理器的一部分進行評估,其中 neoTRNG 可作為標準 SoC 模組。此處理器針對運行頻率為 100MHz 的 Intel Cyclone IV EP4CE22F17C6N
FPGA 進行綜合。為了進行評估,使用了非常小的預設配置:實現了三個熵單元,其中第一個實現了5 個反相器,第二個實現了9 個反相器,第三個實現了11 個反相器。具有更多/更大熵單元的更複雜配置可能提供「更好」的隨機品質。
NUM_CELLS = 3
NUM_INV_START = 5
SIM_MODE = false
筆記
總共獲得了4MB的隨機數據進行評估。此資料集在發布資產中以entropy.bin
進位檔案形式提供。
為了進行簡單的直方圖分析,從 neoTRNG 中取樣了 4MB 的隨機位元組。所得的位元組會根據其出現次數進行累積,並分類到 bin 中,其中每個 bin 代表特定的位元組模式(1 位元組 = 8 位元 = 256 種不同的模式)。然後分析結果的統計特性:
[NOTE] integer numbers only
Number of samples: 4194304
Arithmetic mean: 127 (optimum would be 127)
Histogram occurrence
Average: 16384 (optimum would be 4194304/256 = 16384)
Min: 16051 = average - 333 (deviation) at bin 183 (optimum deviation would be 0)
Max: 16706 = average + 322 (deviation) at bin 144 (optimum deviation would be 0)
Average dev.: +/- 96 (optimum would be 0)
$ ent entropy.bin
Entropy = 7.994306 bits per byte.
Optimum compression would reduce the size
of this 4194304 byte file by 0 percent.
Chi square distribution for 4194304 samples is 16726.32, and randomly
would exceed this value less than 0.01 percent of the times.
Arithmetic mean value of data bytes is 127.9417 (127.5 = random).
Monte Carlo value for Pi is 3.132416851 (error 0.29 percent).
Serial correlation coefficient is 0.000496 (totally uncorrelated = 0.0).
$ rngtest < entropy.bin
rngtest 5
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
rngtest: starting FIPS tests...
rngtest: entropy source drained
rngtest: bits received from input: 33554432
rngtest: FIPS 140-2 successes: 1676
rngtest: FIPS 140-2 failures: 1
rngtest: FIPS 140-2(2001-10-10) Monobit: 0
rngtest: FIPS 140-2(2001-10-10) Poker: 0
rngtest: FIPS 140-2(2001-10-10) Runs: 1
rngtest: FIPS 140-2(2001-10-10) Long run: 0
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=138.214; avg=1557.190; max=2119.276)Mibits/s
rngtest: FIPS tests speed: (min=32.660; avg=106.337; max=111.541)Mibits/s
rngtest: Program run time: 330110 microseconds
Robert G. Brown 的 dieharder 隨機數測試套件(維基百科,首頁)是一個很好的工具集,用於壓力測試和表徵隨機數產生器。
重要的
?工作正在進行中嗎?
dieharder 需要大量隨機樣本(約 4GB)。否則,隨機資料會倒帶,明顯降低整體熵。現在,我使用簡單的 UART 連接將資料從 FPGA 傳輸到 PC。但即使是更高的波特率,4GB 的資料集也需要很長時間才能發送。在我有更好的轉移管道(或只是很多時間)之前,這個評估是「正在進行中的工作」 。
使用預設配置在 NEORV32 RISC-V 處理器內實現的 neoTRNG 的對應結果。使用 Intel Quartus Prime 為以 100MHz 運作的 Intel Cyclone EP4CE22F17C6N
FPGA 產生的結果。
Module Hierarchy Logic Cells Logic Registers
------------------------------------------------------------------------------------
neoTRNG:neoTRNG_inst 56 (27) 46 (19)
neoTRNG_cell:entropy_source:0:neoTRNG_cell_inst 8 (8) 7 (7)
neoTRNG_cell:entropy_source:1:neoTRNG_cell_inst 10 (10) 9 (9)
neoTRNG_cell:entropy_source:2:neoTRNG_cell_inst 14 (14) 11 (11)
筆記
綜合工具可能會發出警告,表示已偵測到鎖存器和組合循環。然而,這並不是設計缺陷,因為這正是我們想要的。
neoTRNG 的最大生成率由兩個因素定義:
因此,neoTRNG至少需要A * B = 2 * 64 = 128
時脈週期才能發出一個隨機位元組。 FPGA評估顯示實際取樣時間約為300個時脈週期。因此,以 100 MHz 運行的實現每秒可以產生大約 330kB 的隨機資料。透過並行運行多個 neoTRNG 實例可以實現更高的生成率。
由於非同步環形振盪器無法進行 RTL 模擬(由於組合循環),neoTRNG 提供了由SIM_MODE
通用函數啟用的專用模擬模式。啟用後,將作為簡單觸發器實現的「傳播延遲」新增至環形振盪器的反相器中。
重要的
模擬模式僅用於模擬/調試!啟用SIM_MODE
的設計可以合成,但完全不會提供任何真實/物理隨機數!
sim
資料夾使用預設配置為 neoTRNG 提供了一個簡單的測試平台。測試平台會將獲得的隨機資料位元組以十進位值輸出到模擬器控制台。可以使用提供的腳本使用 GHDL 模擬測試平台:
neoTRNG/sim$ sh ghdl.sh
../rtl/neoTRNG.vhd:105:3:@0ms:(assertion note): [neoTRNG] The neoTRNG (v3.2) - A Tiny and Platform-Independent True Random Number Generator, https://github.com/stnolting/neoTRNG
../rtl/neoTRNG.vhd:112:3:@0ms:(assertion warning): [neoTRNG] Simulation-mode enabled (NO TRUE/PHYSICAL RANDOM)!
18
210
147
5
79
94
70
100
185
246
203
220
ghdl:info: simulation stopped by --stop-time @100us
GHDL 波形資料儲存到sim/neoTRNG_tb.ghw
中,可以使用gtkwave
查看:
neoTRNG/sim$ gtkwave neoTRNG_tb.ghw
簡單的模擬運行由專案的neoTRNG-sim
GitHub 作業工作流程執行。