]> Cypherpunks.ru repositories - pygost.git/blobdiff - pygost/test_gost3413.py
Raise copyright years
[pygost.git] / pygost / test_gost3413.py
index 31a56f3203f9ad55c5237c625b05bfbadd9343f8..6b2c271177e21438149b034c3092e043fc9dfb0c 100644 (file)
@@ -1,8 +1,26 @@
+# coding: utf-8
+# PyGOST -- Pure Python GOST cryptographic functions library
+# Copyright (C) 2015-2018 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
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
 from os import urandom
 from random import randint
 from unittest import TestCase
 
 from pygost.gost3412 import GOST3412Kuznechik
 from os import urandom
 from random import randint
 from unittest import TestCase
 
 from pygost.gost3412 import GOST3412Kuznechik
+from pygost.gost3412 import GOST3412Magma
 from pygost.gost3413 import _mac_ks
 from pygost.gost3413 import cbc_decrypt
 from pygost.gost3413 import cbc_encrypt
 from pygost.gost3413 import _mac_ks
 from pygost.gost3413 import cbc_decrypt
 from pygost.gost3413 import cbc_encrypt
@@ -17,6 +35,7 @@ from pygost.gost3413 import pad2
 from pygost.gost3413 import unpad2
 from pygost.utils import hexdec
 from pygost.utils import hexenc
 from pygost.gost3413 import unpad2
 from pygost.utils import hexdec
 from pygost.utils import hexenc
+from pygost.utils import strxor
 
 
 class Pad2Test(TestCase):
 
 
 class Pad2Test(TestCase):
@@ -109,6 +128,19 @@ class GOST3412KuznechikModesTest(TestCase):
             ct = ofb(ciph.encrypt, 16, pt, iv)
             self.assertSequenceEqual(ofb(ciph.encrypt, 16, ct, iv), pt)
 
             ct = ofb(ciph.encrypt, 16, pt, iv)
             self.assertSequenceEqual(ofb(ciph.encrypt, 16, ct, iv), pt)
 
+    def test_ofb_manual(self):
+        iv = [urandom(16) for _ in range(randint(2, 10))]
+        pt = [urandom(16) for _ in range(len(iv), len(iv) + randint(1, 10))]
+        ciph = GOST3412Kuznechik(urandom(32))
+        r = [ciph.encrypt(i) for i in iv]
+        for i in range(len(pt) - len(iv)):
+            r.append(ciph.encrypt(r[i]))
+        ct = [strxor(g, r) for g, r in zip(pt, r)]
+        self.assertSequenceEqual(
+            ofb(ciph.encrypt, 16, b"".join(pt), b"".join(iv)),
+            b"".join(ct),
+        )
+
     def test_cbc_vectors(self):
         ciphtext = ""
         ciphtext += "689972d4a085fa4d90e52e3d6d7dcc27"
     def test_cbc_vectors(self):
         ciphtext = ""
         ciphtext += "689972d4a085fa4d90e52e3d6d7dcc27"
@@ -169,3 +201,146 @@ class GOST3412KuznechikModesTest(TestCase):
             data = urandom(randint(0, 16 * 2))
             ciph = GOST3412Kuznechik(urandom(32))
             mac(ciph.encrypt, 16, data)
             data = urandom(randint(0, 16 * 2))
             ciph = GOST3412Kuznechik(urandom(32))
             mac(ciph.encrypt, 16, data)
+
+
+class GOST3412MagmaModesTest(TestCase):
+    key = hexdec("ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
+    ciph = GOST3412Magma(key)
+    plaintext = ""
+    plaintext += "92def06b3c130a59"
+    plaintext += "db54c704f8189d20"
+    plaintext += "4a98fb2e67a8024c"
+    plaintext += "8912409b17b57e41"
+    iv = hexdec("1234567890abcdef234567890abcdef134567890abcdef12")
+
+    def test_ecb_vectors(self):
+        ciphtext = ""
+        ciphtext += "2b073f0494f372a0"
+        ciphtext += "de70e715d3556e48"
+        ciphtext += "11d8d9e9eacfbc1e"
+        ciphtext += "7c68260996c67efb"
+        self.assertSequenceEqual(
+            hexenc(ecb_encrypt(self.ciph.encrypt, 8, hexdec(self.plaintext))),
+            ciphtext,
+        )
+        self.assertSequenceEqual(
+            hexenc(ecb_decrypt(self.ciph.decrypt, 8, hexdec(ciphtext))),
+            self.plaintext,
+        )
+
+    def test_ecb_symmetric(self):
+        for _ in range(100):
+            pt = pad2(urandom(randint(0, 16 * 2)), 16)
+            ciph = GOST3412Magma(urandom(32))
+            ct = ecb_encrypt(ciph.encrypt, 8, pt)
+            self.assertSequenceEqual(ecb_decrypt(ciph.decrypt, 8, ct), pt)
+
+    def test_ctr_vectors(self):
+        ciphtext = ""
+        ciphtext += "4e98110c97b7b93c"
+        ciphtext += "3e250d93d6e85d69"
+        ciphtext += "136d868807b2dbef"
+        ciphtext += "568eb680ab52a12d"
+        iv = self.iv[:4]
+        self.assertSequenceEqual(
+            hexenc(ctr(self.ciph.encrypt, 8, hexdec(self.plaintext), iv)),
+            ciphtext,
+        )
+        self.assertSequenceEqual(
+            hexenc(ctr(self.ciph.encrypt, 8, hexdec(ciphtext), iv)),
+            self.plaintext,
+        )
+
+    def test_ctr_symmetric(self):
+        for _ in range(100):
+            pt = urandom(randint(0, 16 * 2))
+            iv = urandom(4)
+            ciph = GOST3412Magma(urandom(32))
+            ct = ctr(ciph.encrypt, 8, pt, iv)
+            self.assertSequenceEqual(ctr(ciph.encrypt, 8, ct, iv), pt)
+
+    def test_ofb_vectors(self):
+        iv = self.iv[:16]
+        ciphtext = ""
+        ciphtext += "db37e0e266903c83"
+        ciphtext += "0d46644c1f9a089c"
+        ciphtext += "a0f83062430e327e"
+        ciphtext += "c824efb8bd4fdb05"
+        self.assertSequenceEqual(
+            hexenc(ofb(self.ciph.encrypt, 8, hexdec(self.plaintext), iv)),
+            ciphtext,
+        )
+        self.assertSequenceEqual(
+            hexenc(ofb(self.ciph.encrypt, 8, hexdec(ciphtext), iv)),
+            self.plaintext,
+        )
+
+    def test_ofb_symmetric(self):
+        for _ in range(100):
+            pt = urandom(randint(0, 16 * 2))
+            iv = urandom(8 * 2)
+            ciph = GOST3412Magma(urandom(32))
+            ct = ofb(ciph.encrypt, 8, pt, iv)
+            self.assertSequenceEqual(ofb(ciph.encrypt, 8, ct, iv), pt)
+
+    def test_cbc_vectors(self):
+        ciphtext = ""
+        ciphtext += "96d1b05eea683919"
+        ciphtext += "aff76129abb937b9"
+        ciphtext += "5058b4a1c4bc0019"
+        ciphtext += "20b78b1a7cd7e667"
+        self.assertSequenceEqual(
+            hexenc(cbc_encrypt(self.ciph.encrypt, 8, hexdec(self.plaintext), self.iv)),
+            ciphtext,
+        )
+        self.assertSequenceEqual(
+            hexenc(cbc_decrypt(self.ciph.decrypt, 8, hexdec(ciphtext), self.iv)),
+            self.plaintext,
+        )
+
+    def test_cbc_symmetric(self):
+        for _ in range(100):
+            pt = pad2(urandom(randint(0, 16 * 2)), 16)
+            iv = urandom(8 * 2)
+            ciph = GOST3412Magma(urandom(32))
+            ct = cbc_encrypt(ciph.encrypt, 8, pt, iv)
+            self.assertSequenceEqual(cbc_decrypt(ciph.decrypt, 8, ct, iv), pt)
+
+    def test_cfb_vectors(self):
+        iv = self.iv[:16]
+        ciphtext = ""
+        ciphtext += "db37e0e266903c83"
+        ciphtext += "0d46644c1f9a089c"
+        ciphtext += "24bdd2035315d38b"
+        ciphtext += "bcc0321421075505"
+        self.assertSequenceEqual(
+            hexenc(cfb_encrypt(self.ciph.encrypt, 8, hexdec(self.plaintext), iv)),
+            ciphtext,
+        )
+        self.assertSequenceEqual(
+            hexenc(cfb_decrypt(self.ciph.encrypt, 8, hexdec(ciphtext), iv)),
+            self.plaintext,
+        )
+
+    def test_cfb_symmetric(self):
+        for _ in range(100):
+            pt = urandom(randint(0, 16 * 2))
+            iv = urandom(8 * 2)
+            ciph = GOST3412Magma(urandom(32))
+            ct = cfb_encrypt(ciph.encrypt, 8, pt, iv)
+            self.assertSequenceEqual(cfb_decrypt(ciph.encrypt, 8, ct, iv), pt)
+
+    def test_mac_vectors(self):
+        k1, k2 = _mac_ks(self.ciph.encrypt, 8)
+        self.assertSequenceEqual(hexenc(k1), "5f459b3342521424")
+        self.assertSequenceEqual(hexenc(k2), "be8b366684a42848")
+        self.assertSequenceEqual(
+            hexenc(mac(self.ciph.encrypt, 8, hexdec(self.plaintext))[:4]),
+            "154e7210",
+        )
+
+    def test_mac_applies(self):
+        for _ in range(100):
+            data = urandom(randint(0, 16 * 2))
+            ciph = GOST3412Magma(urandom(32))
+            mac(ciph.encrypt, 8, data)