/gdata/Crypto/Util/number.py

http://radioappz.googlecode.com/ · Python · 201 lines · 111 code · 23 blank · 67 comment · 30 complexity · e5e94e6bd70a37273df3643a2f7b0168 MD5 · raw file

  1. #
  2. # number.py : Number-theoretic functions
  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: number.py,v 1.13 2003/04/04 18:21:07 akuchling Exp $"
  13. bignum = long
  14. try:
  15. from Crypto.PublicKey import _fastmath
  16. except ImportError:
  17. _fastmath = None
  18. # Commented out and replaced with faster versions below
  19. ## def long2str(n):
  20. ## s=''
  21. ## while n>0:
  22. ## s=chr(n & 255)+s
  23. ## n=n>>8
  24. ## return s
  25. ## import types
  26. ## def str2long(s):
  27. ## if type(s)!=types.StringType: return s # Integers will be left alone
  28. ## return reduce(lambda x,y : x*256+ord(y), s, 0L)
  29. def size (N):
  30. """size(N:long) : int
  31. Returns the size of the number N in bits.
  32. """
  33. bits, power = 0,1L
  34. while N >= power:
  35. bits += 1
  36. power = power << 1
  37. return bits
  38. def getRandomNumber(N, randfunc):
  39. """getRandomNumber(N:int, randfunc:callable):long
  40. Return an N-bit random number."""
  41. S = randfunc(N/8)
  42. odd_bits = N % 8
  43. if odd_bits != 0:
  44. char = ord(randfunc(1)) >> (8-odd_bits)
  45. S = chr(char) + S
  46. value = bytes_to_long(S)
  47. value |= 2L ** (N-1) # Ensure high bit is set
  48. assert size(value) >= N
  49. return value
  50. def GCD(x,y):
  51. """GCD(x:long, y:long): long
  52. Return the GCD of x and y.
  53. """
  54. x = abs(x) ; y = abs(y)
  55. while x > 0:
  56. x, y = y % x, x
  57. return y
  58. def inverse(u, v):
  59. """inverse(u:long, u:long):long
  60. Return the inverse of u mod v.
  61. """
  62. u3, v3 = long(u), long(v)
  63. u1, v1 = 1L, 0L
  64. while v3 > 0:
  65. q=u3 / v3
  66. u1, v1 = v1, u1 - v1*q
  67. u3, v3 = v3, u3 - v3*q
  68. while u1<0:
  69. u1 = u1 + v
  70. return u1
  71. # Given a number of bits to generate and a random generation function,
  72. # find a prime number of the appropriate size.
  73. def getPrime(N, randfunc):
  74. """getPrime(N:int, randfunc:callable):long
  75. Return a random N-bit prime number.
  76. """
  77. number=getRandomNumber(N, randfunc) | 1
  78. while (not isPrime(number)):
  79. number=number+2
  80. return number
  81. def isPrime(N):
  82. """isPrime(N:long):bool
  83. Return true if N is prime.
  84. """
  85. if N == 1:
  86. return 0
  87. if N in sieve:
  88. return 1
  89. for i in sieve:
  90. if (N % i)==0:
  91. return 0
  92. # Use the accelerator if available
  93. if _fastmath is not None:
  94. return _fastmath.isPrime(N)
  95. # Compute the highest bit that's set in N
  96. N1 = N - 1L
  97. n = 1L
  98. while (n<N):
  99. n=n<<1L
  100. n = n >> 1L
  101. # Rabin-Miller test
  102. for c in sieve[:7]:
  103. a=long(c) ; d=1L ; t=n
  104. while (t): # Iterate over the bits in N1
  105. x=(d*d) % N
  106. if x==1L and d!=1L and d!=N1:
  107. return 0 # Square root of 1 found
  108. if N1 & t:
  109. d=(x*a) % N
  110. else:
  111. d=x
  112. t = t >> 1L
  113. if d!=1L:
  114. return 0
  115. return 1
  116. # Small primes used for checking primality; these are all the primes
  117. # less than 256. This should be enough to eliminate most of the odd
  118. # numbers before needing to do a Rabin-Miller test at all.
  119. sieve=[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
  120. 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127,
  121. 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
  122. 197, 199, 211, 223, 227, 229, 233, 239, 241, 251]
  123. # Improved conversion functions contributed by Barry Warsaw, after
  124. # careful benchmarking
  125. import struct
  126. def long_to_bytes(n, blocksize=0):
  127. """long_to_bytes(n:long, blocksize:int) : string
  128. Convert a long integer to a byte string.
  129. If optional blocksize is given and greater than zero, pad the front of the
  130. byte string with binary zeros so that the length is a multiple of
  131. blocksize.
  132. """
  133. # after much testing, this algorithm was deemed to be the fastest
  134. s = ''
  135. n = long(n)
  136. pack = struct.pack
  137. while n > 0:
  138. s = pack('>I', n & 0xffffffffL) + s
  139. n = n >> 32
  140. # strip off leading zeros
  141. for i in range(len(s)):
  142. if s[i] != '\000':
  143. break
  144. else:
  145. # only happens when n == 0
  146. s = '\000'
  147. i = 0
  148. s = s[i:]
  149. # add back some pad bytes. this could be done more efficiently w.r.t. the
  150. # de-padding being done above, but sigh...
  151. if blocksize > 0 and len(s) % blocksize:
  152. s = (blocksize - len(s) % blocksize) * '\000' + s
  153. return s
  154. def bytes_to_long(s):
  155. """bytes_to_long(string) : long
  156. Convert a byte string to a long integer.
  157. This is (essentially) the inverse of long_to_bytes().
  158. """
  159. acc = 0L
  160. unpack = struct.unpack
  161. length = len(s)
  162. if length % 4:
  163. extra = (4 - length % 4)
  164. s = '\000' * extra + s
  165. length = length + extra
  166. for i in range(0, length, 4):
  167. acc = (acc << 32) + unpack('>I', s[i:i+4])[0]
  168. return acc
  169. # For backwards compatibility...
  170. import warnings
  171. def long2str(n, blocksize=0):
  172. warnings.warn("long2str() has been replaced by long_to_bytes()")
  173. return long_to_bytes(n, blocksize)
  174. def str2long(s):
  175. warnings.warn("str2long() has been replaced by bytes_to_long()")
  176. return bytes_to_long(s)