root/hodgestar/PythonCode/AacsKeyFactoring/numbthy.py

Revision 34, 6.2 kB (checked in by simon, 5 years ago)

Some silly code for factoring a AACS key using numbthy.

  • Property svn:mime-type set to text/python-source
  • Property svn:eol-style set to native
Line 
1######################################################################################
2# NUMBTHY.PY
3# Basic Number Theory functions implemented in Python
4# Note: Currently requires Python 2.x (uses +=, %= and other 2.x-isms)
5# Note: Currently requires Python 2.3 (uses implicit long integers - could be back-ported though)
6# Author: Robert Campbell, <campbell@math.umbc.edu>
7# Date: 27 April, 2007
8# Version 0.41
9######################################################################################
10"""Basic number theory functions.
11   Functions implemented are:
12                gcd(a,b) - Compute the greatest common divisor of a and b.
13                xgcd(a,b) - Find [g,x,y] such that g=gcd(a,b) and g = ax + by.
14                powmod(b,e,n) - Compute b^e mod n efficiently.
15                isprime(n) - Test whether n is prime using a variety of pseudoprime tests.
16                isprimeF(n,b) - Test whether n is prime or a Fermat pseudoprime to base b.
17                isprimeE(n,b) - Test whether n is prime or an Euler pseudoprime to base b.
18                eulerphi(n) - Computer Euler's Phi function of n - the number of integers strictly less than n which are coprime to n.
19                carmichaellambda(n) - Computer Carmichael's Lambda function of n - the smallest exponent e such that b**e = 1 for all b coprime to n.
20                factor(n) - Find a factor of n using a variety of methods.
21                factors(n) - Return a sorted list of the prime factors of n.
22                factorPR(n) - Find a factor of n using the Pollard Rho method
23                isprimitive(g,n) - Test whether g is primitive - generates the group of units mod n.
24   A list of the functions implemented in numbthy is printed by the command info()."""
25   
26   
27Version = 'NUMBTHY.PY, version 0.1, 10 Jan, 2003, by Robert Campbell, campbell@math.umbc.edu'
28
29import math  # Use sqrt, floor
30
31def gcd(a,b):
32        """gcd(a,b) returns the greatest common divisor of the integers a and b."""
33        if a == 0:
34                return b
35        return abs(gcd(b % a, a))
36       
37def powmod(b,e,n):
38        """powmod(b,e,n) computes the eth power of b mod n. 
39        (Actually, this is not needed, as pow(b,e,n) does the same thing for positive integers.
40        This will be useful in future for non-integers or inverses."""
41        accum = 1; i = 0; bpow2 = b
42        while ((e>>i)>0):
43                if((e>>i) & 1):
44                        accum = (accum*bpow2) % n
45                bpow2 = (bpow2*bpow2) % n
46                i+=1
47        return accum
48       
49def xgcd(a,b):
50        """xgcd(a,b) returns a list of form [g,x,y], where g is gcd(a,b) and
51        x,y satisfy the equation g = ax + by."""
52        a1=1; b1=0; a2=0; b2=1; aneg=1; bneg=1; swap = False
53        if(a < 0):
54                a = -a; aneg=-1
55        if(b < 0):
56                b = -b; bneg=-1
57        if(b > a):
58                swap = True
59                [a,b] = [b,a]
60        while (1):
61                quot = -(a / b)
62                a = a % b
63                a1 = a1 + quot*a2; b1 = b1 + quot*b2
64                if(a == 0):
65                        if(swap):
66                                return [b, b2*bneg, a2*aneg]
67                        else:
68                                return [b, a2*aneg, b2*bneg]
69                quot = -(b / a)
70                b = b % a;
71                a2 = a2 + quot*a1; b2 = b2 + quot*b1
72                if(b == 0):
73                        if(swap):
74                                return [a, b1*bneg, a1*aneg]
75                        else:
76                                return [a, a1*aneg, b1*bneg]
77                       
78def isprime(n):
79        """isprime(n) - Test whether n is prime using a variety of pseudoprime tests."""
80        if (n in [2,3,5,7,11,13,17,19,23,29]): return True
81        return isprimeE(n,2) and isprimeE(n,3) and isprimeE(n,5)
82                       
83def isprimeF(n,b):
84        """isprimeF(n) - Test whether n is prime or a Fermat pseudoprime to base b."""
85        return (pow(b,n-1,n) == 1)
86       
87def isprimeE(n,b):
88        """isprimeE(n) - Test whether n is prime or an Euler pseudoprime to base b."""
89        if (not isprimeF(n,b)): return False
90        r = n-1
91        while (r % 2 == 0): r /= 2
92        c = pow(b,r,n)
93        if (c == 1): return True
94        while (1):
95                if (c == 1): return False
96                if (c == n-1): return True
97                c = pow(c,2,n)
98
99def factor(n):
100        """factor(n) - Find a prime factor of n using a variety of methods."""
101        if (isprime(n)): return n
102        for fact in [2,3,5,7,11,13,17,19,23,29]:
103                if n%fact == 0: return fact
104        return factorPR(n)  # Needs work - no guarantee that a prime factor will be returned
105
106def factors(n):
107        """factors(n) - Return a sorted list of the prime factors of n."""
108        if (isprime(n)):
109                return [n]
110        fact = factor(n)
111        if (fact == 1): return "Unable to factor "+str(n)
112        facts = factors(n/fact) + factors(fact)
113        facts.sort()
114        return facts
115
116def factorPR(n):
117        """factorPR(n) - Find a factor of n using the Pollard Rho method.
118        Note: This method will occasionally fail."""
119        for slow in [2,3,4,6]:
120                numsteps=2*math.floor(math.sqrt(math.sqrt(n))); fast=slow; i=1
121                while i<numsteps:
122                        slow = (slow*slow + 1) % n
123                        i = i + 1
124                        fast = (fast*fast + 1) % n
125                        fast = (fast*fast + 1) % n
126                        g = gcd(fast-slow,n)
127                        if (g != 1):
128                                if (g == n):
129                                        break
130                                else:
131                                        return g
132        return 1
133
134def eulerphi(n):
135        """eulerphi(n) - Computer Euler's Phi function of n - the number of integers
136        strictly less than n which are coprime to n.  Otherwise defined as the order
137        of the group of integers mod n."""
138        thefactors = factors(n)
139        thefactors.sort()
140        phi = 1
141        oldfact = 1
142        for fact in thefactors:
143                if fact==oldfact:
144                        phi = phi*fact
145                else:
146                        phi = phi*(fact-1)
147                        oldfact = fact
148        return phi
149
150def carmichaellambda(n):
151        """carmichaellambda(n) - Computer Carmichael's Lambda function
152        of n - the smallest exponent e such that b**e = 1 for all b coprime to n.
153        Otherwise defined as the exponent of the group of integers mod n."""
154        thefactors = factors(n)
155        thefactors.sort()
156        thefactors += [0]  # Mark the end of the list of factors
157        carlambda = 1 # The Carmichael Lambda function of n
158        carlambda_comp = 1 # The Carmichael Lambda function of the component p**e
159        oldfact = 1
160        for fact in thefactors:
161                if fact==oldfact:
162                        carlambda_comp = (carlambda_comp*fact)
163                else:
164                        if ((oldfact == 2) and (carlambda_comp >= 4)): carlambda_comp /= 2 # Z_(2**e) is not cyclic for e>=3
165                        if carlambda == 1:
166                                carlambda = carlambda_comp
167                        else:
168                                carlambda = (carlambda * carlambda_comp)/gcd(carlambda,carlambda_comp)
169                        carlambda_comp = fact-1
170                        oldfact = fact
171        return carlambda
172
173def isprimitive(g,n):
174        """isprimitive(g,n) - Test whether g is primitive - generates the group of units mod n."""
175        if gcd(g,n) != 1: return False  # Not in the group of units
176        order = eulerphi(n)
177        if carmichaellambda(n) != order: return False # Group of units isn't cyclic
178        orderfacts = factors(order)
179        oldfact = 1
180        for fact in orderfacts:
181                if fact!=oldfact:
182                        if pow(g,order/fact,n) == 1: return False
183                        oldfact = fact
184        return True
185
186def info():
187        """Return information about the module"""
188        print locals()
189
190# import numbthy
191# reload(numbthy)
192# print numbthy.__doc__
193
Note: See TracBrowser for help on using the browser.