暗号計算機屋のブログ

なにか思いついたことを不定期に更新。

巨大整数用四則演算プロセッサSnakeCubeが高速である秘密

2020年9月12日、訂正 SnakeCubeの周波数は3倍になるという予測を2倍に。 またUiからT0iの区間を1サイクルと書いていましたが2サイクルに。

はじめに

2020年3月30日、コンピュータサイエンスに関する米国の学会ACM(Association for Computing Machinery)が、 コロナ感染拡大を受けて同学会の論文が6月30日までオープンアクセスになったようです。 早速、僕が発明したSnakeCubeより優れたものがあるのか調べたところ、 電通大の崎山先生の論文(2007年)が検索でヒットしたのでSnakeCubeと比較をしてSnakeCubeが高速であることを説明します。 崎山先生の論文は、ベルギーのルーヴェンカトリック大学との共同研究のように見えています。 崎山先生は僕と同時期に日立製作所に勤務されていましたが事業部が違ったので、一度も連絡が取れたことはありません。 以後、「電通大演算器」と呼ばせていただきます。

注意! SnakeCubeはオープンソースではなく商用開発しているものです。

SnakeCubeとは

ICF3-Fと呼んでいたことがありましたがオープンソースと間違われそうなのでSnakeCubeに改名しました。 1999年 RSA暗号の性能で世界一だった暗号LSI ICF3をベースに高速化した巨大整数用四則演算プロセッサです。 汎用演算プロセッサと暗号専用演算器のセットです。僕はICF3の汎用演算プロセッサの唯一の設計、開発者です。 この汎用演算プロセッサに2018年に僕が発明した暗号専用演算器(モンゴメリ乗算器)を追加したもの。

icf.hatenablog.com

電通大演算器

米国の学会ACMの次の論文にある演算器のこと。SnakeCubeの演算器に近いところがあります。

「Efficient Pipelining for Modular Multiplication Architectures in Prime Fields」 GLSVLSI’07, March 11-13, 2007, Stresa-Lago Maggiore, Italy. Copyright 2007 ACM 978-1-59593-605-9/07/0003

演算器の構造について

大雑把な両者の演算器アーキテクチャの話をします。 モンゴメリ乗算のループ処理では、巨大整数の乗算を2回するのですが、 SnakeCubeは1個の演算器で直列に2回乗算します。 電通大は1/4個の演算器を2個を使って4回乗算します。

このことから同じ周波数であれば理論的にはSnakeCubeのほうが2倍性能が出ます。 後で説明しますが予想ではSnakeCubeのほうが高い周波数で動作します。

つまり2倍の周波数だとするとSnakeCubeは電通大演算器の4倍高速ということになりますが、 電通大演算器が毎サイクル乗算器を使っているのに対しSnakeCubeでは5サイクルに4回なので、 最終的に3.2倍高速ではないかという予測です。 SnakeCubeの最下位ビットからのブロッドキャストの工夫により、 鍵長が大きくなるにしたがってこの差が、さらに大きくなっていきます。

SnakeCubeが高周波数で動作する秘密

この説明を完全理解するには電通大演算器の論文を読む必要があると思いますが、 このタイプのモンゴメリ乗算器のクリティカルパスは最下位ビットからのブロッドキャストです。 電通大演算器は、このクリティカルパスのために周波数が上がりません。 電通大の論文に書かれている図では、UiからT0iの区間のことで2サイクルになっています。

SnakeCubeでは、このクリティカルパス3サイクルピッチの4サイクルディレイとなるような工夫をしています。 正しくは3サイクルピッチの4、5・・・nサイクルディレイです。 鍵長が大きくなるにしたがってnが大きくなっていきます。 鍵長が大きくなっても周波数が落ちません。

このため電通大演算器の1.5倍の周波数を見込めるのです。 3サイクルピッチなのですが電通大のUiからT0iに相当するのは4サイクルなので2倍の周波数。

クリティカルパスが3サイクルあるため乗算器は3回に1回しか利用されていないのかというと、 別の演算を1回入れているので、乗算器を3回に2回利用しています。さらに2スレッドにして クリティカルパスの遅延をオーバーラップさせ5サイクルに4回、乗算器を使うということをします。

まとめ

SnakeCubeは電通大演算器に対して方式性能2倍、周波数3倍。 電通大演算器は乗算器の利用率100%ですがSnakeCubeは80%です。 最終的にSnakeCubeは2×2×0.8 = 3.2倍高速という予想ができました。 また鍵長が大きくなるにしたがってこの差が、さらに大きくなっていきます。

大きなモンゴメリ乗算器は実装できるのか?

はじめに

前回のブログ「わかりやすいICF3-Fのモンゴメリ乗算器の説明」で途方もなく大きなモンゴメリ乗算器を実装できるということ書きました。ここではICF3-Fは複数チップを接続したものでも実装できるのか?という話をしてみたいと思います。そして、そこから何が言えるのか?を考えてみたいと思います。

巨大なモンゴメリ乗算器は実装できる

当たり前のような気もしますが、演算器の周波数を落とさず、演算器の大きさに比例した性能を出すことができる実装ができるという意味です。 RSA暗号をCPUで計算した場合、おおよそ鍵長が2倍になると計算時間は8倍になります。僕が書いた次の記事が参考になると思います。

RSA 8192bitの性能を測定するソースコード - Qiita

ICF3-Fは鍵を大きくしていっても鍵長2倍で計算時間4倍のまま、ほとんど効率は低下しません。

複数チップ上に実装しても効率は下がらないのか

現在の設計では、複数チップ間の遅延時間にもよりますが、演算器の周波数が全く下がらないような設計をしています。現時点(2019年11月6日)では設計までで検証はできていませんけれども。隣接するDSP間の通信が3サイクルあっても、周波数を下げずに動作することができます。もちろんチップ間の遅延時間が大きければ周波数は下がりますが、チップ間の遅延時間が1サイクルに入る限りは大丈夫です。DSPからチップのI/Oピン、チップ間、チップのI/OピンからDSPというぐあいに3サイクルで転送させます。

言えることは

電子投票などの準同型暗号システムや、SSLを使ったシステムを設計する上で、量子コンピュータの解読脅威のため、可能な限り大きな鍵の公開鍵暗号(RSA暗号など)を使いたい。システムに必要な要求性能は、わかっている。ICF3-Fの、あるFPGAの実装から「鍵長2倍で計算時間4倍」法則を使って、システムの鍵長を考えることができる。またICF3-Fは演算器の最下位ビットから最上位ビットまで、一筆書きのように、並べるだけの実装なので開発コストが小さく、見積もりが容易。 サバンチ大学の剰余乗算のFPGA実装は米アマゾンのFPGAコンテストの結果からも言えるように美しい理論はあるものの実際には実装してみないと性能が、わからないところがある。そして鍵長が大きくなるにしたがって効率が、どんどん下がっていく。ICF3-Fの「鍵長2倍で計算時間4倍」が理論のように見えてくるのかも。

わかりやすいICF3-Fのモンゴメリ乗算器の説明

はじめに

米アマゾンとイーサリアム財団らがFPGAコンテストをするそうです。簡単に言うとA×A mod N (A,N: 1024bit)をできる限り速く演算するというコンテスト。コンテストのサイトで紹介されているサバンチ大学の論文「Low-Latency Modular Multiplication Algorithm - Erdinc Ozturk」にはXilinxFPGAで剰余乗算器、A×B mod N(A,B,N: 512bit)を実装した結果がある。巨大な剰余乗算器で、ICF3-Fの剰余乗算器(=モンゴメリ乗算器)よりも、かなり高速な演算器です。コンテストで1024bitのものが実装できれば、ですが。コンテストで1024bitの性能の結果が出たようです。詳しくはコンテストのサイトほうへ。

ご注意! ICF3-Fはオープンソースではありません。

目的

サバンチ大学の論文には128bit、256bit、512bitの結果があるので、そこから1024bitのDSPの数を予想すると4225個。一方、ICF3-Fは44個×2です。 サバンチ大学の論文の方法で1024bitのものが実装されてもICF3-Fは、RSASSLアクセラレータの用途など、実際に利用される用途では負けていないということを言いたいのですが、 あまり細かいことを書きたくなかったので、わかりやすいICF3-Fのモンゴメリ乗算器の説明になりました。ICF3-Fとの違いで大きなものはNの入れ替え。 ICF3-Fは演算毎にNを入れ替えられるが、Nの入れ替えに時間がかかると思われます。つまりサバンチ大学の論文では複数のSSL証明書を運用したい場合、運用が難しい。周波数も考慮しないといけないのですがICF3-Fの約100倍のDSPを使うので100倍以上の性能が出ないとコストパフォーマンスが悪い。100倍以上としたのは、ICF3-FはリダクションもDSPで演算していますが、サバンチ大学の論文では巨大なLUTとBRAMを必要としている点があります。サバンチ大学の論文では小型のSSLアクセラレータを作れないであろうとか。

ICF3-Fのモンゴメリ乗算器(1024bit版 DSP 44個)

f:id:icf:20190812212327p:plain
ICF3-Fのモンゴメリ乗算器
1ループ=3サイクルで17bit分のモンゴメリ乗算。1024×1024bitをするには61ループ(183サイクル)。DSP内のレジスタに入力データを設定、ループ終了後、DSP内のレジスタに答えが格納されている。 uのブロッドキャスト以外は、隣接するDSPしかデータ転送がなくデータのローカリティが高いアーキテクチャ。k番目のDSPは、k-1番目のDSPとk+1番目のDSPと通信するのみで配線実装しやすい。 3サイクル中、乗算は2回行われる。乗算のうち、ひとつはuの値がないと演算できないためDSPが2倍あっても、あまり高速化できない。1つのDSPでuの値が不要な乗算を先に行い、その後、uの値を使う乗算を行う。DSPは乗数を17bitづつシフトする用途にも使われている。サバンチ大学の論文では乗算にRNSを使っているためXilinxDSPの24×17の乗算器を16×16として使っているがICF3-Fでは乗算にRNSは使っていないので24×17として使えている。つまり(24×17)÷(16×16) = 1.59倍、効率良く乗算器を使っている。

このようにループさせるだけでモンゴメリ乗算が正しく演算できることの証明はモンゴメリ乗算の累積加算における分割加算の証明にあります。

大きなモンゴメリ乗算器が実装できる仕組み

f:id:icf:20190812212444p:plain
大きなモンゴメリ乗算器が実装できる仕組み
乗算器が大きくなっていくとuのディレイが間に合わなくなってくる。そこでuのブロッドキャストに中継FFを入れる。 kからk+1のデータはFFで中継。k+1からkのデータを1サイクル早く作る。ここがポイント。このときディレイが心配になるが、それでもクリティカルパスはu生成になると思うので、ここはクリティカルパスにならない。このため、途方もなく大きなモンゴメリ乗算器を実装できる。途方もなく大きな乗算器になってもクリティカルパスが、長くなることはない。つまりDSP当たりの演算効率は、ほとんど下がらない。

ICF3-Fの性能を2倍にする

RSA暗号SSLアクセラレータにおいて、RSA暗号の鍵長が大きくなるとサバンチ大学の論文では実装できなくなるし、ICF3-Fも実装できても性能が遅すぎる問題がでてくる。そこで2個のICF3-Fを連結して中国人剰余定理を使って、性能をほぼ2倍にする方法が、現実可能だということです。

僕の分割加算と準同型暗号

目的

僕の考えた分割加算が準同型暗号を使ったシステムで役に立ちそう。

分割加算とは

大きな数のモンゴメリ乗算を高速に演算するアルゴリズム。僕が考えたもの。 詳しくは「モンゴメリ乗算の累積加算における分割加算の証明」

準同型暗号とは

暗号化されたまま加算や、乗算が行える暗号。RSA暗号など、いくつかの公開鍵暗号がある。僕はアルゴリズムや安全性については詳しくない。 電子投票電子マネーでの応用が期待されている様子。具体的に社会実装するという動きもあるようです。

分割加算は使えるか?

RSA暗号はもちろん。Paillier暗号でも、使えると思われます。 分割加算では基数2n(nは、17~64程度)なので 使えるかどうかは暗号アルゴリズムにあるmod xのxがgcd(2,x)=1であること。すなわちxが奇数かどうかになります。 準同型暗号を使ったシステムで、どのくらいモンゴメリ乗算を使うかによって、実際に分割加算を実装したFPGAなどのハードデバイスが役に立つかが決まります。

分割加算はFPGAに向いている

分割加算を使った暗号プロセッサICF3-FはASICのみならずFPGAでも効率的に実装できる。 ICF3-Fの元となっているICF3は、オープンソースハードウェアとして公式サイトがある。 ただし、まだライセンスの整備が十分でない。 構想の話ですが、ICF3-FとICF3の命令セットを、なるべく共通化して、オープンソースのICF3で広く普及させ、 真に性能が必要なシステムでは、ICF3-Fが売れる。その利益によってオープンソースのICF3が整備されるというような、、、。

仮想マシンの加速支援機構つきの新型8bit CPU

2019年12月29日 修正 XilinxFPGA(XC7A35TICSG324-1L)を搭載したArtyに実装した結果の更新

概要

新型の8bit CPU(ICF3-Z)を設計してFPGAに実装。仮想マシンの加速支援機構を使った、簡単なスタックマシンで、サンプルプログラムがXilinx FPGA Artix-7(-1)の実機上で動作した。たった約400LUTの小さいCPUで。Intel 8051マイコンのFREEな実装にlight52があります。軽量なマイコンですがCPU部だけで約800LUTあるようです。light52は1命令、6サイクルですが、このICF3-Zは1命令、1サイクルが基本で、時に1サイクルに複数命令の実行ができます。周波数比較もICF3-Zが、おおよそ2倍のようで、圧倒的に勝ったのかも。他にあまり比較できるものがなかったという話もありますが。

仮想マシンの加速支援機構とは

新型8bit CPU(ICF3-Z)なのですが命令コードが32bitで、一般的な8bit CPUと比べてメモリ効率が悪い。そこで16bitの圧縮命令の機能を追加した。この機能が仮想マシンの加速支援機構なのです。 圧縮命令のために作られたもので、加速支援機構として、最終的に成立するのかは、わからないですが、需要があって無理がなければ、加速支援機構として考えていく方向です。

加速支援機構が何の役に立つのか?

超低スペックなCPUでは、ソフトウエアで仮想マシンを実装しても性能的な問題で用途が狭められることがあります。この加速支援機構があれば実用の範囲が広がります。

2019年11月23日 追記 仮想マシンの命令列を大容量の安価なプログラムメモリに置けるので、容量の少ない高価なデータメモリを圧迫しないということも利点です。

なぜ低スペックなCPUで仮想マシンなのか?

仮想マシンJavaのようなスタックマシンにしたり、レジスタ1個のマシンにしたりできます。 CPUのアーキテクチャの違いを吸収して、いろいろな言語のコンパイラの開発を容易にします。 非C言語が利用できるようになることで、より多くの人がIoTデバイスなどを開発できるようになります。

試作プログラム

プログラムの上部で簡単なスタックマシンの命令を実装して、仮想マシンの命令列をFPGAの実機で動作させたものです。独自のアセンブラなので多少、わかりにくかもしれません。自作したアセンブラでバイナリを生成して、FPGAのプログラムメモリに、置きます。 即値の5をPUSH、メモリの0番の値をPUSH、メモリの1番の値をPUSH、乗算、加算、LEDに結果を出力。 メモリ0番には、最初のところで2を書き込んでいます。メモリ1番には3。つまり3*2+5 = 11がLEDに出力されます。(確認しました)

########################################################
# vm (Virtual Machie)
#
# C Register : SP(Stack Pointer)
# D Register : PRINT (LED x 8)
# MEM[0-255] : Memory
#
# PUSHI: SP=SP-1 , MEM[SP]=nn                     (5cyc)
# PUSHR: SP=SP-1 , MEM[SP]=MEM[nn]                (5cyc)
# POP  : MEM[nn]=MEM[SP] , SP=SP+1                (4cyc)
# ADD  : MEM[SP+1]=MEM[SP]+MEM[SP+1] , SP=SP+1    (7cyc)
# MUL  : MEM[SP+1]=MEM[SP]*MEM[SP+1] , SP=SP+1    (16cyc)
# PRINT: PRINT MEM[SP]      
########################################################
# Initial MEM[0]=0x02 , MEM[1]=0x03
########################################################
    ADDL=N;N=0x02;A=ANS
    STORE;Z=0
    ADDL=N;N=0x03;A=ANS
    B(START)
    STORE;Z=1;C=ANS;D=ANS
########################################################
%NOP:
    JRETURN
%PUSHI:
    ADDR=C;ADDL=N;N=0xFF;C=ANS
    RETURN;COPR;ADDL=N;A=ANS
    ADDR=C;R(ADDR);STORE
%PUSHR:
    ADDR=C;ADDL=N;N=0xFF;C=ANS
    RETURN;R(N);COPR
    MOV;ADDR=C;R(ADDR);STORE
%POP:
    RETURN;R(ADDR);ADDR=C;ONE;C=ANS
    MOV;COPR;R(N);STORE
%ADD:
    R(ADDR);ADDR=C;ONE;C=ANS
    B=REG;R(ADDR);ADDR=C
    B=REG;ADDR=B;A=ANS
    RETURN;ADDL=A;ADDR=B;A=ANS
    R(ADDR);ADDR=C;STORE
%MUL:
    R(ADDR);ADDR=C;ONE;C=ANS;D=ANS
    C=REG;R(ADDR);ADDR=C
    C=REG;ADDR=C;A=ANS
    B=ANS;I=X;X=7
    MUL;ADDL=A;ADDR=B;B=RSH;C=RSH;WAIT
    RETURN;ADDR=C;A=ANS
    R(ADDR);ADDR=D;STORE;C=ANS
%PRINT:
    RETURN;R(ADDR);ADDR=C
    D=REG
START:
    _%PUSHI,0x05,%PUSHR,0x00
    _%PUSHR,0x01,%MUL,0x00
    _%ADD,0x00,%PRINT,0x00
    EXIT(0);@D
END:
    B(END)
    NOP

ちなみに

割込みの実装もついていて約400LUTです。2つの割込みを受けられます。

2019年12月29日更新

XilinxFPGA(XC7A35TICSG324-1L)に搭載したArtyに実装して面積を確認しています。 論理合成のオプションで結果が違うので、面積重視、性能重視の結果です。

合成方針 LUT数 FF数 BRAM数 LUT-RAM 周波数
面積重視 390 197 1.5 10 150MHz
面積重視 406 197 1.5 10 160MHz
性能重視 481 197 1.5 10 175MHz

BRAM 1.5の内訳はプログラムメモリ 4KBとデータメモリ 2KB

データメモリの先頭32バイトがレジスタ、先頭256バイトがスクラッチパッドメモリ。この合成結果はデータのアドレス線を8bitにしたものです。11bitにすればBRAMを消費することなく2KBのデータメモリをすべて使えます。データのアドレス線を16bitまで設定可能ですがBRAMを消費します。圧縮命令(仮想マシン)を利用する場合はプログラムメモリの先頭の領域を消費します。圧縮命令の命令数によって消費する領域が変化します。

割込みを使ったデバッグ機能の検証をしました。 プログラムのコード中に、ブレークポイントを設定して、そこに、たどり着いた回数を計算して、設定した値(パスカウント)のとき、ブレークさせるみたいな機能が実現できます。 具体的には毎サイクル割込みを入れて、アドレスを確認して、設定されたアドレスなら、指定された回数に到達したかをチェック。 指定された回数の場合は、LEDを点灯させるというプログラムを作成して、FPGAの実機でテストしました。ちゃんと動いているようです。 ただプログラムコード中の一部の命令ではパスカウントを正しく計算できません。遅延分岐で遅延スロットをキャンセルする命令などです。 分岐命令の直後の命令にブレークポイントを設定した場合は、パスカウントは正しくありませんという仕様にしようかと考えています。 割込み処理中でキャンセル信号をチェックしてもいいのですが、 デバッグ機能のためにキャンセル信号をチェックする論理を追加するのは面積最小を追求するプロセッサでは、あまり良くないと考えてのことです。 (面倒とかではなくて)

約400 LUTの面積の小さいCPUで、追加のデバッグモジュールなしにパスカウントを 使ったブレークポイントを設定できるのは、良くできるほうなんだろうと思うが、 他のCPUの面積とかわからないから、なんとも。