秘密計算エンジニアを始めて４年が経った。

## 概要
秘密計算エンジニアを始めて、もう４年が経ってしまいました。

時の流れは非常に早いもので、私が秘密計算について勉強したりいろんな実装を行うのと並行して、

秘密計算に対する注目度やユースケースの創出、または秘密計算の演算実行スピードというものもこの４年を通じてかなり進捗がありました。

今回は今一度、秘密計算という技術全体に対して、さらにその中でも準同型暗号という暗号技術について、自分の知っていることをまとめていきたいと思います。

去年同じような記事を書こうとして書いたのがこちらです。

https://qiita.com/kenmaro/items/a1d90a074d552b7bf886

興味のある方はこちらもみていただければ嬉しいです。

### この記事で何を書くか
良い記事もあればそうでない記事もたくさんあったなと記憶していますが、この4年間で秘密計算に関する記事を書いてきました。

最近は秘密計算以外のこともいろいろと書いていたため記事数も多くなり、
秘密計算については自分でも何を今まで書いたのか記憶があやふやになり、情報が散らかってしまっているなと最近感じていました。

ここら辺の知識をまとめてみようかなと思って検索すると、自分が以前書いた記事がヒットして書いていたことを思い出す、みたいなことが何回か起きたためです。


従って、改めてこの記事に以前の記事もまとめて情報を整理し、
「節目となるまとめ記事」にできるよう頑張りたいと思います。


## 秘密計算とは
秘密計算とは一言でいうと、データがもつプライバシーや機密情報を保護したまま、データを計算し分析することのできる技術のことです。

## 秘密計算のユースケース
機密情報を漏洩することなく安全にデータ解析ができる秘密計算技術を使うと、

たとえば、

- 今まで企業に眠っていたデータ資産を、安全に活用することができたり
- 企業データについてクラウドなどの外部インフラを使うことへのハードルが下がったり、
- 企業間、部署間のデータ連携を、お互いのデータを秘匿したまま可能にしたり、


といったことが可能になります。

- 今まで分断されていたサプライチェーン間のデータに対し、
- 秘密計算技術を用いてそれぞれのデータを連携させ、
- 今まで存在していた煩雑なオペレーションを簡潔にしたり、
- 今まで結合できなかったデータが結合できることにより可能になった、
- 部門を横断したデータに対してより質の高いデータ分析をすることが可能になったり

するでしょう。

秘密計算のユースケースに関しては、以前の

https://qiita.com/kenmaro/items/48059dd60f79e80f5ef8%E3%80%80

この記事でもまとめていました。

##  秘密計算というのは非常に広いキーワード
秘密計算というのは、先ほどのデータを安全に活用するための技術
の総称であり、それらにはいろいろなアプローチがあります。

また、それぞれの技術に対して研究開発が行われており、時にそれらの技術は一長一短をもちお互いがお互いをカバーすることがあります。

システム構築において幾つかの技術を組み合わせて目的のセキュリティ要件を達成することが秘密計算の醍醐味です。


## 準同型暗号とは
準同型暗号とは、上でお話しした幾つも存在する秘密計算を可能にするための技術のうちの一つです。

暗号、と名前がついていることからもわかるように、
データを「暗号化」することにより、秘密鍵を持っていない人に対してデータの漏洩を防ぐことができます。

「準同型」という言葉の意味は、数学からきており、簡単にいうと、
暗号化する前の平文に対する演算と、暗号化した後の暗号文に対する演算が保存するというこです。

このことは、数学の用語で準同型性があるというため、この性質を持つ暗号のことを「準同型暗号」と呼んでいます。

演算が保存するということは言い換えると、暗号状態でも平文と同じように演算を実行することが可能、ということです。


上の準同型性というのは、数学の世界では以下のような数式で表現されます。

```
D(E(f(x, y))) = D(f(E(x), E(y)))
```

この時、x, y は平文データ、
Dは復号（decrypt)、Eは暗号化（encrypt), f はなんらかの演算（例えば足し算とか、掛け算）です。

### 準同型暗号に登場する鍵の種類
準同型暗号を扱う際に登場する鍵はいろいろ種類があることがあり、
混乱の元になりますが、大きく分けると以下の３つになります。

1. データを暗号化する時に使用する公開鍵
2. 暗号文を複号する時に使用する秘密鍵
3. 暗号文を計算する時に使用する計算鍵

です。

準同型暗号は、基本的には公開鍵方式の暗号です。

公開鍵方式とは、暗号化する時に使用する鍵と復号するときに使用する鍵が異なる形式の暗号です。

この方式は基本的には
暗号化と復号の際に使用する鍵が共通している、共通鍵方式の暗号よりも使い勝手が良く、システム的には安全です。

理由は、

- 暗号化する時と復号するときの鍵の種類が異なる
という理由より、

- 秘密鍵安全に格納し公開鍵についてはパブリックに公開していい
- 誰でも暗号文を作ることができる

ということから、秘密鍵を持っている人に対してのメッセージを安全かつ簡単に届けることができるという

便利さがあるからです。

また、システム的な安全面という意味では
復号できる鍵を公開鍵方式では受け渡す必要がないため、
第三者が復号できる鍵へアクセスする可能性を減らすことができ、安全な運用が可能です。

### 計算鍵の存在
また、計算鍵は暗号文に対して計算を実行するときに必要な鍵で、
いくつか種類が分かれることがありますが、ここではまとめて「計算鍵」と呼んでいます。

計算鍵は暗号文を復号できる秘密鍵ではないため、パブリックに公開することができます。

したがって、データ所有者は公開鍵でデータを暗号化した後、
計算鍵と暗号文をデータ分析者に送信し、分析者は暗号文の持つ準同型性を利用して暗号文に対して演算を実行し、データを分析、データの所有者に返却します。

データ所有者は秘密鍵を使用して返却された暗号文を復号し、目的だったデータ分析の結果を得る、というシナリオが成立します。


## 準同型暗号のユースケース
上の、暗号化したあとにも計算できる技術である「準同型暗号」を用いると、いろいろなことが可能になります。


いろいろなユースケースが考えられますが、
大きなポイントとしてデータ所有者とデータの分析者が異なるシナリオに対して有効である、と考えていると分かりやすくなると思います。

この場合、データ所有者はデータ分析者に対して機密情報の入ったデータを秘匿したいが、なんらかの分析を実行してほしい、というモチベーションがあるとします。

上述した通り、データ所有者は公開鍵で暗号化をした暗号文をデータ分析者に送信し、データ分析者は暗号文の準同型性を利用して、暗号文のままデータに演算をかけ結果を送信します。

データ所有者は結果を自身の秘密鍵で復号、結果を取得します。

このように、データ所有者と分析者が異なるパーティである場合、例えば分析を第三者に委託したい場合などに秘密計算の利点である、
データを秘匿化したまま演算が可能であるという点を利用し、目的を達成することができるのです。

今年には、JAL、JALカード、ドコモが準同型暗号及び差分プライバシーに基づくプライバシー保護技術を使った「秘匿クロス統計技術」を用いたデータ活用の実証実験を行なった、というニュースが話題になりました。

https://www.docomo.ne.jp/binary/pdf/info/news_release/topics_221020_00.pdf

### 紛失通信やゼロ知識証明
紛失通信やゼロ知識証明といった、ユーザの教えたくない情報を秘匿したままの認証や、データ転送のプロトコルは準同型暗号を用いることで実装することも可能です。

ゼロ知識証明については以前に記事を書いていました。

https://qiita.com/kenmaro/items/d968375793fe754575fe

また、機械学習の領域においても後述の決定木の準同型暗号を用いて実行する際紛失通信を巧みに使って実装を行うなど、調べていくととても面白い領域です。


## 検索可能暗号とは
秘密計算について調べるときに、検索可能暗号というキーワードも聞くことがあります。

検索可能暗号が何かというと、文字通り「暗号化」した後のデータに対して、
「検索」が可能という技術のことです。

ここで、検索というのはいろいろな検索の仕方があると思います。

例えば、

- 完全一致
- 部分一致
- 大小比較
- 平均値の集計
- 合計の集計
- 正規表現を用いた検索
- データにつけたタグを検索
- データに含まれる文字列を検索
- 異なるテーブルデータに対して結合しつつ検索
- 複雑な複合クエリを用いた検索


など、他にもいろいろな検索が考えられると思います。

検索可能暗号というのは、上記のようにいろいろと考えられる検索に対して、データを暗号化したまま検索が可能なように工夫された暗号と呼ぶことができます。

全てをカバーしているというわけではなく、目的に応じた上記のうちいくつかをカバーしていたりします。


ただし汎用的な検索は難しく、例えば正規表現を用いた検索などは暗号文に対しては不可能に近いと言っていいでしょう。



## 検索可能暗号のユースケース

基本的には、リレーショナルデータベースや、NoSQLと呼ばれる辞書型のデータベースの中身を暗号化したままクエリを実行するというユースケースが考えられます。

### 従来のDB暗号化との違い
従来のデータベースも暗号化をオプションとして実行することができますが、
暗号化はクエリを実行するときには解かれ、クエリによる処理が行われた後にまたデータが暗号化されて保管されます。

従って、暗号化や復号に必要な鍵はデータベース側が保持し都度復号を行えるような権限を持っているため、本当の意味でデータの所有者のプライバシーが保護されるとは言い難いでしょう。

データ所有者はあくまでもデータベースを管理するサーバを信頼しており、サーバ側もみようと思えばいつでも、鍵にアクセスして機密データにアクセスできる（可能性がある）ということは知っておくべきです。

対照的に、検索可能暗号を用いたとき

- データ所有者は鍵を自分で保有し
- サーバサイドには提供する必要がないため、
- 仮にサーバサイドがハッキングなどの攻撃を受けた場合でも
- データ所有者の鍵が漏洩しない限りハッカーが取得できるデータも暗号化されているもののみである


というところが既存の暗号化データベースと異なるところです。

### カラムごとの最適な暗号化

#### RDS
RDSに関しては、カラムごとに暗号鍵を生成して、カラムベース暗号化を行うことができることが検索可能暗号の強みです。

例えば、

- 数値を含むカラムについては準同型暗号を用いて、暗号文のまま計算可能にしたり
- ストリングのカラムについては、検索可能な暗号を用いたり

カラムのタイプごとに暗号方式を柔軟に設定できます。


#### NoSQL
NoSQLの場合はカラムごとに鍵を生成するというような設定は簡単ではないですが、前もってテーブル定義がわかっているのであればそれぞれのコレクションに対して鍵を生成することができるでしょう。

以前記事を書いたのですが、NoSQLについては、MongoDBがアルファ版として検索可能暗号に対応を発表しており、実際に私も試してみました。

鍵はユーザがもちこむBYOK（Bring Your Own Key) の形ではなく、クラウドで作成してKMS（Key Management System）に鍵を格納し、クエリが実行されるたびにKMSから鍵をロードして検索を実行するような形になっているようでした。

MongoDBの検索可能暗号については以前チュートリアルを実際にやってみて、どんな感じで使えるのか、ということは調査しました。

https://qiita.com/kenmaro/items/2185d5402b2e33eb8204


また、検索可能暗号については、一番よくリファレンスされているのはMITのCryptoDB

https://css.csail.mit.edu/cryptdb/


だと思いますので、興味がある人はまずここから読んでみることをお勧めします。
暗号を二重にかけて決定的暗号が外側に見えないような「オニオン型の暗号」(暗号が何層かに連なっているのがタマネギみたいなのでそう呼ばれている)等を理解することができます。

また、検索可能暗号についてはいろいろな手法によってデータベースの内容を盗もうとする攻撃が存在し、取り扱いには注意が必要です。

少し前の記事ですが、このような記事を書いていました。

https://qiita.com/kenmaro/items/1a57866137a6fe668f7c



## 秘密分散とは
既存のRSA暗号などが、量子コンピュータが台頭するときには破られてしまう、
という観点からデータを暗号化ではなく断片化し、複数サーバで連携しながら保存する方式である、「秘密分散」方式も秘密計算を代表する手法の一つです。

暗号化では必要な鍵の生成を行わなくていい（つまり鍵の保管も行わなくていい）という運用面のメリットや、暗号に比べてデータのサイズもさほど大きくならないことなどもあり、さまざまな企業が秘密分散について実証実験を行なったり、いろいろなユースケースもリリースされています。

複数のサーバを使用するという点においては、たくさんのノードが活用されるブロックチェーン技術と構成が近いような気もします。

準同型暗号の難しさが暗号学にしたがった数学理論であるのと対照的に、秘密分散の難しさはそれらのノードの連携に必要なインフラ構成や、データのシンクロにもあるとも考えて良いでしょう。


### 秘密分散のユースケース
秘密分散といえば、NTTコミュニケーションズさんの「析秘」と呼ばれるサービス

https://www.ntt.com/business/services/secihi.html

や、

ZENMU TECHさん の秘密計算プラットフォーム、

https://zenmutech.com/products/secure-computation/

Acompanyさん の「AutoPrivacy」

https://acompany.tech/service/autoprivacy/

をよく聞くことが多いです。


#### 秘密分散のプレーヤー（ベンチャー企業）
また、かなり前ですが秘密分散型のプロダクトを開発するベンチャー企業についてこの記事で言及をしていました。

https://qiita.com/kenmaro/items/2d2091456b84879a79bc



### 秘密分散ライブラリ
秘密分散を実際に実行することのできるライブラリはいくつか存在していますが、
その中でも機械学習（Pytorch）を分散環境で実行できるCryptenをかなり前ですが動かしてみたりしました。

https://qiita.com/kenmaro/items/3f93162943e14c5369a0

興味のある方は参照してみてください。

また、AcompanyさんがOSSとして運用されているQuickMPC もまだ触れていないですが開発が活発で魅力的です。

https://github.com/acompany-develop/QuickMPC



## TEEとは
秘匿計算、コンフィデンシャルコンピューティングが話題になる時、
Trusted Execution Environment (TEE) も取り上げられることが多いです。

Intel SGXを始めとしたTEEの活用により、コンピュータ内部に存在する隔離領域（エンクレーブ）へと暗号化されたデータを移動させ、エンクレーブ内で復号後、計算を実行することができます。

機密性の高いデータが外部に漏洩するリスクを最小限に抑えたまま演算を実行できるため、準同型暗号や秘密分散とは違ったアプローチでセキュリティを担保することができます。

TEEについての詳細はいろいろとわかりやすい記事があるため、そちらを参照してください。LayerXのブログへのリンクを貼っておきます。

https://enterprisezine.jp/article/detail/14749

また、TEEのチュートリアルを実行し、どのようなオペレーションが行われているか実際に触ってみることで、こういうことが行われているのか
と理解するのも非常に重要です。

以前

https://qiita.com/kenmaro/items/17378cd676ca3a549c66　

や

https://qiita.com/kenmaro/items/300039f214a7b539ce52

などでTEEについてのチュートリアルを行っているので、
もし興味がある方がいればぜひ実行してみてください。



## プライバシーテックとは
プライバシーテックという言葉も、今年に入ってからよく耳にするようになりました。

Acompanyさんが取り組んでいらっしゃるAutoPrivacy というデータを保護しながら活用できる総合サービスや、先ほどのJAL、ドコモが開発する「秘匿クロス統計技術」も様々なデータ保護のソリューションを駆使して安全にデータを連携させたり、分析したりするプライバシーテックの総合サービスだと考えることができます。




## 準同型暗号について
さて、秘密計算にはいろいろな分野があり、それぞれの技術を用いてデータの安全な利活用するいろいろな取り組みがあるということについて言及しました。

私はその中でも準同型暗号という領域のサービスや研究開発について一番取り組んでいるため、準同型暗号について以降は少しだけ詳細にまとめていきたいと思います。

### 準同型暗号の種類
準同型暗号は先述の通り、暗号化したままで計算をすることができる特殊な暗号のことですが、その準同型暗号にも実は色々と種類があり、裏でセキュリティを担保している数学理論が異なります。

### RSA暗号

例えば、大きな素数の因数分解の困難性を暗号解読の困難性としている、RSA暗号も、実は暗号化したまま計算できる準同型性を持っています。


RSA暗号は、暗号文同士を乗算すると乗算した後の結果（暗号文）を復号した時の値が元の平文同士の積を取った結果となっています。
詳しくは解説記事がいくつか存在しているため、そちらをご覧ください。


https://zenn.dev/senk/articles/c813085d9d2a9ef37509


ただし、RSA暗号は足し算に関する準同型性は持っておらず、あくまでも可能なのは掛け算のみです。

### 楕円曲線暗号

楕円曲線暗号と呼ばれる暗号も、準同型性を持った暗号としては有名です。


楕円曲線暗号は、楕円関数と呼ばれる代数上で定義される離散対数問題の困難性を暗号の背景にしていますが、楕円曲線暗号は暗号文に対しての足し算に準同型性を持っています（加法準同型）。


下のリンクでは、L1準同型暗号と呼ばれる（ペアリング暗号とも呼ばれる）、楕円曲線暗号ベースの加法準同型に、１回限りで乗算準同型性を持たせた暗号の実装についてまとめられています。

https://qiita.com/herumi/items/d8645efe2cc5be2e7ee3

また、ペアリング暗号は、Identity Based Encryption (IBE) や、Attribute Based Encryption (ABE)といった、属性ベース暗号のライブラリが存在していることも面白いと思うことの一つです。以前IBE、ABE暗号はPBCライブラリというペアリングベース暗号のライブラリを使用して試していました。


https://qiita.com/kenmaro/items/e0b56924d6fac2cf0391



## 格子暗号
格子暗号は上記で説明した加法準同型性と、乗法準同型性を併せ持った暗号方式です。


また、L1準同型暗号のように乗算回数が１回に限定されるのではなく、自分で設定した任意の回数乗算も行うことができます。

しかし、乗算をたくさんできるような構成にすると暗号文の大きさも膨大になっていきますし、演算時間も非常に長くなってしまいます。


ここで言及した、乗算回数は「レベル」と呼ばれ、「レベル回」の乗算を暗号に対して実行できるような暗号を「レベル準同型暗号」と呼んだりします。


この辺りの「レベル準同型暗号」の「レベル」の設定による演算速度の変化については、以前以下のような記事を書いていますので、興味のある方は参照してみてください。


https://qiita.com/kenmaro/items/08493ba82ae50b2e144b

## 格子暗号の特徴

### 完全準同型
さて、上述した「レベル準同型暗号」の実装が可能な格子暗号ですが、
「完全準同型暗号」と呼ばれるものを構成することも可能です。


「完全」と呼ばれる意味合いは、「レベル」によってもともとどのくらいの乗算を暗号状態で行うかどうかを前もって設定する必要なく、任意の計算を実行できる構成だからです。


つまり、「完全準同型暗号」を使うと、実質どんな計算でも暗号状態で実行することが可能であり、この構成が2011年あたりにGentry によって提案されて以来、格子暗号は準同型暗号の中でも1番の研究対象、暗号ライブラリやアプリケーション実装の対象となっています。

特に、後述のTFHEと呼ばれる格子暗号方式を用いると、ビット情報を暗号化したものに対して、NAND回路やAND回路など、を任意回実行することができます。

従って、実質C言語などで書いたプログラムをコンパイルし、プログラムを暗号文を入力として実行することができます。

このあたりのC言語からTFHEベースの実行バイナリへのトランスパイラについては、Googleや京都大学などが積極的にライブラリを研究開発しているようです。詳しくは以下の記事をご覧いただければと思います。


https://qiita.com/kenmaro/items/0f11340986990093c4da


## 量子耐性
量子耐性を持つ暗号としては
他にも多変数多項式を用いた暗号などいろいろと暗号方式が存在しており、暗号系の学生と話をすると割と人気のある研究対象となっているようです。


量子耐性を持つ暗号は以前こちらの記事にまとめていました。


https://qiita.com/kenmaro/items/356095457e21c1930865


https://qiita.com/kenmaro/items/69693fb15f4106f1e763


## 格子暗号の形式
格子暗号は先ほど言及した、２０１１年ごろの理論的なブレークスルーを受け、
いろいろな方式が研究されライブラリなどもたくさん開発されてきました。
その中でも、よく聞く格子暗号形式について少しだけ言及したいと思います。

- BFV、BGV
- CKKS
- TFHE

以上の３つの世代について話したいと思います。

また、以前の記事でも形式については少しまとめていました。

https://qiita.com/kenmaro/items/416657efca2ff296169b%E3%80%80

### BFV, BGV
すごく簡単にまとめると、整数を暗号化することのできる形式です。


小数を暗号化したいときは、前もって整数に丸め込みを行い暗号化する必要があります。


復号する時に丸め込んでいた場合は逆の処理を行なってでコードを行います。


SIMD演算を実行することが可能なため、ベクトル演算とは相性が良いです。

### CKKS
CKKS形式は、今一番よく使われている格子暗号形式です。


BFVやBGVとほとんど使い勝手は同じなのですが、

- 小数をそのまま暗号化できる、という点でとてもUXがいいこと
- 後述のMicrosoft SEALライブラリにかなり使いやすい実装がされていること

などから、格子暗号の実装をやってみたい人はまずCKKS形式を触ることをお勧めします。

### TFHE
完全準同型暗号であるTFHEは、任意の回路について暗号状態で演算を実行できるため原点にして頂点的な存在です。


使い勝手は速度の観点から非常に難しかったのですが、近年プログラマブルブートストラップ手法がZamaAIから提案され、それが一定のブレイクスルーとなり、
また、ハードウェア高速化の後押しも受け、将来性は一番ある暗号形式だと考えて良いでしょう。

プログラマブルブートストラップについての簡単な解説記事は以前書いていました。

https://qiita.com/kenmaro/items/d78f012c522594126afe

また、他にもいろいろな解説記事なども存在するので、もし原論文をよく理解できないときは参照してみると読み解けるのではないでしょうか。

## 格子暗号を実装しているライブラリについて
これらの形式は、Intelやマイクロソフトを始めとした大企業の研究開発の一環としてライブラリがOSSで運用されていたり、スタートアップ企業が運用しているライブラリや、個人が開発しているライブラリなどの存在しています。


たくさん格子暗号を実装しているライブラリはありますが、その中でも、

 

- マイクロソフトが開発している　Microsoft SEAL 
- ZamaAIが開発しているConcrete
- Duality Technologies などが開発している OpenFHE

が有名どころです。


他にもたくさんあって全てについて言及することは難しいですし、自分も全てのライブラリを使ったことがあるわけではないものの、以前使ったことのあるライブラリについては記事を書いていたようです。

https://qiita.com/kenmaro/items/0654ad4d26e7a4dd919b


### Microsoft SEAL
Microsoft SEAL は、私自身一番よく使っているライブラリであるため、
暗号文の大きさや、暗号に対する演算の実行時間などをまとめたいくつかの記事をこれまで書いています。


https://qiita.com/kenmaro/items/8ad20e2c22524d6f9424


https://qiita.com/kenmaro/items/f51ccfe81e4d6886d608

また、SEALで設定するCKKS形式の暗号パラメータについて言及したりもしました。


https://qiita.com/kenmaro/items/931835476ca8781de9f9


### ZamaAIが開発しているConcrete

Concreteは、TFHEをRustで実装したライブラリであり、おそらくTFHE形式のライブラリとしては一番使われているといっても過言ではないライブラリです。

TFHEの実装については、TFHEppという京都大学の方達がOSSとして開発されているライブラリも非常に使いやすく、とても実装がわかりやすかったり、実装を解説している講義資料もあるため、私はよく勉強や速度測定などに使っています。

https://qiita.com/kenmaro/items/b21434e4e3d19043b681

### OpenFHE
OpenFHEに関しては、
OpenFHEがどうすごいのか、ということについて

https://qiita.com/kenmaro/items/de53308b2c964f7469b0

の記事や、実際にOpenFHEをどう使えばいいのか、というチュートリアルに相当する記事を

https://qiita.com/kenmaro/items/44c42080b4056b3d2d58

https://qiita.com/kenmaro/items/709474f2035caf786fb3

こちらに書いたりしました。

興味がある人は是非参照してみてください。


近年の研究の動向について
アプリケーション実装
格子暗号ベースの実装を多くやってきたので、あくまでも格子暗号を用いたアプリケーションについての内容となってしまうことをご了承ください。

格子暗号を用い、データの流れにセキュリティ要件からくる制約（実装上の縛りプレイ）、実行したい演算を効率的に行えるような高速化を加味しながら実装することは結構工夫の余地があって面白い領域です。

高速化という観点からは、格子暗号がSIMD演算（複数の数字を一つの暗号文にして、それらへの演算をまとめて行うこと）を内包していることから、線形演算との相性が良く、SIMDによる高速化はアプリケーションを実装しようとすると必須になってきます。

この辺りのメソッドについて（パッキングとかBatchingとか呼ばれます）は以前こちらにまとめていました。

https://qiita.com/kenmaro/items/a873d55bd4b9e5323098


## 機械学習モデルの推論
### ニューラルネット
ニューラルネットや、畳み込みニューラルネットモデルの推論を、
準同型暗号で暗号化した暗号文に対して実行するというシナリオは研究としても実際のサービスとしても結構ホットになっています。


### 決定木
決定木は機械学習モデルの中でも、かなり汎用的にいろんな場所で使われるモデルのうちの一つですが、準同型暗号を用いて暗号化したデータに対して、決定木を使用した機械学習推論は実装することが可能です。

TFHE形式を用いて実装することももちろん可能ですし、CKKS形式を使っても実装を行うことはできます。

決定木は条件式による分岐をたくさん繰り返すモデルであり比較演算が大量に発生するため、格子暗号にとってはかなり難易度が高いモデルであることは事実です。

しかしながら、いろんな製薬のもとで比較演算を実行し、それらを組み合わせることで決定木の推論は実装することができます。

比較演算についてはかなり前に記事を書いていました。

https://qiita.com/kenmaro/items/9a0362a6f9ab4e802aa3

この記事では、暗号文（ユーザからの入力）と、サーバが保持しているモデル（平文）の比較を、格子暗号ベースの比較演算、紛失通信を工夫して実行することで可能にしています。

やっている内容は実は結構工夫があって面白いので興味のある方は読んでみてください。


## 機械学習モデルの学習
機械学習モデルの学習は、演算の量的にもかなり難易度が高く、高級なアプリケーションに分類されると考えてよいでしょう。

線形回帰やロジスティック回帰などの学習であれば実際に実装することも難しくはないですし、実行時間もそこまで膨大にはならないのですが、ニューラルネットの学習などになると、現在の技術ではちょっと難しいという印象です。

### 線形回帰

線形回帰の学習については、

https://qiita.com/kenmaro/items/35d418d572c87788b820

こちらにOpenFHEを使って学習を実行するチュートリアルを実行しています。


### ロジスティック回帰
ロジスティック回帰の学習についても、CKKS形式のSIMD演算を用いて、効率的に学習を行う実装論文などが発表されています。

この学習について実装の流れがわかれば、かなりのCKKS形式マスター（というよりSEALライブラリマスター？）といっても過言ではない気がしています。

以前この学習についてもまとめていたようです。

https://qiita.com/kenmaro/items/100459d36ca7860e93e2


### サポートベクトル回帰
サポートベクトル回帰は、カーネルトリックを使って特徴空間に非線形マッピングを行うため、格子暗号との親和性はあまり良くなく、学習を実装するのは非常に骨がおれます。

しかしながら差分プライバシーなどを使って安全に復号を挟みながら演算を行なったり、OpenFHEであればブートストラップや非線形関数近似を用いながら、演算は遅くなりますが実装することは可能です。

SVRについてもとても面白い領域だったため以前記事を書いていました。

https://qiita.com/kenmaro/items/efd784bed266fc809381


## ハードウェア高速化

### Intel HEXL
格子暗号の高速化に必要なFFTやNTTの高速化を、最新のISAを使って実装しているIntel HEXLですが、もしNTLとかGMPといったライブラリや、FFTやNTTの高速化について興味のある方は、

https://qiita.com/kenmaro/items/b078eeb6b547c4cf6fb4

こちらを読んでいただければと思います。

そして、HEXLを使うことのできるOpenFHEにおいて、どのくらい高速化が図られているのか、ということについては

https://qiita.com/kenmaro/items/0c418de03f2f5bb646bb

こちらに実測を行っています。

### GPU実装
格子暗号の演算をGPGPUを用いることで高速化しようとしている研究もあります。

こちらも京都大学のレポジトリ（TFHEppをGPUを使用して高速化）がとてもわかりやすいです。

GPU実装は少ないですが存在はいくつかしています。

https://github.com/virtualsecureplatform/cuFHE

ZamaAIが開発する Concrete も、GPUを用いて高速化の恩恵を受けられるライブラリとなっています。

https://www.zama.ai/post/concrete-core-v1-0-gamma-with-gpu-acceleration



### FPGA、ASIC実装
FPGAやASICを用いた格子暗号特化型のハードウェア実装も、研究対象として注目され、いろいろな論文が発表されています。

これについても京都大学の方達のニュースですが、TFHEppをハードウェア高速化する実証実験も行われています。WAHCと呼ばれる準同型暗号の国際会議にも採択されている素晴らしい取り組みだと思います。

https://prtimes.jp/main/html/rd/p/000000050.000004053.html

他にも、いろんな記事で言及していますが、IntelやDuality Technologies, Zama AI など、さまざまな企業がASICの開発を進めており、こちらもZamaAIの記事ですが、
具体的に１万倍の高速化を目指し、FPGAおよびASICの開発に取り組んでいる、と言及しています。

https://www.zama.ai/post/introducing-the-concrete-framework




## 実装側から考える課題
格子暗号ベースの秘密計算をいろいろ実装する上で、実際にアプリケーションを作ろうとしたときの難しさについて言及しようと思います。

### 鍵の置き場所
暗号ベースのアプリケーションであれば、鍵をどこに置くか、というのは非常に重要な事柄です。
SaaS型のサービスが使い勝手としては良いのですが、そもそも暗号化はクライアントサイドで実行されるため、クライアント側で動くサービスも実装される必要があります。

そのSaaSになりきれないアプリケーションとなってしまうことは、導入の難易度などを考えても準同型暗号アプリケーションの難しいところです。

秘密分散についても、実際のアプリケーションを作る以前に、チュートリアルを実行する際にクラスターを作る必要があったり、Kubernetes などのインフラにも精通している必要があり、実装難易度は簡単ではないと考えられます。

準同型暗号ベースの実装で問題となる鍵の置き場所は、もちろんKMSサービスのようなものを運用したりしてもいいですし、準同型暗号のライブラリをブラウザから呼べるようにし（つまりWebAssemblyで実行できるように実装する）、鍵をブラウザで管理する、みたいなのはUXとして非常にいいアプローチだと思っています。

その意味で、これまでにOpenFHEライブラリのWasm化、にも取り組んできました。

https://qiita.com/kenmaro/items/f4e3db3317b6a9c14f13

今年はハッカソンをきっかけにConcreteライブラリのWasm化にも取り組みました。

https://qiita.com/kenmaro/items/1d1c1dcc44097037f121


少し話が逸れるのですが、AIモデルの実行を準同型暗号の大きなユースケースと考えた時に、AIを扱う人はほとんどがPythonを使う、ということを考えると、
C++やRustで実装されることが多い暗号ライブラリについても、インターフェースとしてはPythonで使えるようにバインディングがされているというのはUXとして非常に魅力的になります。

OpenFHEのPythonバインディングについても実装を（少し中途半端ですが）行っています。

https://qiita.com/kenmaro/items/c36f28609c2717923ad6


### 登場する鍵が多すぎる
基本的にはユーザが増えれば鍵も同じように増えていく、というのが準同型暗号を用いてサービスを作ろうとする時に悩ましい事柄です。

複数のユーザがプロットフォームを通じてデータを連携させ、ビッグデータを作って分析を暗号状態で実行する、というようなユースケースは非常に強力です。

しかしながら、たくさん登場する鍵ペアをどうやって共有したり保管しておくかということはサービスを作る上で悩ましいのが現実です。

また、OpenFHEのチュートリアルを行うと分かるように、格子暗号には暗号化に使用する鍵、復号に使用する鍵、計算に使用する鍵（この計算鍵もいくつかに分かれる）など
鍵の種類は５種類くらいあるためそれらをどうやってUXを落とさずに管理するか、ということも非常に大事になってきます。


### セキュリティモデルはユーザによって異なることがほとんど

サービスを作る時、なるべく汎用的なサービスを作りたいということは可能であればそうしたいですが、ユーザが必要としているセキュリティ要件や、データのフローはいろいろな要素が絡まっています。

現オペレーションがあることから簡単にフローを変えることはできない、と考えると、作るサービスもカスタマイズ要素が強くなってしまうことも、秘密計算を用いたサービス作りで難しい観点だと思います。


### 差分プライバシーなどを考慮したデータフローの作り方が複雑

前述したことと同じ内容ではあるのですが、データフローに対してどうしても暗号文を復号しないといけない時、元々のデータが漏洩しないようにノイズを加えたりして差分プライバシーによるデータ保護を考慮する必要があります。

その結果として、いろいろな通信が発生し、開発側としては単純なオペレーションを実装したいだけなのにかなり複雑なプロトコルを作らないといけないことも発生したりします。




## 面白そうなユースケース
いろいろと課題も多い秘密計算、準同型暗号の技術ですが、
最近数年でたくさんの応用先が開拓されているのも事実です。

### ブロックチェーン＋格子暗号
ZamaAIが提案する、プライベートスマートコントラクトはとても面白い実装であり、
とても興味が湧きました。

https://www.zama.ai/post/private-smart-contract-using-homomorphic-encryption-ethcc-2022

是非上のブログを読んでいただければと思います。

Web３ハッカソンに出場した時、実際にSolanaスマートコントラクト上で準同型暗号を動かして、オンチェーンのデータを秘匿したまま計算しようとしました。

https://qiita.com/kenmaro/items/7aa336227d6eb332d791

結果としていろいろな制約があり、既存チェーン上で準同型暗号を動かすのはかなり厳しいな、という結果になってしまいましたが、チェーン自体も開発している（と考えられる）ZamaAIに対しては、そこも含めて期待感が高いです。

また、HuaweiもどうやらBlockchain + HE の領域に取り組んでいるようです。

https://support.huaweicloud.com/intl/en-us/devg-bcs/bcs_devg_0304.html

このDemoでは、まさに私がハッカソンでやろうとしていたオンチェーン上で準同型暗号化を用いて暗号のまま取引がValidかどうか判断させるようなことをやっているみたいです。


### アクセスコントロール＋格子暗号

https://qiita.com/kenmaro/items/709474f2035caf786fb3

この記事で言及した、プロキシ再暗号化を活かすことで、格子暗号を用いたアクセスコントロールの実装は面白いユースケースだと考えています。

アクセスコントロールもできるし、暗号のまま計算もできるので、分析結果を見せたい人だけに見せることができるようにアクセスコントロールしたり、ログの集計をして集計結果だけ誰か特定の人に見せたりなど、なかなかやりがいのある領域だと思います。


### TFHEベースの自動微分を実装した格子暗号版ニューラルネット学習
Pytorch (というよりChainerからの派生）で美しい実装とされている自動微分（autograd)の機構を持った機械学習ライブラリですが、TFHE形式のプログラマブルブートストラップ（PBS)を活用することで、暗号状態でこの自動微分を走らせるようなライブラリは、非常に面白いのではないかと思っています。

ベースは有名な

https://github.com/karpathy/micrograd

この辺りのライブラリにはなるかと思いますが、PBSの性能がこれからハードウェアの開発などによりついてくれば、かなり汎用的に機械学習モデルの学習を完全に秘匿化した状態で実行できるのでは、と考えています。

### VPNのアクセスコントロール＋格子暗号
私自身このトピックは詳しくないのですが、VPNネットワークでアドレスを弾くときのテーブル参照に対して、格子暗号を用いて自分がアクセスしたいアドレス先を秘匿したまま、パケットフィルタをするような研究があるらしいです。

私も詳しくはないのですが、OISTあたりで研究されているらしいので、もし興味のある方がいらっしゃいましたら論文を読んでみてはどうでしょうか。


### 準同型暗号＋認証

面白そうな研究開発が行われているようなので、論文だけシェアします。
中身はまた近いうちに読んでみたいと思っています。

https://www.researchgate.net/publication/322447029_A_new_authentication_and_homomorphic_encryption_as_a_service_model_for_preserving_privacy_in_clouds

また、Huawei が発表しているこのDemoも面白そうです。

https://support.huaweicloud.com/intl/en-us/devg-bcs/bcs_devg_0304.html


## 格子暗号についてこれから勉強したい人へ

以上のように、格子暗号に対しては、

- 実行したい演算のアルゴリズム高速化
- ハードウェア高速化
- 暗号ライブラリのソフトウェア高速化
- アプリケーション実装のレイヤ

など、いろいろなアプローチがあるため、結構面白い領域だと思っています。

以前書いた格子暗号のスタディロードマップについての記事は一年以上前の記事となってしまいましたが、今でも通用するロードマップだと思っておりますので、興味がある人がいらっしゃいましたら是非読んでいただきたいです。

https://qiita.com/kenmaro/items/f2d4fb84833c308a4d29




## まとめ

今回は少し長くなってしまいましたが、
今まで書いた記事を集結させ今年一年でいろいろと進んだ、
準同型暗号周りの研究開発や動向について書けるだけ書いてみました。


まだいろいろと制約も多い技術ですが、

- 理論的な研究
- 高速化を考慮したソフトウェア研究開発
- セキュリティ要件を加味したアプリケーション開発

など、準同型暗号というテーマでいろいろなアプローチをとれるので面白いことも多い領域だと感じています。


興味のある人がいらっしゃいましたら、これからもウォッチしていきましょう。


今回はこの辺で。


@kenmaro