/gdata/Crypto/PublicKey/RSA.py

http://radioappz.googlecode.com/ · Python · 256 lines · 179 code · 41 blank · 36 comment · 26 complexity · dfa2af03e881af60bd2ca69b3a78cc85 MD5 · raw file

  1. #
  2. # RSA.py : RSA encryption/decryption
  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. __revision__ = "$Id: RSA.py,v 1.20 2004/05/06 12:52:54 akuchling Exp $"
  13. from Crypto.PublicKey import pubkey
  14. from Crypto.Util import number
  15. try:
  16. from Crypto.PublicKey import _fastmath
  17. except ImportError:
  18. _fastmath = None
  19. class error (Exception):
  20. pass
  21. def generate(bits, randfunc, progress_func=None):
  22. """generate(bits:int, randfunc:callable, progress_func:callable)
  23. Generate an RSA key of length 'bits', using 'randfunc' to get
  24. random data and 'progress_func', if present, to display
  25. the progress of the key generation.
  26. """
  27. obj=RSAobj()
  28. # Generate the prime factors of n
  29. if progress_func:
  30. progress_func('p,q\n')
  31. p = q = 1L
  32. while number.size(p*q) < bits:
  33. p = pubkey.getPrime(bits/2, randfunc)
  34. q = pubkey.getPrime(bits/2, randfunc)
  35. # p shall be smaller than q (for calc of u)
  36. if p > q:
  37. (p, q)=(q, p)
  38. obj.p = p
  39. obj.q = q
  40. if progress_func:
  41. progress_func('u\n')
  42. obj.u = pubkey.inverse(obj.p, obj.q)
  43. obj.n = obj.p*obj.q
  44. obj.e = 65537L
  45. if progress_func:
  46. progress_func('d\n')
  47. obj.d=pubkey.inverse(obj.e, (obj.p-1)*(obj.q-1))
  48. assert bits <= 1+obj.size(), "Generated key is too small"
  49. return obj
  50. def construct(tuple):
  51. """construct(tuple:(long,) : RSAobj
  52. Construct an RSA object from a 2-, 3-, 5-, or 6-tuple of numbers.
  53. """
  54. obj=RSAobj()
  55. if len(tuple) not in [2,3,5,6]:
  56. raise error, 'argument for construct() wrong length'
  57. for i in range(len(tuple)):
  58. field = obj.keydata[i]
  59. setattr(obj, field, tuple[i])
  60. if len(tuple) >= 5:
  61. # Ensure p is smaller than q
  62. if obj.p>obj.q:
  63. (obj.p, obj.q)=(obj.q, obj.p)
  64. if len(tuple) == 5:
  65. # u not supplied, so we're going to have to compute it.
  66. obj.u=pubkey.inverse(obj.p, obj.q)
  67. return obj
  68. class RSAobj(pubkey.pubkey):
  69. keydata = ['n', 'e', 'd', 'p', 'q', 'u']
  70. def _encrypt(self, plaintext, K=''):
  71. if self.n<=plaintext:
  72. raise error, 'Plaintext too large'
  73. return (pow(plaintext, self.e, self.n),)
  74. def _decrypt(self, ciphertext):
  75. if (not hasattr(self, 'd')):
  76. raise error, 'Private key not available in this object'
  77. if self.n<=ciphertext[0]:
  78. raise error, 'Ciphertext too large'
  79. return pow(ciphertext[0], self.d, self.n)
  80. def _sign(self, M, K=''):
  81. return (self._decrypt((M,)),)
  82. def _verify(self, M, sig):
  83. m2=self._encrypt(sig[0])
  84. if m2[0]==M:
  85. return 1
  86. else: return 0
  87. def _blind(self, M, B):
  88. tmp = pow(B, self.e, self.n)
  89. return (M * tmp) % self.n
  90. def _unblind(self, M, B):
  91. tmp = pubkey.inverse(B, self.n)
  92. return (M * tmp) % self.n
  93. def can_blind (self):
  94. """can_blind() : bool
  95. Return a Boolean value recording whether this algorithm can
  96. blind data. (This does not imply that this
  97. particular key object has the private information required to
  98. to blind a message.)
  99. """
  100. return 1
  101. def size(self):
  102. """size() : int
  103. Return the maximum number of bits that can be handled by this key.
  104. """
  105. return number.size(self.n) - 1
  106. def has_private(self):
  107. """has_private() : bool
  108. Return a Boolean denoting whether the object contains
  109. private components.
  110. """
  111. if hasattr(self, 'd'):
  112. return 1
  113. else: return 0
  114. def publickey(self):
  115. """publickey(): RSAobj
  116. Return a new key object containing only the public key information.
  117. """
  118. return construct((self.n, self.e))
  119. class RSAobj_c(pubkey.pubkey):
  120. keydata = ['n', 'e', 'd', 'p', 'q', 'u']
  121. def __init__(self, key):
  122. self.key = key
  123. def __getattr__(self, attr):
  124. if attr in self.keydata:
  125. return getattr(self.key, attr)
  126. else:
  127. if self.__dict__.has_key(attr):
  128. self.__dict__[attr]
  129. else:
  130. raise AttributeError, '%s instance has no attribute %s' % (self.__class__, attr)
  131. def __getstate__(self):
  132. d = {}
  133. for k in self.keydata:
  134. if hasattr(self.key, k):
  135. d[k]=getattr(self.key, k)
  136. return d
  137. def __setstate__(self, state):
  138. n,e = state['n'], state['e']
  139. if not state.has_key('d'):
  140. self.key = _fastmath.rsa_construct(n,e)
  141. else:
  142. d = state['d']
  143. if not state.has_key('q'):
  144. self.key = _fastmath.rsa_construct(n,e,d)
  145. else:
  146. p, q, u = state['p'], state['q'], state['u']
  147. self.key = _fastmath.rsa_construct(n,e,d,p,q,u)
  148. def _encrypt(self, plain, K):
  149. return (self.key._encrypt(plain),)
  150. def _decrypt(self, cipher):
  151. return self.key._decrypt(cipher[0])
  152. def _sign(self, M, K):
  153. return (self.key._sign(M),)
  154. def _verify(self, M, sig):
  155. return self.key._verify(M, sig[0])
  156. def _blind(self, M, B):
  157. return self.key._blind(M, B)
  158. def _unblind(self, M, B):
  159. return self.key._unblind(M, B)
  160. def can_blind (self):
  161. return 1
  162. def size(self):
  163. return self.key.size()
  164. def has_private(self):
  165. return self.key.has_private()
  166. def publickey(self):
  167. return construct_c((self.key.n, self.key.e))
  168. def generate_c(bits, randfunc, progress_func = None):
  169. # Generate the prime factors of n
  170. if progress_func:
  171. progress_func('p,q\n')
  172. p = q = 1L
  173. while number.size(p*q) < bits:
  174. p = pubkey.getPrime(bits/2, randfunc)
  175. q = pubkey.getPrime(bits/2, randfunc)
  176. # p shall be smaller than q (for calc of u)
  177. if p > q:
  178. (p, q)=(q, p)
  179. if progress_func:
  180. progress_func('u\n')
  181. u=pubkey.inverse(p, q)
  182. n=p*q
  183. e = 65537L
  184. if progress_func:
  185. progress_func('d\n')
  186. d=pubkey.inverse(e, (p-1)*(q-1))
  187. key = _fastmath.rsa_construct(n,e,d,p,q,u)
  188. obj = RSAobj_c(key)
  189. ## print p
  190. ## print q
  191. ## print number.size(p), number.size(q), number.size(q*p),
  192. ## print obj.size(), bits
  193. assert bits <= 1+obj.size(), "Generated key is too small"
  194. return obj
  195. def construct_c(tuple):
  196. key = apply(_fastmath.rsa_construct, tuple)
  197. return RSAobj_c(key)
  198. object = RSAobj
  199. generate_py = generate
  200. construct_py = construct
  201. if _fastmath:
  202. #print "using C version of RSA"
  203. generate = generate_c
  204. construct = construct_c
  205. error = _fastmath.error