]> Cypherpunks.ru repositories - pygost.git/blob - pygost/test_gost28147.py
5928d6fc81ba1aef85c91c6c2b20b4a598ae404f
[pygost.git] / pygost / test_gost28147.py
1 # coding: utf-8
2 # PyGOST -- Pure Python GOST cryptographic functions library
3 # Copyright (C) 2015-2019 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.assertSequenceEqual(encrypted, ciphertext)
113         decrypted = ecb_decrypt(key, encrypted, sbox=sbox)
114         self.assertSequenceEqual(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.assertSequenceEqual(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.assertSequenceEqual(
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.assertSequenceEqual(
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.assertSequenceEqual(
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.assertSequenceEqual(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.assertSequenceEqual(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.assertSequenceEqual(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.assertSequenceEqual(
203                 cfb_decrypt(key, cfb_encrypt(key, pt, iv), iv),
204                 pt,
205             )
206
207
208 class CTRTest(TestCase):
209     def test_gcl(self):
210         """ Test vectors from libgcl3
211         """
212         sbox = "Gost2814789_TestParamSet"
213         key = hexdec(b"0475f6e05038fbfad2c7c390edb3ca3d1547124291ae1e8a2f79cd9ed2bcefbd")
214         plaintext = bytes(bytearray((
215             0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
216             0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
217             0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
218             0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
219             0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,
220             0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28,
221             0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30,
222             0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
223             0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,
224             0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48,
225             0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50,
226             0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58,
227             0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60,
228             0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68,
229             0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
230             0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
231             0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
232             0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88,
233             0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
234             0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98,
235             0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,
236             0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8,
237             0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0,
238             0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
239             0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0,
240             0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8,
241             0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0,
242             0xdf, 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0xd8,
243             0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0,
244             0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8,
245             0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
246             0xff, 0xfe, 0xfd, 0xfc, 0xfb,
247         )))
248         ciphertext = bytes(bytearray((
249             0x4a, 0x5e, 0x37, 0x6c, 0xa1, 0x12, 0xd3, 0x55,
250             0x09, 0x13, 0x1a, 0x21, 0xac, 0xfb, 0xb2, 0x1e,
251             0x8c, 0x24, 0x9b, 0x57, 0x20, 0x68, 0x46, 0xd5,
252             0x23, 0x2a, 0x26, 0x35, 0x12, 0x56, 0x5c, 0x69,
253             0x2a, 0x2f, 0xd1, 0xab, 0xbd, 0x45, 0xdc, 0x3a,
254             0x1a, 0xa4, 0x57, 0x64, 0xd5, 0xe4, 0x69, 0x6d,
255             0xb4, 0x8b, 0xf1, 0x54, 0x78, 0x3b, 0x10, 0x8f,
256             0x7a, 0x4b, 0x32, 0xe0, 0xe8, 0x4c, 0xbf, 0x03,
257             0x24, 0x37, 0x95, 0x6a, 0x55, 0xa8, 0xce, 0x6f,
258             0x95, 0x62, 0x12, 0xf6, 0x79, 0xe6, 0xf0, 0x1b,
259             0x86, 0xef, 0x36, 0x36, 0x05, 0xd8, 0x6f, 0x10,
260             0xa1, 0x41, 0x05, 0x07, 0xf8, 0xfa, 0xa4, 0x0b,
261             0x17, 0x2c, 0x71, 0xbc, 0x8b, 0xcb, 0xcf, 0x3d,
262             0x74, 0x18, 0x32, 0x0b, 0x1c, 0xd2, 0x9e, 0x75,
263             0xba, 0x3e, 0x61, 0xe1, 0x61, 0x96, 0xd0, 0xee,
264             0x8f, 0xf2, 0x9a, 0x5e, 0xb7, 0x7a, 0x15, 0xaa,
265             0x4e, 0x1e, 0x77, 0x7c, 0x99, 0xe1, 0x41, 0x13,
266             0xf4, 0x60, 0x39, 0x46, 0x4c, 0x35, 0xde, 0x95,
267             0xcc, 0x4f, 0xd5, 0xaf, 0xd1, 0x4d, 0x84, 0x1a,
268             0x45, 0xc7, 0x2a, 0xf2, 0x2c, 0xc0, 0xb7, 0x94,
269             0xa3, 0x08, 0xb9, 0x12, 0x96, 0xb5, 0x97, 0x99,
270             0x3a, 0xb7, 0x0c, 0x14, 0x56, 0xb9, 0xcb, 0x49,
271             0x44, 0xa9, 0x93, 0xa9, 0xfb, 0x19, 0x10, 0x8c,
272             0x6a, 0x68, 0xe8, 0x7b, 0x06, 0x57, 0xf0, 0xef,
273             0x88, 0x44, 0xa6, 0xd2, 0x98, 0xbe, 0xd4, 0x07,
274             0x41, 0x37, 0x45, 0xa6, 0x71, 0x36, 0x76, 0x69,
275             0x4b, 0x75, 0x15, 0x33, 0x90, 0x29, 0x6e, 0x33,
276             0xcb, 0x96, 0x39, 0x78, 0x19, 0x2e, 0x96, 0xf3,
277             0x49, 0x4c, 0x89, 0x3d, 0xa1, 0x86, 0x82, 0x00,
278             0xce, 0xbd, 0x54, 0x29, 0x65, 0x00, 0x1d, 0x16,
279             0x13, 0xc3, 0xfe, 0x1f, 0x8c, 0x55, 0x63, 0x09,
280             0x1f, 0xcd, 0xd4, 0x28, 0xca,
281         )))
282         iv = b"\x02\x01\x01\x01\x01\x01\x01\x01"
283         encrypted = cnt(key, plaintext, iv=iv, sbox=sbox)
284         self.assertSequenceEqual(encrypted, ciphertext)
285         decrypted = cnt(key, encrypted, iv=iv, sbox=sbox)
286         self.assertSequenceEqual(decrypted, plaintext)
287
288     def test_gcl2(self):
289         """ Test vectors 2 from libgcl3
290         """
291         sbox = "Gost2814789_TestParamSet"
292         key = hexdec(b"fc7ad2886f455b50d29008fa622b57d5c65b3c637202025799cadf0768519e8a")
293         plaintext = bytes(bytearray((
294             0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
295             0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
296             0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
297             0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
298             0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,
299             0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28,
300             0xff, 0xfe, 0xfd, 0xfc, 0xfb,
301         )))
302         ciphertext = bytes(bytearray((
303             0xd0, 0xbe, 0x60, 0x1a, 0x2c, 0xf1, 0x90, 0x26,
304             0x9b, 0x7b, 0x23, 0xb4, 0xd2, 0xcc, 0xe1, 0x15,
305             0xf6, 0x05, 0x57, 0x28, 0x88, 0x75, 0xeb, 0x1e,
306             0xd3, 0x62, 0xdc, 0xda, 0x9b, 0x62, 0xee, 0x9a,
307             0x57, 0x87, 0x8a, 0xf1, 0x82, 0x37, 0x9c, 0x7f,
308             0x13, 0xcc, 0x55, 0x38, 0xb5, 0x63, 0x32, 0xc5,
309             0x23, 0xa4, 0xcb, 0x7d, 0x51,
310         )))
311         iv = 8 * b"\x00"
312         encrypted = cnt(key, plaintext, iv=iv, sbox=sbox)
313         self.assertSequenceEqual(encrypted, ciphertext)
314         decrypted = cnt(key, encrypted, iv=iv, sbox=sbox)
315         self.assertSequenceEqual(decrypted, plaintext)
316
317
318 class CBCTest(TestCase):
319     def test_pad_requirement(self):
320         key = 32 * b"x"
321         for s in (b"", b"foo", b"foobarbaz"):
322             with self.assertRaises(ValueError):
323                 cbc_encrypt(key, s, pad=False)
324             with self.assertRaises(ValueError):
325                 cbc_decrypt(key, s, pad=False)
326
327     def test_passes(self):
328         iv = urandom(8)
329         key = 32 * b"x"
330         for pt in (b"foo", b"foobarba", b"foobarbaz", 16 * b"x"):
331             ct = cbc_encrypt(key, pt, iv)
332             dt = cbc_decrypt(key, ct)
333             self.assertSequenceEqual(pt, dt)
334
335     def test_iv_existence_check(self):
336         key = 32 * b"x"
337         with self.assertRaises(ValueError):
338             cbc_decrypt(key, 8 * b"x")
339         iv = urandom(8)
340         cbc_decrypt(key, cbc_encrypt(key, 8 * b"x", iv))
341
342     def test_meshing(self):
343         pt = urandom(MESH_MAX_DATA * 3)
344         key = urandom(32)
345         ct = cbc_encrypt(key, pt)
346         dt = cbc_decrypt(key, ct)
347         self.assertSequenceEqual(pt, dt)
348
349
350 class CFBMeshingTest(TestCase):
351     def setUp(self):
352         self.key = urandom(32)
353         self.iv = urandom(8)
354
355     def test_single(self):
356         pt = b"\x00"
357         ct = cfb_encrypt(self.key, pt, mesh=True)
358         dec = cfb_decrypt(self.key, ct, mesh=True)
359         self.assertSequenceEqual(pt, dec)
360
361     def test_short(self):
362         pt = urandom(MESH_MAX_DATA - 1)
363         ct = cfb_encrypt(self.key, pt, mesh=True)
364         dec = cfb_decrypt(self.key, ct, mesh=True)
365         dec_plain = cfb_decrypt(self.key, ct)
366         self.assertSequenceEqual(pt, dec)
367         self.assertSequenceEqual(pt, dec_plain)
368
369     def test_short_iv(self):
370         pt = urandom(MESH_MAX_DATA - 1)
371         ct = cfb_encrypt(self.key, pt, iv=self.iv, mesh=True)
372         dec = cfb_decrypt(self.key, ct, iv=self.iv, mesh=True)
373         dec_plain = cfb_decrypt(self.key, ct, iv=self.iv)
374         self.assertSequenceEqual(pt, dec)
375         self.assertSequenceEqual(pt, dec_plain)
376
377     def test_longer_iv(self):
378         pt = urandom(MESH_MAX_DATA * 3)
379         ct = cfb_encrypt(self.key, pt, iv=self.iv, mesh=True)
380         dec = cfb_decrypt(self.key, ct, iv=self.iv, mesh=True)
381         dec_plain = cfb_decrypt(self.key, ct, iv=self.iv)
382         self.assertSequenceEqual(pt, dec)
383         self.assertNotEqual(pt, dec_plain)