home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 April / enter-2004-04.iso / files / EVE_1424_100181.exe / test.py < prev    next >
Encoding:
Python Source  |  2004-04-20  |  18.1 KB  |  447 lines

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