0. はじめに
本記事では準同型暗号化ライブラリHElibの
- インストール方法
- サンプルを用いた動作確認
- HElibライブラリを用いたコードの実行方法
について説明します。最終的に、HElibを使ったオリジナルのコードを実行できるようになることを目的とします。
なお、以降の文章は2022/09/04時点の公式ドキュメントINSTALL.md、examples/READMEmdに基づいて書かれています。そのため、今後のバージョンアップによりインストール方法などが変更される可能性があります。その場合はこれらのドキュメントの参照をお願いします。
0.1 環境
著者が使用した環境はWindows10とUbuntu(WSL2)です。以降で説明するインストール方法などはLinuxOSでもmasOSでも共通ですが、macOSは実行できるかどうかの確認がとれていませんので、ご了承ください。
ソフトウェア名 | バージョン |
---|---|
Windows 10 | 21H1 |
Ubuntu(WSL2) | 20.04.4 LTS |
0.2 事前準備
事前準備として、HElibを使う際に必要となる各ソフトウェアについて説明します。
LinuxOS
LinuxOSで必要となるバージョンについて次の表に示します。
ソフトウェア名 | バージョン |
---|---|
pthreads | インストールされていてばOK |
git | 2.27 |
GNU make | 4.2 |
g++ | 9.3.0 |
cmake | 3.16 |
m4 | 1.4.16 |
patchelf | 0.9 |
次にWSL2上のUbuntuについて説明します。
まず初めに、初期状態のUbuntuではgitをバージョンアップさせる必要があります。この方法については@cointoss1973さんの記事を参考に行います。
sudo add-apt-repository ppa:git-core/ppa
sudo apt update
sudo apt upgrade
次に、cmake, g++をインストールします。コマンドは次の通りです。
sudo apt install cmake
sudo apt install g++
次に、m4と呼ばれるC言語などのプリプロセッサとして使われるコマンドをインストールします。この方法は次の記事をもとに実行します。
sudo apt-get update
sudo apt-get -y install m4
最後に、patchelfというビルドの際に必要となるソフトウェアをインストールします。これは次の記事を参考に行います。
sudo apt-get update -y
sudo apt-get install -y patchelf
他のソフトウェアについては、初期状態でインストール済みかつバージョンを満たしているため問題ありません
macOS
LinuxOSで必要となるバージョンについて次の表に示します。
ソフトウェア名 | バージョン |
---|---|
pthreads | インストールされていてばOK |
git | 2.27 |
Apple clang | 12.0.0 |
Xcode Command Line Tools |
xcode-select --install を入力しインストール |
cmake | 3.20 |
GNU make | 3.81 |
m4 | 1.4.16 |
patchelf | 0.9 |
macOSについては未検証のため、使用している方はご確認をお願いします。
1. インストール方法
- まず初めにHElibライブラリのインストール先となるディレクトリを作成します。作成場所はホームディレクトリとします。
cd mkdir helib_install
- 次にHElibのリポジトリをクローンします。これも同じくホームディレクトリに作ります。
git clone https://github.com/homenc/HElib.git
ここまでで、ディレクトリ構成は次のようになります。
ディレクトリ構成~/ ├── HElib └── helib_install
- リポジトリに移動し、buildディレクトリを作成します。
cd HElib mkdir build
- buildディレクトリに移動し、cmakeコマンドを実行します。このとき、「-DCMAKE_INSTALL_PREFIX」オプションを、先ほど作成した「helib_install」のパスにします。
cd build cmake -DPACKAGE_BUILD=ON -DCMAKE_INSTALL_PREFIX=~/helib_install ..
- 次にmakeコマンドを実行します。
make
- 最後にmake installコマンドを実行します。このコマンドを実行することで、「~/helib_install」にHElibに関するライブラリや依存ファイルが作成されます。
make install
以上でインストールは完了です。次にサンプルを用いた動作確認について説明します。
2. サンプルを用いた動作確認
- 初めにHElibリポジトリのexampleディレクトリに移動し、buildディレクトリを作成します。
cd ~/HElib/examples/ mkdir build
- buildディレクトリに移動し、cmakeコマンドを実行します。このとき、-Dhelib_DIRオプションにはインストール時に作成した「helib_install」ディレクトリのパスを指定します。
cd build cmake -Dhelib_DIR=~/helib_install/helib_pack/share/cmake/helib ..
- makeコマンドを実行します。
make
- すると、binディレクトリが作成されます。このディレクトリには7つCKKS方式のサンプルと、3つのBGV方式のサンプルがあります。それではこのbinディレクトリに移動し、試しに1つファイルを実行します。実行に1分ほどがかかるのでご注意ください。
cd bin ./BGV_binary_arithmetic
BGV_binary_arithmeticを実行すると、3つの変数a, b, cの準同型加算・準同型乗算を行います。問題なく実行することができれば、HElibライブラリのインストールは成功です。また、これらの実行ファイルのソースコードは、CKKS方式は「HElib/example/tutorial/」、BGV方式は「HElib/example/」に置かれています。
以上で動作確認は完了です。次にHElibライブラリを用いたコードの実行方法について説明します。
3. HElibライブラリを用いたコードの実行方法
- 初めに、ホームディレクトリにhelib_codeディレクトリを作成し、移動します。
cd mkdir helib_code cd helib_code
- HElibライブラリを使ったソースコードを作成します。main.cppを作成し、次のコードをコピペしてください。
main.cpp
#include <iostream> #include <helib/helib.h> using namespace std; int main() { // 前準備として、セットアップに必要な各種パラメータの設定をします。 unsigned long p = 4999; unsigned long m = 32109; unsigned long r = 1; unsigned long bits = 500; unsigned long c = 2; // 設定後、各種パラメータをもとにセットアップを行います。 helib::Context context = helib::ContextBuilder<helib::BGV>() .m(m) .p(p) .r(r) .bits(bits) .c(c) .build(); // 秘密鍵の作成 helib::SecKey secret_key(context); // 秘密鍵を定義し、各種パラメータを受け取る secret_key.GenSecKey(); // 秘密鍵を生成する helib::addSome1DMatrices(secret_key); // Key switchingの行列を作成します。これは準同型乗算後のノイズを取り除くために使われます。 // 公開鍵の設定 const helib::PubKey& public_key = secret_key; // SecKeyはPubKeyのサブクラスのため、「public_key = secret_key」と記述します。 const helib::EncryptedArray& ea = context.getEA(); // 各種パラメータの暗号化行列を作成します。 // 平文の作成 // HElibではSIMDと呼ばれる、複数の平文を1つにまとめて演算ごとに並列に実行できる機能が備わっています。 // そのため、1つの平文はptxt[0], ptxt[1], ... というふうに配列となっており、複数の平文を格納することができます。 // 今回はptxt[0] = 0, ptxt[1] = 1, ..., ptxt[n] = nとし、各要素に0からnまでの値を入れます。 helib::Ptxt<helib::BGV> ptxt(context); for (int i = 0; i < ptxt.size(); ++i) { ptxt[i] = i; } // 演算前の平文を出力します。 cout << ptxt << endl; // 暗号文の作成 helib::Ctxt ctxt(public_key); // 暗号文を作成します。 public_key.Encrypt(ctxt, ptxt); // 平文ptxtを暗号化します。 // 演算(自乗) ctxt.multiplyBy(ctxt); // ctxt *= ctxt を実行しています。 // 復号 helib::Ptxt<helib::BGV> result(context); // 演算後の値を格納する平文を作成します。 secret_key.Decrypt(result, ctxt); // 自乗の結果を復号します。 cout << result << endl; }
このプログラムではまず初めにn個分の平文「$0, 1, \cdots , n$」を暗号化します。次にHelibライブラリの準同型乗算を使い、暗号文に対して自乗します。最後に復号し、演算結果の「$0^2, 1^2, \cdots, n^2$」を出力します。
- main.cppの実行ファイルを作成するため、CMakeLists.txtを作成します。その後、次のコードをコピペしてください。
CMakeLists.txt
set(CMAKE_CXX_STANDARD 17) find_package(helib) add_executable(main main.cpp) target_link_libraries(main helib)
このファイルの1行目では、コンパイル時にc++17を使用するよう設定しています。2行目のfind_package(helib)」ではHElibライブラリのヘッダーファイルをインクルードします。3行目の「add_executable(main main.cpp)」ではビルドの対象であるmain.cppを指定し、実行ファイルを定義します。最後の「target_link_libraries(main helib)」では実行ファイルを作成する際に、HElibライブラリとリンクするようにしています。
- cmakeコマンドを実行します。
cmake -S . -B build -Dhelib_DIR=~/helib_install/helib_pack/share/cmake/helib
- 最後にbuildディレクトリに移動してmakeコマンドでビルドし、作成されたmainファイルを実行します。実行完了にはしばらく時間がかかります。
cd build make ./main
- 出力結果が次のようになればOKです。0の2乗から始まり、n = 23の2乗の529が計算できていることが分かります。
{"HElibVersion":"2.2.0","content":{"scheme":"BGV","slots":[[0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23]]},"serializationVersion":"0.0.1","type":"Ptxt"} {"HElibVersion":"2.2.0","content":{"scheme":"BGV","slots":[[0],[1],[4],[9],[16],[25],[36],[49],[64],[81],[100],[121],[144],[169],[196],[225],[256],[289],[324],[361],[400],[441],[484],[529]]},"serializationVersion":"0.0.1","type":"Ptxt"}
以上でHElibライブラリを用いたコードの実行方法は完了です。
4. おわりに
ここまでくれば、あとはmain.cppをさらにいじったりして、いろいろな処理を実行することができます。
HElibライブラリで提供されている関数等については、「HElib/example/tutorial」にあるCKKS方式のソースコードや「Helib/example/BGV_*」にあるBGV方式のソースコードに書かれたコメントを参考にすると分かりやすいです。本記事のmain.cpp
についても、サンプルの「BGV_packed_arithmetic.cpp」をもとに記述しました。
最後になりますが、本記事の情報が役に立てれば幸いです。なんらかの理由でうまくいかなかった場合は、コメントにて教えていただけるとありがたいです。