暗号勉強会

あまりコードが出てこない話

なんとなく分かってもらうためのSPDZ解説(プリプロセスフェーズ編)

SPDZはsomewhat準同型暗号(以下SHE)を使うことで高い効率性と安全性を実現したマルチパーティ計算プロトコルです。

  • SHEによる効率的なプリプロセスフェーズの実現。

  • semi-honest secureよりも高い、active secureの効率的な実装。

  • active secureなので、n個のパーティのうちn-1がcorruptされていてもUC安全性が保障される。

のような性質を持っています。これについて解説します。



はじめに

ここから登場する記号は太字の場合はすべて\mathbf{v} \in (\mathbb{F _ {p ^ k}}) ^ sである有限体上のs次元ベクトル\mathbf{v}です。 そうでなければv \in \mathbb{F _ {p ^ k}} である有限体の要素vです。

SHEとは加算と乗算に対して準同型性を持つが、計算回数が制限されたものです。SHEのなかでもBVというスキームを活用します。BVでは暗号文のまま十分な数と加算と1回の乗算を行うことが出来ます。暗号文での乗算が1回を超すと、正しく復号できなくなることに注意してください。

SPDZではSHEの準同型性を生かし、平文を暗号化し、暗号文の状態でブロードキャストや計算を行います。この時、

  • 暗号文なので平文の情報は漏れない。

  • SHEの準同型性によって暗号文のまま計算ができる。

となります。こうして、プリプロセスフェーズで必要な情報を各パーティが使用可能な状態にしておくことで、オンラインフェーズでの計算量を減少させます。

加算と乗算

オンラインフェーズでも述べますが、加算と乗算の方法について説明します。 秘密分散方式として、加法的秘密分散を使っています。mm=m _ 1+\dots+m _ nを満たすようなm _ iに分割します。このことをm=\Sigma _ i m _ iと書き、各m _ iのことをシェアということにします。

例えばm=10として、(m _ 1,m _ 2,m_ 3,m _ 4)=(1,5,2,3)とすると、

m=\Sigma _ i m _ i=1+5+2+3=10

  が明らかです。更にそのまま加算を行うこともできます。P _ 1m5を足したい場合は、m _ 15を足します。実際、

m=\Sigma _ i m _ i=(1+5)+5+2+3=15

  なので加算できています。

乗算の場合はMultiplication Triplesを使います。Multiplication Triplesについては以下のサイトが参考になります。

acompany.tech

ここではMultiplication Triplesのことをトリプルと呼ぶことにします。

MACでの認証

さて、SPDZには二つの値表現が登場します。SPDZではシェアをパーティの持つ秘密鍵やグローバル鍵で認証してあげることで、不正を検出します。この認証に使う認証子をMAC(Message Authentication Code)と呼ぶことにします。

\langle \mathbf{m} \rangleMACで認証されたシェアです。この値は単一の値を表現しているわけではなく、以下のような状態を表します。

f:id:ATen:20200712130212p:plain
<m>の表す状態

Privateは各パーティP _ iが個人で所持している値です。Publicはすべてのパーティが参照できる値です。

  • \deltaMACの条件を維持するために利用します。詳しい役割についてはオンラインフェーズで述べます。

  • \ \mathbf{m _ 1} ,\mathbf{m _ 2},\dots,\mathbf{m _ n}は計算は各パーティP _ iの所持するシェアです。

  • \gamma ( \mathbf{m} ) _ iはその計算における不正を検証するためのMACです。

なお、このMAC\alphaがないとチェックできないので計算が全て終わってからでないと誰かが不正したことを検出できません。

[ \mathbf{m} ]秘密鍵\beta _ iで認証された値です。この値も単一の値を表現しているわけではなく、以下のような状態を表します。論文や図では〚〛を使用していますが、texで出す方法が分からないので以降は[]で代用しています。

f:id:ATen:20200712130704p:plain
[m]の状態

  • \ \mathbf{m _ 1} ,\mathbf{m _ 2},\dots,\mathbf{m _ n}は計算は各パーティP _ iの所持するシェアです。

  • (\gamma ( \mathbf{m} ) ^ i _ 1,\dots,\gamma ( \mathbf{m} ) ^ i _ n) _ {i=1,\dots,n}はその計算における不正を検証するためのMACです。

この状態では、ブロードキャストしあってシェアを集めることで\beta _ iに認証された\alphaを復元できます。例えば、下の図の赤く囲われた部分をブロードキャストしあって集めることで\beta _ 1に認証された\alphaを復元できます

f:id:ATen:20200712130208p:plain
[m]の表す状態2

\beta _ 1を持っているP _ 1なら値の正しさを検証できます。P _ 1以外の P_ i についても同様です。

\langle \mathbf{m} \rangleとの違いは\alphaなしに\mathbf{m}を手にいられることです。そのため、オンラインフェーズで\alphaを公開するより前に値が必要な時に利用されています。

この表現はMACの認証に使用するグローバル鍵\alphaの公開を遅らせるために存在しています。各パーティP _ i\alphaがなければMACを確認することができないませんが、\alphaがあると偽造できてしまいます。偽装を防ぐために各パーティの秘密鍵\beta _ iで認証させて、\alphaの公開を遅らせます。

サブプロトコル

プリプロセスフェーズでは同じような処理を繰り返し行う部分があるため、それを一般化したものを定義します。PBracket(\mathbf{m} _ 1,\dots,\mathbf{m} _ n,e _ \mathbf{m})のようになっていますが、\mathbf{m} _ 1,\dots,\mathbf{m} _ nは各パーティP _ iのローカルに保持する値であることに注意してください。

平文のゼロ知識証明

任意の平文に対する正しい暗号文を共有するために以下の処理を行います。これをPoPK(\mathbf{m _ i})としましょう。

  1. 各パーティP _ iはメッセージ空間から\mathbf{m _ i}\in (\mathbb{F _ {p ^ k}}) ^ sを選ぶ。各パーティの生成した平文の和は\mathbf{m}=\Sigma _ i \mathbf{m _ i}となる。

  2. 各パーティP _ ie _ {\mathbf{m _ i}} \leftarrow Enc _ {pk}(\mathbf{m _ i})のように暗号化してブロードキャストする。

  3. 各パーティP _ iは暗号文e _ {\mathbf{m _ i}}に対応する平文\mathbf{m _ i}を知っていることを証明する。

  4. 各パーティP _ ie _ {\mathbf{m }}\leftarrow e _ {\mathbf{m _ 1}}\boxplus \dots \boxplus e _ {\mathbf{m _ n}}を計算する。

暗号文e _ {\mathbf{m _ i}}に対応する平文\mathbf{m _ i}を知っていることを証明する。

この処理によりe _ {\mathbf{m _ i}}を正しく共有し、e _ {\mathbf{m }}を入手できます。

PAngle

PAngleは任意の平文に対するシェアを生成するために以下の処理を行います。これをPAngle(\mathbf{m} _ 1,\dots,\mathbf{m} _ n,e _ \mathbf{m})としましょう。


PAngle(\mathbf{m} _ 1,\dots,\mathbf{m} _ n,e _ \mathbf{m})=\langle \mathbf{m} \rangle

暗号文e _ {\mathbf{m}}と、平文\mathbf{m}のシェアを入力に\langle \mathbf{m} \rangleを生成する。各パーティP _iはグローバル鍵\alphaの暗号文e _ {\alpha}e _ {\mathbf{m}}の積を計算し、e _ {\mathbf{m} \cdot \alpha}を計算します。e _ {\mathbf{m} \cdot \alpha}\alphaで認証したMACの暗号文であり、これをReshareすればMACを共有できます。暗号文での乗算回数は1回です。

PBracket

PBracketは任意の平文に対するシェアを生成するために以下の処理を行います。これをPAngle(\mathbf{m} _ 1,\dots,\mathbf{m} _ n,e _ \mathbf{m})としましょう。


PBracket(\mathbf{m} _ 1,\dots,\mathbf{m} _ n,e _ \mathbf{m})=[ \mathbf{m} ]

  暗号文e _ {\mathbf{m}}と、平文\mathbf{m}のシェアを入力に [\mathbf{m} ]を生成します。各パーティP _i秘密鍵\beta _ iの暗号文e _ {\beta _ i}e _ {\mathbf{m}}の積を計算し、e _ {\gamma _ i}を計算します。e _ {\gamma _ i}\beta _ iで認証したMACの暗号文であり、これをReshareすればMACを共有できます。暗号文での乗算回数は1回です。

Reshare

Reshareは暗号文からシェアを生成するプロトコルです。


Reshare(e _ \mathbf{m},enc)=\langle \mathbf{m} \rangle\ and\   e' _ \mathbf{m}

  暗号文e _ {\mathbf{m}}に対応する平文\mathbf{m}のシェアを秘密分散します。第二引数にNewCiphertextのコマンドを入力されると、平文\mathbf{m}を暗号化しているが暗号文e _ {\mathbf{m}}=e' _ {\mathbf{m}}のような暗号文e' _ {\mathbf{m}}も同時に生成します。暗号状態での乗算回数は0回です。

Reshareは乗算を1回も行わないので、PAnglePBracketと組み合わせても乗算回数が1回を超えることがありません。

プリプロセス(オフライン)フェーズ

サブプロトコルを活用して平文の情報を一切明かすことなく、プロトコルの初期化やトリプルとペアの共有を行うことができます

具体的にはオンラインフェーズで利用する


\langle \mathbf{a} \rangle,\langle \mathbf{b} \rangle,\langle \mathbf{c} \rangle,\langle \mathbf{r} \rangle,\langle \mathbf{f} \rangle,\langle \mathbf{g} \rangle,\langle \mathbf{h} \rangle
[\mathbf{r}],[Diag(\alpha)],[\mathbf{t}],[\mathbf{e}]

を生成します。Diag(\alpha)とは\alphas個を並べた(\alpha,\dots,\alpha)を表します。\alphas次元ベクトルでないので、s次元に拡張しています。

プリプロセスは初期化、ペアの生成、トリプルの生成の3段階に分けることが出来ます。

初期化

まずトリプルやペアの生成のために、鍵を共有します。具体的には各パーティP _ i[Diag(\alpha)]と\beta _ iを持っている状態にします。

  1. 暗号化のためにプロトコルは公開鍵pkをセットする。

  2. 各パーティP _ iはメッセージ空間から\beta _ i\in \mathbb{F _ {p ^ k}}を選ぶ。

  3. \mathbf{m _ i}:=Diag(\alpha _ i)とし、PoPK(Diag(\alpha _ i))を行う。各パーティP _ ie _ {\alpha _ i}\alpha _ iを所持した状態になる。(ここでだけeの添え字はDiag(\alpha _ i)とならない)

  4. e _ {\alpha _ i}Diag(\alpha _ i)を使い、PBracket(Diag(\alpha _ 1),\dots,Diag(\alpha _ n),e _ \alpha)を行う。プロトコル[ Diag(\alpha) ]を手に入れる。

トリプル

Multiplication Tripleを共有することを考えます。オンラインフェーズで一回の乗算ごとに2セットのトリプル

\langle \mathbf{a} \rangle,\langle \mathbf{b} \rangle,\langle \mathbf{c} \rangle\\
\langle \mathbf{f} \rangle,\langle \mathbf{g} \rangle,\langle \mathbf{h} \rangle

を消費します。消費するだけ生成しておく必要があります。\langle \mathbf{f} \rangle,\langle \mathbf{g} \rangle,\langle \mathbf{h} \rangleの必要性についてはオンラインフェーズで述べます。

トリプル\langle \mathbf{a} \rangle,\langle \mathbf{b} \rangle,\langle \mathbf{c } \rangle\mathbf{c}=\mathbf{ab}を満たし、\langle \mathbf{f} \rangle,\langle \mathbf{g} \rangle,\langle \mathbf{h} \rangleも同様に\mathbf{h}=\mathbf{fg}を満たします。

  1. \mathbf{m _ i}:=\mathbf{a _ i}とし、PoPK(\mathbf{a _ i})を行う。各パーティP _ ie _ {\mathbf{a _ i}}\mathbf{a _ i}を所持した状態になる。

  2. e _ {\mathbf{a _ i}}\mathbf{a _ i}を使い、PAngle(\mathbf{a} _ 1,\dots,\mathbf{a} _ n,e _ \mathbf{a})を行う。\langle \mathbf{a} \rangleを手に入れる。

  3. ここまでの処理を\mathbf{m _ i}:=\mathbf{b _ i}に対しても行う。(実際には\mathbf{a}と平行に行っている)

  4. e _ \mathbf{c } = e _ \mathbf{a} \boxtimes e _ \mathbf{b}を計算する。

  5. e _ \mathbf{c}を入力にReshare(e _ \mathbf{m},NewCiphertext)を呼び出す。

  6. e _ {\mathbf{c }}\mathbf{c _ i}を使い、PAngle(\mathbf{c} _ 1,\dots,\mathbf{c} _ n,e _ \mathbf{c})を行う。\langle \mathbf{c} \rangleを手に入れる。

5ReshareNewCiphertextとしているのはe _ \mathbf{c} 4の時点で1回乗算された暗号文となっているためです。 そのまま6PAngleを使うとe _ \mathbf{c}の乗算回数が2回になってしまいます。よって、e' _ {\mathbf{c}}に変換して乗算回数をリセットする必要があります。

ペア

ペアというのは以下の乱数の組です。オンラインフェーズで乱数として活用します。


\langle \mathbf{r} \rangle,[\mathbf{r}]
  1. \mathbf{m _ i}:=\mathbf{r _ i}とし、PoPK(r _i)を行う。各パーティP _ ie _ {\mathbf{r _ i}}\mathbf{r _ i}を所持した状態になる。

  2. e _ {\mathbf{r _ i}}\mathbf{r _ i}を使い、PAngle(\mathbf{r} _ 1,\dots,\mathbf{r} _ n,e _ \mathbf{r})を行う。プロトコル\langle \mathbf{r} \rangleを手に入れる。

  3. e _ {\mathbf{r _ i}}\mathbf{r _ i}を使い、PBracket(\mathbf{r} _ 1,\dots,\mathbf{r} _ n,e _ \mathbf{r})を行う。プロトコル[ \mathbf{r} ]を手に入れる。

このプロトコル2を飛ばすことで、後にオンラインフェーズで


[\mathbf{t}],[\mathbf{e}]

と呼ばれる乱数を生成することもできます。

まとめ

この記事ではSPDZのプリプロセスフェーズについて解説しました。平文を明かすことなくオンラインフェーズの計算の準備をすることができます。このプリプロセスフェーズを前提とすれば、効率的にオンラインフェーズを行うことができます。

オンラインフェーズについては別の記事で解説します。言ってることがおかしい部分などがありましたら、コメントお願いします。

参考文献

Ivan Damg˚ard, Valerio Pastro, Nigel Smart, and Sarah Zakarias Multiparty Computation from Somewhat Homomorphic Encryption 2012

C.Gentry Fully Homomorphic Encryption Using Ideal Lattices 2009

Zvika Brakerski1 and Vinod Vaikuntanathan ,Fully Homomorphic Encryption from Ring-LWE and Security for Key Dependent Messages

秘密分散ベースのMPCプロトコルSPDZ - Develop with pleasure!