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