| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2003-02-28 16:28:35 -07:00
										 |  |  | #   number.py : Number-theoretic functions | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											2002-04-22 21:24:27 -07:00
										 |  |  | #  Part of the Python Cryptography Toolkit | 
					
						
							| 
									
										
										
										
											2003-02-28 16:28:35 -07:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2009-08-03 16:18:22 -04:00
										 |  |  | #  Written by Andrew M. Kuchling, Barry A. Warsaw, and others | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # =================================================================== | 
					
						
							|  |  |  | # The contents of this file are dedicated to the public domain.  To | 
					
						
							|  |  |  | # the extent that dedication to the public domain is not available, | 
					
						
							|  |  |  | # everyone is granted a worldwide, perpetual, royalty-free, | 
					
						
							|  |  |  | # non-exclusive license to exercise all rights associated with the | 
					
						
							|  |  |  | # contents of this file for any purpose whatsoever. | 
					
						
							|  |  |  | # No rights are reserved. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
					
						
							|  |  |  | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 
					
						
							|  |  |  | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 
					
						
							|  |  |  | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | 
					
						
							|  |  |  | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | 
					
						
							|  |  |  | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | 
					
						
							|  |  |  | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 
					
						
							|  |  |  | # SOFTWARE. | 
					
						
							|  |  |  | # =================================================================== | 
					
						
							| 
									
										
										
										
											2003-02-28 16:28:35 -07:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-06 21:27:50 -04:00
										 |  |  | __revision__ = "$Id$" | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | bignum = long | 
					
						
							|  |  |  | try: | 
					
						
							| 
									
										
										
										
											2003-04-03 19:41:06 -07:00
										 |  |  |     from Crypto.PublicKey import _fastmath | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  | except ImportError: | 
					
						
							| 
									
										
										
										
											2003-04-03 19:41:06 -07:00
										 |  |  |     _fastmath = None | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-17 14:15:09 -04:00
										 |  |  | # New functions | 
					
						
							|  |  |  | from _number_new import * | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  | # Commented out and replaced with faster versions below | 
					
						
							|  |  |  | ## def long2str(n): | 
					
						
							|  |  |  | ##     s='' | 
					
						
							|  |  |  | ##     while n>0: | 
					
						
							|  |  |  | ##         s=chr(n & 255)+s | 
					
						
							|  |  |  | ##         n=n>>8 | 
					
						
							|  |  |  | ##     return s | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## import types | 
					
						
							|  |  |  | ## def str2long(s): | 
					
						
							|  |  |  | ##     if type(s)!=types.StringType: return s   # Integers will be left alone | 
					
						
							|  |  |  | ##     return reduce(lambda x,y : x*256+ord(y), s, 0L) | 
					
						
							| 
									
										
										
										
											2003-02-28 16:28:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-04 19:21:07 -07:00
										 |  |  | def size (N): | 
					
						
							|  |  |  |     """size(N:long) : int
 | 
					
						
							|  |  |  |     Returns the size of the number N in bits. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     bits, power = 0,1L | 
					
						
							|  |  |  |     while N >= power: | 
					
						
							|  |  |  |         bits += 1 | 
					
						
							|  |  |  |         power = power << 1 | 
					
						
							|  |  |  |     return bits | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  | def getRandomNumber(N, randfunc=None): | 
					
						
							| 
									
										
										
										
											2002-05-24 14:17:16 -07:00
										 |  |  |     """getRandomNumber(N:int, randfunc:callable):long
 | 
					
						
							| 
									
										
										
										
											2009-03-13 18:47:59 -04:00
										 |  |  |     Return a random N-bit number. | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     If randfunc is omitted, then Random.new().read is used. | 
					
						
							| 
									
										
										
										
											2009-03-13 18:47:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     NOTE: Confusingly, this function does NOT return N random bits; It returns | 
					
						
							|  |  |  |     a random N-bit number, i.e. a random number between 2**(N-1) and (2**N)-1. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This function is for internal use only and may be renamed or removed in | 
					
						
							|  |  |  |     the future. | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     if randfunc is None: | 
					
						
							| 
									
										
										
										
											2008-09-20 23:00:05 -04:00
										 |  |  |         _import_Random() | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  |         randfunc = Random.new().read | 
					
						
							| 
									
										
										
										
											2003-02-28 16:28:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-29 08:11:16 -04:00
										 |  |  |     S = randfunc(N>>3) | 
					
						
							| 
									
										
										
										
											2003-03-21 15:16:35 -07:00
										 |  |  |     odd_bits = N % 8 | 
					
						
							|  |  |  |     if odd_bits != 0: | 
					
						
							|  |  |  |         char = ord(randfunc(1)) >> (8-odd_bits) | 
					
						
							|  |  |  |         S = chr(char) + S | 
					
						
							| 
									
										
										
										
											2003-04-04 19:04:40 -07:00
										 |  |  |     value = bytes_to_long(S) | 
					
						
							|  |  |  |     value |= 2L ** (N-1)                # Ensure high bit is set | 
					
						
							| 
									
										
										
										
											2003-04-04 19:21:07 -07:00
										 |  |  |     assert size(value) >= N | 
					
						
							| 
									
										
										
										
											2003-04-04 19:04:40 -07:00
										 |  |  |     return value | 
					
						
							| 
									
										
										
										
											2003-02-28 16:28:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  | def GCD(x,y): | 
					
						
							| 
									
										
										
										
											2002-05-24 14:17:16 -07:00
										 |  |  |     """GCD(x:long, y:long): long
 | 
					
						
							|  |  |  |     Return the GCD of x and y. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2002-05-17 13:37:31 -07:00
										 |  |  |     x = abs(x) ; y = abs(y) | 
					
						
							|  |  |  |     while x > 0: | 
					
						
							|  |  |  |         x, y = y % x, x | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |     return y | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def inverse(u, v): | 
					
						
							| 
									
										
										
										
											2002-05-24 14:17:16 -07:00
										 |  |  |     """inverse(u:long, u:long):long
 | 
					
						
							|  |  |  |     Return the inverse of u mod v. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |     u3, v3 = long(u), long(v) | 
					
						
							|  |  |  |     u1, v1 = 1L, 0L | 
					
						
							| 
									
										
										
										
											2002-05-17 13:37:31 -07:00
										 |  |  |     while v3 > 0: | 
					
						
							| 
									
										
										
										
											2010-05-29 08:11:16 -04:00
										 |  |  |         q=divmod(u3, v3)[0] | 
					
						
							| 
									
										
										
										
											2003-02-28 16:28:35 -07:00
										 |  |  |         u1, v1 = v1, u1 - v1*q | 
					
						
							|  |  |  |         u3, v3 = v3, u3 - v3*q | 
					
						
							| 
									
										
										
										
											2002-05-17 13:37:31 -07:00
										 |  |  |     while u1<0: | 
					
						
							|  |  |  |         u1 = u1 + v | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |     return u1 | 
					
						
							| 
									
										
										
										
											2003-02-28 16:28:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  | # Given a number of bits to generate and a random generation function, | 
					
						
							|  |  |  | # find a prime number of the appropriate size. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  | def getPrime(N, randfunc=None): | 
					
						
							| 
									
										
										
										
											2002-05-24 14:17:16 -07:00
										 |  |  |     """getPrime(N:int, randfunc:callable):long
 | 
					
						
							|  |  |  |     Return a random N-bit prime number. | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     If randfunc is omitted, then Random.new().read is used. | 
					
						
							| 
									
										
										
										
											2002-05-24 14:17:16 -07:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  |     if randfunc is None: | 
					
						
							| 
									
										
										
										
											2008-09-20 23:00:05 -04:00
										 |  |  |         _import_Random() | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  |         randfunc = Random.new().read | 
					
						
							| 
									
										
										
										
											2003-02-28 16:28:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |     number=getRandomNumber(N, randfunc) | 1 | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  |     while (not isPrime(number, randfunc=randfunc)): | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |         number=number+2 | 
					
						
							|  |  |  |     return number | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  | def isPrime(N, randfunc=None): | 
					
						
							|  |  |  |     """isPrime(N:long, randfunc:callable):bool
 | 
					
						
							| 
									
										
										
										
											2002-05-24 14:17:16 -07:00
										 |  |  |     Return true if N is prime. | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     If randfunc is omitted, then Random.new().read is used. | 
					
						
							| 
									
										
										
										
											2002-05-24 14:17:16 -07:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2008-09-20 23:00:05 -04:00
										 |  |  |     _import_Random() | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  |     if randfunc is None: | 
					
						
							|  |  |  |         randfunc = Random.new().read | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     randint = StrongRandom(randfunc=randfunc).randint | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-04 16:15:13 -07:00
										 |  |  |     if N == 1: | 
					
						
							|  |  |  |         return 0 | 
					
						
							|  |  |  |     if N in sieve: | 
					
						
							|  |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |     for i in sieve: | 
					
						
							| 
									
										
										
										
											2003-04-04 16:15:13 -07:00
										 |  |  |         if (N % i)==0: | 
					
						
							|  |  |  |             return 0 | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-03 19:41:06 -07:00
										 |  |  |     # Use the accelerator if available | 
					
						
							|  |  |  |     if _fastmath is not None: | 
					
						
							| 
									
										
										
										
											2008-09-21 00:47:45 -04:00
										 |  |  |         return _fastmath.isPrime(N) | 
					
						
							| 
									
										
										
										
											2003-03-21 16:12:54 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |     # Compute the highest bit that's set in N | 
					
						
							| 
									
										
										
										
											2003-04-04 16:15:13 -07:00
										 |  |  |     N1 = N - 1L | 
					
						
							|  |  |  |     n = 1L | 
					
						
							|  |  |  |     while (n<N): | 
					
						
							|  |  |  |         n=n<<1L | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |     n = n >> 1L | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Rabin-Miller test | 
					
						
							| 
									
										
										
										
											2008-09-21 00:47:45 -04:00
										 |  |  |     for c in sieve[:7]: | 
					
						
							|  |  |  |         a=long(c) ; d=1L ; t=n | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |         while (t):  # Iterate over the bits in N1 | 
					
						
							|  |  |  |             x=(d*d) % N | 
					
						
							| 
									
										
										
										
											2003-04-03 19:41:06 -07:00
										 |  |  |             if x==1L and d!=1L and d!=N1: | 
					
						
							|  |  |  |                 return 0  # Square root of 1 found | 
					
						
							|  |  |  |             if N1 & t: | 
					
						
							|  |  |  |                 d=(x*a) % N | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 d=x | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |             t = t >> 1L | 
					
						
							| 
									
										
										
										
											2003-04-03 19:41:06 -07:00
										 |  |  |         if d!=1L: | 
					
						
							|  |  |  |             return 0 | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |     return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Small primes used for checking primality; these are all the primes | 
					
						
							|  |  |  | # less than 256.  This should be enough to eliminate most of the odd | 
					
						
							|  |  |  | # numbers before needing to do a Rabin-Miller test at all. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sieve=[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, | 
					
						
							|  |  |  |        61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, | 
					
						
							| 
									
										
										
										
											2003-03-21 16:12:54 -07:00
										 |  |  |        131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, | 
					
						
							|  |  |  |        197, 199, 211, 223, 227, 229, 233, 239, 241, 251] | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Improved conversion functions contributed by Barry Warsaw, after | 
					
						
							| 
									
										
										
										
											2003-02-28 16:28:35 -07:00
										 |  |  | # careful benchmarking | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | import struct | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-24 14:17:16 -07:00
										 |  |  | def long_to_bytes(n, blocksize=0): | 
					
						
							|  |  |  |     """long_to_bytes(n:long, blocksize:int) : string
 | 
					
						
							|  |  |  |     Convert a long integer to a byte string. | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     If optional blocksize is given and greater than zero, pad the front of the | 
					
						
							|  |  |  |     byte string with binary zeros so that the length is a multiple of | 
					
						
							|  |  |  |     blocksize. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     # after much testing, this algorithm was deemed to be the fastest | 
					
						
							|  |  |  |     s = '' | 
					
						
							| 
									
										
										
										
											2002-05-24 14:17:16 -07:00
										 |  |  |     n = long(n) | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |     pack = struct.pack | 
					
						
							|  |  |  |     while n > 0: | 
					
						
							|  |  |  |         s = pack('>I', n & 0xffffffffL) + s | 
					
						
							|  |  |  |         n = n >> 32 | 
					
						
							|  |  |  |     # strip off leading zeros | 
					
						
							|  |  |  |     for i in range(len(s)): | 
					
						
							| 
									
										
										
										
											2002-05-17 13:37:31 -07:00
										 |  |  |         if s[i] != '\000': | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |             break | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         # only happens when n == 0 | 
					
						
							|  |  |  |         s = '\000' | 
					
						
							|  |  |  |         i = 0 | 
					
						
							|  |  |  |     s = s[i:] | 
					
						
							|  |  |  |     # add back some pad bytes.  this could be done more efficiently w.r.t. the | 
					
						
							|  |  |  |     # de-padding being done above, but sigh... | 
					
						
							|  |  |  |     if blocksize > 0 and len(s) % blocksize: | 
					
						
							|  |  |  |         s = (blocksize - len(s) % blocksize) * '\000' + s | 
					
						
							|  |  |  |     return s | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-24 14:17:16 -07:00
										 |  |  | def bytes_to_long(s): | 
					
						
							|  |  |  |     """bytes_to_long(string) : long
 | 
					
						
							|  |  |  |     Convert a byte string to a long integer. | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-24 14:17:16 -07:00
										 |  |  |     This is (essentially) the inverse of long_to_bytes(). | 
					
						
							| 
									
										
										
										
											1998-12-13 19:19:48 -07:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     acc = 0L | 
					
						
							|  |  |  |     unpack = struct.unpack | 
					
						
							|  |  |  |     length = len(s) | 
					
						
							|  |  |  |     if length % 4: | 
					
						
							|  |  |  |         extra = (4 - length % 4) | 
					
						
							|  |  |  |         s = '\000' * extra + s | 
					
						
							|  |  |  |         length = length + extra | 
					
						
							|  |  |  |     for i in range(0, length, 4): | 
					
						
							|  |  |  |         acc = (acc << 32) + unpack('>I', s[i:i+4])[0] | 
					
						
							|  |  |  |     return acc | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # For backwards compatibility... | 
					
						
							| 
									
										
										
										
											2002-07-11 14:23:53 -07:00
										 |  |  | import warnings | 
					
						
							| 
									
										
										
										
											2002-05-17 13:37:31 -07:00
										 |  |  | def long2str(n, blocksize=0): | 
					
						
							| 
									
										
										
										
											2002-05-24 14:17:16 -07:00
										 |  |  |     warnings.warn("long2str() has been replaced by long_to_bytes()") | 
					
						
							|  |  |  |     return long_to_bytes(n, blocksize) | 
					
						
							| 
									
										
										
										
											2002-05-17 13:37:31 -07:00
										 |  |  | def str2long(s): | 
					
						
							| 
									
										
										
										
											2002-05-24 14:17:16 -07:00
										 |  |  |     warnings.warn("str2long() has been replaced by bytes_to_long()") | 
					
						
							|  |  |  |     return bytes_to_long(s) | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-20 23:00:05 -04:00
										 |  |  | def _import_Random(): | 
					
						
							|  |  |  |     # This is called in a function instead of at the module level in order to avoid problems with recursive imports | 
					
						
							|  |  |  |     global Random, StrongRandom | 
					
						
							|  |  |  |     from Crypto import Random | 
					
						
							|  |  |  |     from Crypto.Random.random import StrongRandom | 
					
						
							| 
									
										
										
										
											2008-09-18 12:04:27 -04:00
										 |  |  | 
 |