マルチパーティ計算(MPC)について
マルチパーティ計算(MPC, Multi-Party Computation)は、「秘密情報」の計算を、「秘密情報のシェア」を使って行う技術です。秘密情報を明かさずに計算を行うことができます。
BGW 型 MPC
BGW 型 MPC は、Shamir の秘密分散法を基盤として加算や乗算といった計算を実現する方式です。BGW は、提案者の Ben-Or 氏, Goldwasser 氏, Wigderson 氏 の頭文字を取っています。
加算 - BGW 型 MPC
BGW 型 MPC における加算は、各パーティが保持するシェアを単純に加算することで実現されます。
- 秘密情報
- 秘密情報
- 秘密情報からシェアを作成し、各パーティに配布する
- 各パーティは自身の持つ 2 つのシェアを加算する
- 各パーティが持つ加算結果のシェアを使って秘密情報の復元を行うと、の結果が得られる
- のシェア:
- のシェア:
- のシェア:
- のシェア:
が知りうる情報 → | 39 | 17 | 56 |
が知りうる情報 → | 37 | 20 | 57 |
が知りうる情報 → | 25 | 27 | 52 |
が知りうる情報 → | 3 | 38 | 41 |
各パーティは秘密情報およびその加算結果の「シェア」を保持していますが、秘密情報およびその加算結果そのものを知ることはできません。
乗算 - BGW 型 MPC
加算と同様にシェア同士を乗算すると、秘密情報の復元に必要なシェアの数が増加してしまいます。これは、Shamir の秘密分散法が、次多項式を使用していることに起因します。シェア同士を乗算すると、次多項式から次多項式へと次数が増加します。本来しきい値法として扱っていたものが、しきい値法となります。
そのため、BGW 型 MPC における乗算では、各パーティがシェア同士を乗算した後に、パーティ間でやりとり(通信)を行い、しきい値を調整します。
- 各パーティは自身の持つ乗算結果から、Shamir の秘密分散法でシェアを作成する(パーティがディーラーになる)
- ステップ 1 で作成した個のシェアを各パーティに配布する(個のうちの一つは自身が保持する)
- 各パーティは、受け取ったシェアのうち個を使って秘密情報の復元を行う
ステップ 3 の秘密情報の復元により得られるのは、次数が下がったしきい値法のシェアです。このシェアが個集まることで、乗算結果が得られます。
複製型秘密分散法に基づく MPC
加算 - 複製型秘密分散法に基づく MPC
BGW 型 MPC同様、各パーティが保持するシェアを要素ごとに加算するだけで実現できます。
複製型秘密分散法に基づく MPC での加算 では、秘密情報から加法型秘密分散法シェアとを作成し、以下のように配布します。
- のシェア:
- のシェア:
- のシェア:
各パーティが要素ごとに加算すると、以下のような結果が得られます。
- のシェア:
- のシェア:
- のシェア:
この加算の結果のシェアを任意の 2 パーティから集めることで、加算結果を得られます。
乗算 - 複製型秘密分散法に基づく MPC
乗算では、各パーティが以下に示す計算を行った後に、パーティ間でやりとり(通信)を行います。
複製型秘密分散法に基づく MPC での乗算では、秘密情報から加法型秘密分散法シェアとを作成し、以下のように配布します。
- のシェア:
- のシェア:
- のシェア:
この計算結果は、の加法型秘密分散法のシェアとなります。このことは、全てのパーティのシェアを集めて復元するととなることから確かめられます。
加法型秘密分散法シェアから複製型秘密分散法シェアに変換
がの加法型秘密分散法のシェアであることはわかりましたが、複製型秘密分散法が加法型秘密分散法になってしまっているので、複製型秘密分散法に戻す作業が必要です。
各パーティは現在、以下のシェアを保持しています。
各パーティがをに送信すれば、
となり、複製型秘密分散法に変換することができます。
PRSS
通信を安全かつ効率的に実現する有力な手順として、疑似乱数秘密分散(Pseudorandom secret sharing, PRSS)が用いられます。PRSS は、事前に共有された鍵やシードを用いて各パーティが擬似的に乱数シェアを作成します。この乱数シェアを復元した結果が 0 となる性質を持つため、0 の秘密分散とも言えます。これにより、MPC で計算する本来の値に影響を与えずに、乱数シェアの加算によってシェアをランダム化し、情報の漏れを防ぐことが可能となります。
PRSS を用いて乱数シェアを生成する方法を 2 つ紹介します。
モジュロ演算を用いた PRSS
- 各パーティは乱数を生成し、その乱数をパーティへ送信する(以下、適宜)
- 各パーティは、自身が生成した乱数とから受け取った乱数の差分()を計算する
各パーティは以下の PRSS シェアを保持します。
各パーティが計算したシェアの合計は、モジュロにおいて 0 になります。
HMAC/ハッシュ関数を用いた PRSS
HMAC/ハッシュ関数を用いた PRSS は、特に XOR ベースの秘密分散法(例: 二元体上の計算)で用いられます。
- 各パーティは乱数(キー)を生成し、その乱数をパーティへ送信する
- 各パーティは、自身の持つキーと自身のパーティ ID を入力として HMAC 値を計算する
- 同様に、から受け取ったキーとパーティ ID を入力として HMAC 値を計算する
この手順によって各パーティは 2 つの HMAC 値を保持します。
すべてのシェアを XOR すると、各 HMAC 値がちょうど 2 回出現するため、結果は 0 になります。
モジュロ演算を用いた PRSS によるシェア変換
加法型秘密分散法シェアから複製型秘密分散法シェアに変換のステップで、各パーティは計算結果を持っています。
各パーティは PRSS を使ってシェアをマスクします。先に説明したモジュロ演算を用いた PRSS によって、各パーティは以下の PRSS シェアを持っています。
まず、各パーティは自身の持つを自身の PRSS シェアでマスクします。
次に、各パーティはをに送信します。送信後、各パーティは以下のシェアを保持しています。
これにより、複製型秘密分散法の形式に変換されました。
復元の確認 - モジュロ演算
任意の 2 パーティから 3 つの異なるマスクされたシェアを集めると、それらを加算することで秘密情報を復元できます。
PRSS を用いることで通信内容をマスクしながら、正しく複製型秘密分散法に変換でき、最終的に秘密情報を復元することができます。
XOR ベースの PRSS によるシェア変換
二元体上での計算や XOR ベースの秘密分散法を用いる場合は、先に説明した HMAC/ハッシュ関数を用いた PRSS を適用します。この場合、加算の代わりに XOR 演算を使用します。
各パーティはをに送信し、以下のシェアを保持します。
復元の確認 - XOR ベース
復元の際は、3 つのシェアを XOR することで秘密情報を取得できます。
このように、PRSS を使って通信内容をランダム化することで、MPC の安全性を高めることができます。
PRSS の流れ
===== PRSS(疑似乱数秘密分散)の流れ =====
60行の折りたたみ
ステップ1: 各パーティが乱数を生成パーティ1が生成した乱数: 15パーティ2が生成した乱数: 26パーティ3が生成した乱数: 181
ステップ2: 各パーティから他のパーティへ乱数を送信パーティ1からパーティ2へ乱数 15 を送信パーティ2からパーティ3へ乱数 26 を送信パーティ3からパーティ1へ乱数 181 を送信
ステップ3: 各パーティがPRSSシェアを計算パーティ1のPRSSシェア: 90 = (15 - 181) mod 256パーティ2のPRSSシェア: 11 = (26 - 15) mod 256パーティ3のPRSSシェア: 155 = (181 - 26) mod 256
PRSSシェアの合計 (mod 256): 0 検証: (90 + 11 + 155) mod 256 = 0
===== 秘密値の分散と計算 =====
ステップ4: 秘密値を設定し、加法型シェアを生成元の秘密値: 31加法型シェア: s1=138, s2=70, s3=79 検証: (138 + 70 + 79) mod 256 = 31
ステップ5: 各パーティが加法型シェアとPRSSシェアを組み合わせてマスクパーティ1のマスク済みシェア v1: 228 = (138 + 90) mod 256パーティ2のマスク済みシェア v2: 81 = (70 + 11) mod 256パーティ3のマスク済みシェア v3: 234 = (79 + 155) mod 256
===== 複製型秘密分散法への変換 =====
ステップ6: 各パーティが自分のマスク済みシェアを送信パーティPiがマスク済みシェアv_iをパーティP_{i-1}に送信するパーティ1からパーティ3へマスク済みシェア v1: 228 を送信パーティ2からパーティ1へマスク済みシェア v2: 81 を送信パーティ3からパーティ2へマスク済みシェア v3: 234 を送信
送信後、各パーティが保持するマスク済みシェア:パーティ1が保持するシェア: (v1=228, v2=81)パーティ2が保持するシェア: (v2=81, v3=234)パーティ3が保持するシェア: (v3=234, v1=228)
複製型秘密分散法の形式:P1: (v1, v2) = (u1 + prss1, u2 + prss2)P2: (v2, v3) = (u2 + prss2, u3 + prss3)P3: (v3, v1) = (u3 + prss3, u1 + prss1)
===== シェアから秘密値の再構築 =====
ステップ7: 各パーティのペアで秘密値を再構築パーティ1とパーティ2による再構築: 31 (等しいか: True) 使用したシェア: [228, 81, 234] 検証: (228 + 81 + 234) mod 256 = 31パーティ2とパーティ3による再構築: 31 (等しいか: True) 使用したシェア: [81, 234, 228] 検証: (81 + 234 + 228) mod 256 = 31パーティ3とパーティ1による再構築: 31 (等しいか: True) 使用したシェア: [234, 228, 81] 検証: (234 + 228 + 81) mod 256 = 31
===== PRSS(疑似乱数秘密分散)の流れ =====
60行の折りたたみ
ステップ1: 各パーティが乱数を生成パーティ1が生成した乱数: 151318656パーティ2が生成した乱数: 1862866817パーティ3が生成した乱数: 1594654746
ステップ2: 各パーティから他のパーティへ乱数を送信パーティ1からパーティ2へ乱数 151318656 を送信パーティ2からパーティ3へ乱数 1862866817 を送信パーティ3からパーティ1へ乱数 1594654746 を送信
ステップ3: 各パーティがPRSSシェアを計算パーティ1のPRSSシェア: 704147557 = (151318656 - 1594654746) mod 2147483647パーティ2のPRSSシェア: 1711548161 = (1862866817 - 151318656) mod 2147483647パーティ3のPRSSシェア: 1879271576 = (1594654746 - 1862866817) mod 2147483647
PRSSシェアの合計 (mod 2147483647): 0 検証: (704147557 + 1711548161 + 1879271576) mod 2147483647 = 0
===== 秘密値の分散と計算 =====
ステップ4: 秘密値を設定し、加法型シェアを生成元の秘密値: 42加法型シェア: s1=1776888125, s2=1987674048, s3=530405163 検証: (1776888125 + 1987674048 + 530405163) mod 2147483647 = 42
ステップ5: 各パーティが加法型シェアとPRSSシェアを組み合わせてマスクパーティ1のマスク済みシェア v1: 333552035 = (1776888125 + 704147557) mod 2147483647パーティ2のマスク済みシェア v2: 1551738562 = (1987674048 + 1711548161) mod 2147483647パーティ3のマスク済みシェア v3: 262193092 = (530405163 + 1879271576) mod 2147483647
===== 複製型秘密分散法への変換 =====
ステップ6: 各パーティが自分のマスク済みシェアを送信パーティPiがマスク済みシェアv_iをパーティP_{i-1}に送信するパーティ1からパーティ3へマスク済みシェア v1: 333552035 を送信パーティ2からパーティ1へマスク済みシェア v2: 1551738562 を送信パーティ3からパーティ2へマスク済みシェア v3: 262193092 を送信
送信後、各パーティが保持するマスク済みシェア:パーティ1が保持するシェア: (v1=333552035, v2=1551738562)パーティ2が保持するシェア: (v2=1551738562, v3=262193092)パーティ3が保持するシェア: (v3=262193092, v1=333552035)
複製型秘密分散法の形式:P1: (v1, v2) = (u1 + prss1, u2 + prss2)P2: (v2, v3) = (u2 + prss2, u3 + prss3)P3: (v3, v1) = (u3 + prss3, u1 + prss1)
===== シェアから秘密値の再構築 =====
ステップ7: 各パーティのペアで秘密値を再構築パーティ1とパーティ2による再構築: 42 (等しいか: True) 使用したシェア: [333552035, 1551738562, 262193092] 検証: (333552035 + 1551738562 + 262193092) mod 2147483647 = 42パーティ2とパーティ3による再構築: 42 (等しいか: True) 使用したシェア: [1551738562, 262193092, 333552035] 検証: (1551738562 + 262193092 + 333552035) mod 2147483647 = 42パーティ3とパーティ1による再構築: 42 (等しいか: True) 使用したシェア: [262193092, 333552035, 1551738562] 検証: (262193092 + 333552035 + 1551738562) mod 2147483647 = 42