PageRenderTime 58ms CodeModel.GetById 16ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 0ms

/gdata/Crypto/Util/number.py

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