HN 日本語サマリー

← 一覧へ戻る
セキュリティ

存在しない鍵:ブラウザでの閾値署名セレモニー

The key that never exists: a threshold signing ceremony in the browser (808bits.com)

5 pointsby meehow0 コメント

要約

この記事は、ブラウザ上で実行される閾値署名セレモニーの実装を紹介しています。これにより、秘密鍵が単一の場所に存在することなく、複数の参加者間で共同で署名を生成できます。MPC(安全なマルチパーティ計算)とFROSTプロトコルを利用し、鍵の生成から署名までをブラウザ内で完結させ、セキュリティとプライバシーを向上させる方法を示しています。

全文翻訳

存在しない鍵:ブラウザでの閾値署名セレモニー 2026-08-15 · 7 分 暗号鍵は単一障害点です。それを保持する者が全てを保持し、ほとんどの管理上の大惨事はそれに還元されます。閾値暗号は異なる問いを投げかけます。鍵が単一の場所に存在しないとしたらどうなるでしょうか?誕生の瞬間でさえもです。 このページでは、3人の鍵保持者 - アリス、ボブ、キャロル - が共同で1つの鍵を作成します。彼らのうち任意の2人が署名でき、誰も完全な鍵を保持せず、それを作成して分割する信頼できるディーラーもいません。鍵はすでに断片化された状態で生まれます。 以下の全ては実際の暗号技術であり、ZigからWebAssemblyにコンパイルされ、あなたのタブでローカルに実行されます。ライブラリであるzig-mpcはGitHubにあります。曲線を選択し、「セレモニーを開始」を押してください。ページが各ステップを説明します。 鍵方式を選択 Ed25519 Solana · Cardano · TON secp256k1 Bitcoin · Ethereum BIP-340 Bitcoin Taproot セレモニーを開始 参加者は固定されています:アリスはパーティ1、ボブはパーティ2、キャロルはパーティ3、そして閾値は2です - 任意の2人が署名でき、1人だけでは何もできません。本番環境では、各パーティは個別のマシンになります。このページは3つ全てをプレイし、ネットワークを横断するバイトが正確に何であるかを示します。 セッションID アリスは、この実行を識別する32バイトのランダムバイトを生成します。全てのメッセージはこのIDを運び、全てのハッシュに混合されます - 2つのセレモニーが決して互いに汚染し合うことはありません。それは実行を識別します。秘密ではありません。CLIでは、これは他のパーティのためにzmpc initが出力する値です。 ラウンド開始前の2つの専門用語。MPCは安全なマルチパーティ計算です。複数のパーティが互いにインプットを明らかにすることなく、共同で結果を計算します。これは「MPCウォレット」ベンダーが通常APIの背後で販売しているものです。鍵セレモニーは、鍵材料が作成または使用される正式な手順に対する管理上の名前であり、伝統的には証人や二重制御を備えた金庫で行われます。このページ上のものは、金庫を除いた実際のプロトコルです。 セレモニーは3つの方式全てで同一です。曲線と最終的な署名形式のみが異なります。Ed25519とBIP-340はFROST(Flexible Round-Optimized Schnorr Threshold signatures, RFC 9591)で署名し、同じ分散鍵生成(DKG)が、それが必要なチェーンのために閾値ECDSA(CGGMP24)にも供給します。 表示される全てのバイトは実際のプロトコルメッセージであり、zmpc CLIがマシン間で交換するのと同じワイヤフォーマットです。あなたが入力またはクリックしたものは何もページを離れません。サーバーも分析もありません。1つのwasmファイルをフェッチし、その後静かになります。 全体として存在しない鍵を育てる 分散鍵生成:3つのラウンドと1つのファイナライズ、CLIではラウンドごとにマシンごとに1つのコマンド。各ラウンドは到着したフレームを読み取り、新しいフレームを生成します。ページは、マシン間で配信するのと同じ方法でそれらを配信します:ブロードキャストフレーム(…-t0)は両方の他のパーティにコピーされ、p2pフレーム(…-tN)はパーティNにのみ送信されます。 クリックする前に、このトリックの形状を述べる価値があります。各パーティは独自の秘密多項式を作成し、他のパーティにそれ上の単一の点を渡します。3つの多項式を合計すると、誰も選択せず、誰も知らないグループ秘密が得られます。各パーティのシェアは、単にその点のスタックです。ラウンド1のコミットメントは、他者を見た後に誰かが多項式を選択するのを防ぎ、ラウンド3の検証は一貫性のない点を扱った誰かを捕らえます。不正行為は鍵を破損しません。セレモニーを中止し、不正を行った者を特定します。 シャミアの秘密分散法を知っていれば、代数は馴染み深い(多項式、点、補間)ですが、信頼モデルはそうではありません。シャミアは、分割する前に完全な秘密を保持するディーラーを必要とし、秘密を使用することはそれを再構築することを意味します。したがって、鍵は誕生時および使用時に全体として存在します。ここでは、各パーティは自身の貢献のみを扱い、生成時または署名時に再構築は決して起こりません。 ラウンド1 · コミット ラウンド2 · シェアを配布 ラウンド3 · 検証 ファイナライズ セレモニーを上記で開始すると、ラウンドがアンロックされます。 グループ公開鍵 - 3つのパーティ全てが、互いのコミットメントから、この同じ鍵を独立して計算しました。対応する秘密鍵はどこにも存在しませんでした:アリス、ボブ、キャロルはそれぞれkeyshare.zmpc - 誰も知らない秘密多項式上の1つの点 - を保持しており、そのファイルは彼らのマシンから決して離れません。 任意の2つで署名 署名はFROSTです:2つのラウンドと1つの集約、CLIではzmpc sign commit / share / aggregate。テーブルに着く2人を選んでください。残りの1人は家にいて、何も知りません。署名が発生したことさえ知りません。各署名者は、同じメッセージバイトと新しい署名セッションIDを保持する必要があります。 出力は通常の署名です。BitcoinノードまたはSolanaバリデーターは、標準アルゴリズムを使用してグループ公開鍵に対してそれを検証します。検証者は、セレモニーが発生したことを知ることはできません。閾値構造はオンチェーンでは見えないため、FROSTを知らないチェーンでも今日機能します。 署名者(2人選択) アリス ボブ キャロル 署名するメッセージ ラウンド1 · ノンスへのコミット ラウンド2 · 署名シェア 集約 & 検証 新しい署名セッション 上記の鍵が存在するとアンロックされます。 壊してみる 以下の各実験は、1つの問題がある新しい署名セッションを実行します:転送中にビットが反転した、検証時にメッセージが交換された、閾値未満でパーティが正当なシェアで署名した。 転送中のバイトを破損させる 最初の署名者のコミットメントフレームの1バイトが転送中に反転します。それを選択するか、ランダムな位置のために空白のままにするかしてください。そして、もう一方の署名者はそのフレームを使用しようとします。 バイト位置(空白 = ランダム) 破損させて配信 メッセージを交換する 2人の署名者が署名パネルからのメッセージに対して新しいセッションを実行し、その後、署名はここで入力したものに対して検証されます。1文字変更してみてください - 次に元のメッセージを正確に入力してみてください。 検証対象 署名してから、これに対して検証 単独で署名する 閾値未満:1つのパーティが、その正当なシェアで、全ての署名プロトコルを文句なしに実行します。 誰が試みるか アリス ボブ キャロル 試す 鍵が存在するとアンロックされます - 実験には攻撃するための実際のシェアが必要です。 3番目の実験は、じっくり取り組むべきものです。アリスの単独の試みは、全てのプロトコルステップが文句なしに実行されるにもかかわらず失敗します。1つの点は次数1の多項式を決定しないため、彼女の署名は単に検証されません。閾値は、誰かがパッチアウトできるif文ではなく、代数によって強制されます。 各実験の不可能な結果に対するメッセージは「それはバグです」と読みます。もしそれを見たら、問題を報告してください。 内部構造 このページにはzmpc.wasm(約230 KB)が埋め込まれています。これはZigで書かれ、wasm32-freestandingにコンパイルされたzig-mpcのWebAssemblyビルドであり、EmscriptenやJS暗号化は使用していません。プリミティブは自作ではありません。グループ演算はstd.crypto.eccから、フィールド演算はstd.crypto.ffから、SHA-2とHMACは同じ場所から来ています。zig-mpcはプロトコルレイヤーを追加し、消費された秘密をゼロにし、定数時間で秘密データを比較します。このページのJavaScriptは、線形メモリとの間でバイトを移動し、テーブルを描画します。 ここで実行されているDKGとFROSTのラウンドは、zmpc CLIが実行するのと同じ関数であり、フレームはそれとバイト互換性があります。このページで生成されたkeyshare.zmpcは、実際のマシン間のCLI署名セッションで使用でき、その逆も同様です。実際のハードウェアでは、同じセレモニーはパーティごとに1つのプロセス、ラウンドごとに1つのコマンドです。 zmpc init --dir p1 --suite ed25519 --party 1 --n 3 --threshold 2 zmpc dkg round1 --dir p1 # ... 他のマシンにフレームを配信 ... zmpc dkg round2 --dir p1 zmpc dkg round3 --dir p1 zmpc dkg finalize --dir p1 # -> artifacts/keyshare.zmpc, 公開鍵を表示 全てのリポジトリにあり、Zig標準ライブラリ以外の依存関係はありません。zig buildはCLIを生成し、zig build wasmはこのページがロードしたモジュールを生成します。FROST実装はRFC 9591テストベクトルをバイト単位で再現し、Taprootモードは公式BIP-340ベクター19個全てに合格し、ライブラリは閾値ECDSA(CGGMP24、エンドツーエンド)、プロアクティブシェアリフレッシュ、およびBIP-32/SLIP-10 HD導出も行います。 2つの注意点。MPCのポイントは、各パーティが別々のマシンであり、シェアが決して会わないことです。このタブは3つのパーティ全てをプレイするので、メッセージを見ることができます。そして、zig-mpcは監査されておらず、プレリリース版です。