]> Cypherpunks.ru repositories - pygost.git/blob - pygost/test_gost28147.py
037b7b86ff643502eccc928774c3eafae6665645
[pygost.git] / pygost / test_gost28147.py
1 # coding: utf-8
2 # PyGOST -- Pure Python GOST cryptographic functions library
3 # Copyright (C) 2015-2018 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, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18 from os import urandom
19 from unittest import TestCase
20
21 from pygost.gost28147 import block2ns
22 from pygost.gost28147 import cbc_decrypt
23 from pygost.gost28147 import cbc_encrypt
24 from pygost.gost28147 import cfb_decrypt
25 from pygost.gost28147 import cfb_encrypt
26 from pygost.gost28147 import cnt
27 from pygost.gost28147 import DEFAULT_SBOX
28 from pygost.gost28147 import ecb_decrypt
29 from pygost.gost28147 import ecb_encrypt
30 from pygost.gost28147 import encrypt
31 from pygost.gost28147 import MESH_MAX_DATA
32 from pygost.gost28147 import ns2block
33 from pygost.utils import hexdec
34 from pygost.utils import strxor
35
36
37 class ECBTest(TestCase):
38     def test_gcl(self):
39         """ Test vectors from libgcl3
40         """
41         sbox = "Gost2814789_TestParamSet"
42         key = hexdec(b"0475f6e05038fbfad2c7c390edb3ca3d1547124291ae1e8a2f79cd9ed2bcefbd")
43         plaintext = bytes(bytearray((
44             0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
45             0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
46             0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
47             0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
48             0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,
49             0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28,
50             0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30,
51             0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
52             0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,
53             0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48,
54             0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50,
55             0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58,
56             0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60,
57             0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68,
58             0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
59             0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
60             0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
61             0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88,
62             0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
63             0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98,
64             0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,
65             0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8,
66             0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0,
67             0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
68             0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0,
69             0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8,
70             0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0,
71             0xdf, 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0xd8,
72             0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0,
73             0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8,
74             0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
75             0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
76         )))
77         ciphertext = bytes(bytearray((
78             0x4b, 0x8c, 0x4c, 0x98, 0x15, 0xf2, 0x4a, 0xea,
79             0x1e, 0xc3, 0x57, 0x09, 0xb3, 0xbc, 0x2e, 0xd1,
80             0xe0, 0xd1, 0xf2, 0x22, 0x65, 0x2d, 0x59, 0x18,
81             0xf7, 0xdf, 0xfc, 0x80, 0x4b, 0xde, 0x5c, 0x68,
82             0x46, 0x53, 0x75, 0x53, 0xa7, 0x46, 0x0d, 0xec,
83             0x05, 0x1f, 0x1b, 0xd3, 0x0a, 0x63, 0x1a, 0xb7,
84             0x78, 0xc4, 0x43, 0xe0, 0x5d, 0x3e, 0xa4, 0x0e,
85             0x2d, 0x7e, 0x23, 0xa9, 0x1b, 0xc9, 0x02, 0xbc,
86             0x21, 0x0c, 0x84, 0xcb, 0x0d, 0x0a, 0x07, 0xc8,
87             0x7b, 0xd0, 0xfb, 0xb5, 0x1a, 0x14, 0x04, 0x5c,
88             0xa2, 0x53, 0x97, 0x71, 0x2e, 0x5c, 0xc2, 0x8f,
89             0x39, 0x3f, 0x6f, 0x52, 0xf2, 0x30, 0x26, 0x4e,
90             0x8c, 0xe0, 0xd1, 0x01, 0x75, 0x6d, 0xdc, 0xd3,
91             0x03, 0x79, 0x1e, 0xca, 0xd5, 0xc1, 0x0e, 0x12,
92             0x53, 0x0a, 0x78, 0xe2, 0x0a, 0xb1, 0x1c, 0xea,
93             0x3a, 0xf8, 0x55, 0xb9, 0x7c, 0xe1, 0x0b, 0xba,
94             0xa0, 0xc8, 0x96, 0xeb, 0x50, 0x5a, 0xd3, 0x60,
95             0x43, 0xa3, 0x0f, 0x98, 0xdb, 0xd9, 0x50, 0x6d,
96             0x63, 0x91, 0xaf, 0x01, 0x40, 0xe9, 0x75, 0x5a,
97             0x46, 0x5c, 0x1f, 0x19, 0x4a, 0x0b, 0x89, 0x9b,
98             0xc4, 0xf6, 0xf8, 0xf5, 0x2f, 0x87, 0x3f, 0xfa,
99             0x26, 0xd4, 0xf8, 0x25, 0xba, 0x1f, 0x98, 0x82,
100             0xfc, 0x26, 0xaf, 0x2d, 0xc0, 0xf9, 0xc4, 0x58,
101             0x49, 0xfa, 0x09, 0x80, 0x02, 0x62, 0xa4, 0x34,
102             0x2d, 0xcb, 0x5a, 0x6b, 0xab, 0x61, 0x5d, 0x08,
103             0xd4, 0x26, 0xe0, 0x08, 0x13, 0xd6, 0x2e, 0x02,
104             0x2a, 0x37, 0xe8, 0xd0, 0xcf, 0x36, 0xf1, 0xc7,
105             0xc0, 0x3f, 0x9b, 0x21, 0x60, 0xbd, 0x29, 0x2d,
106             0x2e, 0x01, 0x48, 0x4e, 0xf8, 0x8f, 0x20, 0x16,
107             0x8a, 0xbf, 0x82, 0xdc, 0x32, 0x7a, 0xa3, 0x18,
108             0x69, 0xd1, 0x50, 0x59, 0x31, 0x91, 0xf2, 0x6c,
109             0x5a, 0x5f, 0xca, 0x58, 0x9a, 0xb2, 0x2d, 0xb2,
110         )))
111         encrypted = ecb_encrypt(key, plaintext, sbox=sbox)
112         self.assertEqual(encrypted, ciphertext)
113         decrypted = ecb_decrypt(key, encrypted, sbox=sbox)
114         self.assertEqual(decrypted, plaintext)
115
116     def test_cryptopp(self):
117         """ Test vectors from Crypto++ 5.6.2
118         """
119         sbox = "AppliedCryptography"
120         data = (
121             (b"BE5EC2006CFF9DCF52354959F1FF0CBFE95061B5A648C10387069C25997C0672", b"0DF82802B741A292", b"07F9027DF7F7DF89"),
122             (b"B385272AC8D72A5A8B344BC80363AC4D09BF58F41F540624CBCB8FDCF55307D7", b"1354EE9C0A11CD4C", b"4FB50536F960A7B1"),
123             (b"AEE02F609A35660E4097E546FD3026B032CD107C7D459977ADF489BEF2652262", b"6693D492C4B0CC39", b"670034AC0FA811B5"),
124             (b"320E9D8422165D58911DFC7D8BBB1F81B0ECD924023BF94D9DF7DCF7801240E0", b"99E2D13080928D79", b"8118FF9D3B3CFE7D"),
125             (b"C9F703BBBFC63691BFA3B7B87EA8FD5E8E8EF384EF733F1A61AEF68C8FFA265F", b"D1E787749C72814C", b"A083826A790D3E0C"),
126             (b"728FEE32F04B4C654AD7F607D71C660C2C2670D7C999713233149A1C0C17A1F0", b"D4C05323A4F7A7B5", b"4D1F2E6B0D9DE2CE"),
127             (b"35FC96402209500FCFDEF5352D1ABB038FE33FC0D9D58512E56370B22BAA133B", b"8742D9A05F6A3AF6", b"2F3BB84879D11E52"),
128             (b"D416F630BE65B7FE150656183370E07018234EE5DA3D89C4CE9152A03E5BFB77", b"F86506DA04E41CB8", b"96F0A5C77A04F5CE"),
129         )
130         for key, pt, ct in data:
131             key = hexdec(key)
132             pt = hexdec(pt)
133             ct = hexdec(ct)
134             self.assertEqual(ecb_encrypt(key, pt, sbox=sbox), ct)
135
136     def test_cryptomanager(self):
137         """ Test vector from http://cryptomanager.com/tv.html
138         """
139         sbox = "GostR3411_94_TestParamSet"
140         key = hexdec(b"75713134B60FEC45A607BB83AA3746AF4FF99DA6D1B53B5B1B402A1BAA030D1B")
141         self.assertEqual(
142             ecb_encrypt(key, hexdec(b"1122334455667788"), sbox=sbox),
143             hexdec(b"03251E14F9D28ACB"),
144         )
145
146
147 class CFBTest(TestCase):
148     def test_cryptomanager(self):
149         """ Test vector from http://cryptomanager.com/tv.html
150         """
151         key = hexdec(b"75713134B60FEC45A607BB83AA3746AF4FF99DA6D1B53B5B1B402A1BAA030D1B")
152         sbox = "GostR3411_94_TestParamSet"
153         self.assertEqual(
154             cfb_encrypt(
155                 key,
156                 hexdec(b"112233445566778899AABBCCDD800000"),
157                 iv=hexdec(b"0102030405060708"),
158                 sbox=sbox,
159             ),
160             hexdec(b"6EE84586DD2BCA0CAD3616940E164242"),
161         )
162         self.assertEqual(
163             cfb_decrypt(
164                 key,
165                 hexdec(b"6EE84586DD2BCA0CAD3616940E164242"),
166                 iv=hexdec(b"0102030405060708"),
167                 sbox=sbox,
168             ),
169             hexdec(b"112233445566778899AABBCCDD800000"),
170         )
171
172     def test_steps(self):
173         """ Check step-by-step operation manually
174         """
175         key = urandom(32)
176         iv = urandom(8)
177         plaintext = urandom(20)
178         ciphertext = cfb_encrypt(key, plaintext, iv)
179
180         # First full block
181         step = encrypt(DEFAULT_SBOX, key, block2ns(iv))
182         step = strxor(plaintext[:8], ns2block(step))
183         self.assertEqual(step, ciphertext[:8])
184
185         # Second full block
186         step = encrypt(DEFAULT_SBOX, key, block2ns(step))
187         step = strxor(plaintext[8:16], ns2block(step))
188         self.assertEqual(step, ciphertext[8:16])
189
190         # Third non-full block
191         step = encrypt(DEFAULT_SBOX, key, block2ns(step))
192         step = strxor(plaintext[16:] + 4 * b"\x00", ns2block(step))
193         self.assertEqual(step[:4], ciphertext[16:])
194
195     def test_random(self):
196         """ Random data with various sizes
197         """
198         key = urandom(32)
199         iv = urandom(8)
200         for size in (5, 8, 16, 120):
201             pt = urandom(size)
202             self.assertEqual(
203                 cfb_decrypt(key, cfb_encrypt(key, pt, iv), iv), pt,
204             )
205
206
207 class CTRTest(TestCase):
208     def test_gcl(self):
209         """ Test vectors from libgcl3
210         """
211         sbox = "Gost2814789_TestParamSet"
212         key = hexdec(b"0475f6e05038fbfad2c7c390edb3ca3d1547124291ae1e8a2f79cd9ed2bcefbd")
213         plaintext = bytes(bytearray((
214             0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
215             0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
216             0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
217             0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
218             0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,
219             0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28,
220             0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30,
221             0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
222             0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,
223             0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48,
224             0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50,
225             0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58,
226             0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60,
227             0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68,
228             0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
229             0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
230             0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
231             0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88,
232             0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
233             0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98,
234             0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,
235             0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8,
236             0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0,
237             0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
238             0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0,
239             0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8,
240             0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0,
241             0xdf, 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0xd8,
242             0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0,
243             0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8,
244             0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
245             0xff, 0xfe, 0xfd, 0xfc, 0xfb,
246         )))
247         ciphertext = bytes(bytearray((
248             0x4a, 0x5e, 0x37, 0x6c, 0xa1, 0x12, 0xd3, 0x55,
249             0x09, 0x13, 0x1a, 0x21, 0xac, 0xfb, 0xb2, 0x1e,
250             0x8c, 0x24, 0x9b, 0x57, 0x20, 0x68, 0x46, 0xd5,
251             0x23, 0x2a, 0x26, 0x35, 0x12, 0x56, 0x5c, 0x69,
252             0x2a, 0x2f, 0xd1, 0xab, 0xbd, 0x45, 0xdc, 0x3a,
253             0x1a, 0xa4, 0x57, 0x64, 0xd5, 0xe4, 0x69, 0x6d,
254             0xb4, 0x8b, 0xf1, 0x54, 0x78, 0x3b, 0x10, 0x8f,
255             0x7a, 0x4b, 0x32, 0xe0, 0xe8, 0x4c, 0xbf, 0x03,
256             0x24, 0x37, 0x95, 0x6a, 0x55, 0xa8, 0xce, 0x6f,
257             0x95, 0x62, 0x12, 0xf6, 0x79, 0xe6, 0xf0, 0x1b,
258             0x86, 0xef, 0x36, 0x36, 0x05, 0xd8, 0x6f, 0x10,
259             0xa1, 0x41, 0x05, 0x07, 0xf8, 0xfa, 0xa4, 0x0b,
260             0x17, 0x2c, 0x71, 0xbc, 0x8b, 0xcb, 0xcf, 0x3d,
261             0x74, 0x18, 0x32, 0x0b, 0x1c, 0xd2, 0x9e, 0x75,
262             0xba, 0x3e, 0x61, 0xe1, 0x61, 0x96, 0xd0, 0xee,
263             0x8f, 0xf2, 0x9a, 0x5e, 0xb7, 0x7a, 0x15, 0xaa,
264             0x4e, 0x1e, 0x77, 0x7c, 0x99, 0xe1, 0x41, 0x13,
265             0xf4, 0x60, 0x39, 0x46, 0x4c, 0x35, 0xde, 0x95,
266             0xcc, 0x4f, 0xd5, 0xaf, 0xd1, 0x4d, 0x84, 0x1a,
267             0x45, 0xc7, 0x2a, 0xf2, 0x2c, 0xc0, 0xb7, 0x94,
268             0xa3, 0x08, 0xb9, 0x12, 0x96, 0xb5, 0x97, 0x99,
269             0x3a, 0xb7, 0x0c, 0x14, 0x56, 0xb9, 0xcb, 0x49,
270             0x44, 0xa9, 0x93, 0xa9, 0xfb, 0x19, 0x10, 0x8c,
271             0x6a, 0x68, 0xe8, 0x7b, 0x06, 0x57, 0xf0, 0xef,
272             0x88, 0x44, 0xa6, 0xd2, 0x98, 0xbe, 0xd4, 0x07,
273             0x41, 0x37, 0x45, 0xa6, 0x71, 0x36, 0x76, 0x69,
274             0x4b, 0x75, 0x15, 0x33, 0x90, 0x29, 0x6e, 0x33,
275             0xcb, 0x96, 0x39, 0x78, 0x19, 0x2e, 0x96, 0xf3,
276             0x49, 0x4c, 0x89, 0x3d, 0xa1, 0x86, 0x82, 0x00,
277             0xce, 0xbd, 0x54, 0x29, 0x65, 0x00, 0x1d, 0x16,
278             0x13, 0xc3, 0xfe, 0x1f, 0x8c, 0x55, 0x63, 0x09,
279             0x1f, 0xcd, 0xd4, 0x28, 0xca,
280         )))
281         iv = b"\x02\x01\x01\x01\x01\x01\x01\x01"
282         encrypted = cnt(key, plaintext, iv=iv, sbox=sbox)
283         self.assertEqual(encrypted, ciphertext)
284         decrypted = cnt(key, encrypted, iv=iv, sbox=sbox)
285         self.assertEqual(decrypted, plaintext)
286
287     def test_gcl2(self):
288         """ Test vectors 2 from libgcl3
289         """
290         sbox = "Gost2814789_TestParamSet"
291         key = hexdec(b"fc7ad2886f455b50d29008fa622b57d5c65b3c637202025799cadf0768519e8a")
292         plaintext = bytes(bytearray((
293             0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
294             0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
295             0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
296             0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
297             0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,
298             0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28,
299             0xff, 0xfe, 0xfd, 0xfc, 0xfb,
300         )))
301         ciphertext = bytes(bytearray((
302             0xd0, 0xbe, 0x60, 0x1a, 0x2c, 0xf1, 0x90, 0x26,
303             0x9b, 0x7b, 0x23, 0xb4, 0xd2, 0xcc, 0xe1, 0x15,
304             0xf6, 0x05, 0x57, 0x28, 0x88, 0x75, 0xeb, 0x1e,
305             0xd3, 0x62, 0xdc, 0xda, 0x9b, 0x62, 0xee, 0x9a,
306             0x57, 0x87, 0x8a, 0xf1, 0x82, 0x37, 0x9c, 0x7f,
307             0x13, 0xcc, 0x55, 0x38, 0xb5, 0x63, 0x32, 0xc5,
308             0x23, 0xa4, 0xcb, 0x7d, 0x51,
309         )))
310         iv = 8 * b"\x00"
311         encrypted = cnt(key, plaintext, iv=iv, sbox=sbox)
312         self.assertEqual(encrypted, ciphertext)
313         decrypted = cnt(key, encrypted, iv=iv, sbox=sbox)
314         self.assertEqual(decrypted, plaintext)
315
316
317 class CBCTest(TestCase):
318     def test_pad_requirement(self):
319         key = 32 * b"x"
320         for s in (b"", b"foo", b"foobarbaz"):
321             with self.assertRaises(ValueError):
322                 cbc_encrypt(key, s, pad=False)
323             with self.assertRaises(ValueError):
324                 cbc_decrypt(key, s, pad=False)
325
326     def test_passes(self):
327         iv = urandom(8)
328         key = 32 * b"x"
329         for pt in (b"foo", b"foobarba", b"foobarbaz", 16 * b"x"):
330             ct = cbc_encrypt(key, pt, iv)
331             dt = cbc_decrypt(key, ct)
332             self.assertEqual(pt, dt)
333
334     def test_iv_existence_check(self):
335         key = 32 * b"x"
336         with self.assertRaises(ValueError):
337             cbc_decrypt(key, 8 * b"x")
338         iv = urandom(8)
339         cbc_decrypt(key, cbc_encrypt(key, 8 * b"x", iv))
340
341     def test_meshing(self):
342         pt = urandom(MESH_MAX_DATA * 3)
343         key = urandom(32)
344         ct = cbc_encrypt(key, pt)
345         dt = cbc_decrypt(key, ct)
346         self.assertEqual(pt, dt)
347
348
349 class CFBMeshingTest(TestCase):
350     def setUp(self):
351         self.key = urandom(32)
352         self.iv = urandom(8)
353
354     def test_single(self):
355         pt = b"\x00"
356         ct = cfb_encrypt(self.key, pt, mesh=True)
357         dec = cfb_decrypt(self.key, ct, mesh=True)
358         self.assertEqual(pt, dec)
359
360     def test_short(self):
361         pt = urandom(MESH_MAX_DATA - 1)
362         ct = cfb_encrypt(self.key, pt, mesh=True)
363         dec = cfb_decrypt(self.key, ct, mesh=True)
364         dec_plain = cfb_decrypt(self.key, ct)
365         self.assertEqual(pt, dec)
366         self.assertEqual(pt, dec_plain)
367
368     def test_short_iv(self):
369         pt = urandom(MESH_MAX_DATA - 1)
370         ct = cfb_encrypt(self.key, pt, iv=self.iv, mesh=True)
371         dec = cfb_decrypt(self.key, ct, iv=self.iv, mesh=True)
372         dec_plain = cfb_decrypt(self.key, ct, iv=self.iv)
373         self.assertEqual(pt, dec)
374         self.assertEqual(pt, dec_plain)
375
376     def test_longer_iv(self):
377         pt = urandom(MESH_MAX_DATA * 3)
378         ct = cfb_encrypt(self.key, pt, iv=self.iv, mesh=True)
379         dec = cfb_decrypt(self.key, ct, iv=self.iv, mesh=True)
380         dec_plain = cfb_decrypt(self.key, ct, iv=self.iv)
381         self.assertEqual(pt, dec)
382         self.assertNotEqual(pt, dec_plain)