I2Pのインポート置換:GOST R 34.10-2012に基づく署名

楕円暗号は、高い強度と広さを備えており、さまざまな曲線や署名スキームのブックマークについて、常に多くの論争と憶測を引き起こしました。 同時に、誰もそのようなブックマークの例を挙げたり、彼らの不在を証明することはできませんでした。 そのため、AESがリーダーシップを無条件に所有する対称暗号化とは異なり、非対称暗号化は、好み、技術的または法的要件に応じてさまざまな方法で使用されます。 I2Pの追加タイプのアドレス署名は、アプリケーションの選択肢と柔軟性を高めます。 GOSTは、EVPインターフェースを介してopensslでサポートされますが、バージョン1.1では標準配信から除外されます。さらに、既存の実装には、DER形式での公開鍵と署名の保存と転送が含まれます。



I2Pの署名の種類



現在、I2Pには9種類の署名があり、署名の種類、ハッシュの種類、必要に応じて曲線またはそのパラメーターのセットを示します。



  1. ECDSA_SHA256_P256
  2. ECDSA_SHA384_P384
  3. ECDSA_SHA512_P521
  4. RSA_SHA256_2048
  5. RSA_SHA384_3072
  6. RSA_SHA512_4096
  7. EdDSA_SHA512_Ed25519
  8. EdDSA_SHA512_Ed25519ph


また、古いアドレスはタイプ0-DSA_SHA1を使用しますが、これは廃止と見なされます。

タイプ1と7が推奨されます。



GOSTの場合、私の要求に応じて、2つのタイプが割り当てられます。

9-GOSTR3410_GOSTR3411_256_CRYPTO_PRO_A

10-GOSTR3410_GOSTR3411_512_TC26_A

それぞれ256ビットおよび512ビットキー用。



9の公開キーの長さは64バイト(ポイント座標あたり32バイト)および10の場合は128バイトです。



署名の実装GOST R 34.10



256または512ビットのハッシュが署名および検証されると想定されます。 詳細と例はここで説明されます



通常の楕円曲線が使用されるため、暗号化ライブラリの関数を使用して操作できます。 特に、これらはopensslのEC_GROUP_ *およびEC_POINT_ *であり、その主なものは次のとおりです。



int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx)
      
      





パラメータに応じて、基点に数値と任意の点を乗算するために使用されます。



曲線の場合、6つのパラメーターが指定されます:pはモジュラス、aとbは曲線の方程式の係数、P(x、y)は基点、qは素数、基点のどれがゼロになるかを乗算します。



pとqは大きく、最大に近い値である必要があります。これは、pがすべての数値の範囲を制限し、qが秘密鍵の範囲を制限するためです。 基点とqは同時に計算されます。

原則として、よく知られ、十分にテストされたパラメーターセットが使用されます。



実装では、2セットのパラメーターを使用します。





曲線とは異なり、GOSTの署名スキームは異なるため、ECDSA_signおよびECDSA_verify関数は使用できず、コードに署名および署名検証を実装する必要があります。



署名(r、s)については、乱数kが選択され、点R = k * Pが計算されます。そのx座標は署名の成分rになります。 コンポーネントs = r * d + h * k、ここでdは秘密鍵、hはビッグエンディアンのメッセージの署名のハッシュです。



署名を検証するには、等式の両側に基点Pを掛けます。



実際、s * P = r * d * P + h * k * P = r * Q + h * R、ここでQは公開鍵です。 この等式では、ポイントRはわかりません。rからy座標を復元することは可能ですが、これは非常に遅い操作です。 したがって、等式をh * R = s * P-r * Qの形式に書き換えてから、

R =(s * P -r * Q)/ hおよびx座標のみを比較します。



i2pdコードでは、次のようになります
 bool GOSTR3410Curve::Verify (const EC_POINT * pub, const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s) { BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); BIGNUM * q = BN_CTX_get (ctx); EC_GROUP_get_order(m_Group, q, ctx); BIGNUM * h = BN_CTX_get (ctx); BN_mod (h, digest, q, ctx); // h = digest % q BN_mod_inverse (h, h, q, ctx); // 1/h mod q BIGNUM * z1 = BN_CTX_get (ctx); BN_mod_mul (z1, s, h, q, ctx); // z1 = s/h BIGNUM * z2 = BN_CTX_get (ctx); BN_sub (z2, q, r); // z2 = -r BN_mod_mul (z2, z2, h, q, ctx); // z2 = -r/h EC_POINT * C = EC_POINT_new (m_Group); EC_POINT_mul (m_Group, C, z1, pub, z2, ctx); // z1*P + z2*pub BIGNUM * x = BN_CTX_get (ctx); GetXY (C, x, nullptr); // Cx BN_mod (x, x, q, ctx); // Cx % q bool ret = !BN_cmp (x, r); // Cx = r ? EC_POINT_free (C); BN_CTX_end (ctx); BN_CTX_free (ctx); return ret; }
      
      







ハッシュ関数GOST R 34.11-2012(stribog)



メッセージの署名には、SHA256 / SHA512など、適切なサイズのハッシュを計算する任意の関数を使用できますが、既存の実装との互換性を含め、GOST R 34.11-2012で規定されている標準を使用します。 署名とは異なり、ハッシュははるかに簡単です。



詳細な説明と例 。 主な点に注意してください。





I2CPプロトコルを使用した外部暗号プロバイダーによる署名



アドレスがI2CPプロトコルを使用してルーターに接続されている場合、ルーターの秘密署名キーの知識は必要ありません。



代わりに、ルーターはRequestLeaseSetMessageメッセージ(またはRequestVariableLeaseSetMessage)を送信し、応答でアドレス秘密鍵で署名されたLeaseSetを含むCreateLeaseSetMessageメッセージを待ちます。 プロトコルの説明からわかるように、古いバージョンのI2Pでは、メッセージでこのキーを送信する必要がありましたが、これは不要になりました。

したがって、I2Pアドレスを実装するアプリケーションは、GOSTで既存の暗号プロバイダーの1つを使用してAPIに署名し、I2Pソリューションを既存のインフラストラクチャに効果的に統合できます。



実装



現在、 i2pdは署名タイプ9および10を完全にサポートしています。すべてのクライアントアドレスはi2pdのアドレスで機能します。 使用 サーバーアドレスが機能するには、floodfillsの側からのサポートが必要です。または、メインI2Pから独立したネットワークを2以外のnetidで構築できます。メインネットワークでは、Javaまたはfloodfillsの追加パラメーターで 実装されるまで待つ必要があります



All Articles