PageRenderTime 33ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/gdata/Crypto/Util/test.py

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