
新年の最初の数週間は、私たちが去った年が何をもたらしたかを思い出すために窓際に快適に座るのに最適な時期です。
そして、彼は2つの新しい暗号化標準をもたらしました。 ロシアの標準GOST R 34.12-2015(ブロック暗号Grasshopper)。 そして、ウクライナのDSTU 7624:2014(ブロック暗号Kalina)。 寒い冬の夜には、そのような十分な理由を逃さないでください。 猫の下には、アルゴリズムとPythonでの実装の簡単な説明があります。 そして、新しい暗号をもっと楽しくするために、私たちは彼らの社会をベラルーシのSTB 34.101.31-2007で希釈します。
GOST R 34.12-2015
ロシアの標準であるブロック暗号Grasshopperから始めることを提案します。 入力暗号ブロックの長さは128ビットで、キーの長さは256ビットです。
暗号では次の変換が使用されます。
- X-キーによる2を法とするビット単位の加算:
- 非線形変換Sは 、テーブルπを代入して各バイトを置き換えることにより実行されます。
- 線形変換Lは、多項式を法とするガロア体上の乗算によって実現されます。
:
Δは、バイナリ文字列を有限体の要素にマッピングするマッピングです。
-バイナリ文字列を有限体の要素にマッピングするマッピング。
計算するとき加算および乗算演算は、最終フィールドで実行されます。
128ビットブロックaの暗号化手順は、次の式で正式に記述されます。
より視覚的な形式では、次のようになります。

ラウンド128ビットキーK 1 、K 2は、メインの256ビットキーを半分に分割することによって取得されます。
彼らの助けを借りて、次のラウンドキーが計算されます:
復号化するとき、逆変換が使用されます:
Pythonの使用例:
if __name__ == '__main__': mtest = list(binascii.unhexlify('1122334455667700ffeeddccbbaa9988')) ktest = list(binascii.unhexlify('8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef')) gost =gost2015(ktest) print('GOST 34.12-2015') print(datetime.datetime.now()) c = gost.encryption(mtest) d = gost.decryption(c) print(datetime.datetime.now())
DSTU 7624:2014
2015年7月にウクライナの標準として導入されたKalina暗号は、ブロック長とキーのいくつかのオプションをサポートしています。 ここでは、ブロック長とキー長が128ビットの暗号バージョンについて説明します。
暗号の内部状態は、8行2列のマトリックスです。 暗号化が開始される前に、マトリックスはプレーンテキストバイトで埋められます。 次に、マトリックス要素に対して、10ラウンドの次の変換が実行されます。
-状態行列の列とラウンドキーの列の加算。264を法とする行列の形式で表示されます。
(SubBytes)-4つのテーブルπ0、π1、π2、π3のいずれかを置換することにより、状態行列の各バイトを置換
(SiftRows)-4番目から8番目までの行の1ポジション分だけ右への循環シフト。
(MixColumns)-状態行列列の変換。 新しい行列の各要素は次の式で計算されます:
、ここで⊗はベクトルのスカラー積、vはベクトル、
、G jは行列列です。 乗算と加算の演算は、多項式を法とする有限体で実行されます
-暗号の内部状態の行列の2を法とするビット単位の加算とラウンド鍵K v
暗号化プロセスは、次の式で説明されます。
または、より視覚的な形式で:

ラウンドキーを生成するには、最初にマスターキーKを使用して、中間キーが計算されます
偶数ラウンドのキーは、中間キーに基づいて生成されます。
奇数ラウンドのキーは次のように計算されます。
復号化するとき、逆変換が使用されます:
Pythonの使用例:
if __name__ == '__main__': key = list(binascii.unhexlify('000102030405060708090a0b0c0d0e0f')) pt = list(binascii.unhexlify('101112131415161718191a1b1c1d1e1f')) dstu =dstu2014(key) key2 = list(binascii.unhexlify('0f0e0d0c0b0a09080706050403020100')) ct = list(binascii.unhexlify('1f1e1d1c1b1a19181716151413121110')) dstu2 = dstu2014(key2) print(datetime.datetime.now()) c = dstu.encryption(pt) d = dstu2.decryption(ct) print(datetime.datetime.now())
STB 34.101.31-2007
ブロック長128ビット、キー長256ビットのBelT暗号は、2011年にベラルーシ共和国の対称暗号化の標準として採用されました。 暗号化は、入力ブロックに適用される8ラウンドの変換によって実行されます。
暗号化手順は、次の手順で構成されます。
- 入力ブロックは次のように記述されます
- キーは次のように書かれています
ラウンドキーが決定されます
- 追加の変数a、b、c、dには値が割り当てられます
ここで、G rは32ビット入力文字列の変換操作であり、; RotHi r -rビットによる循環左シフト。 H(u) -テーブルからの置換によって8ビットの入力文字列を置換する操作。
そして
-2 32を法とする加算および減算演算。
暗号文として返されます。
復号化する場合、同じ操作が逆の順序で適用されます。
Pythonの使用例:
if __name__ == '__main__': key = list(binascii.unhexlify('E9DEE72C8F0C0FA62DDB49F46F73964706075316ED247A3739CBA38303A98BF6')) belt1 = belt(key) m = list(binascii.unhexlify('B194BAC80A08F53B366D008E584A5DE4')) key2 = list(binascii.unhexlify('92BD9B1CE5D141015445FBC95E4D0EF2682080AA227D642F2687F93490405511')) belt2 = belt(key2) c = list(binascii.unhexlify('E12BDC1AE28257EC703FCCF095EE8DF1')) print(datetime.datetime.now()) c1 = belt1.encryption(m) d1 = belt2.decryption(c) print(datetime.datetime.now())
PS
Pythonで説明されているすべてのアルゴリズムの実装は、 GitHubにあります 。