MORYLAB;

エンジニアの卵がソースコードやライフログを綴るブログ。

乱数生成について調べてみた

大学のゼミで、ブロックチェーン関連の暗号技術やゲーム理論を学んでるんだけど、乱数生成について興味を持ったので少しだけ調べてみた。

乱数と疑似乱数

疑似乱数は、ソフトウェア的な処理の結果出力されるものであり、純粋な乱数ではない。というのも、疑似乱数生成アルゴリズムによっては、生成法と内部の状態がわかれば乱数を予測できてしまう場合があるからである。

例えば、線形合同法では、規則的な分布が現れたり、最下位ビットが0101で繰り返されたりするため安全な疑似乱数とは言えず、暗号に用いてはいけない。

安全な乱数を生成するには、SecureRandom(Ruby)やCrypto/rand(Go) などを使い、ハードウェアの乱数生成器を使う必要がある。


乱数生成器

IntelAMDのモダンなCPUなら、ハードウェアの乱数生成器がついていて、熱雑音などをもとに安全な乱数を生成してくれる。
Mac/Linux系なら /dev/random(ちょっと遅い)か、
/dev/urandom(少し質が劣るが速い)を使う。 a /dev/random - Wikipedia

cat /dev/random

とすると、乱数列がドウワァァァァって出てくる。
(ターミナルで趣味がばれますね) f:id:morrrry:20181113170245p:plain


乱数生成ライブラリ

普段RailsとかGoとかでWeb開発をしていると、セキュアなところで乱数が必要となるわけですが、以前は脳死で「secure_randomとかcrypto/rand使っとけばいいんじゃろ」とやっていたわけです。 しかし、Java.util.randomが線形合同法と聞いて、多言語のライブラリの実装はどうなんだろうと興味を持ってみたので、普段使っているRubyやGoでポピュラーな乱数生成ライブラリについて少し調べてみました。

Random (Java Platform SE 8)


SecureRandom (Ruby)

よく使うやつです。
サポートしている乱数生成器は openssl と /dev/urandom で、これらが使用できない場合は NotImplementedError が発生する。

docs.ruby-lang.org

crypto/rand (Golang)

これもよく使います。
Linuxでは、/dev/urandom を使用し、使用可能であれば getrandom(2) が使われ、他のUnix-like(Macとか)な環境では、/dev/urandom が使われるとのこと。

rand - The Go Programming Language


おわりに

乱数生成だいじ。