Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Side by Side Diff: third_party/google-endpoints/Crypto/SelfTest/PublicKey/test_RSA.py

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

Powered by Google App Engine
This is Rietveld 408576698