AVR乱数ジェネレーター


12

TIのappnoteslaa338)を読んで、「擬似」ではなく「実数」の乱数を生成する手法について説明しています。この目標を達成するために、MSP430のややエキゾチックなクロックサブシステムを活用します。「実際の」乱数を生成するために、AVR(特にXMegaに興味があります)に実装できる手法を知っている人はいますか?


1
サイコロゲームの擬似ランダムは動作します。私は彼が暗号的に安全であることを望んでいると思う。
Kortuk

2
必要なアプリケーションおよび/またはランダム性の程度についてヒントを提供できますか?暗号化の場合、シードの品質だけでなく、追加の考慮事項があります。さまざまなタイプの環境入力のサンプリングなど、すでに行われている提案のいくつかは、要件に基づいて適切である場合とそうでない場合があります。
ウィンデルオスケイ

回答:


6

XMegaを使用するのはどれほど悪いですか?暗号と乱数の生成がプロジェクトの大きな部分を占める場合、AtmelのSecureAVRシリーズにはハードウェア乱数が組み込まれており、暗号アプリケーション用に設計されています。

とにかく、良い分布を持つランダムなシードソースを見つけることを疑います。疑似乱数ジェネレーターを数回実行する必要があります。毎回異なるシードから開始する限り、これにより素敵な乱数のセットが得られます。LGCは、すばやく簡単な擬似ランダムジェネレーターです。

static unsigned long Seed; 

/* Call before first use of NextVal */
unsigned long InitSeed()
{
   //Your code for random seed here

   // Correct distribution errors in seed
   NextVal();
   NextVal();
   NextVal();
   return NextVal();
}

 /* Linear Congruential Generator 
  * Constants from  
  * "Numerical Recipes in C" 
  * by way of 
   * <http://en.wikipedia.org/wiki/Linear_congruential_generator#LCGs_in_common_use>
   * Note: Secure implementations may want to get uncommon/new LCG values
  */
unsigned long NextVal()
{
  Seed=Seed*1664525L+1013904223L;
  return Seed;
} 

1
それは素晴らしい、私はSecureAVRラインが存在することに気づかなかった、ポインターのおかげで!
vicatcu

ところで:本当にセキュリティが必要な場合、私が提示したシンプルで効果的で高速なLCGの方法は、あなたが望むものではありません。多くのLCGが壊れる可能性があります。連続して2〜3個の値を取得し、一連の既知の定数を使用してLCGジェネレーターに接続します。これには、Wikipediaページのすべてが含まれます。一致するパターンにより、攻撃者は次の数字がどうなるかを予測できます。定数が何からのものであるかを把握することも可能ですが(より困難です)。
ケビンフェルメール

1
@reemrevnivek参考までに、AtmelはSecureAVRラインを販売しています... AVRとは開発環境の点でまったく異なる暗号化が必要な場合、ARMベースの32ビットプロセッサをお勧めします。彼らにはTrue RNGがいくつかありますが、いつか一緒にプレイするかもしれません。
vicatcu

7

ADCをハードウェアノイズソースに接続し、必要に応じてソフトウェアを使用して乱数を「ホワイトニング」します。

これを行うAVRベースのプロジェクトを次に示します。Leonのミニポータブルランダムナンバージェネレーター(mPRNG)

暗号化の必要性に応じて、外部ハードウェアの代わりに、接地されたアナログ入力または「内部温度センサー」のノイズをランダム性シードとして使用できます。

更新:後でチップのタイマーをエントロピーソースとして使用するArduino用のプログラムを作成し(ノイズの多いビットが切り捨てられるためADCは役に立たないことが判明しました)、これがEntropyライブラリの作成に影響を与えました。

どちらの場合も、ランダム性は、たとえば温度値自体からのものではなく、ゆっくりと変化するだけでなく、読み取りごとにランダムに変化する最下位ビットからのものです。出力のビットごとに1回、値を複数回読み取り、前の読み取りとビットシフトおよびXORします。 真にランダムなビットと無相関のビットを排他的論理和すると、ランダム性が保持されるため、ランダム性がすべてのビットに広がり、真のホワイトノイズになります。ただし、取得時間またはタイマーサイクルごとに1ビットの出力しか得られないため、ビットレートはそれほど高くありません。タイマー方式では、約64ビット/秒を取得していました。


5
(多かれ少なかれ)RNGに「-PRNG」という名前を付けるのは残念です。
ニックT

ADCの+1は、おそらく温度センサーよりも高い周波数で変化するものを探していると思います。
タコ

1
@Octopusさて、温度をエントロピーソースとして使用しているのではなく、ノイズのある最下位ビットを使用しているため、温度が一定であってもADCを読み取るたびにランダムに変化します。ただし、Arduinoでテストしたとき、これらのビットは常に0であったため、実行可能ではなく、代わりにタイマーのバリエーションを使用する必要がありました。その方法を使用した別のMCUでは、ADCのLSBはノイズが多く使用できました。
エンドリス

3

ランダムシードを生成するもう1つの方法は、外部イベントが発生するまでのクロックサイクル数をカウントすることです。たとえば、これが人が使用するデバイスである場合、「go」ボタンを押すまでのクロックサイクル数をカウントし、それをランダムシードとして使用します。


4
これは、1つのデバイスの制御を保護することで侵入できるため、サイドチャネル攻撃に対してはあまり安全ではありませんが、すべての暗号化と同様に、アプリケーションは実行可能性を決定します。
Kortuk

3

同じシーケンスで再起動しないようにするには、eepromでsommeバイトを使用します。

#include <avr/eeprom.h>
#include <stdlib.h> // rand

u16  EEMEM randinit; 

int main(void) {
        srand(eeprom_read_word(&randinit));
        eeprom_write_word(&randinit,rand());
        [...]
 }

これは非常に良いランダムを与え、プログラム/メモリに多くの費用はかかりません。


2
これは毎回バイト0を読み取ります。このバイトがランダムであるという証拠はありますか?もしそうなら、これは素晴らしいテクニックです!
ケビンフェルメール

この単語(実際にはバイト0と1)はランダムになります。これは、起動するたびに、そのコンテンツでランダムジェネレーターを初期化するためです。次に、新しいrand()でアップロードします。したがって、次の初期化は現在の初期化からランダムに見えます...など...しかし、randinitをffff(または0000?)にリセットすると、同じrandinitシーケンスになります!完璧ではありません。* .hexをアップロードするときにeepromを消去するヒューズに関する警告を忘れました;)
jojo l'abricot

3

Arduino用に設計されたオリジナルがavrでg ++を使用するC ++実装のクラスとして機能するライブラリを作成しましたが、実際には最近ARMアーキテクチャにも移植されています。

ウォッチドッグタイマーとシステムクロック間のジッターを利用し、さまざまなチップでテストされています(wikiページに記載)

http://code.google.com/p/avr-hardware-random-number-generation/wiki/WikiAVRentropy


2

randomSeed()のようなものを使用して見ましたか?-Arduino IDEで使用

この関数を使用して、atmel AVRのフローティング(フリー)アナログピンをサンプリングし、その値を使用して、擬似乱数関数-random()の任意の開始点を作成できます。

random()によって作成された値は、擬似乱数の場合があります-ただし、randomSeed()によって作成された任意の開始点は、取得できる限り実数の乱数/値である必要があります。


2
アナログピンのようなものをサンプリングすることはランダムに近いですが、均等な分布にはなりません。ただし、シードをランダムに数回実行すると、実際に実行されます。
ケビンフェルメール

....疑似乱数ジェネレーターを介していくつか... <-どのようにしてそれが失われましたか?NTS:最初に脳を、次に指を動かします。
ケビンフェルメール

正確に-暗号化/保護などに使用する場合、これは最も安全ではありませんが、生成音楽やサイコロゲームなどの素敵な乱数を提供します。実装も簡単で良い:)
ジム

1

AVRハードウェアでこれを達成する方法に関する論文があります。クロックジッターに依存します。基本的に、1つのクロックソースに基づくタイマー割り込みを使用して、独立した独立したクロックソースからクロックされる独立したタイマーの下位ビットをサンプリングします。2つのクロックにはランダムなジッターが関連付けられており、サンプリングは完全に周期的ではありません。

STM32マイクロコントローラーでこれの概念実証を少し行いました。コードはgithubにあります。一連のランダム化テストスイートに基づいて、いくつかの良い結果が得られました。

私の意見では、これは非常に攻撃しやすいADCでフローティングピンをサンプリングするよりも良いと思います(ピンをグランドに接続すると、番号はランダムではなくなります!)。クロックジッタベースのRNGを操作する方法があると確信していますが、オンチップの内部クロックソースに基づいて純粋にこれを行うことができると、少し気分が良くなります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.