2 # PyGOST -- Pure Python GOST cryptographic functions library
3 # Copyright (C) 2015-2023 Sergey Matveev <stargrave@stargrave.org>
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.
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.
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/>.
17 from os import urandom
18 from random import randint
19 from unittest import TestCase
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 pad_iso10126
40 from pygost.gost3413 import unpad2
41 from pygost.gost3413 import unpad_iso10126
42 from pygost.utils import hexdec
43 from pygost.utils import hexenc
44 from pygost.utils import strxor
47 class Pad2Test(TestCase):
48 def test_symmetric(self):
50 for blocksize in (GOST3412Magma.blocksize, GOST3412Kuznechik.blocksize):
51 data = urandom(randint(0, blocksize * 3))
52 self.assertSequenceEqual(
53 unpad2(pad2(data, blocksize), blocksize),
58 class GOST3412KuznechikModesTest(TestCase):
59 key = hexdec("8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef")
60 ciph = GOST3412Kuznechik(key)
62 plaintext += "1122334455667700ffeeddccbbaa9988"
63 plaintext += "00112233445566778899aabbcceeff0a"
64 plaintext += "112233445566778899aabbcceeff0a00"
65 plaintext += "2233445566778899aabbcceeff0a0011"
66 iv = hexdec("1234567890abcef0a1b2c3d4e5f0011223344556677889901213141516171819")
68 def test_ecb_vectors(self):
70 ciphtext += "7f679d90bebc24305a468d42b9d4edcd"
71 ciphtext += "b429912c6e0032f9285452d76718d08b"
72 ciphtext += "f0ca33549d247ceef3f5a5313bd4b157"
73 ciphtext += "d0b09ccde830b9eb3a02c4c5aa8ada98"
74 self.assertSequenceEqual(
77 GOST3412Kuznechik.blocksize,
78 hexdec(self.plaintext),
82 self.assertSequenceEqual(
85 GOST3412Kuznechik.blocksize,
91 def test_ecb_symmetric(self):
93 pt = pad2(urandom(randint(0, 16 * 2)), GOST3412Kuznechik.blocksize)
94 ciph = GOST3412Kuznechik(urandom(KEYSIZE))
95 ct = ecb_encrypt(ciph.encrypt, GOST3412Kuznechik.blocksize, pt)
96 self.assertSequenceEqual(ecb_decrypt(
98 GOST3412Kuznechik.blocksize,
102 def test_ctr_vectors(self):
104 ciphtext += "f195d8bec10ed1dbd57b5fa240bda1b8"
105 ciphtext += "85eee733f6a13e5df33ce4b33c45dee4"
106 ciphtext += "a5eae88be6356ed3d5e877f13564a3a5"
107 ciphtext += "cb91fab1f20cbab6d1c6d15820bdba73"
108 iv = self.iv[:GOST3412Kuznechik.blocksize // 2]
109 self.assertSequenceEqual(
112 GOST3412Kuznechik.blocksize,
113 hexdec(self.plaintext),
118 self.assertSequenceEqual(
121 GOST3412Kuznechik.blocksize,
128 def test_ctr_symmetric(self):
130 pt = urandom(randint(0, 16 * 2))
131 iv = urandom(GOST3412Kuznechik.blocksize // 2)
132 ciph = GOST3412Kuznechik(urandom(KEYSIZE))
133 ct = ctr(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv)
134 self.assertSequenceEqual(ctr(
136 GOST3412Kuznechik.blocksize,
141 def test_ofb_vectors(self):
143 ciphtext += "81800a59b1842b24ff1f795e897abd95"
144 ciphtext += "ed5b47a7048cfab48fb521369d9326bf"
145 ciphtext += "66a257ac3ca0b8b1c80fe7fc10288a13"
146 ciphtext += "203ebbc066138660a0292243f6903150"
147 self.assertSequenceEqual(
150 GOST3412Kuznechik.blocksize,
151 hexdec(self.plaintext),
156 self.assertSequenceEqual(
159 GOST3412Kuznechik.blocksize,
166 def test_ofb_symmetric(self):
168 pt = urandom(randint(0, 16 * 2))
169 iv = urandom(GOST3412Kuznechik.blocksize * 2)
170 ciph = GOST3412Kuznechik(urandom(KEYSIZE))
171 ct = ofb(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv)
172 self.assertSequenceEqual(ofb(
174 GOST3412Kuznechik.blocksize,
179 def test_ofb_manual(self):
180 iv = [urandom(GOST3412Kuznechik.blocksize) for _ in range(randint(2, 10))]
182 urandom(GOST3412Kuznechik.blocksize)
183 for _ in range(len(iv), len(iv) + randint(1, 10))
185 ciph = GOST3412Kuznechik(urandom(KEYSIZE))
186 r = [ciph.encrypt(i) for i in iv]
187 for i in range(len(pt) - len(iv)):
188 r.append(ciph.encrypt(r[i]))
189 ct = [strxor(g, r) for g, r in zip(pt, r)]
190 self.assertSequenceEqual(
191 ofb(ciph.encrypt, GOST3412Kuznechik.blocksize, b"".join(pt), b"".join(iv)),
195 def test_cbc_vectors(self):
197 ciphtext += "689972d4a085fa4d90e52e3d6d7dcc27"
198 ciphtext += "2826e661b478eca6af1e8e448d5ea5ac"
199 ciphtext += "fe7babf1e91999e85640e8b0f49d90d0"
200 ciphtext += "167688065a895c631a2d9a1560b63970"
201 self.assertSequenceEqual(
204 GOST3412Kuznechik.blocksize,
205 hexdec(self.plaintext),
210 self.assertSequenceEqual(
213 GOST3412Kuznechik.blocksize,
220 def test_cbc_symmetric(self):
222 pt = pad2(urandom(randint(0, 16 * 2)), GOST3412Kuznechik.blocksize)
223 iv = urandom(GOST3412Kuznechik.blocksize * 2)
224 ciph = GOST3412Kuznechik(urandom(KEYSIZE))
225 ct = cbc_encrypt(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv)
226 self.assertSequenceEqual(cbc_decrypt(
228 GOST3412Kuznechik.blocksize,
233 def test_cfb_vectors(self):
235 ciphtext += "81800a59b1842b24ff1f795e897abd95"
236 ciphtext += "ed5b47a7048cfab48fb521369d9326bf"
237 ciphtext += "79f2a8eb5cc68d38842d264e97a238b5"
238 ciphtext += "4ffebecd4e922de6c75bd9dd44fbf4d1"
239 self.assertSequenceEqual(
242 GOST3412Kuznechik.blocksize,
243 hexdec(self.plaintext),
248 self.assertSequenceEqual(
251 GOST3412Kuznechik.blocksize,
258 def test_cfb_symmetric(self):
260 pt = urandom(randint(0, 16 * 2))
261 iv = urandom(GOST3412Kuznechik.blocksize * 2)
262 ciph = GOST3412Kuznechik(urandom(KEYSIZE))
263 ct = cfb_encrypt(ciph.encrypt, GOST3412Kuznechik.blocksize, pt, iv)
264 self.assertSequenceEqual(cfb_decrypt(
266 GOST3412Kuznechik.blocksize,
271 def test_mac_vectors(self):
272 k1, k2 = _mac_ks(self.ciph.encrypt, GOST3412Kuznechik.blocksize)
273 self.assertSequenceEqual(hexenc(k1), "297d82bc4d39e3ca0de0573298151dc7")
274 self.assertSequenceEqual(hexenc(k2), "52fb05789a73c7941bc0ae65302a3b8e")
275 self.assertSequenceEqual(
278 GOST3412Kuznechik.blocksize,
279 hexdec(self.plaintext),
284 def test_mac_applies(self):
286 data = urandom(randint(0, 16 * 2))
287 ciph = GOST3412Kuznechik(urandom(KEYSIZE))
288 mac(ciph.encrypt, GOST3412Kuznechik.blocksize, data)
291 class GOST3412MagmaModesTest(TestCase):
292 key = hexdec("ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
293 ciph = GOST3412Magma(key)
295 plaintext += "92def06b3c130a59"
296 plaintext += "db54c704f8189d20"
297 plaintext += "4a98fb2e67a8024c"
298 plaintext += "8912409b17b57e41"
299 iv = hexdec("1234567890abcdef234567890abcdef134567890abcdef12")
301 def test_ecb_vectors(self):
303 ciphtext += "2b073f0494f372a0"
304 ciphtext += "de70e715d3556e48"
305 ciphtext += "11d8d9e9eacfbc1e"
306 ciphtext += "7c68260996c67efb"
307 self.assertSequenceEqual(
310 GOST3412Magma.blocksize,
311 hexdec(self.plaintext),
315 self.assertSequenceEqual(
318 GOST3412Magma.blocksize,
324 def test_ecb_symmetric(self):
326 pt = pad2(urandom(randint(0, 16 * 2)), 16)
327 ciph = GOST3412Magma(urandom(KEYSIZE))
328 ct = ecb_encrypt(ciph.encrypt, GOST3412Magma.blocksize, pt)
329 self.assertSequenceEqual(ecb_decrypt(
331 GOST3412Magma.blocksize,
335 def test_ctr_vectors(self):
337 ciphtext += "4e98110c97b7b93c"
338 ciphtext += "3e250d93d6e85d69"
339 ciphtext += "136d868807b2dbef"
340 ciphtext += "568eb680ab52a12d"
342 self.assertSequenceEqual(
345 GOST3412Magma.blocksize,
346 hexdec(self.plaintext),
351 self.assertSequenceEqual(
354 GOST3412Magma.blocksize,
361 def test_ctr_symmetric(self):
363 pt = urandom(randint(0, 16 * 2))
364 iv = urandom(GOST3412Magma.blocksize // 2)
365 ciph = GOST3412Magma(urandom(KEYSIZE))
366 ct = ctr(ciph.encrypt, GOST3412Magma.blocksize, pt, iv)
367 self.assertSequenceEqual(ctr(
369 GOST3412Magma.blocksize,
374 def test_ofb_vectors(self):
377 ciphtext += "db37e0e266903c83"
378 ciphtext += "0d46644c1f9a089c"
379 ciphtext += "a0f83062430e327e"
380 ciphtext += "c824efb8bd4fdb05"
381 self.assertSequenceEqual(
384 GOST3412Magma.blocksize,
385 hexdec(self.plaintext),
390 self.assertSequenceEqual(
393 GOST3412Magma.blocksize,
400 def test_ofb_symmetric(self):
402 pt = urandom(randint(0, 16 * 2))
403 iv = urandom(GOST3412Magma.blocksize * 2)
404 ciph = GOST3412Magma(urandom(KEYSIZE))
405 ct = ofb(ciph.encrypt, GOST3412Magma.blocksize, pt, iv)
406 self.assertSequenceEqual(ofb(
408 GOST3412Magma.blocksize,
413 def test_cbc_vectors(self):
415 ciphtext += "96d1b05eea683919"
416 ciphtext += "aff76129abb937b9"
417 ciphtext += "5058b4a1c4bc0019"
418 ciphtext += "20b78b1a7cd7e667"
419 self.assertSequenceEqual(
422 GOST3412Magma.blocksize,
423 hexdec(self.plaintext),
428 self.assertSequenceEqual(
431 GOST3412Magma.blocksize,
438 def test_cbc_symmetric(self):
440 pt = pad2(urandom(randint(0, 16 * 2)), 16)
441 iv = urandom(GOST3412Magma.blocksize * 2)
442 ciph = GOST3412Magma(urandom(KEYSIZE))
443 ct = cbc_encrypt(ciph.encrypt, GOST3412Magma.blocksize, pt, iv)
444 self.assertSequenceEqual(cbc_decrypt(
446 GOST3412Magma.blocksize,
451 def test_cfb_vectors(self):
454 ciphtext += "db37e0e266903c83"
455 ciphtext += "0d46644c1f9a089c"
456 ciphtext += "24bdd2035315d38b"
457 ciphtext += "bcc0321421075505"
458 self.assertSequenceEqual(
461 GOST3412Magma.blocksize,
462 hexdec(self.plaintext),
467 self.assertSequenceEqual(
470 GOST3412Magma.blocksize,
477 def test_cfb_symmetric(self):
479 pt = urandom(randint(0, 16 * 2))
480 iv = urandom(GOST3412Magma.blocksize * 2)
481 ciph = GOST3412Magma(urandom(KEYSIZE))
482 ct = cfb_encrypt(ciph.encrypt, GOST3412Magma.blocksize, pt, iv)
483 self.assertSequenceEqual(cfb_decrypt(
485 GOST3412Magma.blocksize,
490 def test_mac_vectors(self):
491 k1, k2 = _mac_ks(self.ciph.encrypt, GOST3412Magma.blocksize)
492 self.assertSequenceEqual(hexenc(k1), "5f459b3342521424")
493 self.assertSequenceEqual(hexenc(k2), "be8b366684a42848")
494 self.assertSequenceEqual(
497 GOST3412Magma.blocksize,
498 hexdec(self.plaintext),
503 def test_mac_applies(self):
505 data = urandom(randint(0, 16 * 2))
506 ciph = GOST3412Magma(urandom(KEYSIZE))
507 mac(ciph.encrypt, GOST3412Magma.blocksize, data)
510 class TestVectorACPKM(TestCase):
511 """Test vectors from Ð 1323565.1.017-2018
513 key = hexdec("8899AABBCCDDEEFF0011223344556677FEDCBA98765432100123456789ABCDEF")
515 def test_magma_ctr_acpkm(self):
516 key = acpkm(GOST3412Magma(self.key).encrypt, GOST3412Magma.blocksize)
517 self.assertSequenceEqual(key, hexdec("863EA017842C3D372B18A85A28E2317D74BEFC107720DE0C9E8AB974ABD00CA0"))
518 key = acpkm(GOST3412Magma(key).encrypt, GOST3412Magma.blocksize)
519 self.assertSequenceEqual(key, hexdec("49A5E2677DE555982B8AD5E826652D17EEC847BF5B3997A81CF7FE7F1187BD27"))
520 key = acpkm(GOST3412Magma(key).encrypt, GOST3412Magma.blocksize)
521 self.assertSequenceEqual(key, hexdec("3256BF3F97B5667426A9FB1C5EAABE41893CCDD5A868F9B63B0AA90720FA43C4"))
523 def test_magma_ctr(self):
524 encrypter = GOST3412Magma(self.key).encrypt
525 plaintext = hexdec("""
526 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
527 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
528 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
529 22 33 44 55 66 77 88 99
530 """.replace("\n", "").replace(" ", ""))
531 iv = hexdec("12345678")
532 ciphertext = hexdec("""
533 2A B8 1D EE EB 1E 4C AB 68 E1 04 C4 BD 6B 94 EA
534 C7 2C 67 AF 6C 2E 5B 6B 0E AF B6 17 70 F1 B3 2E
535 A1 AE 71 14 9E ED 13 82 AB D4 67 18 06 72 EC 6F
536 84 A2 F1 5B 3F CA 72 C1
537 """.replace("\n", "").replace(" ", ""))
538 self.assertSequenceEqual(
542 bs=GOST3412Magma.blocksize,
543 section_size=GOST3412Magma.blocksize * 2,
549 self.assertSequenceEqual(
553 bs=GOST3412Magma.blocksize,
554 section_size=GOST3412Magma.blocksize * 2,
561 def test_kuznechik_ctr_acpkm(self):
562 key = acpkm(GOST3412Kuznechik(self.key).encrypt, GOST3412Kuznechik.blocksize)
563 self.assertSequenceEqual(key, hexdec("2666ED40AE687811745CA0B448F57A7B390ADB5780307E8E9659AC403AE60C60"))
564 key = acpkm(GOST3412Kuznechik(key).encrypt, GOST3412Kuznechik.blocksize)
565 self.assertSequenceEqual(key, hexdec("BB3DD5402E999B7A3DEBB0DB45448EC530F07365DFEE3ABA8415F77AC8F34CE8"))
566 key = acpkm(GOST3412Kuznechik(key).encrypt, GOST3412Kuznechik.blocksize)
567 self.assertSequenceEqual(key, hexdec("23362FD553CAD2178299A5B5A2D4722E3BB83C730A8BF57CE2DD004017F8C565"))
569 def test_kuznechik_ctr(self):
570 encrypter = GOST3412Kuznechik(self.key).encrypt
571 iv = hexdec("1234567890ABCEF0")
572 plaintext = hexdec("""
573 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
574 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
575 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
576 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11
577 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22
578 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33
579 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33 44
580 """.replace("\n", "").replace(" ", ""))
581 ciphertext = hexdec("""
582 F1 95 D8 BE C1 0E D1 DB D5 7B 5F A2 40 BD A1 B8
583 85 EE E7 33 F6 A1 3E 5D F3 3C E4 B3 3C 45 DE E4
584 4B CE EB 8F 64 6F 4C 55 00 17 06 27 5E 85 E8 00
585 58 7C 4D F5 68 D0 94 39 3E 48 34 AF D0 80 50 46
586 CF 30 F5 76 86 AE EC E1 1C FC 6C 31 6B 8A 89 6E
587 DF FD 07 EC 81 36 36 46 0C 4F 3B 74 34 23 16 3E
588 64 09 A9 C2 82 FA C8 D4 69 D2 21 E7 FB D6 DE 5D
589 """.replace("\n", "").replace(" ", ""))
590 self.assertSequenceEqual(
594 bs=GOST3412Kuznechik.blocksize,
595 section_size=GOST3412Kuznechik.blocksize * 2,
601 self.assertSequenceEqual(
605 bs=GOST3412Kuznechik.blocksize,
606 section_size=GOST3412Kuznechik.blocksize * 2,
613 def test_magma_omac_1_5_blocks(self):
614 encrypter = GOST3412Magma(self.key).encrypt
615 key_section_size = 640 // 8
616 self.assertSequenceEqual(
620 key_section_size=key_section_size,
621 bs=GOST3412Magma.blocksize,
622 keymat_len=KEYSIZE + GOST3412Magma.blocksize,
624 hexdec("0DF2F5273DA328932AC49D81D36B2558A50DBF9BBCAC74A614B2CCB2F1CBCD8A70638E3DE8B3571E"),
626 text = hexdec("1122334455667700FFEEDDCC")
627 self.assertSequenceEqual(
632 section_size=GOST3412Magma.blocksize * 2,
633 bs=GOST3412Magma.blocksize,
636 hexdec("A0540E3730ACBCF3"),
639 def test_magma_omac_5_blocks(self):
640 encrypter = GOST3412Magma(self.key).encrypt
641 key_section_size = 640 // 8
642 self.assertSequenceEqual(
646 key_section_size=key_section_size,
647 bs=GOST3412Magma.blocksize,
648 keymat_len=3 * (KEYSIZE + GOST3412Magma.blocksize),
651 0D F2 F5 27 3D A3 28 93 2A C4 9D 81 D3 6B 25 58
652 A5 0D BF 9B BC AC 74 A6 14 B2 CC B2 F1 CB CD 8A
653 70 63 8E 3D E8 B3 57 1E 8D 38 26 D5 5E 63 A1 67
654 E2 40 66 40 54 7B 9F 1F 5F 2B 43 61 2A AE AF DA
655 18 0B AC 86 04 DF A6 FE 53 C2 CE 27 0E 9C 9F 52
656 68 D0 FD BF E1 A3 BD D9 BE 5B 96 D0 A1 20 23 48
657 6E F1 71 0F 92 4A E0 31 30 52 CB 5F CA 0B 79 1E
658 1B AB E8 57 6D 0F E3 A8
659 """.replace("\n", "").replace(" ", "")),
662 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
663 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
664 11 22 33 44 55 66 77 88
665 """.replace("\n", "").replace(" ", ""))
666 self.assertSequenceEqual(
671 section_size=GOST3412Magma.blocksize * 2,
672 bs=GOST3412Magma.blocksize,
675 hexdec("34008DAD5496BB8E"),
678 def test_kuznechik_omac_1_5_blocks(self):
679 encrypter = GOST3412Kuznechik(self.key).encrypt
680 key_section_size = 768 // 8
681 self.assertSequenceEqual(
685 key_section_size=key_section_size,
686 bs=GOST3412Kuznechik.blocksize,
687 keymat_len=KEYSIZE + GOST3412Kuznechik.blocksize,
690 0C AB F1 F2 EF BC 4A C1 60 48 DF 1A 24 C6 05 B2
691 C0 D1 67 3D 75 86 A8 EC 0D D4 2C 45 A4 F9 5B AE
692 0F 2E 26 17 E4 71 48 68 0F C3 E6 17 8D F2 C1 37
693 """.replace("\n", "").replace(" ", ""))
696 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
697 00 11 22 33 44 55 66 77
698 """.replace("\n", "").replace(" ", ""))
699 self.assertSequenceEqual(
704 section_size=GOST3412Kuznechik.blocksize * 2,
705 bs=GOST3412Kuznechik.blocksize,
708 hexdec("B5367F47B62B995EEB2A648C5843145E"),
711 def test_kuznechik_omac_5_blocks(self):
712 encrypter = GOST3412Kuznechik(self.key).encrypt
713 key_section_size = 768 // 8
714 self.assertSequenceEqual(
718 key_section_size=key_section_size,
719 bs=GOST3412Kuznechik.blocksize,
720 keymat_len=3 * (KEYSIZE + GOST3412Kuznechik.blocksize),
723 0C AB F1 F2 EF BC 4A C1 60 48 DF 1A 24 C6 05 B2
724 C0 D1 67 3D 75 86 A8 EC 0D D4 2C 45 A4 F9 5B AE
725 0F 2E 26 17 E4 71 48 68 0F C3 E6 17 8D F2 C1 37
726 C9 DD A8 9C FF A4 91 FE AD D9 B3 EA B7 03 BB 31
727 BC 7E 92 7F 04 94 72 9F 51 B4 9D 3D F9 C9 46 08
728 00 FB BC F5 ED EE 61 0E A0 2F 01 09 3C 7B C7 42
729 D7 D6 27 15 01 B1 77 77 52 63 C2 A3 49 5A 83 18
730 A8 1C 79 A0 4F 29 66 0E A3 FD A8 74 C6 30 79 9E
731 14 2C 57 79 14 FE A9 0D 3B C2 50 2E 83 36 85 D9
732 """.replace("\n", "").replace(" ", "")),
735 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
736 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
737 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
738 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11
739 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22
740 """.replace("\n", "").replace(" ", ""))
741 self.assertSequenceEqual(
746 section_size=GOST3412Kuznechik.blocksize * 2,
747 bs=GOST3412Kuznechik.blocksize,
750 hexdec("FBB8DCEE45BEA67C35F58C5700898E5D"),
754 class ISO10126Test(TestCase):
755 def test_symmetric(self):
757 for blocksize in (GOST3412Magma.blocksize, GOST3412Kuznechik.blocksize):
758 data = urandom(randint(0, blocksize * 3))
759 padded = pad_iso10126(data, blocksize)
760 self.assertSequenceEqual(unpad_iso10126(padded, blocksize), data)
761 with self.assertRaises(ValueError):
762 unpad_iso10126(padded[1:], blocksize)
764 def test_small(self):
765 with self.assertRaises(ValueError):
766 unpad_iso10126(b"foobar\x00\x09", 8)