ブロムのスキーム

画像 2015年6月、ロシアは標準ブロック暗号化-GOST R 34.12-2015を採用しました。 このGOST(より正確には、そのGOSTで使用される多項式)とBlomスキームを組み合わせることが、私にとって興味深いものになりました。



ソースコードGOST自体で武装して、ビジネスに取りかかりました 。 しかし、最初に、少し理論。



そのため、Blomのスキームは、通信ネットワークでのキーの事前配布のスキームです。 その動作の原理は次のとおりです。



画像



対称正方行列Tがあります:



画像



マトリックスには、原則として、ネットワーク内のサブスクライバーと同じ数の行(および列)が含まれます。 したがって、サブスクライバーが20の場合、マトリックスのサイズは少なくとも20 * 20です。



サブスクライバAおよびBの公開キー



画像



画像



原則として、公開鍵はVandermortマトリックスの原理に従って形成されます。行の最初の要素はゼロ次数、2番目の数は1次、n番目の数はn次の数です。 プログラムでは、各行の最初の要素はゼロではなく、最初の次数の数値になります。



画像



したがって、すべての公開鍵はすべてのサブスクライバーに対して形成されます。



サブスクライバAの公開キーを取得し、それを行列Tで乗算すると、サブスクライバAの秘密キーが取得されます



画像



同じことは、すべてのネットワークサブスクライバに対して行われます。 これは信頼できる当事者によって行われ、その後、各参加者に公開鍵と秘密鍵が配布されます。 安全でない通信チャネルを介して公開鍵のみを交換する参加者は、自分自身間の通信用の秘密セッションキーを生成できます。



回路の信頼性は、回路で使用される秘密行列のサイズに依存します。 シークレットマトリックスを復元するには、マトリックスの行数に等しいキーの数が必要です。 その後、サブスクライバーAの秘密キーにサブスクライバーBの公開キーを掛けます。これがセッションキーの取得方法です。



わかりやすくするために、 ここでは小さな数字の小さな例を示します



信頼済みセンターは、最終フィールドのサイズと秘密マトリックスを選択します。



画像



加入者は自分自身の識別子を選択します(通常は信頼できるセンターによって発行されます):







トラステッドセンターは秘密鍵を計算します。







その後、各側は秘密鍵を計算し、その秘密鍵に2番目の側の識別子を乗算します。







例に見られるように、同じキーが取得されます。



こすってC ++で実装する



まず、マトリックスを作成して記入します。 明確にするために、8 * 8にします。



randomize(); for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { if (j >= i) { mass[i][j] = random(255); } } } for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { mass[j][i] = mass[i][j]; } }
      
      





また、table.hをプロジェクトに接続します。実際には、GOSTで使用される多項式のすべての可能な乗算は、シフトされた状態でのみ記録されます。



 #include "table.h"
      
      





便利な変数を初期化します。



  int zakr3[8] = {NULL}; //  int zakr2[8] = {NULL}; //  int abon3[8] = {NULL}; //  int abon2[8] = {NULL}; //  int secret3[8] = {NULL};//  int secret2[8] = {NULL}; // 
      
      





Edit-sで、サブスクライバーの数を入力します。



  abon2[0] = StrToInt(Edit1->Text); abon3[0] = StrToInt(Edit2->Text);
      
      





さらに、Vandermortマトリックスの原理を使用して、公開キーの行を完全に埋めるまで「仕上げ」ます。



 for (int j = 1; j < 8; j++) { sum3 = multTable[abon3[j - 1] + 256 * StrToInt(Edit1->Text)]; sum2 = multTable[abon2[j - 1] + 256 *StrToInt(Edit2->Text)]; abon2[j] = sum2; //  abon3[j] = sum3; //  }
      
      





multTableは、先ほど接続したのと同じtable.hです。 秘密鍵を生成します。



  for (int j = 0; j < 8; j++) { int x1= 0,x2 = 0; //  for (int y = 0; y < 8; y++) { sum3 = multTable[mass[j][y] + 256 * abon3[y]]; sum2 = multTable[mass[j][y] + 256 * abon2[y]]; x1 = x1^ sum3; x2 =x2 ^ sum2; } //  : zakr3[j] = x1; zakr2[j] = x2; }
      
      





ここでは、通常の加算の代わりにモジュロ2加算を使用するという例外を除き、行に行列を乗算するルールが適用されます。



次に、共有秘密鍵を計算する必要があります。



  sum3 = NULL; sum2 = NULL; for (int y = 0; y < 8; y++) { secret3[y] = multTable[256 * zakr3[y] + abon2[y]]; //  secret2[y] = multTable[256 * zakr2[y] + abon3[y]]; //  sum3 = sum3 ^ secret3[y]; //    sum2 = sum2 ^ secret2[y];//    }
      
      





ここでは、行に列が掛けられています。 結果は数値です。 すべてが正しく行われた場合、sum2とsum3は同じになります。 それは基本的にそれです。 この例では、int数値を使用しましたが、高次元の数値の使用を禁止している人はいません。



ソース:






All Articles