]> Cypherpunks.ru repositories - pygost.git/blobdiff - pygost/gost3412.py
Raise copyright years
[pygost.git] / pygost / gost3412.py
index 38940b9922ac011e80aacba6760fe0f39a64bade..b68dcb5b2cd334e2d56317ec59f32ee875bd2eaf 100644 (file)
@@ -1,6 +1,6 @@
 # coding: utf-8
 # PyGOST -- Pure Python GOST cryptographic functions library
-# Copyright (C) 2015-2016 Sergey Matveev <stargrave@stargrave.org>
+# Copyright (C) 2015-2019 Sergey Matveev <stargrave@stargrave.org>
 #
 # 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
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
-"""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.
+"""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((
@@ -74,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)
@@ -103,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
@@ -114,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):
@@ -145,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]