]> Cypherpunks.ru repositories - pygost.git/blob - pygost/test_gost3413.py
Rename Kuz to Kuznechik for clarity
[pygost.git] / pygost / test_gost3413.py
1 from os import urandom
2 from random import randint
3 from unittest import TestCase
4
5 from pygost.gost3412 import GOST3412Kuznechik
6 from pygost.gost3413 import _mac_ks
7 from pygost.gost3413 import cbc_decrypt
8 from pygost.gost3413 import cbc_encrypt
9 from pygost.gost3413 import cfb_decrypt
10 from pygost.gost3413 import cfb_encrypt
11 from pygost.gost3413 import ctr
12 from pygost.gost3413 import ecb_decrypt
13 from pygost.gost3413 import ecb_encrypt
14 from pygost.gost3413 import mac
15 from pygost.gost3413 import ofb
16 from pygost.gost3413 import pad2
17 from pygost.gost3413 import unpad2
18 from pygost.utils import hexdec
19 from pygost.utils import hexenc
20
21
22 class Pad2Test(TestCase):
23     def test_symmetric(self):
24         for _ in range(100):
25             for blocksize in (8, 16):
26                 data = urandom(randint(0, blocksize * 3))
27                 self.assertSequenceEqual(
28                     unpad2(pad2(data, blocksize), blocksize),
29                     data,
30                 )
31
32
33 class GOST3412KuznechikModesTest(TestCase):
34     key = hexdec("8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef")
35     ciph = GOST3412Kuznechik(key)
36     plaintext = ""
37     plaintext += "1122334455667700ffeeddccbbaa9988"
38     plaintext += "00112233445566778899aabbcceeff0a"
39     plaintext += "112233445566778899aabbcceeff0a00"
40     plaintext += "2233445566778899aabbcceeff0a0011"
41     iv = hexdec("1234567890abcef0a1b2c3d4e5f0011223344556677889901213141516171819")
42
43     def test_ecb_vectors(self):
44         ciphtext = ""
45         ciphtext += "7f679d90bebc24305a468d42b9d4edcd"
46         ciphtext += "b429912c6e0032f9285452d76718d08b"
47         ciphtext += "f0ca33549d247ceef3f5a5313bd4b157"
48         ciphtext += "d0b09ccde830b9eb3a02c4c5aa8ada98"
49         self.assertSequenceEqual(
50             hexenc(ecb_encrypt(self.ciph.encrypt, 16, hexdec(self.plaintext))),
51             ciphtext,
52         )
53         self.assertSequenceEqual(
54             hexenc(ecb_decrypt(self.ciph.decrypt, 16, hexdec(ciphtext))),
55             self.plaintext,
56         )
57
58     def test_ecb_symmetric(self):
59         for _ in range(100):
60             pt = pad2(urandom(randint(0, 16 * 2)), 16)
61             ciph = GOST3412Kuznechik(urandom(32))
62             ct = ecb_encrypt(ciph.encrypt, 16, pt)
63             self.assertSequenceEqual(ecb_decrypt(ciph.decrypt, 16, ct), pt)
64
65     def test_ctr_vectors(self):
66         ciphtext = ""
67         ciphtext += "f195d8bec10ed1dbd57b5fa240bda1b8"
68         ciphtext += "85eee733f6a13e5df33ce4b33c45dee4"
69         ciphtext += "a5eae88be6356ed3d5e877f13564a3a5"
70         ciphtext += "cb91fab1f20cbab6d1c6d15820bdba73"
71         iv = self.iv[:8]
72         self.assertSequenceEqual(
73             hexenc(ctr(self.ciph.encrypt, 16, hexdec(self.plaintext), iv)),
74             ciphtext,
75         )
76         self.assertSequenceEqual(
77             hexenc(ctr(self.ciph.encrypt, 16, hexdec(ciphtext), iv)),
78             self.plaintext,
79         )
80
81     def test_ctr_symmetric(self):
82         for _ in range(100):
83             pt = urandom(randint(0, 16 * 2))
84             iv = urandom(8)
85             ciph = GOST3412Kuznechik(urandom(32))
86             ct = ctr(ciph.encrypt, 16, pt, iv)
87             self.assertSequenceEqual(ctr(ciph.encrypt, 16, ct, iv), pt)
88
89     def test_ofb_vectors(self):
90         ciphtext = ""
91         ciphtext += "81800a59b1842b24ff1f795e897abd95"
92         ciphtext += "ed5b47a7048cfab48fb521369d9326bf"
93         ciphtext += "66a257ac3ca0b8b1c80fe7fc10288a13"
94         ciphtext += "203ebbc066138660a0292243f6903150"
95         self.assertSequenceEqual(
96             hexenc(ofb(self.ciph.encrypt, 16, hexdec(self.plaintext), self.iv)),
97             ciphtext,
98         )
99         self.assertSequenceEqual(
100             hexenc(ofb(self.ciph.encrypt, 16, hexdec(ciphtext), self.iv)),
101             self.plaintext,
102         )
103
104     def test_ofb_symmetric(self):
105         for _ in range(100):
106             pt = urandom(randint(0, 16 * 2))
107             iv = urandom(16 * 2)
108             ciph = GOST3412Kuznechik(urandom(32))
109             ct = ofb(ciph.encrypt, 16, pt, iv)
110             self.assertSequenceEqual(ofb(ciph.encrypt, 16, ct, iv), pt)
111
112     def test_cbc_vectors(self):
113         ciphtext = ""
114         ciphtext += "689972d4a085fa4d90e52e3d6d7dcc27"
115         ciphtext += "2826e661b478eca6af1e8e448d5ea5ac"
116         ciphtext += "fe7babf1e91999e85640e8b0f49d90d0"
117         ciphtext += "167688065a895c631a2d9a1560b63970"
118         self.assertSequenceEqual(
119             hexenc(cbc_encrypt(self.ciph.encrypt, 16, hexdec(self.plaintext), self.iv)),
120             ciphtext,
121         )
122         self.assertSequenceEqual(
123             hexenc(cbc_decrypt(self.ciph.decrypt, 16, hexdec(ciphtext), self.iv)),
124             self.plaintext,
125         )
126
127     def test_cbc_symmetric(self):
128         for _ in range(100):
129             pt = pad2(urandom(randint(0, 16 * 2)), 16)
130             iv = urandom(16 * 2)
131             ciph = GOST3412Kuznechik(urandom(32))
132             ct = cbc_encrypt(ciph.encrypt, 16, pt, iv)
133             self.assertSequenceEqual(cbc_decrypt(ciph.decrypt, 16, ct, iv), pt)
134
135     def test_cfb_vectors(self):
136         ciphtext = ""
137         ciphtext += "81800a59b1842b24ff1f795e897abd95"
138         ciphtext += "ed5b47a7048cfab48fb521369d9326bf"
139         ciphtext += "79f2a8eb5cc68d38842d264e97a238b5"
140         ciphtext += "4ffebecd4e922de6c75bd9dd44fbf4d1"
141         self.assertSequenceEqual(
142             hexenc(cfb_encrypt(self.ciph.encrypt, 16, hexdec(self.plaintext), self.iv)),
143             ciphtext,
144         )
145         self.assertSequenceEqual(
146             hexenc(cfb_decrypt(self.ciph.encrypt, 16, hexdec(ciphtext), self.iv)),
147             self.plaintext,
148         )
149
150     def test_cfb_symmetric(self):
151         for _ in range(100):
152             pt = urandom(randint(0, 16 * 2))
153             iv = urandom(16 * 2)
154             ciph = GOST3412Kuznechik(urandom(32))
155             ct = cfb_encrypt(ciph.encrypt, 16, pt, iv)
156             self.assertSequenceEqual(cfb_decrypt(ciph.encrypt, 16, ct, iv), pt)
157
158     def test_mac_vectors(self):
159         k1, k2 = _mac_ks(self.ciph.encrypt, 16)
160         self.assertSequenceEqual(hexenc(k1), "297d82bc4d39e3ca0de0573298151dc7")
161         self.assertSequenceEqual(hexenc(k2), "52fb05789a73c7941bc0ae65302a3b8e")
162         self.assertSequenceEqual(
163             hexenc(mac(self.ciph.encrypt, 16, hexdec(self.plaintext))[:8]),
164             "336f4d296059fbe3",
165         )
166
167     def test_mac_applies(self):
168         for _ in range(100):
169             data = urandom(randint(0, 16 * 2))
170             ciph = GOST3412Kuznechik(urandom(32))
171             mac(ciph.encrypt, 16, data)