]> Cypherpunks.ru repositories - pygost.git/blob - pygost/test_wrap.py
Fix wrap_cryptopro's sbox handling
[pygost.git] / pygost / test_wrap.py
1 # coding: utf-8
2 # PyGOST -- Pure Python GOST cryptographic functions library
3 # Copyright (C) 2015-2022 Sergey Matveev <stargrave@stargrave.org>
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, version 3 of the License.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 from os import urandom
18 from unittest import TestCase
19
20 from pygost.gost28147 import DEFAULT_SBOX
21 from pygost.gost3412 import GOST3412Kuznechik
22 from pygost.gost3412 import GOST3412Magma
23 from pygost.utils import hexdec
24 from pygost.wrap import kexp15
25 from pygost.wrap import kimp15
26 from pygost.wrap import unwrap_cryptopro
27 from pygost.wrap import unwrap_gost
28 from pygost.wrap import wrap_cryptopro
29 from pygost.wrap import wrap_gost
30
31
32 class WrapGostTest(TestCase):
33     def test_symmetric(self):
34         for sbox in (DEFAULT_SBOX, "id-tc26-gost-28147-param-Z"):
35             for _ in range(1 << 8):
36                 kek = urandom(32)
37                 cek = urandom(32)
38                 ukm = urandom(8)
39                 wrapped = wrap_gost(ukm, kek, cek, sbox=sbox)
40                 unwrapped = unwrap_gost(kek, wrapped, sbox=sbox)
41                 self.assertSequenceEqual(unwrapped, cek)
42
43     def test_invalid_length(self):
44         with self.assertRaises(ValueError):
45             unwrap_gost(urandom(32), urandom(41))
46         with self.assertRaises(ValueError):
47             unwrap_gost(urandom(32), urandom(45))
48
49
50 class WrapCryptoproTest(TestCase):
51     def test_symmetric(self):
52         for sbox in (DEFAULT_SBOX, "id-tc26-gost-28147-param-Z"):
53             for _ in range(1 << 8):
54                 kek = urandom(32)
55                 cek = urandom(32)
56                 ukm = urandom(8)
57                 wrapped = wrap_cryptopro(ukm, kek, cek, sbox=sbox)
58                 unwrapped = unwrap_cryptopro(kek, wrapped, sbox=sbox)
59                 self.assertSequenceEqual(unwrapped, cek)
60
61
62 class TestVectorKExp15(TestCase):
63     """Test vectors from Р 1323565.1.017-2018
64     """
65     key = hexdec("8899AABBCCDDEEFF0011223344556677FEDCBA98765432100123456789ABCDEF")
66     key_enc = hexdec("202122232425262728292A2B2C2D2E2F38393A3B3C3D3E3F3031323334353637")
67     key_mac = hexdec("08090A0B0C0D0E0F0001020304050607101112131415161718191A1B1C1D1E1F")
68
69     def test_magma(self):
70         iv = hexdec("67BED654")
71         kexp = kexp15(
72             GOST3412Magma(self.key_enc).encrypt,
73             GOST3412Magma(self.key_mac).encrypt,
74             GOST3412Magma.blocksize,
75             self.key,
76             iv,
77         )
78         self.assertSequenceEqual(kexp, hexdec("""
79 CF D5 A1 2D 5B 81 B6 E1 E9 9C 91 6D 07 90 0C 6A
80 C1 27 03 FB 3A BD ED 55 56 7B F3 74 2C 89 9C 75
81 5D AF E7 B4 2E 3A 8B D9
82         """.replace("\n", "").replace(" ", "")))
83         self.assertSequenceEqual(kimp15(
84             GOST3412Magma(self.key_enc).encrypt,
85             GOST3412Magma(self.key_mac).encrypt,
86             GOST3412Magma.blocksize,
87             kexp,
88             iv,
89         ), self.key)
90
91     def test_kuznechik(self):
92         iv = hexdec("0909472DD9F26BE8")
93         kexp = kexp15(
94             GOST3412Kuznechik(self.key_enc).encrypt,
95             GOST3412Kuznechik(self.key_mac).encrypt,
96             GOST3412Kuznechik.blocksize,
97             self.key,
98             iv,
99         )
100         self.assertSequenceEqual(kexp, hexdec("""
101 E3 61 84 E8 4E 8D 73 6F F3 6C C2 E5 AE 06 5D C6
102 56 B2 3C 20 F5 49 B0 2F DF F8 8E 1F 3F 30 D8 C2
103 9A 53 F3 CA 55 4D BA D8 0D E1 52 B9 A4 62 5B 32
104         """.replace("\n", "").replace(" ", "")))
105         self.assertSequenceEqual(kimp15(
106             GOST3412Kuznechik(self.key_enc).encrypt,
107             GOST3412Kuznechik(self.key_mac).encrypt,
108             GOST3412Kuznechik.blocksize,
109             kexp,
110             iv,
111         ), self.key)