X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=pygost%2Fgost3412.py;h=b68dcb5b2cd334e2d56317ec59f32ee875bd2eaf;hb=21a30721c31912c296e1faced73e2fd0db191be9;hp=ba204a0a1e24fa2d744e941b6fe1268193526c09;hpb=9b43fc211fc6f4d2ee95d5716fc7e010dd800a26;p=pygost.git diff --git a/pygost/gost3412.py b/pygost/gost3412.py index ba204a0..b68dcb5 100644 --- a/pygost/gost3412.py +++ b/pygost/gost3412.py @@ -1,6 +1,6 @@ # coding: utf-8 # PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2016 Sergey Matveev +# Copyright (C) 2015-2019 Sergey Matveev # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -14,17 +14,17 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -"""GOST 34.12-2015 128-bit block cipher Кузнечик (Kuznechik) - -:rfc:`7801`. Pay attention that 34.12-2015 also defines 64-bit block -cipher Магма (Magma) -- it is **not** implemented here, but in gost28147 -module. +"""GOST 34.12-2015 64 and 128 bit block ciphers (:rfc:`7801`) Several precalculations are performed during this module importing. """ +from pygost.gost28147 import block2ns as gost28147_block2ns +from pygost.gost28147 import decrypt as gost28147_decrypt +from pygost.gost28147 import encrypt as gost28147_encrypt +from pygost.gost28147 import ns2block as gost28147_ns2block from pygost.utils import strxor -from pygost.utils import xrange +from pygost.utils import xrange # pylint: disable=redefined-builtin LC = bytearray(( @@ -75,7 +75,10 @@ def gf(a, b): # optimization. # Actually it can be computed only once and saved on the disk. ######################################################################## + + GF = [bytearray(256) for _ in xrange(256)] + for x in xrange(256): for y in xrange(256): GF[x][y] = gf(x, y) @@ -104,7 +107,10 @@ def Linv(blk): # Precalculate values of the C -- it does not depend on key. # Actually it can be computed only once and saved on the disk. ######################################################################## + + C = [] + for x in range(1, 33): y = bytearray(16) y[15] = x @@ -115,7 +121,7 @@ def lp(blk): return L([PI[v] for v in blk]) -class GOST3412Kuz(object): +class GOST3412Kuznechik(object): """GOST 34.12-2015 128-bit block cipher Кузнечик (Kuznechik) """ def __init__(self, key): @@ -146,3 +152,30 @@ class GOST3412Kuz(object): for i in range(9, 0, -1): blk = [PIinv[v] for v in Linv(bytearray(strxor(self.ks[i], blk)))] return bytes(strxor(self.ks[0], blk)) + + +class GOST3412Magma(object): + """GOST 34.12-2015 64-bit block cipher Магма (Magma) + """ + def __init__(self, key): + """ + :param key: encryption/decryption key + :type key: bytes, 32 bytes + """ + # Backward compatibility key preparation for 28147-89 key schedule + self.key = b"".join(key[i * 4:i * 4 + 4][::-1] for i in range(8)) + self.sbox = "Gost28147_tc26_ParamZ" + + def encrypt(self, blk): + return gost28147_ns2block(gost28147_encrypt( + self.sbox, + self.key, + gost28147_block2ns(blk[::-1]), + ))[::-1] + + def decrypt(self, blk): + return gost28147_ns2block(gost28147_decrypt( + self.sbox, + self.key, + gost28147_block2ns(blk[::-1]), + ))[::-1]