現在のPCにはCore 2 i3、i5、i7というSandy Bridgeプロセサが使われているが、この後継となるのが、2012年に登場予定のIvy Bridgeと呼ばれるプロセサである。Sandy Bridgeは32nmプロセスで製造されているが、Ivy Bridgeはその次の22nmプロセスに移行する。Intelのプロセサロードマップは新プロセスへの移行とアーキテクチャの革新を1年ごとに交互に繰り返すので、プロセスを更新するIvy Bridgeではアーキテクチャ的には大きな革新は無いが、それでも、次の2枚のスライドに示されるような新機能が追加されている。

IDF2011で発表されたIvy Bridgeの追加機能

ユーザとしては3Dグラフィックスの強化やコアの性能強化に目が行くが、この記事では2枚目のスライドの最初に書いてあるデジタル乱数発生器を取り上げる。

乱数というとゲームの展開などを決めるときに使うという程度の認識が一般的であるが、実用的にも大きな役目がある。Webブラウザで買い物をしたりするときには、鍵マークが出ていることを確認するという人も多いと思うが、これは通信が暗号化されていることを示している。

暗号は、文字列を構成するビットの順番を入れ替えたりして、そのまま見たのでは意味をなさない文字列にしてから相手方に送る。受け取った方は、それを元の順序に戻して理解するというものである。インターネットでの通信の場合は、不特定多数のPCとの暗号通信が必要となるので、このビットの入れ替えと、元に戻すアルゴリズムは公開されている。従って、通信の秘密を保証するのは、そのアルゴリズムに従って具体的にどのように入れ替えが行われるかを指定する鍵の秘密性である。つまり、アルゴリズムが分かっていても、鍵が分からなければ暗号文を元に戻すことはできない。

盗聴しても鍵が分からないと元の情報は分からない

送信側で作った鍵をどのようにして安全に受信側に送るかという話は省略するが、鍵が盗まれるという問題が解決されたとしても、ログインパスワードと同じで推測されやすい鍵を使っていると、推測した鍵を次々と試して意味のある文章が得られるかどうかをチェックするという方法で暗号が解読されてしまう。

そのため、乱数を生成して鍵として使うということが行われる。これも同じ鍵を使い続けるとばれてしまう恐れがあるので、通信のたびごとに新しい乱数を生成して鍵を変える。ということで、インターネットでの暗号通信には高速の乱数生成が必要となる。

この乱数の作り方であるが、真の乱数を作るのは難しいので、疑似乱数という方法が良く使われている。

16ビットのリニアフィードバックシフトレジスタの例

疑似乱数の作り方も色々とあるが、リニアフィードバックシフトレジスタ(Linear Feedback Shift Register:LFSR)を用いる方法は、この図に示すように、シフトレジスタと何個かのXORゲートだけで実現できる。また、C言語などでも簡単に書くことができ、ソフトウェアでもかなり高速に乱数を発生できる。

この16ビットのシフトレジスタに非ゼロの初期値(Seedと呼ぶ)を与えてから次々とシフトすると、1~65535までの数値をほぼランダムな順番で一巡する。この方法でもかなりランダムな数列が得られるが、生成方法がばれてしまうと、次の鍵となる乱数を推測されてしまう。

これに対して、放射性同位元素の崩壊や熱雑音などの物理現象は本当にランダムで、次にどんな数が出てくるかは予測できない。ということで、抵抗に発生する熱雑音を増幅して乱数を発生するような物理乱数発生器が作られている。このような物理乱数発生器は、増幅のためにアナログ回路を必要とする。しかし、半導体プロセスが45nmから32nm、22nmと微細化するとトランジスタの特性が変わってしまうので、毎回、アナログ回路の再設計が必要となってしまうという問題がある。

前置きが長かったが、Ivy Bridgeの乱数発生は、新開発の全デジタル方式の物理乱数発生器を採用している。この乱数発生器について、IEEEのSpectrum誌に発表された論文をもとに紹介する。

「Bull Mountain」というコードネームで開発されたこの物理乱数発生器は、その基本メカニズムとしてラッチ回路の不安定性を利用している。

ラッチを使った物理乱数発生回路の原理図

この乱数発生回路のClock信号がLowの状態では2つのPトランジスタがオンして、Node A、Bともに電源電圧に近いHighの状態になっている。しかし、この状態では、それぞれのインバータの出力はLowになろうとしているのをオンのPトランジスタが無理にHighに引き上げている。

そして、クロックがHighに変化するとPトランジスタはオフとなるので、インバータの出力に引っ張られてNode A、Bともに電位が下がってくる。しかし、Node Aの電位が下がると下側のインバータの出力は上がってくる。また、Node Bの電位が下がると上側のインバータの出力は上がってくる。そして、両方のインバータが完全に同じでバランスしている場合は、理想的にはNode A、Bともに中間電位で止まるはずである。

ラッチを用いた乱数発生回路の動作

しかし、この中間点は安定ではなく、熱雑音でNode Aの電位が少し上がれば、Node Bの電位は下がり、それはNode Aの電位をさらに押し上げ、その結果、Node Bの電位はさらに下がるという正のフィードバックが掛ってNode AはHigh、Node BはLowという状態で落ち着く。また、中間点から熱雑音でNode Bの電位が少し上がると、最終的にはNode BがHigh、Node AがLowとなる。

熱雑音自体は物理的にランダムであるので、Node A(あるいはNode B)のHigh("1")、Low("0")はランダムになる。しかし、これは2つのインバータが完全にバランスしている場合で、偏りがあると、"1"、"0"の出現は等確率にならない。このため、Bull Mountainでは、インバータにフィードバックを掛けて"1"、"0"の出現が等確率になるようにしている。しかし、これだけでは、完全に偏りのない乱数にはならない。

Bull Mountain物理乱数発生器の全体ブロック図

そのため、乱数の性質を改善するコンディショナ(Conditioner)を繋いでいる。コンディショナは物理乱数発生器から2つの256ビット長の乱数を受け取り、1つの256ビットの改善された物理乱数を出力する。コンディショナの処理の一例として、入力の2つの乱数を掛け算して下位のビットだけを使うことにより、"0"、"1"の偏りを大幅に減らすという方法が説明されているが、実際のコンディショナにはより高度な性質改善アルゴリズムが使われているという。

そして、コンディショナが生成した256ビットの乱数を疑似乱数発生器のSeedとして供給し、疑似乱数発生器で作られる128ビットのビット列を乱数として出力するという構成になっている。疑似乱数発生器は、1つのSeedから多数の乱数を高速で発生することができ、高速の乱数発生という要件を満足する。そして、ある程度の数の乱数を発生すると、次の物理乱数をSeedとして使うという方法で高速性とランダム性を両立させている。

また、乱数が物理乱数であると、毎回、生成される乱数列が異なるので、ソフトウェアをデバグするような場合には再現性がなく困ってしまう。しかし、Bull Mountainでは疑似乱数発生器の初期値として同じ値を与えてやれば同じ乱数列が生成されるので、デバグ時に再現性がないという問題を回避できる。

乱数発生器というのは縁の下の力持ち的な存在であるが、インターネットのセキュリティの根幹をなすものであり、Ivy Bridgeでの物理乱数発生機構の実装の意義は大きいと言える。