test_RSA.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. # -*- coding: utf-8 -*-
  2. #
  3. # SelfTest/PublicKey/test_RSA.py: Self-test for the RSA primitive
  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-test suite for Crypto.PublicKey.RSA"""
  25. __revision__ = "$Id$"
  26. import sys
  27. import os
  28. if sys.version_info[0] == 2 and sys.version_info[1] == 1:
  29. from Crypto.Util.py21compat import *
  30. from Crypto.Util.py3compat import *
  31. import unittest
  32. from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
  33. class RSATest(unittest.TestCase):
  34. # Test vectors from "RSA-OAEP and RSA-PSS test vectors (.zip file)"
  35. # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
  36. # See RSADSI's PKCS#1 page at
  37. # http://www.rsa.com/rsalabs/node.asp?id=2125
  38. # from oaep-int.txt
  39. # TODO: PyCrypto treats the message as starting *after* the leading "00"
  40. # TODO: That behaviour should probably be changed in the future.
  41. plaintext = """
  42. eb 7a 19 ac e9 e3 00 63 50 e3 29 50 4b 45 e2
  43. ca 82 31 0b 26 dc d8 7d 5c 68 f1 ee a8 f5 52 67
  44. c3 1b 2e 8b b4 25 1f 84 d7 e0 b2 c0 46 26 f5 af
  45. f9 3e dc fb 25 c9 c2 b3 ff 8a e1 0e 83 9a 2d db
  46. 4c dc fe 4f f4 77 28 b4 a1 b7 c1 36 2b aa d2 9a
  47. b4 8d 28 69 d5 02 41 21 43 58 11 59 1b e3 92 f9
  48. 82 fb 3e 87 d0 95 ae b4 04 48 db 97 2f 3a c1 4f
  49. 7b c2 75 19 52 81 ce 32 d2 f1 b7 6d 4d 35 3e 2d
  50. """
  51. ciphertext = """
  52. 12 53 e0 4d c0 a5 39 7b b4 4a 7a b8 7e 9b f2 a0
  53. 39 a3 3d 1e 99 6f c8 2a 94 cc d3 00 74 c9 5d f7
  54. 63 72 20 17 06 9e 52 68 da 5d 1c 0b 4f 87 2c f6
  55. 53 c1 1d f8 23 14 a6 79 68 df ea e2 8d ef 04 bb
  56. 6d 84 b1 c3 1d 65 4a 19 70 e5 78 3b d6 eb 96 a0
  57. 24 c2 ca 2f 4a 90 fe 9f 2e f5 c9 c1 40 e5 bb 48
  58. da 95 36 ad 87 00 c8 4f c9 13 0a de a7 4e 55 8d
  59. 51 a7 4d df 85 d8 b5 0d e9 68 38 d6 06 3e 09 55
  60. """
  61. modulus = """
  62. bb f8 2f 09 06 82 ce 9c 23 38 ac 2b 9d a8 71 f7
  63. 36 8d 07 ee d4 10 43 a4 40 d6 b6 f0 74 54 f5 1f
  64. b8 df ba af 03 5c 02 ab 61 ea 48 ce eb 6f cd 48
  65. 76 ed 52 0d 60 e1 ec 46 19 71 9d 8a 5b 8b 80 7f
  66. af b8 e0 a3 df c7 37 72 3e e6 b4 b7 d9 3a 25 84
  67. ee 6a 64 9d 06 09 53 74 88 34 b2 45 45 98 39 4e
  68. e0 aa b1 2d 7b 61 a5 1f 52 7a 9a 41 f6 c1 68 7f
  69. e2 53 72 98 ca 2a 8f 59 46 f8 e5 fd 09 1d bd cb
  70. """
  71. e = 0x11L # public exponent
  72. prime_factor = """
  73. c9 7f b1 f0 27 f4 53 f6 34 12 33 ea aa d1 d9 35
  74. 3f 6c 42 d0 88 66 b1 d0 5a 0f 20 35 02 8b 9d 86
  75. 98 40 b4 16 66 b4 2e 92 ea 0d a3 b4 32 04 b5 cf
  76. ce 33 52 52 4d 04 16 a5 a4 41 e7 00 af 46 15 03
  77. """
  78. def setUp(self):
  79. global RSA, Random, bytes_to_long
  80. from Crypto.PublicKey import RSA
  81. from Crypto import Random
  82. from Crypto.Util.number import bytes_to_long, inverse
  83. self.n = bytes_to_long(a2b_hex(self.modulus))
  84. self.p = bytes_to_long(a2b_hex(self.prime_factor))
  85. # Compute q, d, and u from n, e, and p
  86. self.q = divmod(self.n, self.p)[0]
  87. self.d = inverse(self.e, (self.p-1)*(self.q-1))
  88. self.u = inverse(self.p, self.q) # u = e**-1 (mod q)
  89. self.rsa = RSA
  90. def test_generate_1arg(self):
  91. """RSA (default implementation) generated key (1 argument)"""
  92. rsaObj = self.rsa.generate(1024)
  93. self._check_private_key(rsaObj)
  94. self._exercise_primitive(rsaObj)
  95. pub = rsaObj.publickey()
  96. self._check_public_key(pub)
  97. self._exercise_public_primitive(rsaObj)
  98. def test_generate_2arg(self):
  99. """RSA (default implementation) generated key (2 arguments)"""
  100. rsaObj = self.rsa.generate(1024, Random.new().read)
  101. self._check_private_key(rsaObj)
  102. self._exercise_primitive(rsaObj)
  103. pub = rsaObj.publickey()
  104. self._check_public_key(pub)
  105. self._exercise_public_primitive(rsaObj)
  106. def test_generate_3args(self):
  107. rsaObj = self.rsa.generate(1024, Random.new().read,e=65537)
  108. self._check_private_key(rsaObj)
  109. self._exercise_primitive(rsaObj)
  110. pub = rsaObj.publickey()
  111. self._check_public_key(pub)
  112. self._exercise_public_primitive(rsaObj)
  113. self.assertEqual(65537,rsaObj.e)
  114. def test_construct_2tuple(self):
  115. """RSA (default implementation) constructed key (2-tuple)"""
  116. pub = self.rsa.construct((self.n, self.e))
  117. self._check_public_key(pub)
  118. self._check_encryption(pub)
  119. self._check_verification(pub)
  120. def test_construct_3tuple(self):
  121. """RSA (default implementation) constructed key (3-tuple)"""
  122. rsaObj = self.rsa.construct((self.n, self.e, self.d))
  123. self._check_encryption(rsaObj)
  124. self._check_decryption(rsaObj)
  125. self._check_signing(rsaObj)
  126. self._check_verification(rsaObj)
  127. def test_construct_4tuple(self):
  128. """RSA (default implementation) constructed key (4-tuple)"""
  129. rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p))
  130. self._check_encryption(rsaObj)
  131. self._check_decryption(rsaObj)
  132. self._check_signing(rsaObj)
  133. self._check_verification(rsaObj)
  134. def test_construct_5tuple(self):
  135. """RSA (default implementation) constructed key (5-tuple)"""
  136. rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q))
  137. self._check_private_key(rsaObj)
  138. self._check_encryption(rsaObj)
  139. self._check_decryption(rsaObj)
  140. self._check_signing(rsaObj)
  141. self._check_verification(rsaObj)
  142. def test_construct_6tuple(self):
  143. """RSA (default implementation) constructed key (6-tuple)"""
  144. rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q, self.u))
  145. self._check_private_key(rsaObj)
  146. self._check_encryption(rsaObj)
  147. self._check_decryption(rsaObj)
  148. self._check_signing(rsaObj)
  149. self._check_verification(rsaObj)
  150. def test_factoring(self):
  151. rsaObj = self.rsa.construct([self.n, self.e, self.d])
  152. self.failUnless(rsaObj.p==self.p or rsaObj.p==self.q)
  153. self.failUnless(rsaObj.q==self.p or rsaObj.q==self.q)
  154. self.failUnless(rsaObj.q*rsaObj.p == self.n)
  155. self.assertRaises(ValueError, self.rsa.construct, [self.n, self.e, self.n-1])
  156. def _check_private_key(self, rsaObj):
  157. # Check capabilities
  158. self.assertEqual(1, rsaObj.has_private())
  159. self.assertEqual(1, rsaObj.can_sign())
  160. self.assertEqual(1, rsaObj.can_encrypt())
  161. self.assertEqual(1, rsaObj.can_blind())
  162. # Check rsaObj.[nedpqu] -> rsaObj.key.[nedpqu] mapping
  163. self.assertEqual(rsaObj.n, rsaObj.key.n)
  164. self.assertEqual(rsaObj.e, rsaObj.key.e)
  165. self.assertEqual(rsaObj.d, rsaObj.key.d)
  166. self.assertEqual(rsaObj.p, rsaObj.key.p)
  167. self.assertEqual(rsaObj.q, rsaObj.key.q)
  168. self.assertEqual(rsaObj.u, rsaObj.key.u)
  169. # Sanity check key data
  170. self.assertEqual(rsaObj.n, rsaObj.p * rsaObj.q) # n = pq
  171. self.assertEqual(1, rsaObj.d * rsaObj.e % ((rsaObj.p-1) * (rsaObj.q-1))) # ed = 1 (mod (p-1)(q-1))
  172. self.assertEqual(1, rsaObj.p * rsaObj.u % rsaObj.q) # pu = 1 (mod q)
  173. self.assertEqual(1, rsaObj.p > 1) # p > 1
  174. self.assertEqual(1, rsaObj.q > 1) # q > 1
  175. self.assertEqual(1, rsaObj.e > 1) # e > 1
  176. self.assertEqual(1, rsaObj.d > 1) # d > 1
  177. def _check_public_key(self, rsaObj):
  178. ciphertext = a2b_hex(self.ciphertext)
  179. # Check capabilities
  180. self.assertEqual(0, rsaObj.has_private())
  181. self.assertEqual(1, rsaObj.can_sign())
  182. self.assertEqual(1, rsaObj.can_encrypt())
  183. self.assertEqual(1, rsaObj.can_blind())
  184. # Check rsaObj.[ne] -> rsaObj.key.[ne] mapping
  185. self.assertEqual(rsaObj.n, rsaObj.key.n)
  186. self.assertEqual(rsaObj.e, rsaObj.key.e)
  187. # Check that private parameters are all missing
  188. self.assertEqual(0, hasattr(rsaObj, 'd'))
  189. self.assertEqual(0, hasattr(rsaObj, 'p'))
  190. self.assertEqual(0, hasattr(rsaObj, 'q'))
  191. self.assertEqual(0, hasattr(rsaObj, 'u'))
  192. self.assertEqual(0, hasattr(rsaObj.key, 'd'))
  193. self.assertEqual(0, hasattr(rsaObj.key, 'p'))
  194. self.assertEqual(0, hasattr(rsaObj.key, 'q'))
  195. self.assertEqual(0, hasattr(rsaObj.key, 'u'))
  196. # Sanity check key data
  197. self.assertEqual(1, rsaObj.e > 1) # e > 1
  198. # Public keys should not be able to sign or decrypt
  199. self.assertRaises(TypeError, rsaObj.sign, ciphertext, b(""))
  200. self.assertRaises(TypeError, rsaObj.decrypt, ciphertext)
  201. # Check __eq__ and __ne__
  202. self.assertEqual(rsaObj.publickey() == rsaObj.publickey(),True) # assert_
  203. self.assertEqual(rsaObj.publickey() != rsaObj.publickey(),False) # failIf
  204. def _exercise_primitive(self, rsaObj):
  205. # Since we're using a randomly-generated key, we can't check the test
  206. # vector, but we can make sure encryption and decryption are inverse
  207. # operations.
  208. ciphertext = a2b_hex(self.ciphertext)
  209. # Test decryption
  210. plaintext = rsaObj.decrypt((ciphertext,))
  211. # Test encryption (2 arguments)
  212. (new_ciphertext2,) = rsaObj.encrypt(plaintext, b(""))
  213. self.assertEqual(b2a_hex(ciphertext), b2a_hex(new_ciphertext2))
  214. # Test blinded decryption
  215. blinding_factor = Random.new().read(len(ciphertext)-1)
  216. blinded_ctext = rsaObj.blind(ciphertext, blinding_factor)
  217. blinded_ptext = rsaObj.decrypt((blinded_ctext,))
  218. unblinded_plaintext = rsaObj.unblind(blinded_ptext, blinding_factor)
  219. self.assertEqual(b2a_hex(plaintext), b2a_hex(unblinded_plaintext))
  220. # Test signing (2 arguments)
  221. signature2 = rsaObj.sign(ciphertext, b(""))
  222. self.assertEqual((bytes_to_long(plaintext),), signature2)
  223. # Test verification
  224. self.assertEqual(1, rsaObj.verify(ciphertext, (bytes_to_long(plaintext),)))
  225. def _exercise_public_primitive(self, rsaObj):
  226. plaintext = a2b_hex(self.plaintext)
  227. # Test encryption (2 arguments)
  228. (new_ciphertext2,) = rsaObj.encrypt(plaintext, b(""))
  229. # Exercise verification
  230. rsaObj.verify(new_ciphertext2, (bytes_to_long(plaintext),))
  231. def _check_encryption(self, rsaObj):
  232. plaintext = a2b_hex(self.plaintext)
  233. ciphertext = a2b_hex(self.ciphertext)
  234. # Test encryption (2 arguments)
  235. (new_ciphertext2,) = rsaObj.encrypt(plaintext, b(""))
  236. self.assertEqual(b2a_hex(ciphertext), b2a_hex(new_ciphertext2))
  237. def _check_decryption(self, rsaObj):
  238. plaintext = a2b_hex(self.plaintext)
  239. ciphertext = a2b_hex(self.ciphertext)
  240. # Test plain decryption
  241. new_plaintext = rsaObj.decrypt((ciphertext,))
  242. self.assertEqual(b2a_hex(plaintext), b2a_hex(new_plaintext))
  243. # Test blinded decryption
  244. blinding_factor = Random.new().read(len(ciphertext)-1)
  245. blinded_ctext = rsaObj.blind(ciphertext, blinding_factor)
  246. blinded_ptext = rsaObj.decrypt((blinded_ctext,))
  247. unblinded_plaintext = rsaObj.unblind(blinded_ptext, blinding_factor)
  248. self.assertEqual(b2a_hex(plaintext), b2a_hex(unblinded_plaintext))
  249. def _check_verification(self, rsaObj):
  250. signature = bytes_to_long(a2b_hex(self.plaintext))
  251. message = a2b_hex(self.ciphertext)
  252. # Test verification
  253. t = (signature,) # rsaObj.verify expects a tuple
  254. self.assertEqual(1, rsaObj.verify(message, t))
  255. # Test verification with overlong tuple (this is a
  256. # backward-compatibility hack to support some harmless misuse of the
  257. # API)
  258. t2 = (signature, '')
  259. self.assertEqual(1, rsaObj.verify(message, t2)) # extra garbage at end of tuple
  260. def _check_signing(self, rsaObj):
  261. signature = bytes_to_long(a2b_hex(self.plaintext))
  262. message = a2b_hex(self.ciphertext)
  263. # Test signing (2 argument)
  264. self.assertEqual((signature,), rsaObj.sign(message, b("")))
  265. class RSAFastMathTest(RSATest):
  266. def setUp(self):
  267. RSATest.setUp(self)
  268. self.rsa = RSA.RSAImplementation(use_fast_math=True)
  269. def test_generate_1arg(self):
  270. """RSA (_fastmath implementation) generated key (1 argument)"""
  271. RSATest.test_generate_1arg(self)
  272. def test_generate_2arg(self):
  273. """RSA (_fastmath implementation) generated key (2 arguments)"""
  274. RSATest.test_generate_2arg(self)
  275. def test_construct_2tuple(self):
  276. """RSA (_fastmath implementation) constructed key (2-tuple)"""
  277. RSATest.test_construct_2tuple(self)
  278. def test_construct_3tuple(self):
  279. """RSA (_fastmath implementation) constructed key (3-tuple)"""
  280. RSATest.test_construct_3tuple(self)
  281. def test_construct_4tuple(self):
  282. """RSA (_fastmath implementation) constructed key (4-tuple)"""
  283. RSATest.test_construct_4tuple(self)
  284. def test_construct_5tuple(self):
  285. """RSA (_fastmath implementation) constructed key (5-tuple)"""
  286. RSATest.test_construct_5tuple(self)
  287. def test_construct_6tuple(self):
  288. """RSA (_fastmath implementation) constructed key (6-tuple)"""
  289. RSATest.test_construct_6tuple(self)
  290. def test_factoring(self):
  291. RSATest.test_factoring(self)
  292. class RSASlowMathTest(RSATest):
  293. def setUp(self):
  294. RSATest.setUp(self)
  295. self.rsa = RSA.RSAImplementation(use_fast_math=False)
  296. def test_generate_1arg(self):
  297. """RSA (_slowmath implementation) generated key (1 argument)"""
  298. RSATest.test_generate_1arg(self)
  299. def test_generate_2arg(self):
  300. """RSA (_slowmath implementation) generated key (2 arguments)"""
  301. RSATest.test_generate_2arg(self)
  302. def test_construct_2tuple(self):
  303. """RSA (_slowmath implementation) constructed key (2-tuple)"""
  304. RSATest.test_construct_2tuple(self)
  305. def test_construct_3tuple(self):
  306. """RSA (_slowmath implementation) constructed key (3-tuple)"""
  307. RSATest.test_construct_3tuple(self)
  308. def test_construct_4tuple(self):
  309. """RSA (_slowmath implementation) constructed key (4-tuple)"""
  310. RSATest.test_construct_4tuple(self)
  311. def test_construct_5tuple(self):
  312. """RSA (_slowmath implementation) constructed key (5-tuple)"""
  313. RSATest.test_construct_5tuple(self)
  314. def test_construct_6tuple(self):
  315. """RSA (_slowmath implementation) constructed key (6-tuple)"""
  316. RSATest.test_construct_6tuple(self)
  317. def test_factoring(self):
  318. RSATest.test_factoring(self)
  319. def get_tests(config={}):
  320. tests = []
  321. tests += list_test_cases(RSATest)
  322. try:
  323. from Crypto.PublicKey import _fastmath
  324. tests += list_test_cases(RSAFastMathTest)
  325. except ImportError:
  326. from distutils.sysconfig import get_config_var
  327. import inspect
  328. _fm_path = os.path.normpath(os.path.dirname(os.path.abspath(
  329. inspect.getfile(inspect.currentframe())))
  330. +"/../../PublicKey/_fastmath"+get_config_var("SO"))
  331. if os.path.exists(_fm_path):
  332. raise ImportError("While the _fastmath module exists, importing "+
  333. "it failed. This may point to the gmp or mpir shared library "+
  334. "not being in the path. _fastmath was found at "+_fm_path)
  335. if config.get('slow_tests',1):
  336. tests += list_test_cases(RSASlowMathTest)
  337. return tests
  338. if __name__ == '__main__':
  339. suite = lambda: unittest.TestSuite(get_tests())
  340. unittest.main(defaultTest='suite')
  341. # vim:set ts=4 sw=4 sts=4 expandtab: