| 1 | # |
|---|
| 2 | # test.py : Functions used for testing the modules |
|---|
| 3 | # |
|---|
| 4 | # Part of the Python Cryptography Toolkit |
|---|
| 5 | # |
|---|
| 6 | # Distribute and use freely; there are no restrictions on further |
|---|
| 7 | # dissemination and usage except those imposed by the laws of your |
|---|
| 8 | # country of residence. This software is provided "as is" without |
|---|
| 9 | # warranty of fitness for use or suitability for any purpose, express |
|---|
| 10 | # or implied. Use at your own risk or not at all. |
|---|
| 11 | # |
|---|
| 12 | |
|---|
| 13 | __revision__ = "$Id: test.py,v 1.16 2004/08/13 22:24:18 akuchling Exp $" |
|---|
| 14 | |
|---|
| 15 | import binascii |
|---|
| 16 | import string |
|---|
| 17 | import testdata |
|---|
| 18 | |
|---|
| 19 | from Crypto.Cipher import * |
|---|
| 20 | |
|---|
| 21 | def die(string): |
|---|
| 22 | import sys |
|---|
| 23 | print '***ERROR: ', string |
|---|
| 24 | # sys.exit(0) # Will default to continuing onward... |
|---|
| 25 | |
|---|
| 26 | def print_timing (size, delta, verbose): |
|---|
| 27 | if verbose: |
|---|
| 28 | if delta == 0: |
|---|
| 29 | print 'Unable to measure time -- elapsed time too small' |
|---|
| 30 | else: |
|---|
| 31 | print '%.2f K/sec' % (size/delta) |
|---|
| 32 | |
|---|
| 33 | def exerciseBlockCipher(cipher, verbose): |
|---|
| 34 | import string, time |
|---|
| 35 | try: |
|---|
| 36 | ciph = eval(cipher) |
|---|
| 37 | except NameError: |
|---|
| 38 | print cipher, 'module not available' |
|---|
| 39 | return None |
|---|
| 40 | print cipher+ ':' |
|---|
| 41 | str='1' # Build 128K of test data |
|---|
| 42 | for i in xrange(0, 17): |
|---|
| 43 | str=str+str |
|---|
| 44 | if ciph.key_size==0: ciph.key_size=16 |
|---|
| 45 | password = 'password12345678Extra text for password'[0:ciph.key_size] |
|---|
| 46 | IV = 'Test IV Test IV Test IV Test'[0:ciph.block_size] |
|---|
| 47 | |
|---|
| 48 | if verbose: print ' ECB mode:', |
|---|
| 49 | obj=ciph.new(password, ciph.MODE_ECB) |
|---|
| 50 | if obj.block_size != ciph.block_size: |
|---|
| 51 | die("Module and cipher object block_size don't match") |
|---|
| 52 | |
|---|
| 53 | text='1234567812345678'[0:ciph.block_size] |
|---|
| 54 | c=obj.encrypt(text) |
|---|
| 55 | if (obj.decrypt(c)!=text): die('Error encrypting "'+text+'"') |
|---|
| 56 | text='KuchlingKuchling'[0:ciph.block_size] |
|---|
| 57 | c=obj.encrypt(text) |
|---|
| 58 | if (obj.decrypt(c)!=text): die('Error encrypting "'+text+'"') |
|---|
| 59 | text='NotTodayNotEver!'[0:ciph.block_size] |
|---|
| 60 | c=obj.encrypt(text) |
|---|
| 61 | if (obj.decrypt(c)!=text): die('Error encrypting "'+text+'"') |
|---|
| 62 | |
|---|
| 63 | start=time.time() |
|---|
| 64 | s=obj.encrypt(str) |
|---|
| 65 | s2=obj.decrypt(s) |
|---|
| 66 | end=time.time() |
|---|
| 67 | if (str!=s2): |
|---|
| 68 | die('Error in resulting plaintext from ECB mode') |
|---|
| 69 | print_timing(256, end-start, verbose) |
|---|
| 70 | del obj |
|---|
| 71 | |
|---|
| 72 | if verbose: print ' CFB mode:', |
|---|
| 73 | obj1=ciph.new(password, ciph.MODE_CFB, IV) |
|---|
| 74 | obj2=ciph.new(password, ciph.MODE_CFB, IV) |
|---|
| 75 | start=time.time() |
|---|
| 76 | ciphertext=obj1.encrypt(str[0:65536]) |
|---|
| 77 | plaintext=obj2.decrypt(ciphertext) |
|---|
| 78 | end=time.time() |
|---|
| 79 | if (plaintext!=str[0:65536]): |
|---|
| 80 | die('Error in resulting plaintext from CFB mode') |
|---|
| 81 | print_timing(64, end-start, verbose) |
|---|
| 82 | del obj1, obj2 |
|---|
| 83 | |
|---|
| 84 | if verbose: print ' CBC mode:', |
|---|
| 85 | obj1=ciph.new(password, ciph.MODE_CBC, IV) |
|---|
| 86 | obj2=ciph.new(password, ciph.MODE_CBC, IV) |
|---|
| 87 | start=time.time() |
|---|
| 88 | ciphertext=obj1.encrypt(str) |
|---|
| 89 | plaintext=obj2.decrypt(ciphertext) |
|---|
| 90 | end=time.time() |
|---|
| 91 | if (plaintext!=str): |
|---|
| 92 | die('Error in resulting plaintext from CBC mode') |
|---|
| 93 | print_timing(256, end-start, verbose) |
|---|
| 94 | del obj1, obj2 |
|---|
| 95 | |
|---|
| 96 | if verbose: print ' PGP mode:', |
|---|
| 97 | obj1=ciph.new(password, ciph.MODE_PGP, IV) |
|---|
| 98 | obj2=ciph.new(password, ciph.MODE_PGP, IV) |
|---|
| 99 | start=time.time() |
|---|
| 100 | ciphertext=obj1.encrypt(str) |
|---|
| 101 | plaintext=obj2.decrypt(ciphertext) |
|---|
| 102 | end=time.time() |
|---|
| 103 | if (plaintext!=str): |
|---|
| 104 | die('Error in resulting plaintext from PGP mode') |
|---|
| 105 | print_timing(256, end-start, verbose) |
|---|
| 106 | del obj1, obj2 |
|---|
| 107 | |
|---|
| 108 | if verbose: print ' OFB mode:', |
|---|
| 109 | obj1=ciph.new(password, ciph.MODE_OFB, IV) |
|---|
| 110 | obj2=ciph.new(password, ciph.MODE_OFB, IV) |
|---|
| 111 | start=time.time() |
|---|
| 112 | ciphertext=obj1.encrypt(str) |
|---|
| 113 | plaintext=obj2.decrypt(ciphertext) |
|---|
| 114 | end=time.time() |
|---|
| 115 | if (plaintext!=str): |
|---|
| 116 | die('Error in resulting plaintext from OFB mode') |
|---|
| 117 | print_timing(256, end-start, verbose) |
|---|
| 118 | del obj1, obj2 |
|---|
| 119 | |
|---|
| 120 | def counter(length=ciph.block_size): |
|---|
| 121 | return length * 'a' |
|---|
| 122 | |
|---|
| 123 | if verbose: print ' CTR mode:', |
|---|
| 124 | obj1=ciph.new(password, ciph.MODE_CTR, counter=counter) |
|---|
| 125 | obj2=ciph.new(password, ciph.MODE_CTR, counter=counter) |
|---|
| 126 | start=time.time() |
|---|
| 127 | ciphertext=obj1.encrypt(str) |
|---|
| 128 | plaintext=obj2.decrypt(ciphertext) |
|---|
| 129 | end=time.time() |
|---|
| 130 | if (plaintext!=str): |
|---|
| 131 | die('Error in resulting plaintext from CTR mode') |
|---|
| 132 | print_timing(256, end-start, verbose) |
|---|
| 133 | del obj1, obj2 |
|---|
| 134 | |
|---|
| 135 | # Test the IV handling |
|---|
| 136 | if verbose: print ' Testing IV handling' |
|---|
| 137 | obj1=ciph.new(password, ciph.MODE_CBC, IV) |
|---|
| 138 | plaintext='Test'*(ciph.block_size/4)*3 |
|---|
| 139 | ciphertext1=obj1.encrypt(plaintext) |
|---|
| 140 | obj1.IV=IV |
|---|
| 141 | ciphertext2=obj1.encrypt(plaintext) |
|---|
| 142 | if ciphertext1!=ciphertext2: |
|---|
| 143 | die('Error in setting IV') |
|---|
| 144 | |
|---|
| 145 | # Test keyword arguments |
|---|
| 146 | obj1=ciph.new(key=password) |
|---|
| 147 | obj1=ciph.new(password, mode=ciph.MODE_CBC) |
|---|
| 148 | obj1=ciph.new(mode=ciph.MODE_CBC, key=password) |
|---|
| 149 | obj1=ciph.new(IV=IV, mode=ciph.MODE_CBC, key=password) |
|---|
| 150 | |
|---|
| 151 | return ciph |
|---|
| 152 | |
|---|
| 153 | def exerciseStreamCipher(cipher, verbose): |
|---|
| 154 | import string, time |
|---|
| 155 | try: |
|---|
| 156 | ciph = eval(cipher) |
|---|
| 157 | except (NameError): |
|---|
| 158 | print cipher, 'module not available' |
|---|
| 159 | return None |
|---|
| 160 | print cipher + ':', |
|---|
| 161 | str='1' # Build 128K of test data |
|---|
| 162 | for i in xrange(0, 17): |
|---|
| 163 | str=str+str |
|---|
| 164 | key_size = ciph.key_size or 16 |
|---|
| 165 | password = 'password12345678Extra text for password'[0:key_size] |
|---|
| 166 | |
|---|
| 167 | obj1=ciph.new(password) |
|---|
| 168 | obj2=ciph.new(password) |
|---|
| 169 | if obj1.block_size != ciph.block_size: |
|---|
| 170 | die("Module and cipher object block_size don't match") |
|---|
| 171 | if obj1.key_size != ciph.key_size: |
|---|
| 172 | die("Module and cipher object key_size don't match") |
|---|
| 173 | |
|---|
| 174 | text='1234567812345678Python' |
|---|
| 175 | c=obj1.encrypt(text) |
|---|
| 176 | if (obj2.decrypt(c)!=text): die('Error encrypting "'+text+'"') |
|---|
| 177 | text='B1FF I2 A R3A11Y |<00L D00D!!!!!' |
|---|
| 178 | c=obj1.encrypt(text) |
|---|
| 179 | if (obj2.decrypt(c)!=text): die('Error encrypting "'+text+'"') |
|---|
| 180 | text='SpamSpamSpamSpamSpamSpamSpamSpamSpam' |
|---|
| 181 | c=obj1.encrypt(text) |
|---|
| 182 | if (obj2.decrypt(c)!=text): die('Error encrypting "'+text+'"') |
|---|
| 183 | |
|---|
| 184 | start=time.time() |
|---|
| 185 | s=obj1.encrypt(str) |
|---|
| 186 | str=obj2.decrypt(s) |
|---|
| 187 | end=time.time() |
|---|
| 188 | print_timing(256, end-start, verbose) |
|---|
| 189 | del obj1, obj2 |
|---|
| 190 | |
|---|
| 191 | return ciph |
|---|
| 192 | |
|---|
| 193 | def TestStreamModules(args=['arc4', 'XOR'], verbose=1): |
|---|
| 194 | import sys, string |
|---|
| 195 | args=map(string.lower, args) |
|---|
| 196 | |
|---|
| 197 | if 'arc4' in args: |
|---|
| 198 | # Test ARC4 stream cipher |
|---|
| 199 | arc4=exerciseStreamCipher('ARC4', verbose) |
|---|
| 200 | if (arc4!=None): |
|---|
| 201 | for entry in testdata.arc4: |
|---|
| 202 | key,plain,cipher=entry |
|---|
| 203 | key=binascii.a2b_hex(key) |
|---|
| 204 | plain=binascii.a2b_hex(plain) |
|---|
| 205 | cipher=binascii.a2b_hex(cipher) |
|---|
| 206 | obj=arc4.new(key) |
|---|
| 207 | ciphertext=obj.encrypt(plain) |
|---|
| 208 | if (ciphertext!=cipher): |
|---|
| 209 | die('ARC4 failed on entry '+`entry`) |
|---|
| 210 | |
|---|
| 211 | if 'xor' in args: |
|---|
| 212 | # Test XOR stream cipher |
|---|
| 213 | XOR=exerciseStreamCipher('XOR', verbose) |
|---|
| 214 | if (XOR!=None): |
|---|
| 215 | for entry in testdata.xor: |
|---|
| 216 | key,plain,cipher=entry |
|---|
| 217 | key=binascii.a2b_hex(key) |
|---|
| 218 | plain=binascii.a2b_hex(plain) |
|---|
| 219 | cipher=binascii.a2b_hex(cipher) |
|---|
| 220 | obj=XOR.new(key) |
|---|
| 221 | ciphertext=obj.encrypt(plain) |
|---|
| 222 | if (ciphertext!=cipher): |
|---|
| 223 | die('XOR failed on entry '+`entry`) |
|---|
| 224 | |
|---|
| 225 | |
|---|
| 226 | def TestBlockModules(args=['aes', 'arc2', 'des', 'blowfish', 'cast', 'des3', |
|---|
| 227 | 'idea', 'rc5'], |
|---|
| 228 | verbose=1): |
|---|
| 229 | import string |
|---|
| 230 | args=map(string.lower, args) |
|---|
| 231 | if 'aes' in args: |
|---|
| 232 | ciph=exerciseBlockCipher('AES', verbose) # AES |
|---|
| 233 | if (ciph!=None): |
|---|
| 234 | if verbose: print ' Verifying against test suite...' |
|---|
| 235 | for entry in testdata.aes: |
|---|
| 236 | key,plain,cipher=entry |
|---|
| 237 | key=binascii.a2b_hex(key) |
|---|
| 238 | plain=binascii.a2b_hex(plain) |
|---|
| 239 | cipher=binascii.a2b_hex(cipher) |
|---|
| 240 | obj=ciph.new(key, ciph.MODE_ECB) |
|---|
| 241 | ciphertext=obj.encrypt(plain) |
|---|
| 242 | if (ciphertext!=cipher): |
|---|
| 243 | die('AES failed on entry '+`entry`) |
|---|
| 244 | for i in ciphertext: |
|---|
| 245 | if verbose: print hex(ord(i)), |
|---|
| 246 | if verbose: print |
|---|
| 247 | |
|---|
| 248 | for entry in testdata.aes_modes: |
|---|
| 249 | mode, key, plain, cipher, kw = entry |
|---|
| 250 | key=binascii.a2b_hex(key) |
|---|
| 251 | plain=binascii.a2b_hex(plain) |
|---|
| 252 | cipher=binascii.a2b_hex(cipher) |
|---|
| 253 | obj=ciph.new(key, mode, **kw) |
|---|
| 254 | obj2=ciph.new(key, mode, **kw) |
|---|
| 255 | ciphertext=obj.encrypt(plain) |
|---|
| 256 | if (ciphertext!=cipher): |
|---|
| 257 | die('AES encrypt failed on entry '+`entry`) |
|---|
| 258 | for i in ciphertext: |
|---|
| 259 | if verbose: print hex(ord(i)), |
|---|
| 260 | if verbose: print |
|---|
| 261 | |
|---|
| 262 | plain2=obj2.decrypt(ciphertext) |
|---|
| 263 | if plain2!=plain: |
|---|
| 264 | die('AES decrypt failed on entry '+`entry`) |
|---|
| 265 | for i in plain2: |
|---|
| 266 | if verbose: print hex(ord(i)), |
|---|
| 267 | if verbose: print |
|---|
| 268 | |
|---|
| 269 | |
|---|
| 270 | if 'arc2' in args: |
|---|
| 271 | ciph=exerciseBlockCipher('ARC2', verbose) # Alleged RC2 |
|---|
| 272 | if (ciph!=None): |
|---|
| 273 | if verbose: print ' Verifying against test suite...' |
|---|
| 274 | for entry in testdata.arc2: |
|---|
| 275 | key,plain,cipher=entry |
|---|
| 276 | key=binascii.a2b_hex(key) |
|---|
| 277 | plain=binascii.a2b_hex(plain) |
|---|
| 278 | cipher=binascii.a2b_hex(cipher) |
|---|
| 279 | obj=ciph.new(key, ciph.MODE_ECB) |
|---|
| 280 | ciphertext=obj.encrypt(plain) |
|---|
| 281 | if (ciphertext!=cipher): |
|---|
| 282 | die('ARC2 failed on entry '+`entry`) |
|---|
| 283 | for i in ciphertext: |
|---|
| 284 | if verbose: print hex(ord(i)), |
|---|
| 285 | print |
|---|
| 286 | |
|---|
| 287 | if 'blowfish' in args: |
|---|
| 288 | ciph=exerciseBlockCipher('Blowfish',verbose)# Bruce Schneier's Blowfish cipher |
|---|
| 289 | if (ciph!=None): |
|---|
| 290 | if verbose: print ' Verifying against test suite...' |
|---|
| 291 | for entry in testdata.blowfish: |
|---|
| 292 | key,plain,cipher=entry |
|---|
| 293 | key=binascii.a2b_hex(key) |
|---|
| 294 | plain=binascii.a2b_hex(plain) |
|---|
| 295 | cipher=binascii.a2b_hex(cipher) |
|---|
| 296 | obj=ciph.new(key, ciph.MODE_ECB) |
|---|
| 297 | ciphertext=obj.encrypt(plain) |
|---|
| 298 | if (ciphertext!=cipher): |
|---|
| 299 | die('Blowfish failed on entry '+`entry`) |
|---|
| 300 | for i in ciphertext: |
|---|
| 301 | if verbose: print hex(ord(i)), |
|---|
| 302 | if verbose: print |
|---|
| 303 | |
|---|
| 304 | if 'cast' in args: |
|---|
| 305 | ciph=exerciseBlockCipher('CAST', verbose) # CAST-128 |
|---|
| 306 | if (ciph!=None): |
|---|
| 307 | if verbose: print ' Verifying against test suite...' |
|---|
| 308 | for entry in testdata.cast: |
|---|
| 309 | key,plain,cipher=entry |
|---|
| 310 | key=binascii.a2b_hex(key) |
|---|
| 311 | plain=binascii.a2b_hex(plain) |
|---|
| 312 | cipher=binascii.a2b_hex(cipher) |
|---|
| 313 | obj=ciph.new(key, ciph.MODE_ECB) |
|---|
| 314 | ciphertext=obj.encrypt(plain) |
|---|
| 315 | if (ciphertext!=cipher): |
|---|
| 316 | die('CAST failed on entry '+`entry`) |
|---|
| 317 | for i in ciphertext: |
|---|
| 318 | if verbose: print hex(ord(i)), |
|---|
| 319 | if verbose: print |
|---|
| 320 | |
|---|
| 321 | if 0: |
|---|
| 322 | # The full-maintenance test; it requires 4 million encryptions, |
|---|
| 323 | # and correspondingly is quite time-consuming. I've disabled |
|---|
| 324 | # it; it's faster to compile block/cast.c with -DTEST and run |
|---|
| 325 | # the resulting program. |
|---|
| 326 | a = b = '\x01\x23\x45\x67\x12\x34\x56\x78\x23\x45\x67\x89\x34\x56\x78\x9A' |
|---|
| 327 | |
|---|
| 328 | for i in range(0, 1000000): |
|---|
| 329 | obj = cast.new(b, cast.MODE_ECB) |
|---|
| 330 | a = obj.encrypt(a[:8]) + obj.encrypt(a[-8:]) |
|---|
| 331 | obj = cast.new(a, cast.MODE_ECB) |
|---|
| 332 | b = obj.encrypt(b[:8]) + obj.encrypt(b[-8:]) |
|---|
| 333 | |
|---|
| 334 | if a!="\xEE\xA9\xD0\xA2\x49\xFD\x3B\xA6\xB3\x43\x6F\xB8\x9D\x6D\xCA\x92": |
|---|
| 335 | if verbose: print 'CAST test failed: value of "a" doesn\'t match' |
|---|
| 336 | if b!="\xB2\xC9\x5E\xB0\x0C\x31\xAD\x71\x80\xAC\x05\xB8\xE8\x3D\x69\x6E": |
|---|
| 337 | if verbose: print 'CAST test failed: value of "b" doesn\'t match' |
|---|
| 338 | |
|---|
| 339 | if 'des' in args: |
|---|
| 340 | # Test/benchmark DES block cipher |
|---|
| 341 | des=exerciseBlockCipher('DES', verbose) |
|---|
| 342 | if (des!=None): |
|---|
| 343 | # Various tests taken from the DES library packaged with Kerberos V4 |
|---|
| 344 | obj=des.new(binascii.a2b_hex('0123456789abcdef'), des.MODE_ECB) |
|---|
| 345 | s=obj.encrypt('Now is t') |
|---|
| 346 | if (s!=binascii.a2b_hex('3fa40e8a984d4815')): |
|---|
| 347 | die('DES fails test 1') |
|---|
| 348 | obj=des.new(binascii.a2b_hex('08192a3b4c5d6e7f'), des.MODE_ECB) |
|---|
| 349 | s=obj.encrypt('\000\000\000\000\000\000\000\000') |
|---|
| 350 | if (s!=binascii.a2b_hex('25ddac3e96176467')): |
|---|
| 351 | die('DES fails test 2') |
|---|
| 352 | obj=des.new(binascii.a2b_hex('0123456789abcdef'), des.MODE_CBC, |
|---|
| 353 | binascii.a2b_hex('1234567890abcdef')) |
|---|
| 354 | s=obj.encrypt("Now is the time for all ") |
|---|
| 355 | if (s!=binascii.a2b_hex('e5c7cdde872bf27c43e934008c389c0f683788499a7c05f6')): |
|---|
| 356 | die('DES fails test 3') |
|---|
| 357 | obj=des.new(binascii.a2b_hex('0123456789abcdef'), des.MODE_CBC, |
|---|
| 358 | binascii.a2b_hex('fedcba9876543210')) |
|---|
| 359 | s=obj.encrypt("7654321 Now is the time for \000\000\000\000") |
|---|
| 360 | if (s!=binascii.a2b_hex("ccd173ffab2039f4acd8aefddfd8a1eb468e91157888ba681d269397f7fe62b4")): |
|---|
| 361 | die('DES fails test 4') |
|---|
| 362 | del obj,s |
|---|
| 363 | |
|---|
| 364 | # R. Rivest's test: see http://theory.lcs.mit.edu/~rivest/destest.txt |
|---|
| 365 | x=binascii.a2b_hex('9474B8E8C73BCA7D') |
|---|
| 366 | for i in range(0, 16): |
|---|
| 367 | obj=des.new(x, des.MODE_ECB) |
|---|
| 368 | if (i & 1): x=obj.decrypt(x) |
|---|
| 369 | else: x=obj.encrypt(x) |
|---|
| 370 | if x!=binascii.a2b_hex('1B1A2DDB4C642438'): |
|---|
| 371 | die("DES fails Rivest's test") |
|---|
| 372 | |
|---|
| 373 | if verbose: print ' Verifying against test suite...' |
|---|
| 374 | for entry in testdata.des: |
|---|
| 375 | key,plain,cipher=entry |
|---|
| 376 | key=binascii.a2b_hex(key) |
|---|
| 377 | plain=binascii.a2b_hex(plain) |
|---|
| 378 | cipher=binascii.a2b_hex(cipher) |
|---|
| 379 | obj=des.new(key, des.MODE_ECB) |
|---|
| 380 | ciphertext=obj.encrypt(plain) |
|---|
| 381 | if (ciphertext!=cipher): |
|---|
| 382 | die('DES failed on entry '+`entry`) |
|---|
| 383 | for entry in testdata.des_cbc: |
|---|
| 384 | key, iv, plain, cipher=entry |
|---|
| 385 | key, iv, cipher=binascii.a2b_hex(key),binascii.a2b_hex(iv),binascii.a2b_hex(cipher) |
|---|
| 386 | obj1=des.new(key, des.MODE_CBC, iv) |
|---|
| 387 | obj2=des.new(key, des.MODE_CBC, iv) |
|---|
| 388 | ciphertext=obj1.encrypt(plain) |
|---|
| 389 | if (ciphertext!=cipher): |
|---|
| 390 | die('DES CBC mode failed on entry '+`entry`) |
|---|
| 391 | |
|---|
| 392 | if 'des3' in args: |
|---|
| 393 | ciph=exerciseBlockCipher('DES3', verbose) # Triple DES |
|---|
| 394 | if (ciph!=None): |
|---|
| 395 | if verbose: print ' Verifying against test suite...' |
|---|
| 396 | for entry in testdata.des3: |
|---|
| 397 | key,plain,cipher=entry |
|---|
| 398 | key=binascii.a2b_hex(key) |
|---|
| 399 | plain=binascii.a2b_hex(plain) |
|---|
| 400 | cipher=binascii.a2b_hex(cipher) |
|---|
| 401 | obj=ciph.new(key, ciph.MODE_ECB) |
|---|
| 402 | ciphertext=obj.encrypt(plain) |
|---|
| 403 | if (ciphertext!=cipher): |
|---|
| 404 | die('DES3 failed on entry '+`entry`) |
|---|
| 405 | for i in ciphertext: |
|---|
| 406 | if verbose: print hex(ord(i)), |
|---|
| 407 | if verbose: print |
|---|
| 408 | for entry in testdata.des3_cbc: |
|---|
| 409 | key, iv, plain, cipher=entry |
|---|
| 410 | key, iv, cipher=binascii.a2b_hex(key),binascii.a2b_hex(iv),binascii.a2b_hex(cipher) |
|---|
| 411 | obj1=ciph.new(key, ciph.MODE_CBC, iv) |
|---|
| 412 | obj2=ciph.new(key, ciph.MODE_CBC, iv) |
|---|
| 413 | ciphertext=obj1.encrypt(plain) |
|---|
| 414 | if (ciphertext!=cipher): |
|---|
| 415 | die('DES3 CBC mode failed on entry '+`entry`) |
|---|
| 416 | |
|---|
| 417 | if 'idea' in args: |
|---|
| 418 | ciph=exerciseBlockCipher('IDEA', verbose) # IDEA block cipher |
|---|
| 419 | if (ciph!=None): |
|---|
| 420 | if verbose: print ' Verifying against test suite...' |
|---|
| 421 | for entry in testdata.idea: |
|---|
| 422 | key,plain,cipher=entry |
|---|
| 423 | key=binascii.a2b_hex(key) |
|---|
| 424 | plain=binascii.a2b_hex(plain) |
|---|
| 425 | cipher=binascii.a2b_hex(cipher) |
|---|
| 426 | obj=ciph.new(key, ciph.MODE_ECB) |
|---|
| 427 | ciphertext=obj.encrypt(plain) |
|---|
| 428 | if (ciphertext!=cipher): |
|---|
| 429 | die('IDEA failed on entry '+`entry`) |
|---|
| 430 | |
|---|
| 431 | if 'rc5' in args: |
|---|
| 432 | # Ronald Rivest's RC5 algorithm |
|---|
| 433 | ciph=exerciseBlockCipher('RC5', verbose) |
|---|
| 434 | if (ciph!=None): |
|---|
| 435 | if verbose: print ' Verifying against test suite...' |
|---|
| 436 | for entry in testdata.rc5: |
|---|
| 437 | key,plain,cipher=entry |
|---|
| 438 | key=binascii.a2b_hex(key) |
|---|
| 439 | plain=binascii.a2b_hex(plain) |
|---|
| 440 | cipher=binascii.a2b_hex(cipher) |
|---|
| 441 | obj=ciph.new(key[4:], ciph.MODE_ECB, |
|---|
| 442 | version =ord(key[0]), |
|---|
| 443 | word_size=ord(key[1]), |
|---|
| 444 | rounds =ord(key[2]) ) |
|---|
| 445 | ciphertext=obj.encrypt(plain) |
|---|
| 446 | if (ciphertext!=cipher): |
|---|
| 447 | die('RC5 failed on entry '+`entry`) |
|---|
| 448 | for i in ciphertext: |
|---|
| 449 | if verbose: print hex(ord(i)), |
|---|
| 450 | if verbose: print |
|---|
| 451 | |
|---|
| 452 | |
|---|
| 453 | |
|---|