|
24 | 24 | # algorithm. |
25 | 25 | # <[param n integer value to test for primality.]> |
26 | 26 | # <[param precision degree of confidence to use (defaults to 16).]> |
| 27 | +# <[return n if n is prime, fails otherwise.]> |
27 | 28 | #</p> |
28 | 29 | procedure is_prime(n, precision) |
29 | 30 | static known_primes, k_primes_set |
|
60 | 61 | # <[param b base]> |
61 | 62 | # <[param e exponent]> |
62 | 63 | # <[param m modulus]> |
| 64 | +# <[return (b^e)%m]> |
63 | 65 | #</p> |
64 | | -procedure pow(b,e,m) |
| 66 | +procedure powm(b,e,m) |
65 | 67 | r := 1 |
66 | 68 | while e > 0 do |
67 | 69 | if e%2 = 0 then (e /:= 2, b := (b*b)%m) |
|
86 | 88 | # <b>Internal use only unless you know how to compute <i>d</i> and <i>s</i>.</b> |
87 | 89 | #</p> |
88 | 90 | procedure try_composite(n, a, d, s) |
89 | | - if pow(a,d,n) = 1 then fail |
90 | | - every i := 0 to (s-1) do if pow(a,(2^i)*d,n) = n-1 then fail |
| 91 | + if powm(a,d,n) = 1 then fail |
| 92 | + every i := 0 to (s-1) do if powm(a,(2^i)*d,n) = n-1 then fail |
91 | 93 | return n |
92 | 94 | end |
| 95 | + |
| 96 | +#<p> |
| 97 | +# Produce a list of all the factors of <i>n</i> using Pollard's rho algorithm. |
| 98 | +# Note that some factors may repeat, e.g. if <i>n = 5^2</i>. |
| 99 | +# <[param n number to factor]> |
| 100 | +# <[return list of all the factors of <i>n</i>]> |
| 101 | +#</p> |
| 102 | +procedure all_factors(n) |
| 103 | + flist := [] |
| 104 | + f := getfactor(n) |
| 105 | + if f = n then return (put(flist,n), flist) |
| 106 | + flist |||:= all_factors(f) ||| all_factors(n/f) |
| 107 | + suspend sort(flist) |
| 108 | +end |
| 109 | + |
| 110 | +#<p> |
| 111 | +# Generate the prime factors of <i>n</i> using Pollard's rho algorithm. |
| 112 | +# <[param n number to factor]> |
| 113 | +# <[generate the prime factors of n]> |
| 114 | +#</p> |
| 115 | +procedure gen_factors(n) |
| 116 | + suspend !sort(set(all_factors(n))) |
| 117 | +end |
| 118 | + |
| 119 | +#<p> |
| 120 | +# Produce a factor of <i>n</i> using Pollard's rho algorithm. |
| 121 | +# <[param n number to factor]> |
| 122 | +# <[return one factor of <i>n</i>, or <i>n</i> if unable to find a factor.]> |
| 123 | +#</p> |
| 124 | +procedure getfactor(n) |
| 125 | +static sprimes |
| 126 | +initial sprimes := [: prime()\100 :] |
| 127 | + if n == 1 then return n |
| 128 | + if n%(i := !sprimes) == 0 then return i # Speed up for small factors |
| 129 | + y := x := rand_num()%(n-2) + 2 |
| 130 | + c := rand_num()%(n-1) + 1 |
| 131 | + d := 1 |
| 132 | + while d = 1 do { |
| 133 | + x := (powm(x,2,n)+c+n)%n |
| 134 | + every (y|y) := (powm(y,2,n)+c+n)%n |
| 135 | + k := +(x-y)%n |
| 136 | + every (z := k) *:= |k\99 |
| 137 | + d := gcd(z%n,n) |
| 138 | + } |
| 139 | + return d |
| 140 | +end |
0 commit comments