I2P:テーブルを使用した非対称暗号化の高速化

I2Pの非対称暗号化は常に速度低下につながりました。トランスポートセッションを確立するためのDiffie-Hellmanアルゴリズムと、私の意見では、I2PアドレスでのEl-Gamalスキームの選択の失敗です。 これは、弱いハードウェアとフラッドフィルで作業する場合に特に顕著です。 この記事で提案されているアプローチは、I2Pのいくつかの機能の使用に基づいており、作業の大幅な高速化を実現し、プロセッサーの負荷を軽減します。







I2Pの非対称暗号化



現在、非対称暗号化は、モジュロ度を上げる操作と離散対数の実際的な不可能性の仮説に基づいています。他のタイプの非対称暗号化を使用する計画がありますが、これまでは実装されていません。

公開鍵yは、式y = g ^ x mod pに従って秘密鍵xに基づいて計算されます。ここで、pは素数であり、一般的な場合、数字のトリプル(y、p、g)が鍵として渡されます。 I2Pでは、数値pとgは定数であり、すべての実装で同じでなければなりません。

g = 2

p = 2 ^ 2048-2 ^ 1984-1 + 2 ^ 64 *([pi * 2 ^ 1918] + 124476)、

ここで、piはpiの数、[]はその数の整数部分を取得する演算です。

pの長さはそれぞれ256バイトで、公開鍵の長さです。



公式文書によると、秘密鍵の長さはx64で2048ビット、その他すべてで226ビットです。



計算テーブル



計算されたテーブルの使用については、以前にEdDSA署名について説明しました。

その本質を簡単に思い出しましょう。 加算操作は曲線のポイントの上で定義され、この操作を使用して、定数の基点に32バイトの数値を乗算する必要があります。 これを行うには、バイトごとに追加し、開始時に一度計算されたテーブルの各バイトの値でポイントを乗算した結果を取得します。 これには正確に32回の加算が必要になりますが、計算時間は一定になります。これは、秘密鍵を乗算するために非常に重要です。



gをpを法として累乗する操作についても同じことを行います。加算操作の代わりに、乗算操作が使用されます。

各バイトに対して次数pのすべての可能な値のテーブルを計算し、各バイトに255要素の配列を埋め、g = 2の順序で乗算します。

対応する位置にビットを設定することで取得されるため、テーブルの最初の要素を保存する必要がないことに気付くかもしれませんが、値はpを超えてはなりません。実際、これは2048 = 11ビット、つまりテーブルの1番目と3番目のバイトに対応します。



したがって、226ビットの長さの秘密キーの場合、テーブルのサイズは29 * 255 * 255〜2メガバイト、2048の長さのキーの場合、テーブルのサイズは256 * 255 * 255〜16メガバイトですが、この場合の効果は得られますより重要です。



モンゴメリー乗算



各べき乗にはモジュロで少なくとも29の乗算が必要なので、 Montgomery乗算を使用して作業を高速化することをお勧めします。

その意味は、あるモジュールを別のより便利な計算用モジュールに置き換えることに限定されます。 実際の必要に応じて、2の累乗が選択され、遅い除算が高速ビット単位シフトに置き換えられます。

欠点は、モンゴメリーの見解への転換の必要性です。 ただし、この場合、これはテーブルの計算時に一度だけ実行され、追加のアクションは結果の変換のみです。

実際のタスクでは、Montgomery乗算を実装する必要はありません-対応する関数はOpenSSLで提供されます。

int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *m, BN_CTX *ctx);
      
      





モジュールを定義します(この場合はp)

 int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_MONT_CTX *mont, BN_CTX *ctx);
      
      





与えられたモジュールのコンテキストで適切なモンゴメリー乗算

 int BN_from_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx);
      
      





結果を通常のビューに変換します。



i2pdでの実装



リリース2.7.0以降precomputation.elgamalパラメーターによってサポートおよび制御されます。デフォルトでは、x64ではオフになり、残りではオンになります。 メモリの使用に厳密な制限がない場合は、フラッドフィルモードで動作できるようにすることをお勧めします。 この場合のプロセッサの負荷は、他のノードと頻繁に接続する必要があるため、2倍以上削減されます。

接続を確立するときにキーペアを生成するときに、トンネルを構築するときに非対称暗号化を使用し、アドレス間で「ニンニク」暗号化を使用します。 同様に、DSA署名を高速化できますが、I2Pでは廃止されたと見なされ、徐々にEdDSAに置き換えられています。

この記事で検討されているアプローチは簡単に思えるかもしれませんが、その実装はその有効性を示しており、以前はパフォーマンスが不足していたプラットフォームで作業することが可能になりました。



All Articles