test_strxor.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #
  2. # SelfTest/Util/test_strxor.py: Self-test for XORing
  3. #
  4. # ===================================================================
  5. #
  6. # Copyright (c) 2014, Legrandin <helderijs@gmail.com>
  7. # All rights reserved.
  8. #
  9. # Redistribution and use in source and binary forms, with or without
  10. # modification, are permitted provided that the following conditions
  11. # are met:
  12. #
  13. # 1. Redistributions of source code must retain the above copyright
  14. # notice, this list of conditions and the following disclaimer.
  15. # 2. Redistributions in binary form must reproduce the above copyright
  16. # notice, this list of conditions and the following disclaimer in
  17. # the documentation and/or other materials provided with the
  18. # distribution.
  19. #
  20. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  23. # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  24. # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  26. # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27. # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  28. # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  30. # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  31. # POSSIBILITY OF SUCH DAMAGE.
  32. # ===================================================================
  33. import unittest
  34. from binascii import unhexlify, hexlify
  35. from Cryptodome.SelfTest.st_common import list_test_cases
  36. from Cryptodome.Util.strxor import strxor, strxor_c
  37. class StrxorTests(unittest.TestCase):
  38. def test1(self):
  39. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  40. term2 = unhexlify(b"383d4ba020573314395b")
  41. result = unhexlify(b"c70ed123c59a7fcb6f12")
  42. self.assertEqual(strxor(term1, term2), result)
  43. self.assertEqual(strxor(term2, term1), result)
  44. def test2(self):
  45. es = b""
  46. self.assertEqual(strxor(es, es), es)
  47. def test3(self):
  48. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  49. all_zeros = b"\x00" * len(term1)
  50. self.assertEqual(strxor(term1, term1), all_zeros)
  51. def test_wrong_length(self):
  52. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  53. term2 = unhexlify(b"ff339a83e5cd4cdf564990")
  54. self.assertRaises(ValueError, strxor, term1, term2)
  55. def test_bytearray(self):
  56. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  57. term1_ba = bytearray(term1)
  58. term2 = unhexlify(b"383d4ba020573314395b")
  59. result = unhexlify(b"c70ed123c59a7fcb6f12")
  60. self.assertEqual(strxor(term1_ba, term2), result)
  61. def test_memoryview(self):
  62. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  63. term1_mv = memoryview(term1)
  64. term2 = unhexlify(b"383d4ba020573314395b")
  65. result = unhexlify(b"c70ed123c59a7fcb6f12")
  66. self.assertEqual(strxor(term1_mv, term2), result)
  67. def test_output_bytearray(self):
  68. """Verify result can be stored in pre-allocated memory"""
  69. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  70. term2 = unhexlify(b"383d4ba020573314395b")
  71. original_term1 = term1[:]
  72. original_term2 = term2[:]
  73. expected_xor = unhexlify(b"c70ed123c59a7fcb6f12")
  74. output = bytearray(len(term1))
  75. result = strxor(term1, term2, output=output)
  76. self.assertEqual(result, None)
  77. self.assertEqual(output, expected_xor)
  78. self.assertEqual(term1, original_term1)
  79. self.assertEqual(term2, original_term2)
  80. def test_output_memoryview(self):
  81. """Verify result can be stored in pre-allocated memory"""
  82. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  83. term2 = unhexlify(b"383d4ba020573314395b")
  84. original_term1 = term1[:]
  85. original_term2 = term2[:]
  86. expected_xor = unhexlify(b"c70ed123c59a7fcb6f12")
  87. output = memoryview(bytearray(len(term1)))
  88. result = strxor(term1, term2, output=output)
  89. self.assertEqual(result, None)
  90. self.assertEqual(output, expected_xor)
  91. self.assertEqual(term1, original_term1)
  92. self.assertEqual(term2, original_term2)
  93. def test_output_overlapping_bytearray(self):
  94. """Verify result can be stored in overlapping memory"""
  95. term1 = bytearray(unhexlify(b"ff339a83e5cd4cdf5649"))
  96. term2 = unhexlify(b"383d4ba020573314395b")
  97. original_term2 = term2[:]
  98. expected_xor = unhexlify(b"c70ed123c59a7fcb6f12")
  99. result = strxor(term1, term2, output=term1)
  100. self.assertEqual(result, None)
  101. self.assertEqual(term1, expected_xor)
  102. self.assertEqual(term2, original_term2)
  103. def test_output_overlapping_memoryview(self):
  104. """Verify result can be stored in overlapping memory"""
  105. term1 = memoryview(bytearray(unhexlify(b"ff339a83e5cd4cdf5649")))
  106. term2 = unhexlify(b"383d4ba020573314395b")
  107. original_term2 = term2[:]
  108. expected_xor = unhexlify(b"c70ed123c59a7fcb6f12")
  109. result = strxor(term1, term2, output=term1)
  110. self.assertEqual(result, None)
  111. self.assertEqual(term1, expected_xor)
  112. self.assertEqual(term2, original_term2)
  113. def test_output_ro_bytes(self):
  114. """Verify result cannot be stored in read-only memory"""
  115. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  116. term2 = unhexlify(b"383d4ba020573314395b")
  117. self.assertRaises(TypeError, strxor, term1, term2, output=term1)
  118. def test_output_ro_memoryview(self):
  119. """Verify result cannot be stored in read-only memory"""
  120. term1 = memoryview(unhexlify(b"ff339a83e5cd4cdf5649"))
  121. term2 = unhexlify(b"383d4ba020573314395b")
  122. self.assertRaises(TypeError, strxor, term1, term2, output=term1)
  123. def test_output_incorrect_length(self):
  124. """Verify result cannot be stored in memory of incorrect length"""
  125. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  126. term2 = unhexlify(b"383d4ba020573314395b")
  127. output = bytearray(len(term1) - 1)
  128. self.assertRaises(ValueError, strxor, term1, term2, output=output)
  129. class Strxor_cTests(unittest.TestCase):
  130. def test1(self):
  131. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  132. result = unhexlify(b"be72dbc2a48c0d9e1708")
  133. self.assertEqual(strxor_c(term1, 65), result)
  134. def test2(self):
  135. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  136. self.assertEqual(strxor_c(term1, 0), term1)
  137. def test3(self):
  138. self.assertEqual(strxor_c(b"", 90), b"")
  139. def test_wrong_range(self):
  140. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  141. self.assertRaises(ValueError, strxor_c, term1, -1)
  142. self.assertRaises(ValueError, strxor_c, term1, 256)
  143. def test_bytearray(self):
  144. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  145. term1_ba = bytearray(term1)
  146. result = unhexlify(b"be72dbc2a48c0d9e1708")
  147. self.assertEqual(strxor_c(term1_ba, 65), result)
  148. def test_memoryview(self):
  149. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  150. term1_mv = memoryview(term1)
  151. result = unhexlify(b"be72dbc2a48c0d9e1708")
  152. self.assertEqual(strxor_c(term1_mv, 65), result)
  153. def test_output_bytearray(self):
  154. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  155. original_term1 = term1[:]
  156. expected_result = unhexlify(b"be72dbc2a48c0d9e1708")
  157. output = bytearray(len(term1))
  158. result = strxor_c(term1, 65, output=output)
  159. self.assertEqual(result, None)
  160. self.assertEqual(output, expected_result)
  161. self.assertEqual(term1, original_term1)
  162. def test_output_memoryview(self):
  163. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  164. original_term1 = term1[:]
  165. expected_result = unhexlify(b"be72dbc2a48c0d9e1708")
  166. output = memoryview(bytearray(len(term1)))
  167. result = strxor_c(term1, 65, output=output)
  168. self.assertEqual(result, None)
  169. self.assertEqual(output, expected_result)
  170. self.assertEqual(term1, original_term1)
  171. def test_output_overlapping_bytearray(self):
  172. """Verify result can be stored in overlapping memory"""
  173. term1 = bytearray(unhexlify(b"ff339a83e5cd4cdf5649"))
  174. expected_xor = unhexlify(b"be72dbc2a48c0d9e1708")
  175. result = strxor_c(term1, 65, output=term1)
  176. self.assertEqual(result, None)
  177. self.assertEqual(term1, expected_xor)
  178. def test_output_overlapping_memoryview(self):
  179. """Verify result can be stored in overlapping memory"""
  180. term1 = memoryview(bytearray(unhexlify(b"ff339a83e5cd4cdf5649")))
  181. expected_xor = unhexlify(b"be72dbc2a48c0d9e1708")
  182. result = strxor_c(term1, 65, output=term1)
  183. self.assertEqual(result, None)
  184. self.assertEqual(term1, expected_xor)
  185. def test_output_ro_bytes(self):
  186. """Verify result cannot be stored in read-only memory"""
  187. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  188. self.assertRaises(TypeError, strxor_c, term1, 65, output=term1)
  189. def test_output_ro_memoryview(self):
  190. """Verify result cannot be stored in read-only memory"""
  191. term1 = memoryview(unhexlify(b"ff339a83e5cd4cdf5649"))
  192. term2 = unhexlify(b"383d4ba020573314395b")
  193. self.assertRaises(TypeError, strxor_c, term1, 65, output=term1)
  194. def test_output_incorrect_length(self):
  195. """Verify result cannot be stored in memory of incorrect length"""
  196. term1 = unhexlify(b"ff339a83e5cd4cdf5649")
  197. output = bytearray(len(term1) - 1)
  198. self.assertRaises(ValueError, strxor_c, term1, 65, output=output)
  199. def get_tests(config={}):
  200. tests = []
  201. tests += list_test_cases(StrxorTests)
  202. tests += list_test_cases(Strxor_cTests)
  203. return tests
  204. if __name__ == '__main__':
  205. suite = lambda: unittest.TestSuite(get_tests())
  206. unittest.main(defaultTest='suite')