]> Cypherpunks.ru repositories - pygost.git/blob - pygost/test_gost3413.py
f1574eef6f17c73e247b967d199534dbc884b5a7
[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.gost3412 import GOST3412Magma
7 from pygost.gost3413 import _mac_ks
8 from pygost.gost3413 import cbc_decrypt
9 from pygost.gost3413 import cbc_encrypt
10 from pygost.gost3413 import cfb_decrypt
11 from pygost.gost3413 import cfb_encrypt
12 from pygost.gost3413 import ctr
13 from pygost.gost3413 import ecb_decrypt
14 from pygost.gost3413 import ecb_encrypt
15 from pygost.gost3413 import mac
16 from pygost.gost3413 import ofb
17 from pygost.gost3413 import pad2
18 from pygost.gost3413 import unpad2
19 from pygost.utils import hexdec
20 from pygost.utils import hexenc
21
22
23 class Pad2Test(TestCase):
24     def test_symmetric(self):
25         for _ in range(100):
26             for blocksize in (8, 16):
27                 data = urandom(randint(0, blocksize * 3))
28                 self.assertSequenceEqual(
29                     unpad2(pad2(data, blocksize), blocksize),
30                     data,
31                 )
32
33
34 class GOST3412KuznechikModesTest(TestCase):
35     key = hexdec("8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef")
36     ciph = GOST3412Kuznechik(key)
37     plaintext = ""
38     plaintext += "1122334455667700ffeeddccbbaa9988"
39     plaintext += "00112233445566778899aabbcceeff0a"
40     plaintext += "112233445566778899aabbcceeff0a00"
41     plaintext += "2233445566778899aabbcceeff0a0011"
42     iv = hexdec("1234567890abcef0a1b2c3d4e5f0011223344556677889901213141516171819")
43
44     def test_ecb_vectors(self):
45         ciphtext = ""
46         ciphtext += "7f679d90bebc24305a468d42b9d4edcd"
47         ciphtext += "b429912c6e0032f9285452d76718d08b"
48         ciphtext += "f0ca33549d247ceef3f5a5313bd4b157"
49         ciphtext += "d0b09ccde830b9eb3a02c4c5aa8ada98"
50         self.assertSequenceEqual(
51             hexenc(ecb_encrypt(self.ciph.encrypt, 16, hexdec(self.plaintext))),
52             ciphtext,
53         )
54         self.assertSequenceEqual(
55             hexenc(ecb_decrypt(self.ciph.decrypt, 16, hexdec(ciphtext))),
56             self.plaintext,
57         )
58
59     def test_ecb_symmetric(self):
60         for _ in range(100):
61             pt = pad2(urandom(randint(0, 16 * 2)), 16)
62             ciph = GOST3412Kuznechik(urandom(32))
63             ct = ecb_encrypt(ciph.encrypt, 16, pt)
64             self.assertSequenceEqual(ecb_decrypt(ciph.decrypt, 16, ct), pt)
65
66     def test_ctr_vectors(self):
67         ciphtext = ""
68         ciphtext += "f195d8bec10ed1dbd57b5fa240bda1b8"
69         ciphtext += "85eee733f6a13e5df33ce4b33c45dee4"
70         ciphtext += "a5eae88be6356ed3d5e877f13564a3a5"
71         ciphtext += "cb91fab1f20cbab6d1c6d15820bdba73"
72         iv = self.iv[:8]
73         self.assertSequenceEqual(
74             hexenc(ctr(self.ciph.encrypt, 16, hexdec(self.plaintext), iv)),
75             ciphtext,
76         )
77         self.assertSequenceEqual(
78             hexenc(ctr(self.ciph.encrypt, 16, hexdec(ciphtext), iv)),
79             self.plaintext,
80         )
81
82     def test_ctr_symmetric(self):
83         for _ in range(100):
84             pt = urandom(randint(0, 16 * 2))
85             iv = urandom(8)
86             ciph = GOST3412Kuznechik(urandom(32))
87             ct = ctr(ciph.encrypt, 16, pt, iv)
88             self.assertSequenceEqual(ctr(ciph.encrypt, 16, ct, iv), pt)
89
90     def test_ofb_vectors(self):
91         ciphtext = ""
92         ciphtext += "81800a59b1842b24ff1f795e897abd95"
93         ciphtext += "ed5b47a7048cfab48fb521369d9326bf"
94         ciphtext += "66a257ac3ca0b8b1c80fe7fc10288a13"
95         ciphtext += "203ebbc066138660a0292243f6903150"
96         self.assertSequenceEqual(
97             hexenc(ofb(self.ciph.encrypt, 16, hexdec(self.plaintext), self.iv)),
98             ciphtext,
99         )
100         self.assertSequenceEqual(
101             hexenc(ofb(self.ciph.encrypt, 16, hexdec(ciphtext), self.iv)),
102             self.plaintext,
103         )
104
105     def test_ofb_symmetric(self):
106         for _ in range(100):
107             pt = urandom(randint(0, 16 * 2))
108             iv = urandom(16 * 2)
109             ciph = GOST3412Kuznechik(urandom(32))
110             ct = ofb(ciph.encrypt, 16, pt, iv)
111             self.assertSequenceEqual(ofb(ciph.encrypt, 16, ct, iv), pt)
112
113     def test_cbc_vectors(self):
114         ciphtext = ""
115         ciphtext += "689972d4a085fa4d90e52e3d6d7dcc27"
116         ciphtext += "2826e661b478eca6af1e8e448d5ea5ac"
117         ciphtext += "fe7babf1e91999e85640e8b0f49d90d0"
118         ciphtext += "167688065a895c631a2d9a1560b63970"
119         self.assertSequenceEqual(
120             hexenc(cbc_encrypt(self.ciph.encrypt, 16, hexdec(self.plaintext), self.iv)),
121             ciphtext,
122         )
123         self.assertSequenceEqual(
124             hexenc(cbc_decrypt(self.ciph.decrypt, 16, hexdec(ciphtext), self.iv)),
125             self.plaintext,
126         )
127
128     def test_cbc_symmetric(self):
129         for _ in range(100):
130             pt = pad2(urandom(randint(0, 16 * 2)), 16)
131             iv = urandom(16 * 2)
132             ciph = GOST3412Kuznechik(urandom(32))
133             ct = cbc_encrypt(ciph.encrypt, 16, pt, iv)
134             self.assertSequenceEqual(cbc_decrypt(ciph.decrypt, 16, ct, iv), pt)
135
136     def test_cfb_vectors(self):
137         ciphtext = ""
138         ciphtext += "81800a59b1842b24ff1f795e897abd95"
139         ciphtext += "ed5b47a7048cfab48fb521369d9326bf"
140         ciphtext += "79f2a8eb5cc68d38842d264e97a238b5"
141         ciphtext += "4ffebecd4e922de6c75bd9dd44fbf4d1"
142         self.assertSequenceEqual(
143             hexenc(cfb_encrypt(self.ciph.encrypt, 16, hexdec(self.plaintext), self.iv)),
144             ciphtext,
145         )
146         self.assertSequenceEqual(
147             hexenc(cfb_decrypt(self.ciph.encrypt, 16, hexdec(ciphtext), self.iv)),
148             self.plaintext,
149         )
150
151     def test_cfb_symmetric(self):
152         for _ in range(100):
153             pt = urandom(randint(0, 16 * 2))
154             iv = urandom(16 * 2)
155             ciph = GOST3412Kuznechik(urandom(32))
156             ct = cfb_encrypt(ciph.encrypt, 16, pt, iv)
157             self.assertSequenceEqual(cfb_decrypt(ciph.encrypt, 16, ct, iv), pt)
158
159     def test_mac_vectors(self):
160         k1, k2 = _mac_ks(self.ciph.encrypt, 16)
161         self.assertSequenceEqual(hexenc(k1), "297d82bc4d39e3ca0de0573298151dc7")
162         self.assertSequenceEqual(hexenc(k2), "52fb05789a73c7941bc0ae65302a3b8e")
163         self.assertSequenceEqual(
164             hexenc(mac(self.ciph.encrypt, 16, hexdec(self.plaintext))[:8]),
165             "336f4d296059fbe3",
166         )
167
168     def test_mac_applies(self):
169         for _ in range(100):
170             data = urandom(randint(0, 16 * 2))
171             ciph = GOST3412Kuznechik(urandom(32))
172             mac(ciph.encrypt, 16, data)
173
174
175 class GOST3412MagmaModesTest(TestCase):
176     key = hexdec("ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
177     ciph = GOST3412Magma(key)
178     plaintext = ""
179     plaintext += "92def06b3c130a59"
180     plaintext += "db54c704f8189d20"
181     plaintext += "4a98fb2e67a8024c"
182     plaintext += "8912409b17b57e41"
183     iv = hexdec("1234567890abcdef234567890abcdef134567890abcdef12")
184
185     def test_ecb_vectors(self):
186         ciphtext = ""
187         ciphtext += "2b073f0494f372a0"
188         ciphtext += "de70e715d3556e48"
189         ciphtext += "11d8d9e9eacfbc1e"
190         ciphtext += "7c68260996c67efb"
191         self.assertSequenceEqual(
192             hexenc(ecb_encrypt(self.ciph.encrypt, 8, hexdec(self.plaintext))),
193             ciphtext,
194         )
195         self.assertSequenceEqual(
196             hexenc(ecb_decrypt(self.ciph.decrypt, 8, hexdec(ciphtext))),
197             self.plaintext,
198         )
199
200     def test_ecb_symmetric(self):
201         for _ in range(100):
202             pt = pad2(urandom(randint(0, 16 * 2)), 16)
203             ciph = GOST3412Magma(urandom(32))
204             ct = ecb_encrypt(ciph.encrypt, 8, pt)
205             self.assertSequenceEqual(ecb_decrypt(ciph.decrypt, 8, ct), pt)
206
207     def test_ctr_vectors(self):
208         ciphtext = ""
209         ciphtext += "4e98110c97b7b93c"
210         ciphtext += "3e250d93d6e85d69"
211         ciphtext += "136d868807b2dbef"
212         ciphtext += "568eb680ab52a12d"
213         iv = self.iv[:4]
214         self.assertSequenceEqual(
215             hexenc(ctr(self.ciph.encrypt, 8, hexdec(self.plaintext), iv)),
216             ciphtext,
217         )
218         self.assertSequenceEqual(
219             hexenc(ctr(self.ciph.encrypt, 8, hexdec(ciphtext), iv)),
220             self.plaintext,
221         )
222
223     def test_ctr_symmetric(self):
224         for _ in range(100):
225             pt = urandom(randint(0, 16 * 2))
226             iv = urandom(4)
227             ciph = GOST3412Magma(urandom(32))
228             ct = ctr(ciph.encrypt, 8, pt, iv)
229             self.assertSequenceEqual(ctr(ciph.encrypt, 8, ct, iv), pt)
230
231     def test_ofb_vectors(self):
232         iv = self.iv[:16]
233         ciphtext = ""
234         ciphtext += "db37e0e266903c83"
235         ciphtext += "0d46644c1f9a089c"
236         ciphtext += "a0f83062430e327e"
237         ciphtext += "c824efb8bd4fdb05"
238         self.assertSequenceEqual(
239             hexenc(ofb(self.ciph.encrypt, 8, hexdec(self.plaintext), iv)),
240             ciphtext,
241         )
242         self.assertSequenceEqual(
243             hexenc(ofb(self.ciph.encrypt, 8, hexdec(ciphtext), iv)),
244             self.plaintext,
245         )
246
247     def test_ofb_symmetric(self):
248         for _ in range(100):
249             pt = urandom(randint(0, 16 * 2))
250             iv = urandom(8 * 2)
251             ciph = GOST3412Magma(urandom(32))
252             ct = ofb(ciph.encrypt, 8, pt, iv)
253             self.assertSequenceEqual(ofb(ciph.encrypt, 8, ct, iv), pt)
254
255     def test_cbc_vectors(self):
256         ciphtext = ""
257         ciphtext += "96d1b05eea683919"
258         ciphtext += "aff76129abb937b9"
259         ciphtext += "5058b4a1c4bc0019"
260         ciphtext += "20b78b1a7cd7e667"
261         self.assertSequenceEqual(
262             hexenc(cbc_encrypt(self.ciph.encrypt, 8, hexdec(self.plaintext), self.iv)),
263             ciphtext,
264         )
265         self.assertSequenceEqual(
266             hexenc(cbc_decrypt(self.ciph.decrypt, 8, hexdec(ciphtext), self.iv)),
267             self.plaintext,
268         )
269
270     def test_cbc_symmetric(self):
271         for _ in range(100):
272             pt = pad2(urandom(randint(0, 16 * 2)), 16)
273             iv = urandom(8 * 2)
274             ciph = GOST3412Magma(urandom(32))
275             ct = cbc_encrypt(ciph.encrypt, 8, pt, iv)
276             self.assertSequenceEqual(cbc_decrypt(ciph.decrypt, 8, ct, iv), pt)
277
278     def test_cfb_vectors(self):
279         iv = self.iv[:16]
280         ciphtext = ""
281         ciphtext += "db37e0e266903c83"
282         ciphtext += "0d46644c1f9a089c"
283         ciphtext += "24bdd2035315d38b"
284         ciphtext += "bcc0321421075505"
285         self.assertSequenceEqual(
286             hexenc(cfb_encrypt(self.ciph.encrypt, 8, hexdec(self.plaintext), iv)),
287             ciphtext,
288         )
289         self.assertSequenceEqual(
290             hexenc(cfb_decrypt(self.ciph.encrypt, 8, hexdec(ciphtext), iv)),
291             self.plaintext,
292         )
293
294     def test_cfb_symmetric(self):
295         for _ in range(100):
296             pt = urandom(randint(0, 16 * 2))
297             iv = urandom(8 * 2)
298             ciph = GOST3412Magma(urandom(32))
299             ct = cfb_encrypt(ciph.encrypt, 8, pt, iv)
300             self.assertSequenceEqual(cfb_decrypt(ciph.encrypt, 8, ct, iv), pt)
301
302     def test_mac_vectors(self):
303         k1, k2 = _mac_ks(self.ciph.encrypt, 8)
304         self.assertSequenceEqual(hexenc(k1), "5f459b3342521424")
305         self.assertSequenceEqual(hexenc(k2), "be8b366684a42848")
306         self.assertSequenceEqual(
307             hexenc(mac(self.ciph.encrypt, 8, hexdec(self.plaintext))[:4]),
308             "154e7210",
309         )
310
311     def test_mac_applies(self):
312         for _ in range(100):
313             data = urandom(randint(0, 16 * 2))
314             ciph = GOST3412Magma(urandom(32))
315             mac(ciph.encrypt, 8, data)