あらゆるFPGA (さらには ASIC) に対応した、プラットフォームに依存しない小型の真の乱数ジェネレーターです。
neoTRNG は、あらゆるターゲット テクノロジ (FPGA や ASIC) 向けに合成できる、小型でプラットフォームに依存しないTRUE 乱数生成器 (TRNG) を目指しています。これは、あらゆるプラットフォームでの合成を可能にするために特別な技術によって強化された、シンプルなフリーランニング リング オシレーターに基づいています。フリーランニング リング発振器のサンプリング時に発生する位相ノイズは、物理エントロピー ソースとして使用されます。
このプロジェクトは、neoTRNG がデフォルトの SoC モジュールとして実装されている NEORV32 RISC-V プロセッサからの「スピンオフ」です。
主な特長
注意
内部/外部信号/イベントと生成された乱数の間に少なくともある程度の相互相関がある可能性があります。したがって、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'
に接続します)。ランダム データは、単純な data/valid インターフェイスを使用して取得されます。新しい有効なランダム バイトが利用可能な場合は常に、 valid_o
出力が正確に 1 サイクルの間 High になるため、 data_o
出力はユーザー ロジックによってサンプリングできます。
enable_i
信号は、TRNG の初期化と開始に使用されます。 TRNG を使用する前に、内部シフト レジスタのすべてのビットが再度クリアされるように、この信号を少なくとも数 100 クロック サイクル (構成に応じて) ローに保つ必要があります。 enable_i
が設定され、 valid_o
初めて設定されると、TRNG が動作可能になります。 TRNG を無効にするには、同じクロック サイクルの間、 enable_i
Low である必要もあります。 enable_i
Low になると、すべてのリング発振器が停止され、動的スイッチング動作と消費電力が削減されます。
neoTRNG を設定するために 3 つのジェネリックが提供されています。 NUM_CELLS
エントロピー セルの総数を定義します。 NUM_INV_START
最初のセル内のインバーターの数 (= リングオシレーターの長さ) を定義します。これら 2 つのジェネリックについては、以下の「アーキテクチャ」セクションで詳しく説明します。最後の汎用SIM_MODE
、プレーンな RTL シミュレーション内で TRNG のシミュレーションを可能にするように設定できます。
neoTRNG は、構成可能な数 ( NUM_CELLS
) のエントロピー セルに基づいています。各セルは、奇数のインバータを使用して構築された単純なリング発振器 (「RO」) を提供します。 RO の発振周波数は、リング内の要素の伝播遅延によって定義されます。この周波数は、熱雑音、電子ショットノイズによって引き起こされる最小限の変動を受けるため、静的ではありません。 RO の最後のインバーターの状態は、スタティック クロック ( clk_i
) を使用してフリップ フロップにサンプリングされます。 RO の周波数は時間の経過とともに無秩序に変化するため、サンプリングされたデータに固有の位相ノイズが実際のエントロピー ソースとして使用されます。
各エントロピー セルは、ランダム データの 1 ビット ストリームを生成します。すべてのセルの出力は、単純なランダムネス エクストラクターによってストリームのバイアスが解除される前に、ワイド XOR ゲートを使用して混合されます。バイアス解除されたいくつかのビットがサンプリング ユニットによってサンプリング/逆シリアル化され、バイト幅の乱数が提供されます。サンプリング ユニットは、乱数のスペクトル分布を改善するために簡単な後処理も適用します。
各エントロピー セルは、奇数の反転ラッチから構築されたリング オシレーターで構成されています。一番最初のエントロピー セルのリングの長さは、 NUM_INV_START
ジェネリックによって定義されます。エントロピー セルを追加するたびに、この初期チェーン長にさらに 2 つのインバーターが追加されます。したがって、追加のエントロピー セルはそれぞれ、以前のものよりも低い周波数で振動します。
リングオシレーターのような非同期要素は、通常、プラットフォーム/テクノロジー固有のプリミティブ、属性、または合成設定を使用する必要があるため、プラットフォームに依存しない方法で実装するのは困難です。あらゆるターゲット テクノロジ向けに合成できる、実際のターゲットに依存しないアーキテクチャを提供するために、特別な技術が適用されます。RO 内の各インバータの後には、グローバル リセットを提供するラッチと、スイッチを有効にする個別のラッチが続きます。ラッチを透明モードにします。
個々のラッチ イネーブルは、RO チェーン内の単一ラッチごとに個別の FF を備えた長いシフト レジスタによって制御されます。 TRNG が有効になると、このシフト レジスタは 1 で埋められ始めます。したがって、ラッチは 1 つずつ個別にイネーブルされ、各ラッチの起動状態は (理論的には) 外部ロジックによって監視できるため、合成ツールが RO チェーンからロジック/要素をトリミングすることは不可能になります。すべてのエントロピー セルのイネーブル シフト レジスタはデイジーチェーン接続され、エントロピー アレイ全体にわたってこの起動手順を継続します。
次の図は、リング オシレータ用の 5 つのインバータ ラッチ要素、イネーブル シフト レジスタ用の 5 つのフリップ フロップ、およびシンクロナイザ用の別の 2 つのフリップ フロップで構成される最初のエントロピー セルの簡略図を示しています。
FPGA による最初のエントロピー・セルのマッピング結果 (インテル Quartus Prime によって生成) を示す画像は、ここで見ることができます。これは、リング オシレーター チェーンのすべてのラッチ + インバーター要素が個々の LUT4 に正常にマッピングされたことを示しています。
エントロピー セルのデイジーチェーン イネーブル シフト レジスタの最後のビットが設定されるとすぐに、バイアス解除ユニットが開始されます。このユニットは、取得されたランダム データ ストリームのバイアスを除去するための単純な「ジョン フォン ノイマンランダムネス エクストラクター」を実装しています。エクストラクターは、エントロピー セル配列から XOR 演算されたランダム ビットをサンプリングする 2 ビット シフト レジスタを実装します。抽出器は 2 サイクルごとに 2 つのサンプリングされたビットを評価し、エッジの重複していないビットのペアをチェックします。
エッジが検出されるたびに、「有効」信号が次のサンプリング ユニットに送信されます。立ち上がりエッジ ( 01
) は1
データ ビットを出力し、立ち下がりエッジ ( 10
) は0
データ ビットを出力します。したがって、バイアス解除ユニットは単一のランダム ビットを生成するのに少なくとも 2 クロック サイクルを必要とします。エッジが検出されない場合 ( 00
または11
)、有効信号は Low のままで、サンプリング ユニットは停止します。
サンプリング ユニットは 8 ビット シフト レジスタを実装して、シリアル デバイアスされたビットストリームをバイト幅の乱数に変換します。さらに、サンプル ユニットは、取得したランダム サンプルのスペクトル分布を改善するための簡単な後処理を提供します。
1 バイトのランダム データを生成するために、サンプリング ユニットは内部シフト レジスタをオール 0 にリセットし、バイアス解除されたランダム ストリームの 64 ビットの消費を開始します。シフト レジスタは線形フィードバック シフト レジスタ(LFSR) として実装されており、入力ストリームとレジスタの最後のビットとの XOR を計算して、ランダム ビットストリームをさらにスクランブルおよび混合します。
neoTRNG は NEORV32 プロセッサの一部として評価され、neoTRNG は標準 SoC モジュールとして利用できます。このプロセッサは、100MHz で動作する Intel Cyclone IV EP4CE22F17C6N
FPGA 用に合成されました。評価には非常に小さなデフォルト構成が使用されています。3 つのエントロピー セルが実装されており、最初のエントロピー セルは 5 つのインバーターを実装し、2 番目のエントロピー セルは 9 つのインバーターを実装し、3 番目のエントロピー セルは 11 のインバーターを実装します。より多くの/より大きなエントロピー セルを備えたより複雑な構成では、「より良い」ランダム品質が提供される可能性があります。
NUM_CELLS = 3
NUM_INV_START = 5
SIM_MODE = false
注記
評価用に合計4MBのランダム データが取得されました。このデータ セットは、リリース アセットのentropy.bin
バイナリ ファイルとして利用できます。
単純なヒストグラム分析のために、4MB のランダム バイトが neoTRNG からサンプリングされました。取得されたバイトは出現に従って蓄積され、各ビンが 1 つの特定のバイト パターンを表すビンに分類されます (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 乱数テストスイート (wikipedia、ホームページ) は、乱数ジェネレーターのストレス テストと特性評価に最適なツールセットです。
重要
?作業中ですか?
dieharder には大規模なランダム サンプル (約 4 GB) のセットが必要です。そうしないと、ランダム データが巻き戻され、全体のエントロピーが明らかに減少します。現在、単純な UART 接続を使用して FPGA から PC にデータを転送しています。しかし、ボーレートが高くても、4GB のデータセットを送信するには時間がかかります。より良い転送チャネルが見つかるまで (または十分な時間がかかるまで)、この評価は「進行中」です。
デフォルト構成を使用して NEORV32 RISC-V プロセッサー内に実装された neoTRNG のマッピング結果。インテル Quartus Prime を使用して 100MHz で動作するインテル 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 の最大生成レートは、次の 2 つの要素によって定義されます。
したがって、neoTRNG は 1 つのランダム バイトを送信するために少なくともA * B = 2 * 64 = 128
クロック サイクルを必要とします。 FPGA の評価により、実際のサンプリング時間は約 300 クロック サイクルであることがわかりました。したがって、100 MHz で実行する実装では、1 秒あたり約 330 KB のランダム データを生成できます。複数の neoTRNG インスタンスを並行して実行すると、より高い生成速度を実現できます。
非同期リング オシレーターは (組み合わせループのため) rtl シミュレーションできないため、neoTRNG はSIM_MODE
ジェネリックによって有効になる専用のシミュレーション モードを提供します。有効にすると、単純なフリップフロップとして実装された「伝播遅延」がリングオシレータのインバータに追加されます。
重要
シミュレーション モードはシミュレーション/デバッグのみを目的としています。 SIM_MODE
が有効になっているデザインは合成できますが、真の物理乱数はまったく提供されません。
sim
フォルダーは、デフォルト構成を使用した neoTRNG の単純なテストベンチを提供します。テストベンチは、取得したランダム データ バイトを 10 進数値としてシミュレータ コンソールに出力します。テストベンチは、提供されたスクリプトを使用して 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 アクション ワークフローによって実行されます。