図解で理解するvetKD
当資料は connpass で共有予定
2023/11/25 @tokuryoo
vetKey とは
IC の Dapp 用に提供される
暗号化・復号化技術の総称
vetKD とは
vetKey を実現するための暗号プリミティブ(暗号技術の基本的な構成要素)
https://internetcomputer.org/blog/features/vetkey-primer
用語の定義
vetKD
注)まだ正式にはリリースされていない。ローカルでのみ試すことができる。
ドラフト版が 2023年7月 に公開。実験段階。
Veri
fi
ably Encrypted Threshold Key Derivation (vetKD)
検証可能な暗号化された閾値鍵導出
ユーザーの秘密鍵の導出が特徴的
・復号化の度に IC 上で秘密鍵を導出
→ユーザーは復号化の度に秘密鍵を捨てて良い
→ Dapp の開発が楽になる(セキュリティ上の配慮が減る/複数のデバイスをまたがりやすい)
・ユーザーの秘密鍵を導出するには、一定以上のノードが協力する必要がある
※閾値。2/3 になる予定。
IC 独自の end-to-end 用の暗号技術
基本的にブラウザ上で暗号化・復号化
(デバイス)
公開鍵暗号 → IBE → vetKD
の順で理解することで
vetKD を理解
IBE をトラストレスにしたもの
(ID-Based Encryption)
復号化の度に秘密鍵導出
本題
図解で理解するvetKD
※補足 vetKD は IBE 以外に AES-GCM-256(共通鍵暗号)も提供しているが
今回は省く(未調査)
公開鍵暗号
1. 秘密鍵、公開鍵
生成
2. 公開鍵 共有
3. 暗号文 ← 暗号化(公開鍵, メッセージ)
5. メッセージ ←
復号化(秘密鍵, メッセージ)
Bob
※秘密鍵を元に公開鍵が導出される。
(数学的にその逆はできない)
Alice Bob
4.暗号文
※秘密鍵を持っている
Bob だけが復号化できる
問題:インターネットを介して公開鍵が共有された場合
公開鍵が確かに Bob のものかわからない。
→ 公開鍵証明書(電子証明書)…例:SSL証明書
Alice がメッセージを暗号化して Bob へ送る。
Bob は暗号文を受け取り復号化する。
IBE 簡易説明
1.
暗号文 ← 暗号化(BobのID, メッセージ)
2.暗号文
4.秘密鍵̲Bob
5.
メッセージ ← 復号化(暗号文, 秘密鍵̲Bob)
次のスライドで詳細あり
(ID-Based Encryption)
☝ポイント
・Bob は秘密鍵、公開鍵を生成しない
・秘密鍵̲Bob を作るより先に、公開鍵(BobのID)が存在する。
(数学的に公開鍵を元に秘密鍵を導出できないはずなのに、不思議)
↑ID が公開鍵相当
※PKGだけが導出できる
PKG
Private-Key Generator
Alice Bob
3. 認証&秘密鍵要求
IBE 詳細 1.セットアップ
マスター公開鍵とマスター秘密鍵生成
2.
暗号文 ← 暗号化(マスター公開鍵, BobのID, メッセージ)
3.暗号文
5.
秘密鍵̲Bob ← 秘密鍵導出(マスター秘密鍵, BobのID)
6.秘密鍵̲Bob
7.
メッセージ ← 復号化(暗号文, 秘密鍵̲Bob)
先に公開鍵が作られて、後で秘密鍵が作られる
(通常の公開鍵暗号では不可能)
PKG への信用が必要であり
トラストレスではない。
マスター秘密鍵を持っている
PKGだけが導出できる
PKG
Private-Key Generator
Alice Bob
4. 認証&秘密鍵要求
共有
実は、Bob の ID は公開鍵暗号で言うところの公開鍵ではない。
実際には、Bob の ID のハッシュ値とマスター公開鍵を利用して
メッセージを暗号化
↑ID が公開鍵相当
PKG への信用が必要であり
トラストレスではない。
IBE 詳細 1.セットアップ
マスター公開鍵とマスター秘密鍵生成
2.
暗号文 ← 暗号化(マスター公開鍵, BobのID, メッセージ)
3.暗号文
5.
秘密鍵̲Bob ← 秘密鍵導出(マスター秘密鍵, BobのID)
6.秘密鍵̲Bob
7.
メッセージ ← 復号化(暗号文, 秘密鍵̲Bob)
↑ID が公開鍵相当
先に公開鍵が作られて、後で秘密鍵が作られる
(通常の公開鍵暗号では不可能)
IBE のメリット?
マスター秘密鍵を持っている
PKGだけが導出できる
PKG
Private-Key Generator
Alice Bob
4. 認証&秘密鍵要求
共有
•受信者は鍵管理が不要:受信者は自ら秘密鍵を管理する必要はない(ブラウザで秘密鍵を保持する必要はない)。受
信者は都度、PKG から秘密鍵をもらう。
•受信者の公開鍵の配布は不要:公開鍵暗号では、あらかじめ各受信者の公開鍵を配る必要があるが、IBE ではその必
要はない(代わりに共通のマスター公開鍵を配る必要はあるが、各受信者の公開鍵を配るのと比べると手間が減る。)。
•受信者の公開鍵の保証は不要:公開鍵暗号では、公開鍵が受信者(ID)のものであるという保証(公開鍵証明書)が
必要だが、IBE では保証する必要はない。IBE では、ID と 公開鍵に分かれているわけではなく、ID そのものが公開鍵であ
り、保証するまでもないから。
•開発しやすい:受信者は自ら秘密鍵を管理する必要はないため、セキュリティ上の配慮が減る/複数のデバイスをま
たがりやすい。つまりは開発しやすい。
IBEメリット
秘密分散:秘密鍵等を複数の断片(シェア)に
分割する暗号技術
vetKD 詳細
2.
暗号文 ← 暗号化(派生公開鍵, BobのID, メッセージ)
3.暗号文
4.
トランスポート公開鍵
トランスポート秘密鍵
生成
PKG
Private-Key Generator
5. 認証&秘密鍵要求
6. 秘密鍵の導出と検証
暗号化された秘密鍵̲Bob ← 暗号化された秘密鍵導出(マスター秘密鍵̲i, BobのID, トランスポート公開鍵)
0/1 ← 暗号化された秘密鍵の検証(暗号化された秘密鍵̲Bob, マスター公開鍵, BobのID, tpk)
7.暗号化された秘密鍵̲Bob
8.
秘密鍵̲Bob ← 復号化(暗号化された秘密鍵̲Bob, トランスポート秘密鍵)
メッセージ ← 復号化(暗号文, 秘密鍵̲Bob)
Alice Bob
マスター秘密鍵を複数の断片に分割し サーバ S_i へ配る
認証した上で
トランスポート公開鍵を渡す
(スマートコントラクト経由)
↑マスター公開鍵から派生した公開鍵
スマートコントラクト毎に異なる公開鍵が導出される。
・一定数のノードが参加することで導出できる。分散されてトラストレスに!
・ノードは 秘密鍵_Bob を知り得ないようになっている。
別途、詳細の詳細
※スマートコントラクト経由で派生公開鍵を取得(マスター公開鍵は取得しない)
※ブラウザ上で暗号化
※論文上は派生公開鍵は書かれていないが、実装されている。
共有(スマートコントラクト経由)
NI-DKG:検証可能な秘密分散。セキュアかつ
効率よく配る。
1.セットアップ
マスター公開鍵, マスター公開鍵̲i, マスター秘密鍵̲i ← NI-DKG
(スマートコントラクトのステートで保持する等の方法で)
(予定)
マスター秘密鍵をサーバ S_i へ安全に秘密分散したもの(シェア)
vetKD 詳細の詳細
EKDerive(mski, id, tpk) → eki
EKSVerify(mpk, id, tpk, eki) → 0/1
Combine(mpk, id, S, {mpki, eki}i∈S) → ek
EKVerify(mpk, id, tpk, ek) → 0/1
マスター秘密鍵シェア BoBのID Bobのトランスポート公開鍵
ek_i : 暗号化されたBobの秘密鍵シェア
各ノードで ek_i を導出し、他ノードへブロードキャスト
ブロードキャストされた ek_i を受け取り、検証。
ek を検証:導出された ek が、id 用に PKG が生成したものであることの検証
導出された ek が、tpk で暗号化されたものであることの検証
7. Bob へ ek を返す
6 - 1
6 - 2
6 - 3
6 - 4
※ ek: 暗号化されたBobの秘密鍵 = 閾値BLS署名
2/3 以上のノードから ek̲i を集めることで、ek を導出できる。
i: ノードの番号
PKG
Private-Key Generator
6. 秘密鍵の導出と検証
暗号化された秘密鍵̲Bob ← 暗号化された秘密鍵導出(マスター秘密鍵̲i, BobのID, トランスポート公開鍵)
0/1 ← 暗号化された秘密鍵の検証(暗号化された秘密鍵̲Bob, マスター公開鍵, BobのID, tpk)
Veri
fi
ably Encrypted Threshold Key Derivation (vetKD)
検証可能な暗号化された閾値鍵導出
という名前の通りである
mpk:マスター公開鍵
S: サーバーの集合, mpk_i: マスター公開鍵シェア
1.セットアップ
マスター公開鍵, マスター公開鍵̲i, マスター秘密鍵̲i ← NI-DKG
BLS署名
1. 鍵セットアップ:署名者が、 乱数の秘密鍵 s と公開鍵 を生成(P:楕円曲線上の基点・固定値)。
2. 署名生成:証明者がメッセージ m へ署名。楕円曲線上で を計算して 署名 を生成。
3. 署名検証:ペアリングの等式 e(σ, P) = e(H(m), P̲pub) が成り立つ時、署名者が署名したことの証明になる。
IBE 秘密鍵 = 署名
IBE
1. 鍵セットアップ:PKG が、乱数の秘密鍵 s と 公開鍵 を生成(P:は楕円曲線上の基点・固定値)
2. ユーザーの秘密鍵生成:楕円曲線上で を計算して ユーザーの秘密鍵 を生成。
3. 復号化:ユーザーは、秘密鍵 k を使って暗号文を復号化
数式は同じであり、数学上同じであると解釈できる。
→ IBE の 秘密鍵 は、同時に BLS 署名 でもある
IBE の 秘密鍵 は、同時に BLS 署名 でもある
お前は何を言っているんだ
vetKD は
IBE の「ユーザーの秘密鍵 = BLS署名」を「ユーザーの秘密鍵 = 閾値BLS署名」に置き換えていることで
ユーザーの秘密鍵導出を分散化し、検証できるようにした。
数式を見比べてみる
Kpub = s * P
Kpub = s * P
dID = s * Hash(ID) dID
σ = s * Hash(m) σ
メリットまとめ
• 鍵管理が不要:受信者は自ら秘密鍵を管理する必要はない(ブラウザで秘密鍵を保持する必要はな
い)。受信者は都度、PKGから秘密鍵をもらう。
• 受信者の公開鍵の配布が不要:公開鍵暗号では、あらかじめ各受信者の公開鍵を配る必要があるが、
IBE ではその必要はない(代わりに共通のマスター公開鍵を配る必要はあるが、各受信者の公開鍵を配る
のと比べると手間が減る。)。
• 受信者の公開鍵の保証が不要:公開鍵暗号では、公開鍵が受信者のものであるという保証(公開鍵証明
書)が別途必要だが、IBE では別途保証する必要はない(IBE では公開鍵相当が ID であり ID で認証する
ため)。
• 開発しやすい:受信者は自ら秘密鍵を管理する必要はないため、セキュリティ上の配慮が減る/複数のデ
バイスをまたがりやすい。つまりは開発しやすい。
IBE のメリット
• トラストレス:IBE では PKG への信頼が必要だったが、vetKD では分散することでトラスト
レスになった。
•分散による単一障害点の解消・攻撃に対する耐性
vetKD のメリット(IBE のメリットに加え)
vetKDサンプル実装デモ(動画)
https://github.com/d
fi
nity/examples/tree/master/motoko/vetkd
1. ブラウザ上で Bob̲ID(Principal) で暗号化
2. 暗号文をブラウザ上で保持
3. Bob̲ID でログイン
4. Bob の秘密鍵を取得して
ブラウザ上で秘密鍵で復号化
※簡易的な実装であり
暗号文をスマートコントラクトへ送っていない。
実装
ic-vetkd-utils
暗号化・復号化するためのユーティリティを利用。
ブラウザ上で動作する(IC 上ではない)。
Rust で実装されており WASM にコンパイルされているが
JavaScript のラッパーを経由して、呼び出せるようになっている。
・vetKD はまだ正式にはリリースされておらず、互換性なく仕様が変わる可能性あり。
・マスター秘密鍵がハードコートされている等、セキュリティ上の問題が解消されていないため
本番ではまだ使えない。
注意
サンプル実装-ブラウザ上で暗号化
197 async function ibe̲encrypt(message) {
198 document.getElementById("ibe̲encrypt̲result").innerText = "Fetching IBE encryption key..."
199 const pk̲bytes̲hex = await app̲backend̲actor.ibe̲encryption̲key(); // スマートコントラクト経由で派生公開鍵を取得
200
201 document.getElementById("ibe̲encrypt̲result").innerText = "Preparing IBE-encryption..."
202 const message̲encoded = new TextEncoder().encode(message);
203 const seed = window.crypto.getRandomValues(new Uint8Array(32));
204 let ibe̲principal = Principal.fromText(document.getElementById(“ibe̲principal").value);
205
206 document.getElementById("ibe̲encrypt̲result").innerText = "IBE-encrypting for principal" + ibe̲principal.toText()
+ "...";
// ic-vetkd-utils を利用して、メッセージを 派生公開鍵 と Bob̲ID で暗号化
207 const ibe̲ciphertext = vetkd.IBECiphertext.encrypt(
208 hex̲decode(pk̲bytes̲hex), // 派生公開鍵
209 ibe̲principal.toUint8Array(), // ブラウザで入力した Principal 。Alice->Bob の文脈の場合は Bob の Principal
210 message̲encoded, // メッセージ(平文)
211 seed // 必ず乱数を渡すこと。選択平文攻撃に対する対策。
// シードは、メッセージをマスキングするために使われる。
// マスキングとは:シードを元にメッセージと同じ長さのランダム値が作られ、そのランダム値とメッセージを XOR することでマスキングしている。
// マスキングしている理由:同じメッセージに対して複数回暗号化を行った際、それぞれ異なる暗号文を生成できる。これにより選択平文攻撃に対する耐性を高めることができる。
212 );
213 return hex̲encode(ibe̲ciphertext.serialize()); // 暗号文を返す
※スマートコントラクトのソースは次のスライド
フロントエンド JavaScript https://github.com/d
fi
nity/examples/blob/master/motoko/vetkd/src/app̲frontend̲js/src/index.js#L197
サンプル実装-派生公開鍵の導出
55 public shared ({ caller }) func ibe̲encryption̲key() : async Text { // caller は使われていない
56 let { public̲key } = await vetkd̲system̲api.vetkd̲public̲key({ // IC の System API を呼び出して派生公開鍵を導出
57 canister̲id = null; // デフォルト値の caller(スマートコントラクト自身の Principal)が適用される。
58 derivation̲path = Array.make(Text.encodeUtf8(“ibe̲encryption”)); // 固定値 “ibe̲encryption”
59 key̲id = { curve = #bls12̲381; name = "test̲key̲1" }; // 楕円曲線を指定。現状 bls12̲381 のみ使える。
60 });
61 Hex.encode(Blob.toArray(public̲key));
62 };
スマートコントラクト https://github.com/d
fi
nity/examples/blob/master/motoko/vetkd/src/app̲backend/Main.mo#L55
vetKD(System API) は「マスター公開鍵」と「canister̲id」と「derivation̲path」を元に
派生公開鍵を導出している。
つまりは、「canister̲id」と「derivation̲path」を元にドメインを分けており
他のスマートコントラクトとは異なる派生公開鍵が導出されることになる。
前のスライドで暗号化する際に使っていた派生公開鍵を導出
サンプル実装-ブラウザ上で復号化
216 async function ibe̲decrypt(ibe̲ciphertext̲hex) { // 引数 暗号文
217 document.getElementById("ibe̲decrypt̲result").innerText = "Preparing IBE-decryption..."
218 const tsk̲seed = window.crypto.getRandomValues(new Uint8Array(32));
219 const tsk = new vetkd.TransportSecretKey(tsk̲seed); // ic-vetkd-utils を利用して、トランスポート秘密鍵, 公開鍵 を導出
220 document.getElementById("ibe̲decrypt̲result").innerText = "Fetching IBE decryption key..."
// スマートコントラクト経由で 暗号化された IBE の復号鍵(秘密鍵)を取得。※スマートコントラクトのソースは次のスライド
221 const ek̲bytes̲hex = await app̲backend̲actor.encrypted̲ibe̲decryption̲key̲for̲caller(tsk.public̲key());
222 document.getElementById("ibe̲decrypt̲result").innerText = "Fetching IBE enryption key (needed for veri
fi
cation)..."
223 const pk̲bytes̲hex = await app̲backend̲actor.ibe̲encryption̲key(); // マスター公開鍵の派生公開鍵を取得
224
// 暗号化された「IBE の秘密鍵」を、トランスポート秘密鍵で復号化。同時に検証も行っている。
// tsk はトランスポート秘密鍵を保持しているため、引数にトランスポート秘密鍵は不要。
// https://github.com/d
fi
nity/ic/blob/master/packages/ic-vetkd-utils/src/lib.rs#L64
225 const k̲bytes = tsk.decrypt(
226 hex̲decode(ek̲bytes̲hex), // encrypted̲key̲bytes : 暗号化された IBE の秘密鍵
227 hex̲decode(pk̲bytes̲hex), // derived̲public̲key̲bytes : 派生公開鍵。検証用(どのような検証なのかは未調査)
228 app̲backend̲principal.toUint8Array() // derivation̲id : スマートコントラクトのPrincipal。検証用(どのような検証なのかは未調査)
229 );
230 // ic-vetkd-utils を利用して、「IBE の秘密鍵」で暗号文を復号化。
231 const ibe̲ciphertext = vetkd.IBECiphertext.deserialize(hex̲decode(ibe̲ciphertext̲hex));
232 const ibe̲plaintext = ibe̲ciphertext.decrypt(k̲bytes); // k̲bytes : IBE の秘密鍵。IBE の秘密鍵で暗号文を復号化。
233 return new TextDecoder().decode(ibe̲plaintext); // 復号化された平文を返す
216 }
フロントエンド JavaScript https://github.com/d
fi
nity/examples/blob/master/motoko/vetkd/src/app̲frontend̲js/src/index.js#L216
サンプル実装-秘密鍵の導出
スマートコントラクト https://github.com/d
fi
nity/examples/blob/master/motoko/vetkd/src/app̲backend/Main.mo#L64
// スライドの221行目から呼ばれている。
// 引数 encryption̲public̲key:トランスポート公開鍵
// 戻り値:トランスポート公開鍵で暗号化された IBE の復号鍵(秘密鍵)
64 public shared ({ caller }) func encrypted̲ibe̲decryption̲key̲for̲caller(encryption̲public̲key : Blob) : async Text {
// スマートコントラクトが caller を受け取れている時点で、caller は確かに本人であることは検証済みであり
// 認証できていると言えることから、IBE の認証相当になっている。
65 Debug.print("encrypted̲ibe̲decryption̲key̲for̲caller: caller: " # debug̲show (caller));
66
// 参考 https://jfhyp-gaaaa-aaaak-qck6q-cai.icp0.io/docs#ic-vetkd̲encrypted̲key
// System API を呼び出すことで、 PKG が「トランスポート公開鍵で暗号化された IBE の復号鍵(秘密鍵)」を導出
67 let { encrypted̲key } = await vetkd̲system̲api.vetkd̲encrypted̲key({
68 derivation̲id = Principal.toBlob(caller); // Alice->Bob の文脈の場合は Bob の Principal
69 public̲key̲derivation̲path = Array.make(Text.encodeUtf8(“ibe̲encryption")); // 派生公開鍵を導出した際に指定した値
70 key̲id = { curve = #bls12̲381; name = "test̲key̲1" }; // 派生公開鍵を導出した際に指定した値
71 encryption̲public̲key; // トランスポート公開鍵
72 });
73 Hex.encode(Blob.toArray(encrypted̲key));
74 };
復号化に必要な秘密鍵の導出
参考文献
ドキュメント
vetKeys: technology overview https://internetcomputer.org/docs/current/developer-docs/integrations/vetkeys/technology-overview
VETKeys Primer https://internetcomputer.org/blog/features/vetkey-primer
IC method vetkd̲public̲key https://jfhyp-gaaaa-aaaak-qck6q-cai.icp0.io/docs#ic-vetkd̲public̲key
実装
vetKeys API demo
https://internetcomputer.org/docs/current/developer-docs/integrations/vetkeys/using-vetkeys
https://github.com/dfinity/examples/blob/master/motoko/vetkd/README.md
ic-vetkd-utils https://github.com/dfinity/ic/tree/master/packages/ic-vetkd-utils
vetKD 本体 https://github.com/dfinity/interface-spec/pull/158
vetKD の仕組み
vetKeys: How a blockchain can keep many secrets
学会発表資料:https://iacr.org/submit/files/slides/2023/rwc/rwc2023/82/slides.pdf
その動画:https://www.youtube.com/watch?v=-d0Ny7NAG-w&t=3586s
その論文:https://eprint.iacr.org/2023/616.pdf
Dfinity Foundation 提供の動画
・Community Conversation: On-Chain Encryption
https://www.youtube.com/watch?v=baM6jHnmMq8
・Community Conversation: vetKeys ̶ Enabling Privacy Preserving
https://www.youtube.com/watch?v=-u97HhHTSQI
補足
マスター秘密鍵をサーバ S_i へ安全に秘密分散したもの(シェア)
vetKD 詳細の詳細
EKDerive(mski, id, tpk) → eki
EKSVerify(mpk, id, tpk, eki) → 0/1
Combine(mpk, id, S, {mpki, eki}i∈S) → ek
EKVerify(mpk, id, tpk, ek) → 0/1
マスター秘密鍵シェア BoBのID Bobのトランスポート公開鍵
ek_i : 暗号化されたBobの秘密鍵シェア
各ノードで ek_i を導出し、他ノードへブロードキャスト
ブロードキャストされた ek_i を受け取り、検証。
ek を検証:導出された ek が、id 用に PKG が生成したものであることの検証
導出された ek が、tpk で暗号化されたものであることの検証
7. Bob へ ek を返す
6 - 1
6 - 2
6 - 3
6 - 4
※ ek: 暗号化されたBobの秘密鍵 = 閾値BLS署名
2/3 以上のノードから ek̲i を集めることで、ek を導出できる。
i: ノードの番号
PKG
Private-Key Generator
6. 秘密鍵の導出と検証
暗号化された秘密鍵̲Bob ← 暗号化された秘密鍵導出(マスター秘密鍵̲i, BobのID, トランスポート公開鍵)
0/1 ← 暗号化された秘密鍵の検証(暗号化された秘密鍵̲Bob, マスター公開鍵, BobのID, tpk)
Veri
fi
ably Encrypted Threshold Key Derivation (vetKD)
検証可能な暗号化された閾値鍵導出
という名前の通りである
mpk:マスター公開鍵
S: サーバーの集合, mpk_i: マスター公開鍵シェア
1.セットアップ
マスター公開鍵, マスター公開鍵̲i, マスター秘密鍵̲i ← NI-DKG
つまり、ノードは秘密鍵_Bobを知ること
はできないが、「暗号化された秘密鍵
_Bob」を導出できると言えそう?
ek は「暗号化された秘密鍵_Bob」である
と同時に 閾値BLS署名だから。
補足
• ノードが新たなノードに置き換わった場合、各ユーザまたは各暗号文に対応した公開鍵を
共有するという方法では、膨大な数のユーザ・暗号文に対して対応できない。という問題
を vetKD は解決しているらしい。
• vetKD は IBE に閾値を加えたものであると言えるが、veri
fi
ably en crypted signature
(VES) scheme due to Boneh et al. [BGLS03] に閾値を加えたものであるとも言える。
• 秘密鍵 = 閾値署名 だから、NI-DKG を適用できると言える。
• スマートコントラクト上で復号化したいユースケースの場合は、平文がメモリ上に展開され
てしまうため、AMD SEV が必要になりそう。

図解で理解するvetKD

  • 1.
  • 2.
    vetKey とは IC のDapp 用に提供される 暗号化・復号化技術の総称 vetKD とは vetKey を実現するための暗号プリミティブ(暗号技術の基本的な構成要素) https://internetcomputer.org/blog/features/vetkey-primer 用語の定義
  • 3.
    vetKD 注)まだ正式にはリリースされていない。ローカルでのみ試すことができる。 ドラフト版が 2023年7月 に公開。実験段階。 Veri fi ablyEncrypted Threshold Key Derivation (vetKD) 検証可能な暗号化された閾値鍵導出 ユーザーの秘密鍵の導出が特徴的 ・復号化の度に IC 上で秘密鍵を導出 →ユーザーは復号化の度に秘密鍵を捨てて良い → Dapp の開発が楽になる(セキュリティ上の配慮が減る/複数のデバイスをまたがりやすい) ・ユーザーの秘密鍵を導出するには、一定以上のノードが協力する必要がある ※閾値。2/3 になる予定。 IC 独自の end-to-end 用の暗号技術 基本的にブラウザ上で暗号化・復号化 (デバイス)
  • 4.
    公開鍵暗号 → IBE→ vetKD の順で理解することで vetKD を理解 IBE をトラストレスにしたもの (ID-Based Encryption) 復号化の度に秘密鍵導出 本題 図解で理解するvetKD ※補足 vetKD は IBE 以外に AES-GCM-256(共通鍵暗号)も提供しているが 今回は省く(未調査)
  • 5.
    公開鍵暗号 1. 秘密鍵、公開鍵 生成 2. 公開鍵共有 3. 暗号文 ← 暗号化(公開鍵, メッセージ) 5. メッセージ ← 復号化(秘密鍵, メッセージ) Bob ※秘密鍵を元に公開鍵が導出される。 (数学的にその逆はできない) Alice Bob 4.暗号文 ※秘密鍵を持っている Bob だけが復号化できる 問題:インターネットを介して公開鍵が共有された場合 公開鍵が確かに Bob のものかわからない。 → 公開鍵証明書(電子証明書)…例:SSL証明書 Alice がメッセージを暗号化して Bob へ送る。 Bob は暗号文を受け取り復号化する。
  • 6.
    IBE 簡易説明 1. 暗号文 ←暗号化(BobのID, メッセージ) 2.暗号文 4.秘密鍵̲Bob 5. メッセージ ← 復号化(暗号文, 秘密鍵̲Bob) 次のスライドで詳細あり (ID-Based Encryption) ☝ポイント ・Bob は秘密鍵、公開鍵を生成しない ・秘密鍵̲Bob を作るより先に、公開鍵(BobのID)が存在する。 (数学的に公開鍵を元に秘密鍵を導出できないはずなのに、不思議) ↑ID が公開鍵相当 ※PKGだけが導出できる PKG Private-Key Generator Alice Bob 3. 認証&秘密鍵要求
  • 7.
    IBE 詳細 1.セットアップ マスター公開鍵とマスター秘密鍵生成 2. 暗号文← 暗号化(マスター公開鍵, BobのID, メッセージ) 3.暗号文 5. 秘密鍵̲Bob ← 秘密鍵導出(マスター秘密鍵, BobのID) 6.秘密鍵̲Bob 7. メッセージ ← 復号化(暗号文, 秘密鍵̲Bob) 先に公開鍵が作られて、後で秘密鍵が作られる (通常の公開鍵暗号では不可能) PKG への信用が必要であり トラストレスではない。 マスター秘密鍵を持っている PKGだけが導出できる PKG Private-Key Generator Alice Bob 4. 認証&秘密鍵要求 共有 実は、Bob の ID は公開鍵暗号で言うところの公開鍵ではない。 実際には、Bob の ID のハッシュ値とマスター公開鍵を利用して メッセージを暗号化 ↑ID が公開鍵相当
  • 8.
    PKG への信用が必要であり トラストレスではない。 IBE 詳細1.セットアップ マスター公開鍵とマスター秘密鍵生成 2. 暗号文 ← 暗号化(マスター公開鍵, BobのID, メッセージ) 3.暗号文 5. 秘密鍵̲Bob ← 秘密鍵導出(マスター秘密鍵, BobのID) 6.秘密鍵̲Bob 7. メッセージ ← 復号化(暗号文, 秘密鍵̲Bob) ↑ID が公開鍵相当 先に公開鍵が作られて、後で秘密鍵が作られる (通常の公開鍵暗号では不可能) IBE のメリット? マスター秘密鍵を持っている PKGだけが導出できる PKG Private-Key Generator Alice Bob 4. 認証&秘密鍵要求 共有 •受信者は鍵管理が不要:受信者は自ら秘密鍵を管理する必要はない(ブラウザで秘密鍵を保持する必要はない)。受 信者は都度、PKG から秘密鍵をもらう。 •受信者の公開鍵の配布は不要:公開鍵暗号では、あらかじめ各受信者の公開鍵を配る必要があるが、IBE ではその必 要はない(代わりに共通のマスター公開鍵を配る必要はあるが、各受信者の公開鍵を配るのと比べると手間が減る。)。 •受信者の公開鍵の保証は不要:公開鍵暗号では、公開鍵が受信者(ID)のものであるという保証(公開鍵証明書)が 必要だが、IBE では保証する必要はない。IBE では、ID と 公開鍵に分かれているわけではなく、ID そのものが公開鍵であ り、保証するまでもないから。 •開発しやすい:受信者は自ら秘密鍵を管理する必要はないため、セキュリティ上の配慮が減る/複数のデバイスをま たがりやすい。つまりは開発しやすい。 IBEメリット
  • 9.
    秘密分散:秘密鍵等を複数の断片(シェア)に 分割する暗号技術 vetKD 詳細 2. 暗号文 ←暗号化(派生公開鍵, BobのID, メッセージ) 3.暗号文 4. トランスポート公開鍵 トランスポート秘密鍵 生成 PKG Private-Key Generator 5. 認証&秘密鍵要求 6. 秘密鍵の導出と検証 暗号化された秘密鍵̲Bob ← 暗号化された秘密鍵導出(マスター秘密鍵̲i, BobのID, トランスポート公開鍵) 0/1 ← 暗号化された秘密鍵の検証(暗号化された秘密鍵̲Bob, マスター公開鍵, BobのID, tpk) 7.暗号化された秘密鍵̲Bob 8. 秘密鍵̲Bob ← 復号化(暗号化された秘密鍵̲Bob, トランスポート秘密鍵) メッセージ ← 復号化(暗号文, 秘密鍵̲Bob) Alice Bob マスター秘密鍵を複数の断片に分割し サーバ S_i へ配る 認証した上で トランスポート公開鍵を渡す (スマートコントラクト経由) ↑マスター公開鍵から派生した公開鍵 スマートコントラクト毎に異なる公開鍵が導出される。 ・一定数のノードが参加することで導出できる。分散されてトラストレスに! ・ノードは 秘密鍵_Bob を知り得ないようになっている。 別途、詳細の詳細 ※スマートコントラクト経由で派生公開鍵を取得(マスター公開鍵は取得しない) ※ブラウザ上で暗号化 ※論文上は派生公開鍵は書かれていないが、実装されている。 共有(スマートコントラクト経由) NI-DKG:検証可能な秘密分散。セキュアかつ 効率よく配る。 1.セットアップ マスター公開鍵, マスター公開鍵̲i, マスター秘密鍵̲i ← NI-DKG (スマートコントラクトのステートで保持する等の方法で) (予定)
  • 10.
    マスター秘密鍵をサーバ S_i へ安全に秘密分散したもの(シェア) vetKD詳細の詳細 EKDerive(mski, id, tpk) → eki EKSVerify(mpk, id, tpk, eki) → 0/1 Combine(mpk, id, S, {mpki, eki}i∈S) → ek EKVerify(mpk, id, tpk, ek) → 0/1 マスター秘密鍵シェア BoBのID Bobのトランスポート公開鍵 ek_i : 暗号化されたBobの秘密鍵シェア 各ノードで ek_i を導出し、他ノードへブロードキャスト ブロードキャストされた ek_i を受け取り、検証。 ek を検証:導出された ek が、id 用に PKG が生成したものであることの検証 導出された ek が、tpk で暗号化されたものであることの検証 7. Bob へ ek を返す 6 - 1 6 - 2 6 - 3 6 - 4 ※ ek: 暗号化されたBobの秘密鍵 = 閾値BLS署名 2/3 以上のノードから ek̲i を集めることで、ek を導出できる。 i: ノードの番号 PKG Private-Key Generator 6. 秘密鍵の導出と検証 暗号化された秘密鍵̲Bob ← 暗号化された秘密鍵導出(マスター秘密鍵̲i, BobのID, トランスポート公開鍵) 0/1 ← 暗号化された秘密鍵の検証(暗号化された秘密鍵̲Bob, マスター公開鍵, BobのID, tpk) Veri fi ably Encrypted Threshold Key Derivation (vetKD) 検証可能な暗号化された閾値鍵導出 という名前の通りである mpk:マスター公開鍵 S: サーバーの集合, mpk_i: マスター公開鍵シェア 1.セットアップ マスター公開鍵, マスター公開鍵̲i, マスター秘密鍵̲i ← NI-DKG
  • 11.
    BLS署名 1. 鍵セットアップ:署名者が、 乱数の秘密鍵s と公開鍵 を生成(P:楕円曲線上の基点・固定値)。 2. 署名生成:証明者がメッセージ m へ署名。楕円曲線上で を計算して 署名 を生成。 3. 署名検証:ペアリングの等式 e(σ, P) = e(H(m), P̲pub) が成り立つ時、署名者が署名したことの証明になる。 IBE 秘密鍵 = 署名 IBE 1. 鍵セットアップ:PKG が、乱数の秘密鍵 s と 公開鍵 を生成(P:は楕円曲線上の基点・固定値) 2. ユーザーの秘密鍵生成:楕円曲線上で を計算して ユーザーの秘密鍵 を生成。 3. 復号化:ユーザーは、秘密鍵 k を使って暗号文を復号化 数式は同じであり、数学上同じであると解釈できる。 → IBE の 秘密鍵 は、同時に BLS 署名 でもある IBE の 秘密鍵 は、同時に BLS 署名 でもある お前は何を言っているんだ vetKD は IBE の「ユーザーの秘密鍵 = BLS署名」を「ユーザーの秘密鍵 = 閾値BLS署名」に置き換えていることで ユーザーの秘密鍵導出を分散化し、検証できるようにした。 数式を見比べてみる Kpub = s * P Kpub = s * P dID = s * Hash(ID) dID σ = s * Hash(m) σ
  • 12.
    メリットまとめ • 鍵管理が不要:受信者は自ら秘密鍵を管理する必要はない(ブラウザで秘密鍵を保持する必要はな い)。受信者は都度、PKGから秘密鍵をもらう。 • 受信者の公開鍵の配布が不要:公開鍵暗号では、あらかじめ各受信者の公開鍵を配る必要があるが、 IBEではその必要はない(代わりに共通のマスター公開鍵を配る必要はあるが、各受信者の公開鍵を配る のと比べると手間が減る。)。 • 受信者の公開鍵の保証が不要:公開鍵暗号では、公開鍵が受信者のものであるという保証(公開鍵証明 書)が別途必要だが、IBE では別途保証する必要はない(IBE では公開鍵相当が ID であり ID で認証する ため)。 • 開発しやすい:受信者は自ら秘密鍵を管理する必要はないため、セキュリティ上の配慮が減る/複数のデ バイスをまたがりやすい。つまりは開発しやすい。 IBE のメリット • トラストレス:IBE では PKG への信頼が必要だったが、vetKD では分散することでトラスト レスになった。 •分散による単一障害点の解消・攻撃に対する耐性 vetKD のメリット(IBE のメリットに加え)
  • 13.
    vetKDサンプル実装デモ(動画) https://github.com/d fi nity/examples/tree/master/motoko/vetkd 1. ブラウザ上で Bob̲ID(Principal)で暗号化 2. 暗号文をブラウザ上で保持 3. Bob̲ID でログイン 4. Bob の秘密鍵を取得して ブラウザ上で秘密鍵で復号化 ※簡易的な実装であり 暗号文をスマートコントラクトへ送っていない。
  • 14.
    実装 ic-vetkd-utils 暗号化・復号化するためのユーティリティを利用。 ブラウザ上で動作する(IC 上ではない)。 Rust で実装されておりWASM にコンパイルされているが JavaScript のラッパーを経由して、呼び出せるようになっている。 ・vetKD はまだ正式にはリリースされておらず、互換性なく仕様が変わる可能性あり。 ・マスター秘密鍵がハードコートされている等、セキュリティ上の問題が解消されていないため 本番ではまだ使えない。 注意
  • 15.
    サンプル実装-ブラウザ上で暗号化 197 async functionibe̲encrypt(message) { 198 document.getElementById("ibe̲encrypt̲result").innerText = "Fetching IBE encryption key..." 199 const pk̲bytes̲hex = await app̲backend̲actor.ibe̲encryption̲key(); // スマートコントラクト経由で派生公開鍵を取得 200 201 document.getElementById("ibe̲encrypt̲result").innerText = "Preparing IBE-encryption..." 202 const message̲encoded = new TextEncoder().encode(message); 203 const seed = window.crypto.getRandomValues(new Uint8Array(32)); 204 let ibe̲principal = Principal.fromText(document.getElementById(“ibe̲principal").value); 205 206 document.getElementById("ibe̲encrypt̲result").innerText = "IBE-encrypting for principal" + ibe̲principal.toText() + "..."; // ic-vetkd-utils を利用して、メッセージを 派生公開鍵 と Bob̲ID で暗号化 207 const ibe̲ciphertext = vetkd.IBECiphertext.encrypt( 208 hex̲decode(pk̲bytes̲hex), // 派生公開鍵 209 ibe̲principal.toUint8Array(), // ブラウザで入力した Principal 。Alice->Bob の文脈の場合は Bob の Principal 210 message̲encoded, // メッセージ(平文) 211 seed // 必ず乱数を渡すこと。選択平文攻撃に対する対策。 // シードは、メッセージをマスキングするために使われる。 // マスキングとは:シードを元にメッセージと同じ長さのランダム値が作られ、そのランダム値とメッセージを XOR することでマスキングしている。 // マスキングしている理由:同じメッセージに対して複数回暗号化を行った際、それぞれ異なる暗号文を生成できる。これにより選択平文攻撃に対する耐性を高めることができる。 212 ); 213 return hex̲encode(ibe̲ciphertext.serialize()); // 暗号文を返す ※スマートコントラクトのソースは次のスライド フロントエンド JavaScript https://github.com/d fi nity/examples/blob/master/motoko/vetkd/src/app̲frontend̲js/src/index.js#L197
  • 16.
    サンプル実装-派生公開鍵の導出 55 public shared({ caller }) func ibe̲encryption̲key() : async Text { // caller は使われていない 56 let { public̲key } = await vetkd̲system̲api.vetkd̲public̲key({ // IC の System API を呼び出して派生公開鍵を導出 57 canister̲id = null; // デフォルト値の caller(スマートコントラクト自身の Principal)が適用される。 58 derivation̲path = Array.make(Text.encodeUtf8(“ibe̲encryption”)); // 固定値 “ibe̲encryption” 59 key̲id = { curve = #bls12̲381; name = "test̲key̲1" }; // 楕円曲線を指定。現状 bls12̲381 のみ使える。 60 }); 61 Hex.encode(Blob.toArray(public̲key)); 62 }; スマートコントラクト https://github.com/d fi nity/examples/blob/master/motoko/vetkd/src/app̲backend/Main.mo#L55 vetKD(System API) は「マスター公開鍵」と「canister̲id」と「derivation̲path」を元に 派生公開鍵を導出している。 つまりは、「canister̲id」と「derivation̲path」を元にドメインを分けており 他のスマートコントラクトとは異なる派生公開鍵が導出されることになる。 前のスライドで暗号化する際に使っていた派生公開鍵を導出
  • 17.
    サンプル実装-ブラウザ上で復号化 216 async functionibe̲decrypt(ibe̲ciphertext̲hex) { // 引数 暗号文 217 document.getElementById("ibe̲decrypt̲result").innerText = "Preparing IBE-decryption..." 218 const tsk̲seed = window.crypto.getRandomValues(new Uint8Array(32)); 219 const tsk = new vetkd.TransportSecretKey(tsk̲seed); // ic-vetkd-utils を利用して、トランスポート秘密鍵, 公開鍵 を導出 220 document.getElementById("ibe̲decrypt̲result").innerText = "Fetching IBE decryption key..." // スマートコントラクト経由で 暗号化された IBE の復号鍵(秘密鍵)を取得。※スマートコントラクトのソースは次のスライド 221 const ek̲bytes̲hex = await app̲backend̲actor.encrypted̲ibe̲decryption̲key̲for̲caller(tsk.public̲key()); 222 document.getElementById("ibe̲decrypt̲result").innerText = "Fetching IBE enryption key (needed for veri fi cation)..." 223 const pk̲bytes̲hex = await app̲backend̲actor.ibe̲encryption̲key(); // マスター公開鍵の派生公開鍵を取得 224 // 暗号化された「IBE の秘密鍵」を、トランスポート秘密鍵で復号化。同時に検証も行っている。 // tsk はトランスポート秘密鍵を保持しているため、引数にトランスポート秘密鍵は不要。 // https://github.com/d fi nity/ic/blob/master/packages/ic-vetkd-utils/src/lib.rs#L64 225 const k̲bytes = tsk.decrypt( 226 hex̲decode(ek̲bytes̲hex), // encrypted̲key̲bytes : 暗号化された IBE の秘密鍵 227 hex̲decode(pk̲bytes̲hex), // derived̲public̲key̲bytes : 派生公開鍵。検証用(どのような検証なのかは未調査) 228 app̲backend̲principal.toUint8Array() // derivation̲id : スマートコントラクトのPrincipal。検証用(どのような検証なのかは未調査) 229 ); 230 // ic-vetkd-utils を利用して、「IBE の秘密鍵」で暗号文を復号化。 231 const ibe̲ciphertext = vetkd.IBECiphertext.deserialize(hex̲decode(ibe̲ciphertext̲hex)); 232 const ibe̲plaintext = ibe̲ciphertext.decrypt(k̲bytes); // k̲bytes : IBE の秘密鍵。IBE の秘密鍵で暗号文を復号化。 233 return new TextDecoder().decode(ibe̲plaintext); // 復号化された平文を返す 216 } フロントエンド JavaScript https://github.com/d fi nity/examples/blob/master/motoko/vetkd/src/app̲frontend̲js/src/index.js#L216
  • 18.
    サンプル実装-秘密鍵の導出 スマートコントラクト https://github.com/d fi nity/examples/blob/master/motoko/vetkd/src/app̲backend/Main.mo#L64 // スライドの221行目から呼ばれている。 //引数 encryption̲public̲key:トランスポート公開鍵 // 戻り値:トランスポート公開鍵で暗号化された IBE の復号鍵(秘密鍵) 64 public shared ({ caller }) func encrypted̲ibe̲decryption̲key̲for̲caller(encryption̲public̲key : Blob) : async Text { // スマートコントラクトが caller を受け取れている時点で、caller は確かに本人であることは検証済みであり // 認証できていると言えることから、IBE の認証相当になっている。 65 Debug.print("encrypted̲ibe̲decryption̲key̲for̲caller: caller: " # debug̲show (caller)); 66 // 参考 https://jfhyp-gaaaa-aaaak-qck6q-cai.icp0.io/docs#ic-vetkd̲encrypted̲key // System API を呼び出すことで、 PKG が「トランスポート公開鍵で暗号化された IBE の復号鍵(秘密鍵)」を導出 67 let { encrypted̲key } = await vetkd̲system̲api.vetkd̲encrypted̲key({ 68 derivation̲id = Principal.toBlob(caller); // Alice->Bob の文脈の場合は Bob の Principal 69 public̲key̲derivation̲path = Array.make(Text.encodeUtf8(“ibe̲encryption")); // 派生公開鍵を導出した際に指定した値 70 key̲id = { curve = #bls12̲381; name = "test̲key̲1" }; // 派生公開鍵を導出した際に指定した値 71 encryption̲public̲key; // トランスポート公開鍵 72 }); 73 Hex.encode(Blob.toArray(encrypted̲key)); 74 }; 復号化に必要な秘密鍵の導出
  • 19.
    参考文献 ドキュメント vetKeys: technology overviewhttps://internetcomputer.org/docs/current/developer-docs/integrations/vetkeys/technology-overview VETKeys Primer https://internetcomputer.org/blog/features/vetkey-primer IC method vetkd̲public̲key https://jfhyp-gaaaa-aaaak-qck6q-cai.icp0.io/docs#ic-vetkd̲public̲key 実装 vetKeys API demo https://internetcomputer.org/docs/current/developer-docs/integrations/vetkeys/using-vetkeys https://github.com/dfinity/examples/blob/master/motoko/vetkd/README.md ic-vetkd-utils https://github.com/dfinity/ic/tree/master/packages/ic-vetkd-utils vetKD 本体 https://github.com/dfinity/interface-spec/pull/158 vetKD の仕組み vetKeys: How a blockchain can keep many secrets 学会発表資料:https://iacr.org/submit/files/slides/2023/rwc/rwc2023/82/slides.pdf その動画:https://www.youtube.com/watch?v=-d0Ny7NAG-w&t=3586s その論文:https://eprint.iacr.org/2023/616.pdf Dfinity Foundation 提供の動画 ・Community Conversation: On-Chain Encryption https://www.youtube.com/watch?v=baM6jHnmMq8 ・Community Conversation: vetKeys ̶ Enabling Privacy Preserving https://www.youtube.com/watch?v=-u97HhHTSQI
  • 20.
  • 21.
    マスター秘密鍵をサーバ S_i へ安全に秘密分散したもの(シェア) vetKD詳細の詳細 EKDerive(mski, id, tpk) → eki EKSVerify(mpk, id, tpk, eki) → 0/1 Combine(mpk, id, S, {mpki, eki}i∈S) → ek EKVerify(mpk, id, tpk, ek) → 0/1 マスター秘密鍵シェア BoBのID Bobのトランスポート公開鍵 ek_i : 暗号化されたBobの秘密鍵シェア 各ノードで ek_i を導出し、他ノードへブロードキャスト ブロードキャストされた ek_i を受け取り、検証。 ek を検証:導出された ek が、id 用に PKG が生成したものであることの検証 導出された ek が、tpk で暗号化されたものであることの検証 7. Bob へ ek を返す 6 - 1 6 - 2 6 - 3 6 - 4 ※ ek: 暗号化されたBobの秘密鍵 = 閾値BLS署名 2/3 以上のノードから ek̲i を集めることで、ek を導出できる。 i: ノードの番号 PKG Private-Key Generator 6. 秘密鍵の導出と検証 暗号化された秘密鍵̲Bob ← 暗号化された秘密鍵導出(マスター秘密鍵̲i, BobのID, トランスポート公開鍵) 0/1 ← 暗号化された秘密鍵の検証(暗号化された秘密鍵̲Bob, マスター公開鍵, BobのID, tpk) Veri fi ably Encrypted Threshold Key Derivation (vetKD) 検証可能な暗号化された閾値鍵導出 という名前の通りである mpk:マスター公開鍵 S: サーバーの集合, mpk_i: マスター公開鍵シェア 1.セットアップ マスター公開鍵, マスター公開鍵̲i, マスター秘密鍵̲i ← NI-DKG つまり、ノードは秘密鍵_Bobを知ること はできないが、「暗号化された秘密鍵 _Bob」を導出できると言えそう? ek は「暗号化された秘密鍵_Bob」である と同時に 閾値BLS署名だから。
  • 22.
    補足 • ノードが新たなノードに置き換わった場合、各ユーザまたは各暗号文に対応した公開鍵を 共有するという方法では、膨大な数のユーザ・暗号文に対して対応できない。という問題 を vetKDは解決しているらしい。 • vetKD は IBE に閾値を加えたものであると言えるが、veri fi ably en crypted signature (VES) scheme due to Boneh et al. [BGLS03] に閾値を加えたものであるとも言える。 • 秘密鍵 = 閾値署名 だから、NI-DKG を適用できると言える。 • スマートコントラクト上で復号化したいユースケースの場合は、平文がメモリ上に展開され てしまうため、AMD SEV が必要になりそう。