common.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. # -*- coding: utf-8 -*-
  2. #
  3. # SelfTest/Hash/common.py: Common code for Crypto.SelfTest.Hash
  4. #
  5. # Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
  6. #
  7. # ===================================================================
  8. # The contents of this file are dedicated to the public domain. To
  9. # the extent that dedication to the public domain is not available,
  10. # everyone is granted a worldwide, perpetual, royalty-free,
  11. # non-exclusive license to exercise all rights associated with the
  12. # contents of this file for any purpose whatsoever.
  13. # No rights are reserved.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19. # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  20. # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. # SOFTWARE.
  23. # ===================================================================
  24. """Self-testing for PyCrypto hash modules"""
  25. __revision__ = "$Id$"
  26. import sys
  27. import unittest
  28. import binascii
  29. from Crypto.Util.py3compat import *
  30. # For compatibility with Python 2.1 and Python 2.2
  31. if sys.hexversion < 0x02030000:
  32. # Python 2.1 doesn't have a dict() function
  33. # Python 2.2 dict() function raises TypeError if you do dict(MD5='blah')
  34. def dict(**kwargs):
  35. return kwargs.copy()
  36. else:
  37. dict = dict
  38. class HashDigestSizeSelfTest(unittest.TestCase):
  39. def __init__(self, hashmod, description, expected):
  40. unittest.TestCase.__init__(self)
  41. self.hashmod = hashmod
  42. self.expected = expected
  43. self.description = description
  44. def shortDescription(self):
  45. return self.description
  46. def runTest(self):
  47. self.failUnless(hasattr(self.hashmod, "digest_size"))
  48. self.assertEquals(self.hashmod.digest_size, self.expected)
  49. h = self.hashmod.new()
  50. self.failUnless(hasattr(h, "digest_size"))
  51. self.assertEquals(h.digest_size, self.expected)
  52. class HashSelfTest(unittest.TestCase):
  53. def __init__(self, hashmod, description, expected, input):
  54. unittest.TestCase.__init__(self)
  55. self.hashmod = hashmod
  56. self.expected = expected
  57. self.input = input
  58. self.description = description
  59. def shortDescription(self):
  60. return self.description
  61. def runTest(self):
  62. h = self.hashmod.new()
  63. h.update(self.input)
  64. out1 = binascii.b2a_hex(h.digest())
  65. out2 = h.hexdigest()
  66. h = self.hashmod.new(self.input)
  67. out3 = h.hexdigest()
  68. out4 = binascii.b2a_hex(h.digest())
  69. # PY3K: hexdigest() should return str(), and digest() bytes
  70. self.assertEqual(self.expected, out1) # h = .new(); h.update(data); h.digest()
  71. if sys.version_info[0] == 2:
  72. self.assertEqual(self.expected, out2) # h = .new(); h.update(data); h.hexdigest()
  73. self.assertEqual(self.expected, out3) # h = .new(data); h.hexdigest()
  74. else:
  75. self.assertEqual(self.expected.decode(), out2) # h = .new(); h.update(data); h.hexdigest()
  76. self.assertEqual(self.expected.decode(), out3) # h = .new(data); h.hexdigest()
  77. self.assertEqual(self.expected, out4) # h = .new(data); h.digest()
  78. # Verify that new() object method produces a fresh hash object
  79. h2 = h.new()
  80. h2.update(self.input)
  81. out5 = binascii.b2a_hex(h2.digest())
  82. self.assertEqual(self.expected, out5)
  83. class HashTestOID(unittest.TestCase):
  84. def __init__(self, hashmod, oid):
  85. unittest.TestCase.__init__(self)
  86. self.hashmod = hashmod
  87. self.oid = oid
  88. def runTest(self):
  89. h = self.hashmod.new()
  90. if self.oid==None:
  91. try:
  92. raised = 0
  93. a = h.oid
  94. except AttributeError:
  95. raised = 1
  96. self.assertEqual(raised,1)
  97. else:
  98. self.assertEqual(h.oid, self.oid)
  99. class MACSelfTest(unittest.TestCase):
  100. def __init__(self, hashmod, description, expected_dict, input, key, hashmods):
  101. unittest.TestCase.__init__(self)
  102. self.hashmod = hashmod
  103. self.expected_dict = expected_dict
  104. self.input = input
  105. self.key = key
  106. self.hashmods = hashmods
  107. self.description = description
  108. def shortDescription(self):
  109. return self.description
  110. def runTest(self):
  111. for hashname in self.expected_dict.keys():
  112. hashmod = self.hashmods[hashname]
  113. key = binascii.a2b_hex(b(self.key))
  114. data = binascii.a2b_hex(b(self.input))
  115. # Strip whitespace from the expected string (which should be in lowercase-hex)
  116. expected = b("".join(self.expected_dict[hashname].split()))
  117. h = self.hashmod.new(key, digestmod=hashmod)
  118. h.update(data)
  119. out1 = binascii.b2a_hex(h.digest())
  120. out2 = h.hexdigest()
  121. h = self.hashmod.new(key, data, hashmod)
  122. out3 = h.hexdigest()
  123. out4 = binascii.b2a_hex(h.digest())
  124. # Test .copy()
  125. h2 = h.copy()
  126. h.update(b("blah blah blah")) # Corrupt the original hash object
  127. out5 = binascii.b2a_hex(h2.digest()) # The copied hash object should return the correct result
  128. # PY3K: hexdigest() should return str(), and digest() bytes
  129. self.assertEqual(expected, out1)
  130. if sys.version_info[0] == 2:
  131. self.assertEqual(expected, out2)
  132. self.assertEqual(expected, out3)
  133. else:
  134. self.assertEqual(expected.decode(), out2)
  135. self.assertEqual(expected.decode(), out3)
  136. self.assertEqual(expected, out4)
  137. self.assertEqual(expected, out5)
  138. def make_hash_tests(module, module_name, test_data, digest_size, oid=None):
  139. tests = []
  140. for i in range(len(test_data)):
  141. row = test_data[i]
  142. (expected, input) = map(b,row[0:2])
  143. if len(row) < 3:
  144. description = repr(input)
  145. else:
  146. description = row[2].encode('latin-1')
  147. name = "%s #%d: %s" % (module_name, i+1, description)
  148. tests.append(HashSelfTest(module, name, expected, input))
  149. if oid is not None:
  150. oid = b(oid)
  151. name = "%s #%d: digest_size" % (module_name, i+1)
  152. tests.append(HashDigestSizeSelfTest(module, name, digest_size))
  153. tests.append(HashTestOID(module, oid))
  154. return tests
  155. def make_mac_tests(module, module_name, test_data, hashmods):
  156. tests = []
  157. for i in range(len(test_data)):
  158. row = test_data[i]
  159. (key, data, results, description) = row
  160. name = "%s #%d: %s" % (module_name, i+1, description)
  161. tests.append(MACSelfTest(module, name, results, data, key, hashmods))
  162. return tests
  163. # vim:set ts=4 sw=4 sts=4 expandtab: