]> Cypherpunks.ru repositories - pygost.git/blob - pygost/test_gost3413.py
Raise copyright years
[pygost.git] / pygost / test_gost3413.py
1 # coding: utf-8
2 # PyGOST -- Pure Python GOST cryptographic functions library
3 # Copyright (C) 2015-2021 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 random import randint
19 from unittest import TestCase
20
21 from pygost.gost3412 import GOST3412Kuznechik
22 from pygost.gost3412 import GOST3412Magma
23 from pygost.gost3413 import _mac_ks
24 from pygost.gost3413 import acpkm
25 from pygost.gost3413 import acpkm_master
26 from pygost.gost3413 import cbc_decrypt
27 from pygost.gost3413 import cbc_encrypt
28 from pygost.gost3413 import cfb_decrypt
29 from pygost.gost3413 import cfb_encrypt
30 from pygost.gost3413 import ctr
31 from pygost.gost3413 import ctr_acpkm
32 from pygost.gost3413 import ecb_decrypt
33 from pygost.gost3413 import ecb_encrypt
34 from pygost.gost3413 import KEYSIZE
35 from pygost.gost3413 import mac
36 from pygost.gost3413 import mac_acpkm_master
37 from pygost.gost3413 import ofb
38 from pygost.gost3413 import pad2
39 from pygost.gost3413 import unpad2
40 from pygost.utils import hexdec
41 from pygost.utils import hexenc
42 from pygost.utils import strxor
43
44
45 class Pad2Test(TestCase):
46     def test_symmetric(self):
47         for _ in range(100):
48             for blocksize in (GOST3412Magma.blocksize, GOST3412Kuznechik.blocksize):
49                 data = urandom(randint(0, blocksize * 3))
50                 self.assertSequenceEqual(
51                     unpad2(pad2(data, blocksize), blocksize),
52                     data,
53                 )
54
55
56 class GOST3412KuznechikModesTest(TestCase):
57     key = hexdec("8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef")
58     ciph = GOST3412Kuznechik(key)
59     plaintext = ""
60     plaintext += "1122334455667700ffeeddccbbaa9988"
61     plaintext += "00112233445566778899aabbcceeff0a"
62     plaintext += "112233445566778899aabbcceeff0a00"
63     plaintext += "2233445566778899aabbcceeff0a0011"
64     iv = hexdec("1234567890abcef0a1b2c3d4e5f0011223344556677889901213141516171819")
65
66     def test_ecb_vectors(self):
67         ciphtext = ""
68         ciphtext += "7f679d90bebc24305a468d42b9d4edcd"
69         ciphtext += "b429912c6e0032f9285452d76718d08b"
70         ciphtext += "f0ca33549d247ceef3f5a5313bd4b157"
71         ciphtext += "d0b09ccde830b9eb3a02c4c5aa8ada98"
72         self.assertSequenceEqual(
73             hexenc(ecb_encrypt(
74                 self.ciph.encrypt,
75                 GOST3412Kuznechik.blocksize,
76                 hexdec(self.plaintext),
77             )),
78             ciphtext,
79         )
80         self.assertSequenceEqual(
81             hexenc(ecb_decrypt(
82                 self.ciph.decrypt,
83                 GOST3412Kuznechik.blocksize,
84                 hexdec(ciphtext),
85             )),
86             self.plaintext,
87         )
88
89     def test_ecb_symmetric(self):
90         for _ in range(100):
91             pt = pad2(urandom(randint(0, 16 * 2)), GOST3412Kuznechik.blocksize)
92             ciph = GOST3412Kuznechik(urandom(KEYSIZE))
93             ct = ecb_encrypt(ciph.encrypt, GOST3412Kuznechik.blocksize, pt)
94             self.assertSequenceEqual(ecb_decrypt(
95                 ciph.decrypt,
96                 GOST3412Kuznechik.blocksize,
97                 ct,
98             ), pt)
99
100     def test_ctr_vectors(self):
101         ciphtext = ""
102         ciphtext += "f195d8bec10ed1dbd57b5fa240bda1b8"
103         ciphtext += "85eee733f6a13e5df33ce4b33c45dee4"
104         ciphtext += "a5eae88be6356ed3d5e877f13564a3a5"
105         ciphtext += "cb91fab1f20cbab6d1c6d15820bdba73"
106         iv = self.iv[:GOST3412Kuznechik.blocksize // 2]
107         self.assertSequenceEqual(
108             hexenc(ctr(
109                 self.ciph.encrypt,
110                 GOST3412Kuznechik.blocksize,
111                 hexdec(self.plaintext),
112                 iv,
113             )),
114             ciphtext,
115         )
116         self.assertSequenceEqual(
117             hexenc(ctr(
118                 self.ciph.encrypt,
119                 GOST3412Kuznechik.blocksize,
120                 hexdec(ciphtext),
121                 iv,
122             )),
123             self.plaintext,
124         )
125
126     def test_ctr_symmetric(self):
127         for _ in range(100):
128             pt = urandom(randint(0, 16 * 2))
129             iv = urandom(GOST3412Kuznechik.blocksize // 2)
130             ciph = GOST3412Kuznechik(urandom(KEYSIZE))
131             ct = ctr(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv)
132             self.assertSequenceEqual(ctr(
133                 ciph.encrypt,
134                 GOST3412Kuznechik.blocksize,
135                 ct,
136                 iv,
137             ), pt)
138
139     def test_ofb_vectors(self):
140         ciphtext = ""
141         ciphtext += "81800a59b1842b24ff1f795e897abd95"
142         ciphtext += "ed5b47a7048cfab48fb521369d9326bf"
143         ciphtext += "66a257ac3ca0b8b1c80fe7fc10288a13"
144         ciphtext += "203ebbc066138660a0292243f6903150"
145         self.assertSequenceEqual(
146             hexenc(ofb(
147                 self.ciph.encrypt,
148                 GOST3412Kuznechik.blocksize,
149                 hexdec(self.plaintext),
150                 self.iv,
151             )),
152             ciphtext,
153         )
154         self.assertSequenceEqual(
155             hexenc(ofb(
156                 self.ciph.encrypt,
157                 GOST3412Kuznechik.blocksize,
158                 hexdec(ciphtext),
159                 self.iv,
160             )),
161             self.plaintext,
162         )
163
164     def test_ofb_symmetric(self):
165         for _ in range(100):
166             pt = urandom(randint(0, 16 * 2))
167             iv = urandom(GOST3412Kuznechik.blocksize * 2)
168             ciph = GOST3412Kuznechik(urandom(KEYSIZE))
169             ct = ofb(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv)
170             self.assertSequenceEqual(ofb(
171                 ciph.encrypt,
172                 GOST3412Kuznechik.blocksize,
173                 ct,
174                 iv,
175             ), pt)
176
177     def test_ofb_manual(self):
178         iv = [urandom(GOST3412Kuznechik.blocksize) for _ in range(randint(2, 10))]
179         pt = [
180             urandom(GOST3412Kuznechik.blocksize)
181             for _ in range(len(iv), len(iv) + randint(1, 10))
182         ]
183         ciph = GOST3412Kuznechik(urandom(KEYSIZE))
184         r = [ciph.encrypt(i) for i in iv]
185         for i in range(len(pt) - len(iv)):
186             r.append(ciph.encrypt(r[i]))
187         ct = [strxor(g, r) for g, r in zip(pt, r)]
188         self.assertSequenceEqual(
189             ofb(ciph.encrypt, GOST3412Kuznechik.blocksize, b"".join(pt), b"".join(iv)),
190             b"".join(ct),
191         )
192
193     def test_cbc_vectors(self):
194         ciphtext = ""
195         ciphtext += "689972d4a085fa4d90e52e3d6d7dcc27"
196         ciphtext += "2826e661b478eca6af1e8e448d5ea5ac"
197         ciphtext += "fe7babf1e91999e85640e8b0f49d90d0"
198         ciphtext += "167688065a895c631a2d9a1560b63970"
199         self.assertSequenceEqual(
200             hexenc(cbc_encrypt(
201                 self.ciph.encrypt,
202                 GOST3412Kuznechik.blocksize,
203                 hexdec(self.plaintext),
204                 self.iv,
205             )),
206             ciphtext,
207         )
208         self.assertSequenceEqual(
209             hexenc(cbc_decrypt(
210                 self.ciph.decrypt,
211                 GOST3412Kuznechik.blocksize,
212                 hexdec(ciphtext),
213                 self.iv,
214             )),
215             self.plaintext,
216         )
217
218     def test_cbc_symmetric(self):
219         for _ in range(100):
220             pt = pad2(urandom(randint(0, 16 * 2)), GOST3412Kuznechik.blocksize)
221             iv = urandom(GOST3412Kuznechik.blocksize * 2)
222             ciph = GOST3412Kuznechik(urandom(KEYSIZE))
223             ct = cbc_encrypt(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv)
224             self.assertSequenceEqual(cbc_decrypt(
225                 ciph.decrypt,
226                 GOST3412Kuznechik.blocksize,
227                 ct,
228                 iv,
229             ), pt)
230
231     def test_cfb_vectors(self):
232         ciphtext = ""
233         ciphtext += "81800a59b1842b24ff1f795e897abd95"
234         ciphtext += "ed5b47a7048cfab48fb521369d9326bf"
235         ciphtext += "79f2a8eb5cc68d38842d264e97a238b5"
236         ciphtext += "4ffebecd4e922de6c75bd9dd44fbf4d1"
237         self.assertSequenceEqual(
238             hexenc(cfb_encrypt(
239                 self.ciph.encrypt,
240                 GOST3412Kuznechik.blocksize,
241                 hexdec(self.plaintext),
242                 self.iv,
243             )),
244             ciphtext,
245         )
246         self.assertSequenceEqual(
247             hexenc(cfb_decrypt(
248                 self.ciph.encrypt,
249                 GOST3412Kuznechik.blocksize,
250                 hexdec(ciphtext),
251                 self.iv,
252             )),
253             self.plaintext,
254         )
255
256     def test_cfb_symmetric(self):
257         for _ in range(100):
258             pt = urandom(randint(0, 16 * 2))
259             iv = urandom(GOST3412Kuznechik.blocksize * 2)
260             ciph = GOST3412Kuznechik(urandom(KEYSIZE))
261             ct = cfb_encrypt(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv)
262             self.assertSequenceEqual(cfb_decrypt(
263                 ciph.encrypt,
264                 GOST3412Kuznechik.blocksize,
265                 ct,
266                 iv,
267             ), pt)
268
269     def test_mac_vectors(self):
270         k1, k2 = _mac_ks(self.ciph.encrypt, GOST3412Kuznechik.blocksize)
271         self.assertSequenceEqual(hexenc(k1), "297d82bc4d39e3ca0de0573298151dc7")
272         self.assertSequenceEqual(hexenc(k2), "52fb05789a73c7941bc0ae65302a3b8e")
273         self.assertSequenceEqual(
274             hexenc(mac(
275                 self.ciph.encrypt,
276                 GOST3412Kuznechik.blocksize,
277                 hexdec(self.plaintext),
278             )[:8]),
279             "336f4d296059fbe3",
280         )
281
282     def test_mac_applies(self):
283         for _ in range(100):
284             data = urandom(randint(0, 16 * 2))
285             ciph = GOST3412Kuznechik(urandom(KEYSIZE))
286             mac(ciph.encrypt, GOST3412Kuznechik.blocksize, data)
287
288
289 class GOST3412MagmaModesTest(TestCase):
290     key = hexdec("ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
291     ciph = GOST3412Magma(key)
292     plaintext = ""
293     plaintext += "92def06b3c130a59"
294     plaintext += "db54c704f8189d20"
295     plaintext += "4a98fb2e67a8024c"
296     plaintext += "8912409b17b57e41"
297     iv = hexdec("1234567890abcdef234567890abcdef134567890abcdef12")
298
299     def test_ecb_vectors(self):
300         ciphtext = ""
301         ciphtext += "2b073f0494f372a0"
302         ciphtext += "de70e715d3556e48"
303         ciphtext += "11d8d9e9eacfbc1e"
304         ciphtext += "7c68260996c67efb"
305         self.assertSequenceEqual(
306             hexenc(ecb_encrypt(
307                 self.ciph.encrypt,
308                 GOST3412Magma.blocksize,
309                 hexdec(self.plaintext),
310             )),
311             ciphtext,
312         )
313         self.assertSequenceEqual(
314             hexenc(ecb_decrypt(
315                 self.ciph.decrypt,
316                 GOST3412Magma.blocksize,
317                 hexdec(ciphtext),
318             )),
319             self.plaintext,
320         )
321
322     def test_ecb_symmetric(self):
323         for _ in range(100):
324             pt = pad2(urandom(randint(0, 16 * 2)), 16)
325             ciph = GOST3412Magma(urandom(KEYSIZE))
326             ct = ecb_encrypt(ciph.encrypt, GOST3412Magma.blocksize, pt)
327             self.assertSequenceEqual(ecb_decrypt(
328                 ciph.decrypt,
329                 GOST3412Magma.blocksize,
330                 ct,
331             ), pt)
332
333     def test_ctr_vectors(self):
334         ciphtext = ""
335         ciphtext += "4e98110c97b7b93c"
336         ciphtext += "3e250d93d6e85d69"
337         ciphtext += "136d868807b2dbef"
338         ciphtext += "568eb680ab52a12d"
339         iv = self.iv[:4]
340         self.assertSequenceEqual(
341             hexenc(ctr(
342                 self.ciph.encrypt,
343                 GOST3412Magma.blocksize,
344                 hexdec(self.plaintext),
345                 iv,
346             )),
347             ciphtext,
348         )
349         self.assertSequenceEqual(
350             hexenc(ctr(
351                 self.ciph.encrypt,
352                 GOST3412Magma.blocksize,
353                 hexdec(ciphtext),
354                 iv,
355             )),
356             self.plaintext,
357         )
358
359     def test_ctr_symmetric(self):
360         for _ in range(100):
361             pt = urandom(randint(0, 16 * 2))
362             iv = urandom(GOST3412Magma.blocksize // 2)
363             ciph = GOST3412Magma(urandom(KEYSIZE))
364             ct = ctr(ciph.encrypt, GOST3412Magma.blocksize, pt, iv)
365             self.assertSequenceEqual(ctr(
366                 ciph.encrypt,
367                 GOST3412Magma.blocksize,
368                 ct,
369                 iv,
370             ), pt)
371
372     def test_ofb_vectors(self):
373         iv = self.iv[:16]
374         ciphtext = ""
375         ciphtext += "db37e0e266903c83"
376         ciphtext += "0d46644c1f9a089c"
377         ciphtext += "a0f83062430e327e"
378         ciphtext += "c824efb8bd4fdb05"
379         self.assertSequenceEqual(
380             hexenc(ofb(
381                 self.ciph.encrypt,
382                 GOST3412Magma.blocksize,
383                 hexdec(self.plaintext),
384                 iv,
385             )),
386             ciphtext,
387         )
388         self.assertSequenceEqual(
389             hexenc(ofb(
390                 self.ciph.encrypt,
391                 GOST3412Magma.blocksize,
392                 hexdec(ciphtext),
393                 iv,
394             )),
395             self.plaintext,
396         )
397
398     def test_ofb_symmetric(self):
399         for _ in range(100):
400             pt = urandom(randint(0, 16 * 2))
401             iv = urandom(GOST3412Magma.blocksize * 2)
402             ciph = GOST3412Magma(urandom(KEYSIZE))
403             ct = ofb(ciph.encrypt, GOST3412Magma.blocksize, pt, iv)
404             self.assertSequenceEqual(ofb(
405                 ciph.encrypt,
406                 GOST3412Magma.blocksize,
407                 ct,
408                 iv,
409             ), pt)
410
411     def test_cbc_vectors(self):
412         ciphtext = ""
413         ciphtext += "96d1b05eea683919"
414         ciphtext += "aff76129abb937b9"
415         ciphtext += "5058b4a1c4bc0019"
416         ciphtext += "20b78b1a7cd7e667"
417         self.assertSequenceEqual(
418             hexenc(cbc_encrypt(
419                 self.ciph.encrypt,
420                 GOST3412Magma.blocksize,
421                 hexdec(self.plaintext),
422                 self.iv,
423             )),
424             ciphtext,
425         )
426         self.assertSequenceEqual(
427             hexenc(cbc_decrypt(
428                 self.ciph.decrypt,
429                 GOST3412Magma.blocksize,
430                 hexdec(ciphtext),
431                 self.iv,
432             )),
433             self.plaintext,
434         )
435
436     def test_cbc_symmetric(self):
437         for _ in range(100):
438             pt = pad2(urandom(randint(0, 16 * 2)), 16)
439             iv = urandom(GOST3412Magma.blocksize * 2)
440             ciph = GOST3412Magma(urandom(KEYSIZE))
441             ct = cbc_encrypt(ciph.encrypt, GOST3412Magma.blocksize, pt, iv)
442             self.assertSequenceEqual(cbc_decrypt(
443                 ciph.decrypt,
444                 GOST3412Magma.blocksize,
445                 ct,
446                 iv,
447             ), pt)
448
449     def test_cfb_vectors(self):
450         iv = self.iv[:16]
451         ciphtext = ""
452         ciphtext += "db37e0e266903c83"
453         ciphtext += "0d46644c1f9a089c"
454         ciphtext += "24bdd2035315d38b"
455         ciphtext += "bcc0321421075505"
456         self.assertSequenceEqual(
457             hexenc(cfb_encrypt(
458                 self.ciph.encrypt,
459                 GOST3412Magma.blocksize,
460                 hexdec(self.plaintext),
461                 iv,
462             )),
463             ciphtext,
464         )
465         self.assertSequenceEqual(
466             hexenc(cfb_decrypt(
467                 self.ciph.encrypt,
468                 GOST3412Magma.blocksize,
469                 hexdec(ciphtext),
470                 iv,
471             )),
472             self.plaintext,
473         )
474
475     def test_cfb_symmetric(self):
476         for _ in range(100):
477             pt = urandom(randint(0, 16 * 2))
478             iv = urandom(GOST3412Magma.blocksize * 2)
479             ciph = GOST3412Magma(urandom(KEYSIZE))
480             ct = cfb_encrypt(ciph.encrypt, GOST3412Magma.blocksize, pt, iv)
481             self.assertSequenceEqual(cfb_decrypt(
482                 ciph.encrypt,
483                 GOST3412Magma.blocksize,
484                 ct,
485                 iv,
486             ), pt)
487
488     def test_mac_vectors(self):
489         k1, k2 = _mac_ks(self.ciph.encrypt, GOST3412Magma.blocksize)
490         self.assertSequenceEqual(hexenc(k1), "5f459b3342521424")
491         self.assertSequenceEqual(hexenc(k2), "be8b366684a42848")
492         self.assertSequenceEqual(
493             hexenc(mac(
494                 self.ciph.encrypt,
495                 GOST3412Magma.blocksize,
496                 hexdec(self.plaintext),
497             )[:4]),
498             "154e7210",
499         )
500
501     def test_mac_applies(self):
502         for _ in range(100):
503             data = urandom(randint(0, 16 * 2))
504             ciph = GOST3412Magma(urandom(KEYSIZE))
505             mac(ciph.encrypt, GOST3412Magma.blocksize, data)
506
507
508 class TestVectorACPKM(TestCase):
509     """Test vectors from Ð  1323565.1.017-2018
510     """
511     key = hexdec("8899AABBCCDDEEFF0011223344556677FEDCBA98765432100123456789ABCDEF")
512
513     def test_magma_ctr_acpkm(self):
514         key = acpkm(GOST3412Magma(self.key).encrypt, GOST3412Magma.blocksize)
515         self.assertSequenceEqual(key, hexdec("863EA017842C3D372B18A85A28E2317D74BEFC107720DE0C9E8AB974ABD00CA0"))
516         key = acpkm(GOST3412Magma(key).encrypt, GOST3412Magma.blocksize)
517         self.assertSequenceEqual(key, hexdec("49A5E2677DE555982B8AD5E826652D17EEC847BF5B3997A81CF7FE7F1187BD27"))
518         key = acpkm(GOST3412Magma(key).encrypt, GOST3412Magma.blocksize)
519         self.assertSequenceEqual(key, hexdec("3256BF3F97B5667426A9FB1C5EAABE41893CCDD5A868F9B63B0AA90720FA43C4"))
520
521     def test_magma_ctr(self):
522         encrypter = GOST3412Magma(self.key).encrypt
523         plaintext = hexdec("""
524 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
525 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
526 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
527 22 33 44 55 66 77 88 99
528         """.replace("\n", "").replace(" ", ""))
529         iv = hexdec("12345678")
530         ciphertext = hexdec("""
531 2A B8 1D EE EB 1E 4C AB 68 E1 04 C4 BD 6B 94 EA
532 C7 2C 67 AF 6C 2E 5B 6B 0E AF B6 17 70 F1 B3 2E
533 A1 AE 71 14 9E ED 13 82 AB D4 67 18 06 72 EC 6F
534 84 A2 F1 5B 3F CA 72 C1
535         """.replace("\n", "").replace(" ", ""))
536         self.assertSequenceEqual(
537             ctr_acpkm(
538                 GOST3412Magma,
539                 encrypter,
540                 bs=GOST3412Magma.blocksize,
541                 section_size=GOST3412Magma.blocksize * 2,
542                 data=plaintext,
543                 iv=iv
544             ),
545             ciphertext,
546         )
547         self.assertSequenceEqual(
548             ctr_acpkm(
549                 GOST3412Magma,
550                 encrypter,
551                 bs=GOST3412Magma.blocksize,
552                 section_size=GOST3412Magma.blocksize * 2,
553                 data=ciphertext,
554                 iv=iv
555             ),
556             plaintext,
557         )
558
559     def test_kuznechik_ctr_acpkm(self):
560         key = acpkm(GOST3412Kuznechik(self.key).encrypt, GOST3412Kuznechik.blocksize)
561         self.assertSequenceEqual(key, hexdec("2666ED40AE687811745CA0B448F57A7B390ADB5780307E8E9659AC403AE60C60"))
562         key = acpkm(GOST3412Kuznechik(key).encrypt, GOST3412Kuznechik.blocksize)
563         self.assertSequenceEqual(key, hexdec("BB3DD5402E999B7A3DEBB0DB45448EC530F07365DFEE3ABA8415F77AC8F34CE8"))
564         key = acpkm(GOST3412Kuznechik(key).encrypt, GOST3412Kuznechik.blocksize)
565         self.assertSequenceEqual(key, hexdec("23362FD553CAD2178299A5B5A2D4722E3BB83C730A8BF57CE2DD004017F8C565"))
566
567     def test_kuznechik_ctr(self):
568         encrypter = GOST3412Kuznechik(self.key).encrypt
569         iv = hexdec("1234567890ABCEF0")
570         plaintext = hexdec("""
571 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
572 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
573 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
574 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11
575 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22
576 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33
577 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33 44
578         """.replace("\n", "").replace(" ", ""))
579         ciphertext = hexdec("""
580 F1 95 D8 BE C1 0E D1 DB D5 7B 5F A2 40 BD A1 B8
581 85 EE E7 33 F6 A1 3E 5D F3 3C E4 B3 3C 45 DE E4
582 4B CE EB 8F 64 6F 4C 55 00 17 06 27 5E 85 E8 00
583 58 7C 4D F5 68 D0 94 39 3E 48 34 AF D0 80 50 46
584 CF 30 F5 76 86 AE EC E1 1C FC 6C 31 6B 8A 89 6E
585 DF FD 07 EC 81 36 36 46 0C 4F 3B 74 34 23 16 3E
586 64 09 A9 C2 82 FA C8 D4 69 D2 21 E7 FB D6 DE 5D
587         """.replace("\n", "").replace(" ", ""))
588         self.assertSequenceEqual(
589             ctr_acpkm(
590                 GOST3412Kuznechik,
591                 encrypter,
592                 bs=GOST3412Kuznechik.blocksize,
593                 section_size=GOST3412Kuznechik.blocksize * 2,
594                 data=plaintext,
595                 iv=iv,
596             ),
597             ciphertext,
598         )
599         self.assertSequenceEqual(
600             ctr_acpkm(
601                 GOST3412Kuznechik,
602                 encrypter,
603                 bs=GOST3412Kuznechik.blocksize,
604                 section_size=GOST3412Kuznechik.blocksize * 2,
605                 data=ciphertext,
606                 iv=iv,
607             ),
608             plaintext,
609         )
610
611     def test_magma_omac_1_5_blocks(self):
612         encrypter = GOST3412Magma(self.key).encrypt
613         key_section_size = 640 // 8
614         self.assertSequenceEqual(
615             acpkm_master(
616                 GOST3412Magma,
617                 encrypter,
618                 key_section_size=key_section_size,
619                 bs=GOST3412Magma.blocksize,
620                 keymat_len=KEYSIZE + GOST3412Magma.blocksize,
621             ),
622             hexdec("0DF2F5273DA328932AC49D81D36B2558A50DBF9BBCAC74A614B2CCB2F1CBCD8A70638E3DE8B3571E"),
623         )
624         text = hexdec("1122334455667700FFEEDDCC")
625         self.assertSequenceEqual(
626             mac_acpkm_master(
627                 GOST3412Magma,
628                 encrypter,
629                 key_section_size,
630                 section_size=GOST3412Magma.blocksize * 2,
631                 bs=GOST3412Magma.blocksize,
632                 data=text,
633             ),
634             hexdec("A0540E3730ACBCF3"),
635         )
636
637     def test_magma_omac_5_blocks(self):
638         encrypter = GOST3412Magma(self.key).encrypt
639         key_section_size = 640 // 8
640         self.assertSequenceEqual(
641             acpkm_master(
642                 GOST3412Magma,
643                 encrypter,
644                 key_section_size=key_section_size,
645                 bs=GOST3412Magma.blocksize,
646                 keymat_len=3 * (KEYSIZE + GOST3412Magma.blocksize),
647             ),
648             hexdec("""
649 0D F2 F5 27 3D A3 28 93 2A C4 9D 81 D3 6B 25 58
650 A5 0D BF 9B BC AC 74 A6 14 B2 CC B2 F1 CB CD 8A
651 70 63 8E 3D E8 B3 57 1E 8D 38 26 D5 5E 63 A1 67
652 E2 40 66 40 54 7B 9F 1F 5F 2B 43 61 2A AE AF DA
653 18 0B AC 86 04 DF A6 FE 53 C2 CE 27 0E 9C 9F 52
654 68 D0 FD BF E1 A3 BD D9 BE 5B 96 D0 A1 20 23 48
655 6E F1 71 0F 92 4A E0 31 30 52 CB 5F CA 0B 79 1E
656 1B AB E8 57 6D 0F E3 A8
657             """.replace("\n", "").replace(" ", "")),
658         )
659         text = hexdec("""
660 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
661 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
662 11 22 33 44 55 66 77 88
663         """.replace("\n", "").replace(" ", ""))
664         self.assertSequenceEqual(
665             mac_acpkm_master(
666                 GOST3412Magma,
667                 encrypter,
668                 key_section_size,
669                 section_size=GOST3412Magma.blocksize * 2,
670                 bs=GOST3412Magma.blocksize,
671                 data=text,
672             ),
673             hexdec("34008DAD5496BB8E"),
674         )
675
676     def test_kuznechik_omac_1_5_blocks(self):
677         encrypter = GOST3412Kuznechik(self.key).encrypt
678         key_section_size = 768 // 8
679         self.assertSequenceEqual(
680             acpkm_master(
681                 GOST3412Kuznechik,
682                 encrypter,
683                 key_section_size=key_section_size,
684                 bs=GOST3412Kuznechik.blocksize,
685                 keymat_len=KEYSIZE + GOST3412Kuznechik.blocksize,
686             ),
687             hexdec("""
688 0C AB F1 F2 EF BC 4A C1 60 48 DF 1A 24 C6 05 B2
689 C0 D1 67 3D 75 86 A8 EC 0D D4 2C 45 A4 F9 5B AE
690 0F 2E 26 17 E4 71 48 68 0F C3 E6 17 8D F2 C1 37
691             """.replace("\n", "").replace(" ", ""))
692         )
693         text = hexdec("""
694 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
695 00 11 22 33 44 55 66 77
696         """.replace("\n", "").replace(" ", ""))
697         self.assertSequenceEqual(
698             mac_acpkm_master(
699                 GOST3412Kuznechik,
700                 encrypter,
701                 key_section_size,
702                 section_size=GOST3412Kuznechik.blocksize * 2,
703                 bs=GOST3412Kuznechik.blocksize,
704                 data=text,
705             ),
706             hexdec("B5367F47B62B995EEB2A648C5843145E"),
707         )
708
709     def test_kuznechik_omac_5_blocks(self):
710         encrypter = GOST3412Kuznechik(self.key).encrypt
711         key_section_size = 768 // 8
712         self.assertSequenceEqual(
713             acpkm_master(
714                 GOST3412Kuznechik,
715                 encrypter,
716                 key_section_size=key_section_size,
717                 bs=GOST3412Kuznechik.blocksize,
718                 keymat_len=3 * (KEYSIZE + GOST3412Kuznechik.blocksize),
719             ),
720             hexdec("""
721 0C AB F1 F2 EF BC 4A C1 60 48 DF 1A 24 C6 05 B2
722 C0 D1 67 3D 75 86 A8 EC 0D D4 2C 45 A4 F9 5B AE
723 0F 2E 26 17 E4 71 48 68 0F C3 E6 17 8D F2 C1 37
724 C9 DD A8 9C FF A4 91 FE AD D9 B3 EA B7 03 BB 31
725 BC 7E 92 7F 04 94 72 9F 51 B4 9D 3D F9 C9 46 08
726 00 FB BC F5 ED EE 61 0E A0 2F 01 09 3C 7B C7 42
727 D7 D6 27 15 01 B1 77 77 52 63 C2 A3 49 5A 83 18
728 A8 1C 79 A0 4F 29 66 0E A3 FD A8 74 C6 30 79 9E
729 14 2C 57 79 14 FE A9 0D 3B C2 50 2E 83 36 85 D9
730             """.replace("\n", "").replace(" ", "")),
731         )
732         text = hexdec("""
733 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
734 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
735 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
736 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11
737 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22
738         """.replace("\n", "").replace(" ", ""))
739         self.assertSequenceEqual(
740             mac_acpkm_master(
741                 GOST3412Kuznechik,
742                 encrypter,
743                 key_section_size,
744                 section_size=GOST3412Kuznechik.blocksize * 2,
745                 bs=GOST3412Kuznechik.blocksize,
746                 data=text,
747             ),
748             hexdec("FBB8DCEE45BEA67C35F58C5700898E5D"),
749         )