Miller–Rabin primality test: Difference between revisions
Content added Content deleted
m (→gmp version) |
(→{{header|Ruby}}: Update to 2.5+ and tidy) |
||
Line 4,391: | Line 4,391: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
===Standard Probabilistic=== |
|||
From 2.5 Ruby has fast modular exponentiation built in. For alternatives prior to 2.5 please see [[Modular_exponentiation#F.23]] |
|||
<lang ruby> |
<lang ruby> |
||
def mod_exp(n, e, mod) |
|||
fail ArgumentError, 'negative exponent' if e < 0 |
|||
prod = 1 |
|||
base = n % mod |
|||
until e.zero? |
|||
prod = (prod * base) % mod if e.odd? |
|||
e >>= 1 |
|||
base = (base * base) % mod |
|||
end |
|||
prod |
|||
end |
|||
def miller_rabin_prime?(n, g) |
def miller_rabin_prime?(n, g) |
||
d = n - 1 |
d = n - 1 |
||
Line 4,413: | Line 4,403: | ||
g.times do |
g.times do |
||
a = 2 + rand(n - 4) |
a = 2 + rand(n - 4) |
||
x = |
x = a.pow(d, n) # x = (a**d) % n |
||
next if x == 1 || x == n - 1 |
next if x == 1 || x == n - 1 |
||
for r in (1..s - 1) |
for r in (1..s - 1) |
||
x = |
x = x.pow(2, n) # x = (x**2) % n |
||
return false if x == 1 |
return false if x == 1 |
||
break if x == n - 1 |
break if x == n - 1 |
||
Line 4,439: | Line 4,429: | ||
puts miller_rabin_prime?(103130593592068072608023213244858971741946977638988649427937324034014356815504971087381663169829571046157738503075005527471064224791270584831779395959349442093395294980019731027051356344056416276026592333932610954020105156667883269888206386119513058400355612571198438511950152690467372712488391425876725831041,1000) |
puts miller_rabin_prime?(103130593592068072608023213244858971741946977638988649427937324034014356815504971087381663169829571046157738503075005527471064224791270584831779395959349442093395294980019731027051356344056416276026592333932610954020105156667883269888206386119513058400355612571198438511950152690467372712488391425876725831041,1000) |
||
</lang> |
</lang> |
||
===Deterministic for integers < 3,317,044,064,679,887,385,961,981=== |
|||
⚫ | |||
=== This is a correct M-R test implementation for using bases > input. === |
|||
⚫ | |||
==== It is deterministic for all integers < 3_317_044_064_679_887_385_961_981.==== |
|||
==== Increase 'primes' array members for more "confidence" past this value. ==== |
|||
<lang ruby> |
<lang ruby> |
||
require "openssl" # for fast n.to_bn.mod_exp(exponent, modulus) method |
|||
class Integer |
class Integer |
||
# Returns true if +self+ is a prime number, else returns false. |
# Returns true if +self+ is a prime number, else returns false. |
||
def primemr? |
def primemr? |
||
Line 4,461: | Line 4,444: | ||
miller_rabin_test(witnesses) |
miller_rabin_test(witnesses) |
||
end |
end |
||
private |
private |
||
# Returns true if +self+ passes Miller-Rabin Test with witness bases +b+ |
# Returns true if +self+ passes Miller-Rabin Test with witness bases +b+ |
||
Line 4,471: | Line 4,454: | ||
next if (b % self) == 0 # **skip base if a multiple of input** |
next if (b % self) == 0 # **skip base if a multiple of input** |
||
s = d |
s = d |
||
y = b. |
y = b.pow(d, self) # y = (b**d) mod self |
||
until s == n || y == 1 || y == neg_one_mod |
until s == n || y == 1 || y == neg_one_mod |
||
y = y. |
y = y.pow(2, self) # y = (y**2) mod self |
||
s <<= 1 |
s <<= 1 |
||
end |
end |
||
Line 4,480: | Line 4,463: | ||
true |
true |
||
end |
end |
||
# Best known deterministic witnesses for given range and set of bases |
# Best known deterministic witnesses for given range and set of bases |
||
# https://miller-rabin.appspot.com/ |
# https://miller-rabin.appspot.com/ |