2 from random import randint
3 from unittest import TestCase
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 from pygost.utils import strxor
24 class Pad2Test(TestCase):
25 def test_symmetric(self):
27 for blocksize in (8, 16):
28 data = urandom(randint(0, blocksize * 3))
29 self.assertSequenceEqual(
30 unpad2(pad2(data, blocksize), blocksize),
35 class GOST3412KuznechikModesTest(TestCase):
36 key = hexdec("8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef")
37 ciph = GOST3412Kuznechik(key)
39 plaintext += "1122334455667700ffeeddccbbaa9988"
40 plaintext += "00112233445566778899aabbcceeff0a"
41 plaintext += "112233445566778899aabbcceeff0a00"
42 plaintext += "2233445566778899aabbcceeff0a0011"
43 iv = hexdec("1234567890abcef0a1b2c3d4e5f0011223344556677889901213141516171819")
45 def test_ecb_vectors(self):
47 ciphtext += "7f679d90bebc24305a468d42b9d4edcd"
48 ciphtext += "b429912c6e0032f9285452d76718d08b"
49 ciphtext += "f0ca33549d247ceef3f5a5313bd4b157"
50 ciphtext += "d0b09ccde830b9eb3a02c4c5aa8ada98"
51 self.assertSequenceEqual(
52 hexenc(ecb_encrypt(self.ciph.encrypt, 16, hexdec(self.plaintext))),
55 self.assertSequenceEqual(
56 hexenc(ecb_decrypt(self.ciph.decrypt, 16, hexdec(ciphtext))),
60 def test_ecb_symmetric(self):
62 pt = pad2(urandom(randint(0, 16 * 2)), 16)
63 ciph = GOST3412Kuznechik(urandom(32))
64 ct = ecb_encrypt(ciph.encrypt, 16, pt)
65 self.assertSequenceEqual(ecb_decrypt(ciph.decrypt, 16, ct), pt)
67 def test_ctr_vectors(self):
69 ciphtext += "f195d8bec10ed1dbd57b5fa240bda1b8"
70 ciphtext += "85eee733f6a13e5df33ce4b33c45dee4"
71 ciphtext += "a5eae88be6356ed3d5e877f13564a3a5"
72 ciphtext += "cb91fab1f20cbab6d1c6d15820bdba73"
74 self.assertSequenceEqual(
75 hexenc(ctr(self.ciph.encrypt, 16, hexdec(self.plaintext), iv)),
78 self.assertSequenceEqual(
79 hexenc(ctr(self.ciph.encrypt, 16, hexdec(ciphtext), iv)),
83 def test_ctr_symmetric(self):
85 pt = urandom(randint(0, 16 * 2))
87 ciph = GOST3412Kuznechik(urandom(32))
88 ct = ctr(ciph.encrypt, 16, pt, iv)
89 self.assertSequenceEqual(ctr(ciph.encrypt, 16, ct, iv), pt)
91 def test_ofb_vectors(self):
93 ciphtext += "81800a59b1842b24ff1f795e897abd95"
94 ciphtext += "ed5b47a7048cfab48fb521369d9326bf"
95 ciphtext += "66a257ac3ca0b8b1c80fe7fc10288a13"
96 ciphtext += "203ebbc066138660a0292243f6903150"
97 self.assertSequenceEqual(
98 hexenc(ofb(self.ciph.encrypt, 16, hexdec(self.plaintext), self.iv)),
101 self.assertSequenceEqual(
102 hexenc(ofb(self.ciph.encrypt, 16, hexdec(ciphtext), self.iv)),
106 def test_ofb_symmetric(self):
108 pt = urandom(randint(0, 16 * 2))
110 ciph = GOST3412Kuznechik(urandom(32))
111 ct = ofb(ciph.encrypt, 16, pt, iv)
112 self.assertSequenceEqual(ofb(ciph.encrypt, 16, ct, iv), pt)
114 def test_ofb_manual(self):
115 iv = [urandom(16) for _ in range(randint(2, 10))]
116 pt = [urandom(16) for _ in range(len(iv), len(iv) + randint(1, 10))]
117 ciph = GOST3412Kuznechik(urandom(32))
118 r = [ciph.encrypt(i) for i in iv]
119 for i in range(len(pt) - len(iv)):
120 r.append(ciph.encrypt(r[i]))
121 ct = [strxor(g, r) for g, r in zip(pt, r)]
122 self.assertSequenceEqual(
123 ofb(ciph.encrypt, 16, b"".join(pt), b"".join(iv)),
127 def test_cbc_vectors(self):
129 ciphtext += "689972d4a085fa4d90e52e3d6d7dcc27"
130 ciphtext += "2826e661b478eca6af1e8e448d5ea5ac"
131 ciphtext += "fe7babf1e91999e85640e8b0f49d90d0"
132 ciphtext += "167688065a895c631a2d9a1560b63970"
133 self.assertSequenceEqual(
134 hexenc(cbc_encrypt(self.ciph.encrypt, 16, hexdec(self.plaintext), self.iv)),
137 self.assertSequenceEqual(
138 hexenc(cbc_decrypt(self.ciph.decrypt, 16, hexdec(ciphtext), self.iv)),
142 def test_cbc_symmetric(self):
144 pt = pad2(urandom(randint(0, 16 * 2)), 16)
146 ciph = GOST3412Kuznechik(urandom(32))
147 ct = cbc_encrypt(ciph.encrypt, 16, pt, iv)
148 self.assertSequenceEqual(cbc_decrypt(ciph.decrypt, 16, ct, iv), pt)
150 def test_cfb_vectors(self):
152 ciphtext += "81800a59b1842b24ff1f795e897abd95"
153 ciphtext += "ed5b47a7048cfab48fb521369d9326bf"
154 ciphtext += "79f2a8eb5cc68d38842d264e97a238b5"
155 ciphtext += "4ffebecd4e922de6c75bd9dd44fbf4d1"
156 self.assertSequenceEqual(
157 hexenc(cfb_encrypt(self.ciph.encrypt, 16, hexdec(self.plaintext), self.iv)),
160 self.assertSequenceEqual(
161 hexenc(cfb_decrypt(self.ciph.encrypt, 16, hexdec(ciphtext), self.iv)),
165 def test_cfb_symmetric(self):
167 pt = urandom(randint(0, 16 * 2))
169 ciph = GOST3412Kuznechik(urandom(32))
170 ct = cfb_encrypt(ciph.encrypt, 16, pt, iv)
171 self.assertSequenceEqual(cfb_decrypt(ciph.encrypt, 16, ct, iv), pt)
173 def test_mac_vectors(self):
174 k1, k2 = _mac_ks(self.ciph.encrypt, 16)
175 self.assertSequenceEqual(hexenc(k1), "297d82bc4d39e3ca0de0573298151dc7")
176 self.assertSequenceEqual(hexenc(k2), "52fb05789a73c7941bc0ae65302a3b8e")
177 self.assertSequenceEqual(
178 hexenc(mac(self.ciph.encrypt, 16, hexdec(self.plaintext))[:8]),
182 def test_mac_applies(self):
184 data = urandom(randint(0, 16 * 2))
185 ciph = GOST3412Kuznechik(urandom(32))
186 mac(ciph.encrypt, 16, data)
189 class GOST3412MagmaModesTest(TestCase):
190 key = hexdec("ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
191 ciph = GOST3412Magma(key)
193 plaintext += "92def06b3c130a59"
194 plaintext += "db54c704f8189d20"
195 plaintext += "4a98fb2e67a8024c"
196 plaintext += "8912409b17b57e41"
197 iv = hexdec("1234567890abcdef234567890abcdef134567890abcdef12")
199 def test_ecb_vectors(self):
201 ciphtext += "2b073f0494f372a0"
202 ciphtext += "de70e715d3556e48"
203 ciphtext += "11d8d9e9eacfbc1e"
204 ciphtext += "7c68260996c67efb"
205 self.assertSequenceEqual(
206 hexenc(ecb_encrypt(self.ciph.encrypt, 8, hexdec(self.plaintext))),
209 self.assertSequenceEqual(
210 hexenc(ecb_decrypt(self.ciph.decrypt, 8, hexdec(ciphtext))),
214 def test_ecb_symmetric(self):
216 pt = pad2(urandom(randint(0, 16 * 2)), 16)
217 ciph = GOST3412Magma(urandom(32))
218 ct = ecb_encrypt(ciph.encrypt, 8, pt)
219 self.assertSequenceEqual(ecb_decrypt(ciph.decrypt, 8, ct), pt)
221 def test_ctr_vectors(self):
223 ciphtext += "4e98110c97b7b93c"
224 ciphtext += "3e250d93d6e85d69"
225 ciphtext += "136d868807b2dbef"
226 ciphtext += "568eb680ab52a12d"
228 self.assertSequenceEqual(
229 hexenc(ctr(self.ciph.encrypt, 8, hexdec(self.plaintext), iv)),
232 self.assertSequenceEqual(
233 hexenc(ctr(self.ciph.encrypt, 8, hexdec(ciphtext), iv)),
237 def test_ctr_symmetric(self):
239 pt = urandom(randint(0, 16 * 2))
241 ciph = GOST3412Magma(urandom(32))
242 ct = ctr(ciph.encrypt, 8, pt, iv)
243 self.assertSequenceEqual(ctr(ciph.encrypt, 8, ct, iv), pt)
245 def test_ofb_vectors(self):
248 ciphtext += "db37e0e266903c83"
249 ciphtext += "0d46644c1f9a089c"
250 ciphtext += "a0f83062430e327e"
251 ciphtext += "c824efb8bd4fdb05"
252 self.assertSequenceEqual(
253 hexenc(ofb(self.ciph.encrypt, 8, hexdec(self.plaintext), iv)),
256 self.assertSequenceEqual(
257 hexenc(ofb(self.ciph.encrypt, 8, hexdec(ciphtext), iv)),
261 def test_ofb_symmetric(self):
263 pt = urandom(randint(0, 16 * 2))
265 ciph = GOST3412Magma(urandom(32))
266 ct = ofb(ciph.encrypt, 8, pt, iv)
267 self.assertSequenceEqual(ofb(ciph.encrypt, 8, ct, iv), pt)
269 def test_cbc_vectors(self):
271 ciphtext += "96d1b05eea683919"
272 ciphtext += "aff76129abb937b9"
273 ciphtext += "5058b4a1c4bc0019"
274 ciphtext += "20b78b1a7cd7e667"
275 self.assertSequenceEqual(
276 hexenc(cbc_encrypt(self.ciph.encrypt, 8, hexdec(self.plaintext), self.iv)),
279 self.assertSequenceEqual(
280 hexenc(cbc_decrypt(self.ciph.decrypt, 8, hexdec(ciphtext), self.iv)),
284 def test_cbc_symmetric(self):
286 pt = pad2(urandom(randint(0, 16 * 2)), 16)
288 ciph = GOST3412Magma(urandom(32))
289 ct = cbc_encrypt(ciph.encrypt, 8, pt, iv)
290 self.assertSequenceEqual(cbc_decrypt(ciph.decrypt, 8, ct, iv), pt)
292 def test_cfb_vectors(self):
295 ciphtext += "db37e0e266903c83"
296 ciphtext += "0d46644c1f9a089c"
297 ciphtext += "24bdd2035315d38b"
298 ciphtext += "bcc0321421075505"
299 self.assertSequenceEqual(
300 hexenc(cfb_encrypt(self.ciph.encrypt, 8, hexdec(self.plaintext), iv)),
303 self.assertSequenceEqual(
304 hexenc(cfb_decrypt(self.ciph.encrypt, 8, hexdec(ciphtext), iv)),
308 def test_cfb_symmetric(self):
310 pt = urandom(randint(0, 16 * 2))
312 ciph = GOST3412Magma(urandom(32))
313 ct = cfb_encrypt(ciph.encrypt, 8, pt, iv)
314 self.assertSequenceEqual(cfb_decrypt(ciph.encrypt, 8, ct, iv), pt)
316 def test_mac_vectors(self):
317 k1, k2 = _mac_ks(self.ciph.encrypt, 8)
318 self.assertSequenceEqual(hexenc(k1), "5f459b3342521424")
319 self.assertSequenceEqual(hexenc(k2), "be8b366684a42848")
320 self.assertSequenceEqual(
321 hexenc(mac(self.ciph.encrypt, 8, hexdec(self.plaintext))[:4]),
325 def test_mac_applies(self):
327 data = urandom(randint(0, 16 * 2))
328 ciph = GOST3412Magma(urandom(32))
329 mac(ciph.encrypt, 8, data)